【音頻處理】如何“認識”一個濾波器?

Introduction

對一段音頻信號進行處理,例如添加一個音效,有時候我們要考慮這樣的處理對音頻的影響是什麼?是提高了低頻,還是提高高頻?或者頻率做週期變化?

當然,你完全可以用耳朵來聽,但是這麼做難度太大了,畢竟並不是每個人都有一副金耳朵。即使你的耳朵非常好使,能夠分辨最爲細微的差別,但是你如何用人類能夠理解的方式描述這種區別呢?畢竟並不是每個人都有莫言般的描述能力。

綜上,我們需要一種可以量化的方式來描述”處理“的過程。毋庸置疑,我們只能藉助數學來描述這種複雜過程。這篇文章中,我們將以多個視角來觀察”處理“過程。

一些知識鋪墊

下面介紹一些基礎的信號處理知識,並不會很詳細,都是點到爲止,目的是將整體內容串起來,形成自我閉環。更多深入的介紹,大家有興趣的話找本 dsp 的書來看吧。

信號表示

首先,如何表示一個音頻信號(我們只討論離散信號)?很簡單,我們用一個數組來描述它,一個長度爲 N 的信號,可以表示爲:
x[0],x[1],...,x[N1](1) x[0],x[1],...,x[N-1] \tag{1}
我們稱 x[n] 爲離散時間序列

單位脈衝信號

