同样的音符,不同的声音:我最初测错的那次
三种频率为528 Hz的波形虽然测量的是同一个音符,听起来却截然不同。在追查原因的过程中,我发现了一个本不该存在的数值,而我最初的测量结果也是错误的。
同时播放频率相同的正弦波和方波,没有人会把它们混淆。一个声音柔和,另一个则刺耳。然而,如果你问乐器正在演奏的是哪个音符,它两次给出的答案都是一样的。
这一差距正是本题的核心所在。它还让我发现了一个数值——根据理论,这个数值本不该存在——而我对该数值的首轮测量结果是错误的,这种错误值得特别指出,而不是悄悄修正。
音符不等于声音
在 Python 中生成三个频率为 528 Hz 的波形——正弦波、方波和三角波——并对每个波形进行 FFT 分析。三者的基频均显示为 528.00 Hz。从音高来看,它们完全相同。
不同之处在于基频之上的所有成分。一个周期性波形可以表示为由基频的整数倍组成的普通正弦波叠加。这些倍频就是谐波,而哪些谐波存在以及它们的强度如何,正是人耳所感知到的音色。
对于方波,有一条古老而具体的规律:只有奇次谐波会保留下来,且每个谐波所携带的基波振幅比例等于其次数的倒数。第三次谐波的振幅为基波振幅的三分之一,第五次谐波的振幅为基波振幅的五分之一。
根据我自己的文件测得:
| Harmonic | Predicted | Measured |
|---|---|---|
| 3rd | −9.5 dB | −9.5 dB |
| 5th | −14.0 dB | −14.0 dB |
| 7th | −16.9 dB | −16.9 dB |
| 9th | −19.1 dB | −19.1 dB |
该规则在小数点后一位上也成立。这部分很简单。
本应为零的数字
同一条规则指出,偶数次谐波应该完全不存在。不是微量,而是完全不存在。
它们并非不存在。第二谐波比基频低75.9 dB——约为六千分之一。微弱、不可闻,但并非零。理论上应为零。
最明显的嫌疑对象是测量仪器。事实并非如此:在纯正弦波上进行相同的测量时,同一量程的读数低了238 dB,这纯粹是数字本身产生的算术噪声。该仪器能够检测到比这小得多的信号。
真正的答案是,采样后的方波根本不会以528 Hz的频率重复。
计算频率与采样率的最大公约数:gcd(528, 44100) = 12。 采样模式每秒仅重复十二次,因此变换所看到的并非纯净的谐波列,而是一把梳状谱,每隔 12 Hz 出现一条谱线。其中一些梳状谱线位于谐波应出现的位置附近,而其中一条正是出现在偶数频窗中的信号。
我哪里搞错了
视频花了不少时间在这一部分,因为这是大多数频道都会剪掉的部分。
我对该偶次谐波的首次测量结果为 −67.3 dB,我便将其记录为答案。
这并不是答案。我曾在预期频率周围宽度约为±14 Hz的窗口内搜索峰值,认为稍大的容差应该能容纳误差。但梳状谱线的间隔是12 Hz。 如此宽的窗口必然会包含相邻的梳状谱线,而该谱线的幅度比我实际想要测量的谐波还要大。测量结果如实报告了窗口内最强的信号,而我却误将其当作我想要测量的对象。
在确切的频段上测得的正确数值(而非附近最响的声音)是−75.9 dB。比我最初记录的数值要安静8.5分贝。
本文的启示不仅限于此文件:容差范围并非没有代价。为了安全起见而扩大容差范围,反而会使测量结果更可能回答一个与你所问不同的问题。如果你要从这篇文章中汲取一个实用经验,那就记住这一点吧。
把窗户开大一点后,发现情况更糟了
一旦我不再局限于狭隘的解读,而是放眼全局,便发现了一个更大的伪影,而它与梳状线毫无关系。
方波永远存在谐波。高于采样率一半的所有频率都无法被准确表示,最终会折返到可听范围内。 在较高音高时,即使不进行任何分析也能听出这一点:生成一个3000 Hz的方波,其下方会存在一个音高中本不存在的低音。这就是第十五次谐波,频率为45 kHz,折返至900 Hz——比实际发出的音低两个八度。
回到528 Hz时,最响的折叠点位于**−33 dB**处。这比我一直在追踪的偶次谐波伪影高出四十分贝。我之前称之为“伪影”的那个,其实并不是最大的那个。
以下两项测试证实,这确实是折叠现象,而非其他情况:
每当采样率翻倍,折叠值就会下降6分贝,每次都是如此。 −33、−39、−45、−51。这并非偶然:当第一个谐波不再符合条件时,其数值会翻倍;而根据“1/n”规则,频率翻倍的谐波音量会降低6分贝。
利用完全吻合的正弦波构建相同的形状——既没有无穷级数,也没有会产生混叠的边缘——这样噪声水平就会降至比原始值低236分贝,重新回到算术噪声的范围。
音色绝非以下三者
**不是那个音符。**这三个音形频率均为528.00 Hz。询问乐器正在演奏什么,它会连续三次给出相同的答案。
**并非响度。**在峰值高度相同的情况下,方波的能量比正弦波多出约3 dB。这是事实,但这只是峰值因子的差异——即相同能量在峰值处的密集程度——而非谐波会增加响度的证据。 若以能量为基准将两者进行匹配,方波自身的基频会比正弦波低约1 dB:能量相同,但分布在更多的阶次上。
**并非质量问题。**这里没有任何一种音形比另一种更丰富、更纯粹或更适合你。 我们所测量的,是能量在音阶上的分布——正方形对应六个数值,三角形对应六个不同的数值,二者底层都基于同一个音高。这就是对稳定音调的完整描述,也是物理学所能支持的全部论点。而真实的乐器在演奏过程中也会发生变化,这则是另一个问题。
试一试,并查看确切的二进制文件
四行代码。以528 Hz的频率、每秒44,100个采样点构建一个方波,对其进行FFT变换,并分别读取基频3倍和2倍处的电平值。
请读取确切的频段,而不是它附近最响的声音,否则你会重蹈我的覆辙。你应该在奇数频段处测得−9.5 dB,而在偶数频段处则应比其低约76 dB。
然后改变频率并重新运行。无论频率在100 Hz到1000 Hz之间的任何位置,−9.5都不会发生变化,因为这是一条定律。 偶数值一定会发生偏移,而且你可以在运行之前预测其位置:计算该频率与44,100的最大公约数,该数值即为采样网格所增加的所有间隔值。
上述两处更正均已反映在视频的发布版本中。将错误数值与正确数值并列公布并非谦虚;这是除提出该测量结果的人之外,其他人能够核查该测量结果的唯一途径。
参考文献
此处的内容属于信号处理的基础理论,而非临床证据:离散傅里叶变换及其频点网格(numpy.fft)、频谱泄漏与窗函数分辨率、奈奎斯特极限与混叠,以及方波的傅里叶级数及其“1/n”奇次谐波振幅。 使用 numpy 实现;配套视频中展示了测量脚本及其输出结果。
关于音频信号处理的教育内容。本内容不构成医疗建议。
Listen · FFT-verified session 同样的音符,不同的声音:我最初测错的那次 Watch on YouTube →