Matlab 消除wav文件上的噪声

Matlab 消除wav文件上的噪声,matlab,filtering,signal-processing,Matlab,Filtering,Signal Processing,我正在编写一个小代码来学习Matlab上的信号处理。我有一个带有一些噪音的.wav声音,我只想消除噪音。我在下尝试了该代码,但未正确删除噪音。我的想法是做一个剪切带滤波器来去除fft上的不同噪声成分。经过大量的研究,我不知道我的问题在哪里。这是我的代码: clear all; clc; close all; % We load and plot the signal [sig,Fs] = audioread('11.wav'); N = length(sig); figure,plot(s

我正在编写一个小代码来学习Matlab上的信号处理。我有一个带有一些噪音的.wav声音,我只想消除噪音。我在下尝试了该代码,但未正确删除噪音。我的想法是做一个剪切带滤波器来去除fft上的不同噪声成分。经过大量的研究,我不知道我的问题在哪里。这是我的代码:

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轴上有一个修改:

采样频率为Fs=22050


提前感谢您的帮助,我希望我的描述足够清楚

,因为您没有明确说明,您提供的代码基本上将噪声定义为两个频率下的窄带干扰(即使该干扰看起来“噪声”较小)

首先要注意的是,从
max(fft\u sig)
获得的
x(i)
值对应于所定位的最大值的基于1的索引。对于较大的
N
,它不会产生很大的差异,但对于较小的值,它可能会产生影响,尤其是在尝试设计非常窄的陷波滤波器时。相应的频率为:

freq =  (x(i)-1) * (Fs/N);
此外,如果要迭代衰减频率分量,则需要更新用于拾取要衰减的频率分量的
fft_sig
(否则将始终拾取相同的分量)。最简单的方法是从过滤后的
sig
重新计算
fft\u 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轴。

尝试使用“freqz”查看滤波器的外观。你想建立一个陷波滤波器。如果您有dsp工具箱,则可以使用“iirnotch”,这可能是规范化的问题
fir1
要求单位为rad/sec,您还没有考虑到这一点。您还可以丢弃
fft
输出的后半部分,因为它只是前半部分的镜像(否则可能会破坏峰值分量检测方案)。关于峰值分量检测,目前为止,每次调用max(fft_sig)都会返回相同的精确分量,而每次迭代都需要它来输出下一个最大分量。最重要的是,用对数标度绘制幅值!