它的數學表示是這樣的:
δ(n)={1n = 00otherwise(2)\delta(n)= \begin{cases} 1& \text{n = 0} \\ 0& \text{otherwise} \end{cases} \tag{2}
也就是長這樣:δ(n)=[1,0,0,0,...,0]\delta(n) = [1,0,0,0,...,0]

線性時不變濾波器

所謂濾波器,其實就是對信號”操作“:一個信號,經過濾波器,變成了另一個信號。我們這裏關注的是線性時不變(Linearity and time-invariance; LTI)濾波器。LTI濾波器應用廣泛,是濾波器家族中最爲壯大的一簇。我們可以差分方程來表示一個 LTI 濾波器:
y[n]=b0x[n]+b1x[n1]+...+bnx[nN]a1y[n1]...aMy[nM](3) y[n] = b_0x[n] + b_1x[n-1] + ... + b_nx[n-N]- a_1y[n-1] - ... a_My[n-M] \tag{3}
其中 x 爲輸入序列,y爲輸出序列。b0,...,bNb_0,...,b_Na0,...,aNa_0,...,a_N 爲係數。

脈衝響應

將單位脈衝信號輸入到一個 LTI 濾波器中得到的結果,我們稱之爲脈衝響應,通常表示爲h(n)h(n)

卷積

信號x(n)x(n)經過 LTI 濾波器後得到 y(n)y(n),這個過程可以表示爲脈衝響應h(n)h(n)x(n)x(n)的卷積:
y(n)=(hx)(n)(4) y(n) = (h*x)(n) \tag{4}

Z 變換

接下來我們介紹下 Z 變換,它非常重要。

Z變換可將離散時間序列變換爲在複頻域的表達式。額…好吧,前面那句話是百度百科抄的,對於那些從沒有接觸過 Z 變換的同學而言,這句話簡直了。我們還是通過具體的例子,從感性的角度來理解下它。

Z變換的公式很簡單的,如下:
X(z)=n=0x[n]zn(5) X(z) = \sum_{n=0}^{\infty}x[n]z^{-n} \tag{5}

舉個例子,離散時間序列爲:x[0]=1, x[1]=2, x[2]=3,那麼:
X(z)=1+2z1+3z2=1+2z1+3(z1)2 X(z) = 1 + 2z^{-1} + 3z^{-2} = 1 + 2z^{-1} + 3(z^{-1})^2

通過 Z變換,我們將一組序列(N個值)轉換爲一個關於z的表達式(一個值)。
Z變換可以看成是線性變換,就比如上面的例子,可以改寫爲兩個向量相乘:
[1z1z2][123]=[1+2z1+3(z1)2] \begin{bmatrix} 1 & z^{-1} & z^{-2} \end{bmatrix} \begin{bmatrix} 1\\ 2\\ 3 \end{bmatrix} = \begin{bmatrix} 1 + 2z^{-1} + 3(z^{-1})^2 \end{bmatrix}

關於 Z變換有一個重要的性質,卷積。兩個信號在時域上做卷積,等於在 z變換域中相乘
x0[n]x1[n]=X0(z)X1(z)(6) x_0[n]*x_1[n] = X_0(z)X_1(z) \tag{6}

在前面提到,信號經過濾波器可以表示爲卷積過程(5),那麼對y(n)y(n)進行Z變化得到:
Y(z)=H(z)X(z)(7) Y(z)=H(z)X(z) \tag{7}
從這個公式的角度來看,Y(z)Y(z)其實是X(z)X(z)進行了一次線性變換得到的,其中 H(z)H(z) 被我們成爲 傳遞函數(Transfer function; TF)
H(z)=Y(z)X(z)(8) H(z)=\frac{Y(z)}{X(z)} \tag{8}
上面的公式同時表明,脈衝響應h(n)h(n)的Z變化 等於 轉換方程 H(z)=Y(z)/X(z)H(z)=Y(z)/X(z)。這也是求 h(n)h(n) 的一種方法,通過計算 H(z)H(z),然後做 z變換的逆變換,求得 h(n)h(n)

關於 Z 變換還有一些性質我們需要掌握:
Z{x1[n]+x2[n]}=Z{x1[n]}+Z{x2[n]}=X1(z)+X2(z)(9) Z\{x_1[n] + x_2[n]\} = Z\{x_1[n]\} + Z\{x_2[n]\} = X_1(z) + X_2(z) \tag{9}

Z{ax[n]}=aZ{x[n]}=aX(z)(10) Z\{ax[n]\} = aZ\{x[n]\} = aX(z) \tag{10}

Z{x[n1]}=n=x[n1]zn=z1n=x[n1]z(n1)=z1Z{x[n]}=z1X(z)(11) \begin{aligned} Z\{x[n-1]\} &= \sum_{n=-\infty}^{\infty} x[n-1]z^{-n} \\ &= z^{-1}\sum_{n=-\infty}^{\infty}x[n-1]z^{-(n-1)} \\ &= z^{-1}Z\{x[n]\} = z^{-1}X(z) \end{aligned} \tag{11}

因此對於一個 LTI 濾波器(3),我們對其進行 Z變換得到:
Y(z)=b0X(z)+b1z1X(z)+...+bnzNX(z)a1z1Y(Z)...aMzMY(z)(12) Y(z) = b_0X(z) + b_1z^{-1}X(z) + ... + b_nz^{-N}X(z)- a_1z^{-1}Y(Z) - ... a_Mz^{-M}Y(z) \tag{12}

合併同類項得:
(1+a1z1++aMzM)Y(z)=(b0+b1z1++bnzN)X(z) (1+a_1z^{-1}+\dots+a_Mz^{-M})Y(z) = (b_0+b_1z^{-1}+\dots+b_nz^{-N})X(z)

如果 MNM\ne N,我們添加一些 0 係數進去,讓左右兩邊的個數一直。

可得傳遞方程 H(z)H(z):
H(z)=Y(z)X(z)=b0+b1z1++bnzN1+a1z1++aNzN(13) H(z) = \frac{Y(z)}{X(z)} = \frac{b_0+b_1z^{-1}+\dots+b_nz^{-N}}{1+a_1z^{-1}+\dots+a_Nz^{-N}} \tag{13}

多角度描述一個濾波器

差分方程 Difference equation

如公式(3),這就是差分方程。讓我們舉兩個例子來感受下它。

y[n]=x[n]+0.5y[n1](14) y[n] = x[n] + 0.5y[n-1] \tag{14}

y[n]=x[n]+2y[n1](15) y[n] = x[n] + 2y[n-1] \tag{15}

將一個脈衝信號輸入至 (14) 中,可得脈衝響應h(n)=1,0.5,0.25,h(n) = 1,0.5,0.25,\dotsh(n)h(n)的值逐漸接近 0,我們這樣的濾波器是穩定的。

將一個脈衝信號輸入至 (15) 中,可得脈衝響應h(n)=1,2,4,8h(n) = 1,2,4,8\dotsh(n)h(n)的值逐漸無窮大,我們稱這樣的濾波器是不穩定的。

塊狀圖 Block diagram

有時候用圖形的形式來展示濾波器更加符合人類的認知過程,以公式(3)爲例,它的塊磚圖如下:
LTI塊狀圖

好吧,它看起比較複雜,我們看一個簡單的例子,延遲信號:
y[n]=x[n]+gx[nN] y[n] = x[n] + gx[n-N]
它的塊狀圖如下:
delay塊狀圖

脈衝響應 Impulse response

正如前面提到的那樣,將一個脈衝信號(公式(3))輸入至濾波器中,然後觀察輸出,就能得到脈衝響應。

例如有個濾波器爲:
y(n)=x(n)+0.53x(n3)0.95y(n5)(16) y(n) = x(n) + 0.5^3x(n-3) - 0.9^5y(n-5) \tag{16}

你可以用下面這段 MATLAB 代碼來畫出該濾波器的脈衝響應

g1 = 0.5^3;  B = [1 0 0 g1];      % Feedforward coeffs
g2 = 0.9^5;  A = [1 0 0 0 0 g2];  % Feedback coefficients

h = filter(B,A,[1,zeros(1,50)]);  % Impulse response
% h = impz(B,A,50); % alternative in octave-forge or MSPTB

% Matlab-compatible plot:
clf; figure(1); stem([0:50],h,'-k'); axis([0 50 -0.8 1.1]);
ylabel('Amplitude'); xlabel('Time (samples)'); grid;

impulse response

當然,我們還有更爲精確的計算 h(n)h(n) 的方法:對h(n)h(n) 進行 z變換可以得到傳遞函數 H(z)H(z),因此對 H(z)H(z) 做逆 z變化得到 h(n)h(n)

H(z)H(z)可以通過公式(13)得到,相當的容易。逆 z變換我還沒學會,所以沒法和大家解釋了。但是我們可以來驗證h(n)h(n)的z變換就是公式(13)的結果。

對公式(16)做z變換,得到傳遞方程:
H(z)=Y(z)X(z)=1+0.53z31+0.95z5 H(z) = \frac{Y(z)}{X(z)} = \frac{1+0.5^3z^{-3}}{1+0.9^5z^{-5}}

z=2z=2,可得 H(z)=1+0.53231+0.9525=0.9972H(z) = \frac{1+0.5^32^{-3}}{1+0.9^52^{-5}} = 0.9972

然後我們在代碼中計算 H(z) 的值,也是得到 0.9972,完全一致。

g1 = 0.5^3;  B = [1 0 0 g1];      % Feedforward coeffs
g2 = 0.9^5;  A = [1 0 0 0 0 g2];  % Feedback coefficients

h = filter(B,A,[1,zeros(1,50)]);  % Impulse response
z_value = 2;                      % z = 2
z = zeros(1,length(h)) + z_value; 
Z = z.^-(0:length(h)-1);
HZ = h*Z';                        %計算 H(z),結果爲 0.9972

傳遞方程 Transfer function

傳遞方程已經在上面說過了,對 h(n)h(n) 做z變換可以得到,也可用公式(13)得到。在分析 LTI 濾波器時,傳遞方程是一種重要的方法。

極點、零點及增益 Poles zeros gain

我們對公式(13)上下同時乘上 zNz^N,得到一組多項式,並因式分解
H(z)=b0zN+b1zN1++bnzN+a1zN1++aN=g(zq1)(zq2)(zqN)(zp1)(zp2)(zpN)(17) \begin{aligned} H(z) &= \frac{b_0z^{N}+b_1z^{N-1}+\dots+b_n}{z^N+a_1z^{N-1}+\dots+a_N} \\ &= g\frac{(z-q_1)(z-q_2)\dots(z-q_N)}{(z-p_1)(z-p_2)\dots(z-p_N)} \end{aligned} \tag{17}

我們稱 gg增益(Gain)

我們稱 p1,,pNp_1,\dots,p_N極點(Poles),當 zpz\in{p}H(z)=H(z) = \infty

我們稱 q1,,qNq_1,\dots,q_N零點(Zeros),當 zqz\in{q}H(z)=0H(z)=0

我們將所有極點和零點畫在一個複平面上,如果所有極點都在單位圓內,那麼濾波器是穩定的;如果所有零點在單位圓內,那麼我們稱這個濾波器是最小相位濾波器。

頻譜響應 Frequency Response

頻譜響應指的是,信號經過濾波器後,在頻域發生的變化,定義爲:輸出信號的頻譜除以輸入信號的頻譜

一個信號經過傅里葉變化(DTFT)便可以得到其頻譜信息:
DTFTω(x)=n=0x(n)ejωTn DTFT_{\omega(x)} = \sum_{n=0}^{\infty}x(n)e^{-j\omega Tn}

你看DTFT是不是很像 z變換?公式(5)中 z=ejωTz=e^{j\omega T},那麼就完美對應上了 DTFT。
又有 Y(z)=H(z)X(z)Y(z)=H(z)X(z),因此得到:
Y(ejωT)=H(ejωT)X(ejωT) Y(e^{j\omega T}) = H(e^{j\omega T})X(e^{j\omega T})

那麼頻譜響應其實就是
H(ejωT)=Y(ejωT)X(ejωT) H(e^{j\omega T}) = \frac{Y(e^{j\omega T}) }{X(e^{j\omega T})}

其中 T=f/fsT=f/f_s,其中ff爲信號頻率其範圍在 (0,fs/2)(0, f_s/2),因此 ωT(0,π)\omega T \in (0, \pi)

頻譜響應又分 幅度響應(Amplitude response)相位響應(Phase response)

幅度響應其實就是 $\vert H(e^{j\omega T})\vert $,取個絕對值就ok了。幅度響應能夠說明濾波器對每個頻率幅度的影響。

相位響應其實就是 H(ejωT)\angle H(e^{j\omega T}),它說明了濾波器對每個頻率相位的影響

實際的例子

千言萬語不如一個實際的例子,假設我們有這樣一個濾波器:
y[n]=4x[n]4x[n1]+x[n2]y[n1]y[n2]/2 y[n] = 4x[n]-4x[n-1] + x[n-2] - y[n-1] - y[n-2]/2

做z變換的:
Y(z)=4X(z)4X(z)z1+X(z)z2Y(z)z1Y(z)z2/2 Y(z) = 4X(z) - 4X(z)z^{-1} + X(z)z^{-2} - Y(z)z^{-1} - Y(z)z^{-2}/2
計算傳遞方程:
H(z)=Y(z)X(z)=4z24z+1z2+z+1/2 H(z) = \frac{Y(z)}{X(z)} = \frac{4z^2-4z+1}{z^2+z+1/2}

做因式分解
H(z)=4(z1/2)(z1/2)(z1+j2)(z1j2) H(z) = \frac{4(z-1/2)(z-1/2)}{(z-\frac{-1+j}{2})(z-\frac{-1-j}{2})}

得到兩個極點: (1+j)(-1+j)(1j)(-1-j)

得到兩個零點,它們都在 12\frac{1}{2},將它們畫在複平面上,可以發現所有極點都在單位圓內,因此這個濾波器是穩定的;所有零點都在單位圓內,因此它是最小相位的

z=ejωTz=e^{j\omega T}時,且ωT(0,π)\omega T\in (0, \pi),計算其幅度響應和相位響應,直接上代碼計算:

w = 0:0.001:pi;
E = exp(1j*w);

Hz = (4*(E.^2) - 4*E + 1) ./ ((E.^2) + E + 0.5);

amplitude_Hz = abs(Hz);
phase_Hz = angle(Hz);

figure(1);
plot(20*log10(amplitude_Hz));

figure(2);
plot(phase_Hz*180/pi);

其結果大概長這樣:

從圖可以看出,這個濾波器抑制信號中的低頻信息,增益高頻信息。在 0.785π0.785\pi(在 44.1kHz 採樣率下爲 17.3kHz)增益最大。
對於特別高和特別低的頻率信息,這個濾波器在相位上只有很小的影響。但是在 0.5π0.5\pi(在 44.1kHz 採樣率下爲 11.025kHz)處,其相位信息偏移了 116度

總結

本文介紹了多種方式來認識一個濾波器,

  • 差分方程
  • 塊狀圖
  • 脈衝響應
  • 傳遞方程
  • 極點、零點和增益
  • 頻譜響應

並列舉相關例子,讓大家有更爲深入的理解和體會。

轉載請註明出處 https://blog.csdn.net/weiwei9363/article/details/104950007

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章