基頻、音高與音分:演算法究竟在追蹤什麼

「這段聲音是多少赫茲」看起來很簡單,實際上卻包含聲帶振動、泛音結構、短時間估算與人耳感知四個不同層次。

基頻是重複週期,不是音色的總和

當一個近似週期性的聲音每秒重複 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 當作八個聲音方向之一。

參考資料