wiener filter not able to cancel noise

5 次查看(过去 30 天)
I am performing noise cancellation using Wiener filter for a project. The project statement is "to record our voice and take it as desired signal, add a noise, use wiener filter to estimate the previously added noise and finally plot the mean square error and estimated signal". So far, the algorithm looks correct but i am still not able to extract the filtered desired signal properly. The final output is the same as input(desired signal+noise).
d = desired signal
v1 = added noise
v2 = secondary noise which is to be approximated to v1 using wiener filter
appx = the final cleaned signal (should contain only my desired signal)
clc;
close all;
%taking the recorded signal as d
[d, fs] = audioread('ADSP recording .m4a');
%taking noisy signal 2 (v2 in Monson hayes diagram) as g
n=length(d);
v2=0.5*randn(n,2);
p=20;
v2filt=filter(1, [1 -0.5] ,v2);
%%randn(1,n) is noisy signal 1 (v1) as per monson hayes diagram. we want to
% to approximate v1 using v2
v1=0.1*randn(n,2);
x=d+v1;
Rv1=covar(v2filt,p) ;
rxv=convm(x,p)'*convm(v2filt,p)/(n-1);
w=rxv(1,:)/Rv1;
v1hat=filter(w,1,v2filt);
appx=x-v1hat;
error=mse(d-appx);
%frequency domain mse
P = periodogram(d-appx,[],[],fs);
Hmss = dspdata.msspectrum(P,'Fs',fs,'spectrumtype','onesided');
%display
subplot(5,1,1),plot(d);
title('desired signal:');
subplot(5,1,2),plot(x);
title('desired + noise signal:');
subplot(5,1,3),plot(v1hat);
title('estimated signal:');
subplot(5,1,4),plot(appx);
title('Noise-removed signal');
subplot(5,1,5),plot(Hmss);
%title('frequency domain mean square error signal');

回答(1 个)

Paras Gupta
Paras Gupta 2023-9-4
Hi,
I understand that you are trying to perform noise cancellation using Wiener Filter. The provided code does not consider the correlation between the noise in the primary and the secondary sensers (v1 and v2). Consequently, the final signal does not match the desired signal.
Please refer to updated code below to perform noise cancellation using Wiener Filter.
clc;
close all;
%taking the recorded signal as d
[d, fs] = audioread('sound.mp3');
%taking noisy signal 2 (v2 in Monson hayes diagram) as g
n=length(d);
v2=0.5*randn(n,2);
p=20;
v2filt=filter(1, [1 -0.5] ,v2);
%%randn(1,n) is noisy signal 1 (v1) as per monson hayes diagram. we want to
% to approximate v1 using v2
%%%%%%%%%%%%%%
% v1=0.1*randn(n,2);
% Creating another random signal will make v1 and v2filt uncorrelated
% Generating v1 from the initial created random signal v2
v1=filter(1, [1 -0.1] ,v2);
%%%%%%%%%%%%%%
x=d+v1;
Rv1=covar(v2filt,p) ;
rxv=convm(x,p)'*convm(v2filt,p)/(n-1);
w=rxv(1,:)/Rv1;
v1hat=filter(w,1,v2filt);
appx=x-v1hat;
error=mse(d-appx);
%frequency domain mse
P = periodogram(d-appx,[],[],fs);
Hmss = dspdata.msspectrum(P,'Fs',fs,'spectrumtype','onesided');
%display
subplot(5,1,1),plot(d);
title('desired signal:');
subplot(5,1,2),plot(x);
title('desired + noise signal:');
subplot(5,1,3),plot(v1hat);
title('estimated signal:');
subplot(5,1,4),plot(appx);
title('Noise-removed signal');
subplot(5,1,5),plot(Hmss);
%title('frequency domain mean square error signal');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% Defining convm and covar functions
function y = convm(x, p)
% Generate a convolution matrix of signal x with given order p
N = length(x);
y = zeros(N-p, p+1);
for n = p+1:N
y(n-p, :) = x(n:-1:n-p);
end
end
function R = covar(x, p)
% Compute the covariance matrix of signal x using the given order p
N = length(x);
R = zeros(p+1, p+1);
for n = p+1:N
x_p = x(n-p:n);
R = R + x_p' * x_p;
end
R = R / (N - p);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The output of the code for a sample audio file has been shown below.
Hope this helps.

类别

Help CenterFile Exchange 中查找有关 Audio I/O and Waveform Generation 的更多信息

产品


版本

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by