# 风格：八音盒

> 这是 anidoodle 最初的音乐配方，留在下面是为了它的**声音**数值（`musicBox` 和 `bell` 两件乐器实现了这些数值）和它的伤疤故事（守卫为什么存在）。它是 `engine/src/canvas-core/music/vocab.ts`（`VOCAB.musicBox`）里众多词汇中的一种风格，不是默认值：根本没有默认风格。它原先那些写死的作曲选择（一个和弦进行、一个音阶、一个伴奏音型）在下面已改写成范围：音符由作曲者来写（[../compose.md](../compose.md)）。它的禁用清单只是**这个**风格的规矩；对其他风格，这些禁令变成了可测量的守卫。

---

# 音乐配方

> 这套规矩是做 MECHANICAL LEPIDOPTERA 时换来的，那部片就是 [example/](../../../example/index.md) 里的完整示例。下面每一条规则都是在那部影片上付过代价的；凡是错误出在导演自己身上的，都照实说了，因为带着伤疤的规则，人们才会一直守着。

**错误。** 用代码做音乐是这个 skill 里最难的事，因为做的人听不见它。我的需求说明要一个八音盒，「提出一个问题，在五度音上不解决地结束」，要一个滴答声「渐渐稀薄成毡垫般的轻颤」，还要「从起飞开始铺一层弓弦铺底」。这些单拿出来都是好句子，合在一起却正是客户所说的「鬼在哭」的配方：缓慢的起音、持续的长音、一个悬了十八秒的乐句、混响。这不是谁的 bug。这是一份形容词 brief，形容词 brief 产出的是氛围，而合成出来的氛围就是鬼屋。

**规则：绝不说「把它做好」。照下面这份交付。**

**禁用，全部，永远：** 小调和小调式；任何持续的铺底、弓弦或吹奏的长音、持续音（drone）或超低音；超过 10 ms 的起音时间；混响尾巴、反馈延迟、卷积；失谐、滑音、颤音；用滤波噪声做的「风声」或渐强；一个乐句悬着不解决超过四小节；音乐开始后任何一处超过一拍的完全无声。

**乐器：八音盒 / 钢片琴拨奏。** 每个频率为 `f` 的音：

- 分音：`f` 处正弦波增益 1.0，`2f` 0.35，`3f` 0.12，再加一个约在 `5.4f`、增益 0.08 的敲击「叮」声，60 ms 内消失；
- 包络：2 ms 线性起音，然后纯指数衰减，没有持续段。时间常数 `tau = 0.45 * sqrt(440 / f)` 秒，所以高音短而闪亮，低音会多响一小会儿；
- 力度：强拍 1.0，其他 0.7，装饰音 0.45。
- 贝斯：同样的拨奏，低一到两个八度，只取前两个分音，增益 0.5。它仍然是拨奏。它永远不持续。
- 「房间」：**一个**早期反射，晚 30 ms，低 14 dB。没有尾巴。

**调、音区、和声。** 按情绪选任何大调、利底亚、多利亚或小调都行（小调八音盒是一种真实存在的、诡异的声音）。旋律在 C5 到 C7 之间，贝斯 C3 到 G3。和声节奏是每小节一个和弦；和弦进行由你定（变格和阻碍式的转折效果好；原片用了最朴素的进行，还说「别搞得更聪明」，那是一个选择，不是规则）。要在高潮回报处抬一下，就把调升高一级。

**旋律。** 和弦音加上调式音阶，多用级进，跳进时落在和弦音上。四小节乐句成对出现：**问句**结束在主音以外的音上，**答句**落在主音上，**而且答句紧接着出现。** 用你自己的动机，带着它自己的节奏。

**节奏。** 在 120 bpm、30 fps 下，一拍是 15 帧，一个平直八分音符是 7.5 帧，而这个帧数并不存在。改用三连音八分音符，5 帧：也就是 12/8，八音盒本来就这么弹。伴奏是你在三连音上设计的琶音音型（自己选和弦音的顺序和循环长度；在 3 音一组上叠一个 4 音单元，会形成柔和的三对二交错（hemiola））；旋律多数落在拍上。每个起音都是 cue 表里的一行，带着它的**帧号**，模块加载时断言每个采样索引都等于 `round(frame / fps * sampleRate)`。

**音效轻轻地叠在上面：** 「滴」是一段 2 ms 的噪声脉冲，过一个 3 kHz 的带通，「嗒」在 2 kHz，都比旋律低 20 dB。一次落地就是落在它那一拍上的一个轻柔拨奏。**叮**是主音上的一记钟声（分音 1、2、3、4.2，tau 1.2 s，低八度加倍），放在最后一个强拍上，后面至少还要有四拍的影片。

**不靠铺底做起伏。** 一幕接一幕：只有旋律；加贝斯；加琶音；加高八度的闪光；钟声。音更多，绝不是音更长。

**母带。** 归一化到峰值 -3 dBFS，用 `tanh` 软削波，RMS 接近 -18 dBFS。

**验证，因为你是聋的。** 把配乐打印成文字，逐小节写出音名和和弦，让人能读。从**解码后**的文件测量：峰值、每小节 RMS、最长静音和频谱质心（明亮的拨奏配乐远高于 1.5 kHz；数字接近 400 Hz 说明有铺底混进来了）。然后是唯一算数的测试：**给影片配乐之前，先发一段 8 秒的小样给客户。** 它就是音乐的定调静帧。我们跳过了这一步，结果配了六十秒的错东西。

---

## 这里哪些验证过，哪些没有

写下这套规矩时导演就标注过，因为至今仍然适用，所以原样沿用：上面「哪里出了错」的依据是**客户对渲染结果的描述**，加上导演自己的需求说明，而那份说明要的恰恰就是她点名的那些成分。导演自己也听不见。**合成参数是一个好的起点，不是定死的答案**——在新影片上信任它们之前，先找一个人听一遍确认。

相关的 `doodle-film` skill 给配乐的建议（每次重复时把循环往下失谐一点、一段静默加一个心跳底鼓）是为怅惘的影片调的，和上面好几条禁令相矛盾。两者都没错；它们针对不同的情绪。挑之前先说清你要的是哪种情绪。
