從《法證先鋒4》的一段劇情說起
在港劇《法證先鋒4》第9集中,有一段劇情是這樣的:家希的朋友Monica被網絡上的一段視訊誣陷送外賣上門,于是找到了聲紋專家做聲紋鑒别、出具專家報告,證明視訊中的聲音不屬于Monica。
至于具體的操作,劇中原話是這樣的:

MFCC(梅爾頻率倒譜系數)除了可以像劇中那樣用來做聲紋鑒定,更廣泛的用途是進行音樂風格分類、音樂檢索和語音識别等。那麼MFCC到底是什麼東西?
MFCC概述
梅爾頻率倒譜系數(Mel-scale Frequency Cepstral Coefficients,簡稱MFCC)是在Mel标度頻率域提取出來的倒譜參數。Mel标度描述了人耳頻率的非線性特性,它與頻率的關系可用下式近似表示:
式中f為頻率,機關為Hz。
MFCC提取過程及MATLAB實作
要得到一段音頻的MFCC,需要經過以下步驟:
接下來會給每個步驟的詳細介紹以及對應的MATLAB代碼。
0、讀取音頻
這一步比較簡單了,直接上代碼:
[
要注意的是,如果音頻檔案是雙聲道,可以轉換成單聲道進行處理。
1、預加重
将音頻信号通過一個高通濾波器,用來增強高頻資訊:
μ的取值在0.9-1.0之間,一般取為0.97。
代碼如下:
x
2、分幀
在前面提到過,MFCC是在Mel标度頻率域上提取出來的。Mel标度可以由頻率得到。如果我們直接對音頻進行傅裡葉變換,就隻能得到整段音頻的頻譜,沒辦法觀察頻譜随時間變化的情況。為此,我們需要把音頻切成一小段一小段,每一小段稱為一幀。之後再對每小段進行傅裡葉變換,這樣就可以得到随時間變化的頻譜了。每一段的頻譜拼起來就是所謂的“聲譜圖”(spectrogram)。
我們通常取20~30ms為一幀。假設聲音的采樣頻率為44.1kHz,一幀長20ms,那麼一幀的采樣點個數為44100*20/1000=882。為了保證兩幀聲音之間的差異不大,通常幀與幀之間還存在重疊部分。重疊部分占比稱為“重疊率”,一般為1/2~1/3。本文的MATLAB代碼取1/2。
分幀操作示意圖
這段代碼需要用到MATLAB的voicebox工具箱。
x
3、加窗
為了增加幀左端和右端的連續性,也為了避免頻譜洩露,需要對每一幀的音頻信号乘上窗函數。這個過程叫“加窗”。通常情況下窗函數選取的是“漢明窗”。假設N為幀的大小,漢明窗W(n)公式為
不同的a值會産生不同的漢明窗,一般情況下a取0.46。将a=0.46代入上式得:
具體代碼如下:
s
4、FFT(快速傅裡葉變換)
加窗後的音頻經過FFT後就可以得到頻譜。FFT可以由離散傅裡葉變換(DFT)的公式,利用周期性和對稱性的性質推導出來。這裡不再贅述。
順便說一句,
分幀、加窗、FFT這三個操作合起來是一種數字信号處理技術——
STFT(短時傅裡葉變換)。利用STFT可以觀察音頻在不同時間的頻率分布。
對音頻信号的頻譜取模平方得到語音信号的功率譜。在具體實作中,也可以對頻譜直接取絕對值而不作平方,這樣得到的是能量譜。本文的MATLAB代碼求得的是功率譜。
具體代碼如下:
t
5、通過Mel濾波器組
将功率譜通過一組Mel尺度的三角帶通濾波器組。這個濾波器組有M個三角帶通濾波器,它們的中心頻率為f(m),m=1,2,...,M。M通常取22-26,本文取24。各f(m)之間的間隔随着m值的減小而縮小,随着m值的增大而增寬,如圖所示:
Mel頻率濾波器組,圖中M=6
三角帶通濾波器有兩個主要目的:
對頻譜進行平滑化,并消除諧波的作用,突顯原先語音的共振峰。(是以一段語音的音調或音高,是不會呈現在 MFCC 參數内。在《法證先鋒4》中,也有相應的台詞說明這一點。)
生成Mel濾波器組的具體代碼如下:
bank
6、取對數
計算每個濾波器組輸出的對數能量,即子帶能量
這一步的MATLAB代碼和下一步的放在一起。
7.DCT(離散餘弦變換)
直接使用下列公式進行計算:
将第6步求得的結果代入離散餘弦變換,求出L個MFCC系數,L通常取12-16。本文取12。
6、7步具體代碼如下:
for
有的人可能會疑惑,為什麼功率譜有這麼多的點,隻取出1+floor(N/2)個點進行計算?其實這些點是功率譜的正半側(可以調用MATLAB的fftshift函數對功率譜進行處理後,再觀察),我們的Mel濾波器組隻需要正半側的資料。
這樣,最基本的12維MFCC的系數已經提取出來了。
完整MATLAB程式如下:
[
在此基礎上,後續還有倒譜提升公式、MFCC一階差分系數、MFCC二階差分系數等。這裡不再贅述。