基频、音高与音分:算法究竟在追踪什么

“这段声音是多少赫兹”看似简单,实际包含声带振动、泛音结构、短时估计与人耳感知四个不同层次。

基频是重复周期,不是音色总和

当一个近似周期性的声音每秒重复 220 次,它的基础频率(F0)约为 220 Hz。人耳通常把这个周期感知为音高,但听到的信号并不只有 220 Hz:它还包含 440、660、880 Hz 等泛音,以及噪声和共振造成的能量起伏。

因此,两个人都唱 A3,基频可以接近,声音仍可能一个明亮、一个柔和。F0 回答“周期大致多快”,音色还要看泛音比例、频谱形状、共振和时间变化。

算法为什么要一帧一帧估计

说话的音高持续变化,算法会把音频切成互相重叠的短帧,在每帧中寻找最可能的周期。YIN 使用差分函数寻找周期候选,再通过插值细化;概率版 pYIN 会同时考虑多个候选和随时间连续性。短帧响应快但频率分辨率有限,长帧更稳定却会抹平快速变化。

CVoice 先尝试 YIN,在有效性不足时用 pYIN 补充;FrostNote 更重视低延迟,所以会结合连续帧和保持时间,而不是把一帧读数当作最终答案。

音分让比例差异变得可比较

十二平均律中,一个八度分成 1200 音分,一个半音是 100 音分。音分比较的是频率比例,不是简单相减:

音分差 = 1200 × log₂(测得频率 ÷ 目标频率)

这意味着 220 Hz 到 221 Hz 与 880 Hz 到 881 Hz 的听觉意义不同。FrostNote 使用目标附近约 ±25 音分作为成功区,是为了让不同音区使用一致的相对尺度。

为什么会跳到两倍或一半

如果第二泛音比基频更强,算法可能把 220 Hz 看成 440 Hz;如果周期结构允许更长的解释,也可能读成 110 Hz。这叫八度错误。气声、鼻音、哼鸣、房间共振、手机降噪和背景乐都会提高发生概率。

解决方法不是一味唱得更响:保持稳定元音、减少混响、避开伴奏、让麦克风不过载,并对连续多帧做中位数和跳变抑制,通常更有效。

读数应该怎样用

  • 看一段时间的中位数与变化范围,不迷信单帧峰值。
  • 区分 F0、音名和音色;它们相关,但不是同一个概念。
  • 比较录音时控制文本、设备和环境,否则变化不只来自发声。

应用延伸:FrostNote 用 F0 做即时音准训练;CVoice 只把 F0 作为八个声音方向之一。

参考资料