在合成器音乐系统中,12-TET(十二平均律)虽标准化,但限制了微分音(microtonal)探索,如纯律(just intonation)或历史调律(meantone)。工程化精确微分音阶需可靠序列化格式,Scala 的 .scl 纯文本格式已成为事实标准:人类可读、跨平台,支持 cents(音分)或分数比(ratio)表示间隔,便于从 12-TET 基准偏离。相比二进制格式,其优势在于版本控制友好、易调试,且兼容众多 VST/AU 合成器如 Surge、Vital 和 Pigments。
.scl 格式核心规则简洁高效:文件以 ASCII 文本存储,一文件一音阶。第一行(非注释)为描述,如“1/4-comma meantone scale”;第二行为音符数 N(0~无上限,实际建议<1000避免解析开销);后续 N 行每行一间隔值。若含小数点则为 cents(如 76.04900),否则为 ratio(如 5/4),整数视作“X/1”(如 2 为 2/1)。以 ! 开头行忽略为注释,首音 1/1(0 cents)隐式省略。负值无效,分子/分母上限 2^31-1,确保高精度。[1] 示例文件(meanquar.scl):
! meanquar.scl
1/4-comma meantone scale. Pietro Aaron's temperament (1523)
12
76.04900
193.15686
310.26471
5/4
503.42157
579.47057
696.57843
25/16
889.73529
1006.84314
1082.89214
2/1
此 12 音阶累计至 1200 cents(八度),每个值相对 1/1 偏差。工程中,优先用 cents 表示精确浮点偏差,便于计算:cents = 1200 * log2(ratio)。从 12-TET 偏离时,计算公式为 target_cents - (note % 12 * 100),如 C#4(12-TET 350 cents)在 meantone 中偏至 310.26471 cents,偏差 -39.73529 cents,实现“甜美”三和弦。
落地参数设计需考虑精度与兼容:cents 小数位≥5 位(0.001 cents ~1Hz@A440),避免舍入误差;ratio 化简至最低项(如 10/20→1/2),但保留原值解析后检查。验证清单:
- 解析校验:读文件,跳 ! 行;第2非空行转 int 为 N;后续 N 行提取首 token,若含 '.' 则 float(cents),else ratio(a/b)→1200*log2(a/b),累计偏差<1e-6。
- 八度闭合:第 N 值 ≈1200 cents(容差±0.01),否则重标。
- 单调递增:间隔 i < i+1,防倒挂。
- 基准锚定:可选 A4=440Hz,计算 freq[i] = 440 * 2^(cum_cents[i]/1200),生成 tun 文件。
- 键盘映射:配 .kbm 文件定义 MIDI 键→音阶度数,避免 12-TET 限制(如 19-EDO 用 19 键/八度)。
合成器集成直观:Surge/Vital 等原生载入 .scl,触发全键盘重调;MTS(MIDI Tuning Standard)兼容器用 Scala 导出 SysEx dump(单音/八度/通道)。参数阈值:弯音范围±2音(MIDI CC1/弯曲),超时重载<50ms;监控点包括音高偏差直方图(目标<5 cents RMS)、CPU 占用(解析<1ms/文件)。回滚策略:fallback 至 12-TET,日志“scl_load_failed”。
实际工程案例:构建 31-TET(每音≈38.71 cents),文件:
31-TET from 12-TET detune
31
38.70968
77.41935
116.12903
154.83871
...
1200.00000
加载至 Pigments,detune 参数从 12-TET 均匀分布偏离,生成“波奈丽”泛音簇。风险:大 N (>256) 增延迟,限 128;非 Latin-1 编码乱码,用 UTF-8 fallback。参数调优:合成器分辨率≥0.01 cents(如 Hydrasynth),否则近似 ratio。
此格式工程化微分音的核心在于参数化偏差清单:从理论(如 Euler-Fokker genera)生成 cents 序列,经验证后序列化,便于 A/B 测试与迭代。最终,.scl 桥接理论与实时合成,实现超越 12-TET 的精确调律系统。
资料来源:
[1] https://huygens-fokker.org/scala/scl_format.html “If the value contains a period, it is a cents value, otherwise a ratio.”
[2] https://huygens-fokker.org/scala/ Scala 主页,支持 100+ 合成器导出。