概念
在數字信號處理過程中,每次FFT變換只能對有限長度的時域數據進行變換,因此,需要對時域信號進行信號截斷。即使是周期信號,如果截斷的時間長度不是周期的整數倍(周期截斷),那么,截取后的信號將會存在泄漏。為了將這個泄漏誤差減少到最小程度(注意我說是的減少,而不是消除),我們需要使用加權函數,也叫窗函數。加窗主要是為了使時域信號似乎更好地滿足FFT處理的周期性要求,減少泄漏。這里面,有很多窗函數可以使用,不過,每種窗函數的使用場景是不同的。由於直接對信號(加矩形窗)截斷會產生頻率泄露,為了改善頻率泄露的情況,加非矩形窗,一般都是加漢明窗,因為漢明窗的幅頻特性是旁瓣衰減較大,主瓣峰值與第一個旁瓣峰值衰減可達40db。
原理
hamming窗函數其實很簡單。可以使用一個公式來表示:
當 a0=0.53836 ,稱作 Hamming窗;當 a0=0.5 則叫作 Hann窗。
Hann窗又稱升余弦窗。Hann窗可以看作是3個矩形時間窗的頻譜之和,或者說是 3個 sinc(t) 型函數之和,而括號中的兩項相對於第一個譜窗向左、右各移動了π/T,從而使旁瓣互相抵消,消去高頻干擾和漏能。
從減小泄漏觀點出發,Hann窗優於矩形窗。但Hann窗主瓣加寬,相當於分析帶寬加寬,頻率分辨力下降。
如果我們將a0設為接近 0.53836 的數值,或是更精確來說是 25/46,便會得到Hamming窗,而設定這個數值的用意,是在頻率為 5π/(N − 1) 處產生零交會處(zero-crossing),使原先Hann窗的第一個旁瓣(sidelobe)可以被大幅消除,產生只有Hann窗 1/5 高度的旁瓣。
一般來說,為了減少運算量,可以把公式精簡為:
在matlab中,這個是非常容易實現的,只需要一個語句,就可以把漢明窗的數值求出來:
L = 64;
wvtool(hamming(L))
順便可以看到它的頻響曲線:
實例分析
這里給出一個matlab的音頻處理例子,給大家一個直觀的印象:
[x, fs] = audioread('mic1_data.wav'); N=256; %設置短時傅里葉變換的長度,同時也是漢明窗的長度 h=hamming(N); %設置漢明窗 sprintf("%d",h); for m=1:N %用漢明窗截取信號,長度為N,主要是為了減少截斷引起的柵欄效應等 b(m)=x(m)*h(m) end for mm=1:N y1(mm)=x(mm) end ya=20*log(abs(fft(y1))) %做傅里葉變換,取其模值,即幅頻特性,然后用分貝(dB)表示 subplot(2,1,1), %分配畫布,一幅圖上共兩個圖,這是第一個 plot(ya);title('original signal'); %畫出原始信號,即前面這個音頻信號的原始波形 grid %添加網格線 y=20*log(abs(fft(b))) %做傅里葉變換,取其模值,即幅頻特性,然后用分貝(dB)表示 subplot(2,1,2) %分配畫布,第二副圖 plot(y);title('hamming added signal'); %畫出短時譜 grid
運算結果:
備忘
在音頻處理領域,漢明窗應用十分廣泛,希望這里能給大家一些解惑。