2015-09-20 247 views
0

我正在研究一個小的代碼來學習Matlab上的信號處理。我收到了一些帶有噪音的.wav聲音,我只是想消除噪音。我嘗試了下面的代碼,但沒有正確刪除噪音。我的想法是做一個切帶濾波器去除fft上的不同噪聲成分。經過大量研究,我不明白我的問題在哪裏。在這裏我的代碼:去除wav文件上的噪音

clear all; 
clc; 
close all; 

% We load and plot the signal 
[sig,Fs] = audioread('11.wav'); 

N = length(sig); 

figure,plot(sig); title 'signal' 

% FFT of the signal 
fft_sig = abs(fft(sig)); 

% Normalisation of the frequencies for the plot 
k = 0 : length(sig) - 1; 
f = k*Fs/length(sig); 

plot(f,fft_sig); 

% Loop with 2 elements because there are 2 amplitudes (not sure about 
% this) 
for i = 1:2 

% I put noise components in an array 
[y(i),x(i)] = max(fft_sig); 

% Normalisation of the frequencies to eliminate 
f(i) = x(i) * (Fs/N); 

% Cut band filter with elimination of f from f-20 to f+20 Hz 
b = fir1(2 , 2 * [f(i)-20 f(i)+20]/Fs, 'stop') 

sig = filter(b,1,sig); 

figure,plot(abs(fft(sig)));title 'fft of the signal' 

end 

在這裏,我得到了圖像,FFT圖正是之前和應用過濾器後是相同的,只有在X軸上的修改:

enter image description here

enter image description here

enter image description here

的採樣頻率是Fs的= 22050.

預先感謝您的幫助,我希望我在我的描述

+0

嘗試使用'freqz'來查看您的過濾器的樣子。你想建立一個陷波濾波器。如果你有dsp工具箱,你可以使用'iirnotch' – crowdedComputeeer

+0

這可能是你的規範化問題。 'fir1'的單位爲rad/sec,你沒有在這個地方考慮​​過。您也可以丟棄'fft'輸出的後半部分,因爲它僅僅是前半部分的鏡像(否則這可能會影響峯值分量檢測方案)。關於峯值分量檢測,現在您對max(fft_sig)的調用將每次返回相同的精確分量,而您需要它在每次迭代時輸出下一個最大分量。 – Falimond

+0

什麼是最重要的 - 繪製對數級別的大小! – jojek

回答

0

不夠清楚你既然沒有明確這麼說,你所提供的代碼基本上是在兩個頻率的噪音定義窄帶干擾(儘管干擾可能看起來不那麼「嘈雜」)。

要注意的第一點是,從max(fft_sig)獲得的值x(i)對應於基於1 索引所定位的最大的。它不會對大型N產生巨大影響,但它可能會影響較小的值,特別是在嘗試設計非常窄的陷波濾波器時。那麼相應的頻率將是:

freq = (x(i)-1) * (Fs/N); 

此外,如果你要反覆地衰減頻率組件,您將需要更新fft_sig您使用挑頻率分量衰減(否則你始終會選擇相同的組件)。最簡單的是從過濾sig重新計算fft_sig

sig = filter(b,1,sig); 
fft_sig = abs(fft(sig)); 

最後,因爲你正試圖削弱一個很窄的頻率範圍內,你可能會發現,你需要通過一些命令來增加FIR濾波器的階大小,以期望的頻率獲得良好的衰減,而不會衰減其他任何部分。正如在評論中指出的那樣,使用IIR濾波器通常可以更好地實現這種窄陷波濾波器。

更新的代碼將隨後看起來有點像:

% Loop with 2 elements because there are 2 amplitudes 
for i = 1:2 

    % I put noise components in an array 
    % Limit peak search to the lower-half of the spectrum since the 
    % upper half is symmetric 
    [y(i),x(i)] = max(fft_sig(1:floor(N/2)+1)); 

    % Normalisation of the frequencies to eliminate 
    freq = (x(i)-1) * (Fs/N); 

    % Cut band filter with elimination of f from f-20 to f+20 Hz 
    b = fir1(2000 , 2 * [freq-20 freq+20]/Fs, 'stop') 

    sig = filter(b,1,sig); 
    fft_sig = abs(fft(sig)); 

    %figure;plot(f, abs(fft_sig));title 'fft of the signal' 
    figure;plot(f, 20*log10(abs(fft_sig)));title 'fft of the signal' 
end 

至於呈現出不同的x軸的最後FFT圖,它僅僅是因爲你省略以提供x軸變量(在發生f),因此該圖顯示數組索引(而不是頻率)作爲x軸。