全系音色合成器
① 现代器乐物理原理分类(声学 DSP 模型)
② 周礼八音体系(金、石、丝、竹、匏、土、革、木)
③ 十二平均律阶梯键盘 (三个八度 · 36半音)
一、 音色合成与十二平均律核心数学模型
1. 音色数学模型(傅里叶级数加时变包络):
音色(Timbre)由复合声波的泛音频谱比率 $r_k$ 与时变能量包络 $A_k(t)$ 共同决定:
$$x(t) = \sum_{k=1}^{N} A_k(t) \cdot \sin(2\pi \cdot r_k f_0 \cdot t + \phi_k) +
\mathcal{F}_{\text{filter}}(\text{Noise}(t))$$
2. 十二平均律与自然大调音程数学机理(全全半全全全半):
十二平均律将一个八度(倍频程)等比分成 12 个半音,相邻半音的公比为 $\sqrt[12]{2} \approx 1.05946$:
$$f_n = f_{\text{base}} \times 2^{\frac{n}{12}} \quad (n \in [0, 11] \text{ 为半音序号})$$
“全全半全全全半”是自然大调(Major Scale)中相邻两个自然音级之间的音程步进(Interval Step):
- 全音(Whole Step,跨 2 个半音):频率比为 $(\sqrt[12]{2})^2 = 2^{\frac{2}{12}} \approx 1.1225$,对应步进:$C \to D$、$D \to E$、$F \to G$、$G \to A$、$A \to B$。
- 半音(Half Step,跨 1 个半音):频率比为 $2^{\frac{1}{12}} \approx 1.0595$,对应步进:自然大调中无黑键阻隔的 $E \to F$ 以及 $B \to C’$。
二、 核心代码架构与 Web Audio API 编程原理
程序采用原生 Web Audio API 构建实时音频拓扑图(Audio Graph),其信号处理链路如下:
【声源振荡器】OscillatorNode (Sine/Sawtooth/Square) $\to$ $f = f_0 \times r_k$
$\downarrow$
【时域包络】GainNode (ADSR 时变包络计算) $\to$ setValueAtTime / exponentialRampToValueAtTime
$\downarrow$
【频响雕刻】BiquadFilterNode (低通 Lowpass / 峰值 Peaking) $\to$ 模拟共鸣箱与阻尼
$\downarrow$
【总线输出】Master GainNode $\to$ AudioDestinationNode (声卡扬声器)
1. 频率与音阶计算代码实现:
// 遍历每个半音,通过 Math.pow(2, nIdx / 12) 严格实现十二平均律频率换算
const freq = oct.baseC * Math.pow(2, nIdx / 12);
2. 时域包络(ADSR)指数衰减代码实现:
// 利用 GainNode 的时间调度精确绘制能量起振 (Attack) 与指数耗散 (Decay &
Release)
g.gain.setValueAtTime(0.0001, t);
g.gain.linearRampToValueAtTime(h.a, t + a); // 线性起振:A(t) =
a * (t / a)
g.gain.exponentialRampToValueAtTime(0.0001, t + a +
d + r); // 指数衰减:A(t) = A_0 * e^(-alpha * t)
3. 加法合成 vs 减法合成代码控制流:
if (p.model === “subtractive”)
{
// 减法合成:生成富谐波母波 (Sawtooth) $\to$ 串联 BiquadFilter 动态滤波削切
osc.type = p.wave || ‘sawtooth’;
osc.connect(gainNode); gainNode.connect(filterNode);
} else {
// 加法合成:并发派生 N 个 OscillatorNode 并行振荡,加权相加到 master 输出总线
p.harmonics.forEach(h => {
const osc = ctx.createOscillator();
osc.frequency.setValueAtTime(freq * h.r, t);
osc.connect(g); g.connect(out);
});
}
三、 现代器乐声学 6 大类的数学与代码映射
纯音 (Sine) 电鸣基底
$$x(t) = A(t)\sin(2\pi f_0 t)$$
代码实现:harmonics: [{ r: 1.0, a: 1.0 }]。单频简谐波,无泛音成分,频域表现为单一脉冲冲激 $\delta(f – f_0)$。
击弦 (String) 一维弦振动
$$\frac{\partial^2 y}{\partial t^2} = c^2 \frac{\partial^2 y}{\partial x^2}
\implies r_k = k \ (k \in \mathbb{N}^+)$$
代码实现:r: [1.0, 2.0, 3.0, 4.0] + lowpass: 4000Hz。两端固定边界导出完整整数谐波列,能量呈反比衰减 $A_k \propto 1/k$。
木管 (Woodwind) 闭管奇次谐波
$$r_k = 2m – 1 \implies r_k \in \{1, 3, 5, 7\dots\}$$
代码实现:r: [1.0, 3.0, 5.0, 7.0] + attack: 0.08s。一端开一端闭的管内驻波共振,偶次谐波相互抵消,呈现空灵木质感。
铜管 (Brass) 减法合成与滤波
$$x_{\text{saw}}(t) \xrightarrow{\text{IIR Filter}} H(z) = \frac{b_0 + b_1
z^{-1} + b_2 z^{-2}}{1 + a_1 z^{-1} + a_2 z^{-2}}$$
代码实现:wave: "sawtooth" + lowpass: 2800Hz, Q: 2.0。全阶锯齿波通过二阶低通滤波器动态衰减高频成分。
钟鸣 (Bell) 非谐波厚壳振动
$$r_k \notin \mathbb{Z} \implies r_k \in \{1.0, 2.01, 3.0, 4.16\}$$
代码实现:引入 $2.01f_0$ 与 $4.16f_0$ 微失谐泛音。三维刚体弹性壳偏微分方程的非整数特征值,引入金属拍频干涉。
打击 (Percussion) 膜鸣贝塞尔解
$$\nabla^2 u = \frac{1}{c^2}\frac{\partial^2 u}{\partial t^2} \implies
J_m(\alpha_{m,n}) = 0$$
代码实现:r: [0.5, 1.0, 1.73] + decay: 0.2s +
lowpass: 400Hz。二维圆膜振动由贝塞尔函数零点决定,能量集中在超低频且衰减极快。
四、 周礼八音体系的物理与代码映射
金 · 编钟 合瓦双振模
$$f_{\text{main}} = f_0, \ f_{\text{side}} = 1.20 f_0$$
代码实现:内置 r: 1.2 侧鼓音 + decay: 4.0s 长衰减 +
lowpass: 3000Hz。正鼓音与侧鼓音双特征值共存。
石 · 特磬 板弯曲振动
$$r_k \in \{1.0, 2.5, 4.2\}, \ t_{\text{attack}} = 0.003\text{s}$$
代码实现:r: [1.0, 2.5, 4.2] +
attack: 0.003s。欧拉-伯努利板振动,泛音稀疏跨度大,高频能量快速耗散。
丝 · 琴瑟 张弦拍频干涉
$$\sin(\omega t) + \sin(1.002\omega t) = 2\cos(0.001\omega
t)\sin(1.001\omega t)$$
代码实现:r: 1.002 + peaking: 3200Hz, +6dB。微失谐干涉产生周期揉弦拍频,3.2kHz 处设箱体共鸣峰。
竹 · 箫笛 边棱管鸣与笛膜
$$r_k \in \{1, 3, 5\}, \ \text{Peaking}(2500\text{Hz}, +7\text{dB})$$
代码实现:奇次谐波 + attack: 0.12s 气流慢建立 + peaking: 2500Hz, +7dB 笛膜非线性共鸣。
匏 · 笙簧 自由簧管偶合
$$x(t) = \sum \text{Sawtooth}(2\pi \cdot \{1.0, 1.25, 1.5, 2.0\} f_0 t)$$
代码实现:wave: "sawtooth" +
r: [1.0, 1.25, 1.5, 2.0]。簧片脉冲列内置大三度与纯五度耦合和鸣矩阵。
土 · 陶埙 亥姆霍兹共振
$$f_{\text{res}} = \frac{v}{2\pi}\sqrt{\frac{S}{V L’}}, \ r_k \in \{1.0,
2.0, 0.5\}$$
代码实现:基频占 70% + r: 0.5 低八度暗音 + lowpass: 2200Hz。空腔吸收高次谐波,基频圆润空灵。
革 · 建鼓 膜受迫振动
$$r_k \in \{0.25, 0.45, 0.8\}, \ \text{Lowpass}(250\text{Hz})$$
代码实现:r: [0.25, 0.45, 0.8] + decay: 0.45s +
lowpass: 250Hz。超低频下潜与空气弹簧阻尼爆破。
木 · 雅柷 刚体强阻尼
$$x_{\text{sqr}}(t) \cdot e^{-\alpha t}, \ \alpha \ge 25 \ (\text{Decay}
\le 0.12\text{s})$$
代码实现:wave: "square" +
decay: 0.12s, release: 0.02s。实心方木碰撞,方波谐波伴随极短时域截断。