欢迎来到 Sonic Pi 的核心逻辑世界。既然你已经具备识读五线谱的能力,并且熟悉基础的和弦进行,那么掌握 Sonic Pi 对你来说将非常快——你只需要完成一次思维上的“翻译”。
在传统的五线谱(Staff Notation)中,你是在告诉演奏者“看这里,弹这个音”。但在 Sonic Pi 中,你的角色从“作曲家”变成了“指挥家兼程序员”。计算机是世界上最听话但也最死板的演奏者,它不会自己感悟“这里应该慢一点”或“这里应该悲伤一点”,你必须用精确的数字告诉它。
本章的目标是立一种直觉映射:
release 参数;我们将学会如何精确地控制时间与频率,这是通往“精确配乐”的第一步。
在 Sonic Pi 中,音高主要有两种表示法:MIDI 编号和音名符号。对于习惯读谱的你,音名符号是最直观的,但理解 MIDI 编号对后续做“转调算法”非常有用。
Sonic Pi 遵循标准的国际音高记法。中央 C(Middle C)在五线谱上是高音谱表的下加一线,在 Sonic Pi 代码中是 :c4。
五线谱位置 音名(Sonic Pi) MIDI 编号 备注
-----------------------------------------------------------------------
(高音谱表上加一线) :a5 81 人声高音区极限附近
|
(高音谱表第三间) :c5 72 高音区
|
(高音谱表下加一线) :c4 60 中央 C
|
(低音谱表第二间) :c3 48 大提琴/男低音常用区
|
(低音谱表下加二线) :c2 36 低音贝司/电影Sub区
Sonic Pi 使用 s (sharp, $\sharp$) 代表升号,b (flat, $\flat$) 代表降号。
虽然 :ds4 (D$\sharp$4) 和 :eb4 (E$\flat$4) 在物理频率上完全一样(MIDI 均为 63),但在代码写作中,建议严格遵循调号逻辑。
:fs:ebRule of Thumb (经验法则):调号可读性 如果你在写一首 c 小调(3 个降号:Bb, Eb, Ab)的曲子,请务必在代码中使用
:bb,:eb,:ab,而不要混用:as或:ds。 当三个月后你回头看代码时,看到:eb你会立刻反应出“这是三级音”,看到:ds你会困惑“这是升二级音?我要离调了吗?”。
华语戏腔和蓝调音乐中,常出现“不到半音”的微小音高变化。Sonic Pi 的 MIDI 值支持浮点数。
:c4 = 6060.5 = C4 与 C#4 正中间的音。
这对模拟滑音(Glissando)和老唱片的走调感至关重要(后续章节详述)。这是 Sonic Pi 与 DAW(数字音频工作站)最大的思维差异点。
核心命令是 sleep。它控制的是“音头到下一个音头的时间距离”(Onset to Onset),而不是音符本身的持续时间。
默认情况下,我们将 sleep 1 视为 一拍(One Beat / 四分音符)。
音符名称 五线谱形状 Sonic Pi 代码 (sleep)
-------------------------------------------------------
全音符 空心圆 sleep 4
二分音符 空心加符干 sleep 2
四分音符 实心加符干 sleep 1
八分音符 单符尾 sleep 0.5
十六分音符 双符尾 sleep 0.25
三十二分音符 三符尾 sleep 0.125
附点代表“延长原时值的一半”。
sleep 1.5sleep 0.75古风节奏 Tip: 古风旋律中极常用
sleep 1.5紧接sleep 0.5(附点),或者sleep 0.75紧接sleep 0.25(小附点)。这种“长短交替”产生了独特的吟唱感。
Hans Zimmer 的动作配乐(如《蝙蝠侠》《盗梦空间》)大量依赖 三连音 (Triplets) 和 五连音 (Quintuplets) 来制造这种“一直在奔跑”的滚动感。
在数学上,三连音将标准时值平均分为 3 份。
sleep 0.33!
$0.33 \times 3 = 0.99$。每过一个小节,你的节奏就会快 0.01 拍。100 个小节后,你的鼓点就会和旋律完全错开(Phase Drift)。sleep 1.0 / 3 (注意 1.0 这种写法强制使用浮点运算)。# Zimmer 式 12/8 拍感觉的 Action Strings
3.times do
play :c3
sleep 1.0 / 3 # 极其精确的三分这一拍
end
在五线谱上,音符的时值决定了多长;但在 Sonic Pi 里,sleep 只决定什么时候开始下一个音,release: 参数决定这个音响多久。
这是新手最容易混淆的地方:
play :c4, release: 0.1 接着 sleep 1play :c4, release: 1.0 接着 sleep 1配器直觉:
- 古风笛子:通常是 Legato,
release甚至要比sleep稍微长一点点(如release: 1.1),制造混响和重叠的连绵感。- 动作片弦乐:通常是 Staccato,
release极短(0.1-0.2),哪怕sleep是 0.5,也要留出空气感,这样才“有劲”。
Sonic Pi 默认没有“小节”的概念。如果你写 6/8 拍,你需要自己用代码结构来体现。
4/4 拍结:
live_loop :beat_44 do
4.times do # 明确的 4 拍结构
play :c2
sleep 1
end
end
6/8 拍结构(两组 3 拍):
live_loop :beat_68 do
2.times do # 两个大拍
play :c2, amp: 1.0 # 强拍
sleep 0.5
play :c2, amp: 0.5 # 弱
sleep 0.5
play :c2, amp: 0.5 # 弱
sleep 0.5
end
end
:c4 格式,遵循调号逻辑选用 :fs 或 :gb。sleep 是“间隔”,不是“音长”。release 是“音长”。release 短于 sleep = 断奏;release 等于或长于 sleep = 连奏。1.0/3 处理三连音,拒绝 0.33。目标:熟悉 MIDI 音名与降号。
题目C 小调(自然小调)的音是 C, D, Eb, F, G, Ab, Bb, C。请写出上行音阶,速度为四分音符。
要求:必须使用降号标记(:eb, :ab…),不可以使用升号。
目标:构建进行曲或史诗感的骨架。
题目:模拟《星球大战》或类似进行曲的开头节奏:| 强(1.5拍) - 弱(0.5拍) | 强(1.5拍) - 弱(0.5拍) |。
提示:使用 amp: 区分强弱。
目标:学会“留白”。 题目:写出以下谱面:| C4(1拍) | (休止1拍) | E4(0.5拍) | G4(0.5拍) | (休止1拍) | 总共 4 拍。
目标:体验 Hans Zimmer 在《邓刻尔克》或《沙丘》中常用的非常规拍号带来的焦虑感。 题目:构造一个 5/4 拍的循环(总时长 5)。 结构:3 个四分音符 + 4 个八分音符。 挑战:在最后一个八分音符上加上重音(amp: 1.2),其余为 amp: 0.6。
目标:古风引子(Intro)通常没有严格节拍,称为“散板”。
题目:写一句笛子旋律,要求音符之间的 sleep 不是固定的,而是具有微小的随机性,模拟人的随意吹奏。
提示:使用 rrand(min, max) 函数来生成随机时值。例如 sleep rrand(0.8, 1.2)。
目标:用代码控制“情感”。 题目:在一个循环中,先播放 4 个断奏(Staccato)的 C4,再播放 4 个连奏(Legato)的 C4。 要求:
release 时间必须小于 0.2。release 时间必须大于等于 1.0。sleep 1)。这是程序员最熟悉但音乐人最易崩溃的坑。 在 Ruby (Sonic Pi 的底层语言) 中:
1 / 3 等于 0 (整数除以整数,结果只保留整数部分)。1.0 / 3 等于 0.333333...。现象:你写了 sleep 1/2,想表达八分音符,结果声音像机关枪一样重叠爆发(因为 sleep 变成了 0)。
解决:永远在分子或分母上加个 .0。习惯写 sleep 0.5 而不是 1/2,写 1.0/3 而不是 1/3。
release 导致的“糊成一团”现象:你的古风旋律听起来很浑浊,像是在混响巨大的浴室里弹快板。
原因:你可能设置了很长的 release(例如默认的 release 可能是 1),但你在写快速的十六分音符(sleep 0.25)。前一个音还没消失,后三个音就叠上去了。
解决:快节奏配短 release,慢节奏配长 release。
现象:你从外部复制了一段代码,行时报错 Unexpected end 或缩进极其混乱。
原因:Sonic Pi 对代码块 do ... end 的配对要求严格。
解决:善用快捷键 Alt + Shift + F (Windows) 或 Cmd + Shift + F (Mac) 自动美化/对齐代码。如果对齐后发现最后少了一个 end,那就是因为你少复制了。