MATLAB做滤波器

[复制链接]
2321|6
 楼主| gaoyang9992006 发表于 2017-8-23 19:13 | 显示全部楼层 |阅读模式
我們可以使用 butter 指令來設計一個 Butterworth 濾波器,範例如下:
  1. fs=8000;                % Sampling rate
  2. filterOrder=5;                % Order of filter
  3. cutOffFreq=1000;        % Cutoff frequency
  4. [b, a]=butter(filterOrder, cutOffFreq/(fs/2), 'low');
  5. % === Plot frequency response
  6. [h, w]=freqz(b, a);
  7. plot(w/pi*fs/2, abs(h), '.-'); title('Magnitude frequency response');
  8. grid on
butter01.png
在上述範例中,我們使用 butter 指令來設計一個 Butterworth 低通濾波器,其格式如下:
[b, a] = butter(order, Wn, function)
對於輸入參數,我們可以說明如下:
order 是濾波器的階數,階數越大,濾波效果越好,但是計算量也會跟著變大。所產生的濾波器參數 a 和 b 的長度,等於 order+1。
Wn 是正規化的截止頻率,介於 0 和 1 之間,當取樣頻率是 fs 時,所能處理的最高頻率是 fs/2,所以如果實際的截止頻率是 f = 1000,那麼 Wn = f/(fs/2)。
function 是一個字串,function = 'low' 代表是低通濾波器,function = 'high' 代表是高通濾波器。
上述範例所產生的四個圖形,事實上是同一個圖,只是分別在x軸或y軸使用對數刻度,所以造成不同的效果。這些圖都稱為濾波器的「頻率響應」(Frequency Response),顯示不同頻率的訊號經過此濾波器時,所乘上的衰減率。上述範例中,我們是要設計一個截止頻率為 1000 Hz 的濾波器,由頻率響應可以看出,這果然是一個低通濾波器。
當濾波器的階數越高時,,因為濾波器參數 a 和 b 的長度變長,濾波的效果越明顯,但是計算量也會跟著提高;反之,若階數越低,濾波器參數 a 和 b 的長度變短,計算量降低,但是濾波的效果也會變差,請見


 楼主| gaoyang9992006 发表于 2017-8-23 19:15 | 显示全部楼层
下列範例:
  1. fs=8000;                        % Sampling rate
  2. cutOffFreq=1000;                % Cutoff frequency
  3. allH=[];
  4. for filterOrder=1:8;
  5.         [b, a]=butter(filterOrder, cutOffFreq/(fs/2), 'low');
  6.         % === Plot frequency response
  7.         [h, w]=freqz(b, a);
  8.         allH=[allH, h];
  9. end
  10. plot(w/pi*fs/2, abs(allH)); title('Frequency response of a low-pass utterworth filter');
  11. legend('order=1', 'order=2', 'order=3', 'order=4', 'order=5', 'order=6', 'order=7', 'order=8');
butter02.png

在上述範例中,可以很明顯地看出,當階數由 1 慢慢增大成 8 時,濾波器的效果也會越來越明顯。
 楼主| gaoyang9992006 发表于 2017-8-23 19:17 | 显示全部楼层
我們可以將音訊通過截止頻率為 1000 Hz 的低通濾波器,看是否能夠把過濾高音,範例如下:
  1. cutOffFreq=1000;        % Cutoff frequency
  2. filterOrder=5;                % Order of filter
  3. au=myAudioRead('wubai_solicitude.wav');
  4. [b, a]=butter(filterOrder, cutOffFreq/(au.fs/2), 'low');
  5. au.signal=au.signal(60*au.fs:90*au.fs);        % 30-second signal
  6. y=filter(b, a, au.signal);
  7. % ====== Plot the result
  8. time=(1:length(au.signal))/au.fs;
  9. subplot(2,1,1);
  10. plot(time, au.signal);
  11. subplot(2,1,2);
  12. plot(time, y);
  13. % ====== Save output files
  14. myAudioWrite(au, 'wubai_solicitude_orig.wav');
  15. au.signal=y;
  16. myAudioWrite(au, sprintf('wubai_solicitude_%d.wav', cutOffFreq));
butter03.png
我們可以聽看看原訊號和濾波器輸出訊號的差異:
可以很明顯地聽到,高音部分都幾乎被刪除了。

 楼主| gaoyang9992006 发表于 2017-8-23 19:19 | 显示全部楼层
如果我們將截止頻率設定成 100 Hz,此時濾波器的訊號,就幾乎只能聽到低音鼓的聲音,範例如下:
  1. cutOffFreq=100;                % Cutoff freq (截止頻率)
  2. filterOrder=5;                % Order of filter (濾波器的階數)
  3. au=myAudioRead('wubai_solicitude.wav');
  4. [b, a]=butter(filterOrder, cutOffFreq/(au.fs/2), 'low');
  5. au.signal=au.signal(60*au.fs:90*au.fs);        % 30 seconds of singing (30 秒歌聲)
  6. y=filter(b, a, au.signal);
  7. % ====== Plotting (畫圖)
  8. time=(1:length(au.signal))/au.fs;
  9. subplot(2,1,1);
  10. plot(time, au.signal);
  11. subplot(2,1,2);
  12. plot(time, y);
  13. % ====== Save wav files (存檔)
  14. myAudioWrite(au, 'wubai_solicitude_orig.wav');
  15. au.signal=y;
  16. myAudioWrite(au, sprintf('wubai_solicitude_%d.wav', cutOffFreq));
butter04.png
很明顯地,經過了濾波器的作用,只留下低音鼓的聲音,而且由這些規律出現的低音鼓聲音,我們就可以進行節拍追蹤,找出這一段音樂的節拍。(當然,這只是一個開始,若要進行節拍追蹤,還有很多細節要處理。)
如果你還是聽不出來低音鼓在原來音樂的位置,可以嘗試逐次聽聽下列檔案(最好使用 CoolEdit 來聽,可以同步顯示播放進度),就應該可以慢慢抓到低音鼓的位置:



 楼主| gaoyang9992006 发表于 2017-8-23 19:21 | 显示全部楼层
大家试听完这个例子,是不是觉得好神奇。
dilidexiaomao 发表于 2018-6-8 15:02 | 显示全部楼层
总结的很到位
loloo 发表于 2018-6-25 17:05 | 显示全部楼层
简单明了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16405

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部