Forums

Wiener filter with smoothed estimation of Noise

Started by stefanb August 2, 2007
Hello all,

I implemented a blockwise Wiener Filter with Matlab like this:

H = a_priori_SNR./(a_priori_SNR+1)

a_priori_SNR = S./N;

S = magnitude of fft of clean signal s; S= abs(fft(s)), of current block
N = magnitude of fft of noise  n;  N= abs(fft(n)), of current block
Y = magnitude of fft of noisy signal  y;  Y= abs(fft(y)), of current
block

Since in real life I have neither the signal nor the noise, I started with
estimating the noise by smoothing the actual noise over one block. I've
been told that I should also get pretty good results with it. But I dont.
For smoothing I tried both magnitude smoothing of noise and squared
magnitude smoothing:

N_smoothed = old_N*0.9 + N;
old_N = N;

S_smoothed = Y-N_smoothed;

where 
S_smoothed = estimation of the clean speech signal magnitude.
old_N      = magnitude of fft of noise n; of the last block


Now my question: 

When I calculate S_smoothed, I even get negative values which make no
sense to me since I try to estimate a magnitude. The same happens if I do
squared magnitude estimation the same way. 
I also squared the estimated N_smoothed and S_smoothed to calculate the a
priori SNR and then the wiener filter. But it all sounds pretty bad. I
used a noisy signal with SNR of 1.5 dB. Should I try to also smooth over
my estimation of clean speech?

best regards,

Stefan Bleiholder
On Aug 2, 6:17 am, "stefanb" <stefanb52-k...@yahoo.de> wrote:
> Hello all, > > I implemented a blockwise Wiener Filter with Matlab like this: > > H = a_priori_SNR./(a_priori_SNR+1) > > a_priori_SNR = S./N; > > S = magnitude of fft of clean signal s; S= abs(fft(s)), of current block > N = magnitude of fft of noise n; N= abs(fft(n)), of current block > Y = magnitude of fft of noisy signal y; Y= abs(fft(y)), of current > block > > Since in real life I have neither the signal nor the noise, I started with > estimating the noise by smoothing the actual noise over one block. I've > been told that I should also get pretty good results with it. But I dont. > For smoothing I tried both magnitude smoothing of noise and squared > magnitude smoothing: > > N_smoothed = old_N*0.9 + N; > old_N = N; > > S_smoothed = Y-N_smoothed; > > where > S_smoothed = estimation of the clean speech signal magnitude. > old_N = magnitude of fft of noise n; of the last block > > Now my question: > > When I calculate S_smoothed, I even get negative values which make no > sense to me since I try to estimate a magnitude. The same happens if I do > squared magnitude estimation the same way. > I also squared the estimated N_smoothed and S_smoothed to calculate the a > priori SNR and then the wiener filter. But it all sounds pretty bad. I > used a noisy signal with SNR of 1.5 dB. Should I try to also smooth over > my estimation of clean speech? > > best regards, > > Stefan Bleiholder
That's really the problem with actually using a Wiener filter; you have to have knowledge of the statistics of the filter input and how correlated it is with your desired signal. In your example, you're using finite-length FFTs to judge the noise and signal spectra; this will not give you consistent results (e.g. the fact that you calculated negative values for the signal magnitude). This just isn't the way to go about implementing a noise-removal filter. You could instead use an adaptive filter; an LMS filter is easy to implement and doesn't require much additional computation. Jason
>That's really the problem with actually using a Wiener filter; you >have to have knowledge of the statistics of the filter input and how >correlated it is with your desired signal. In your example, you're >using finite-length FFTs to judge the noise and signal spectra; this >will not give you consistent results (e.g. the fact that you >calculated negative values for the signal magnitude). This just isn't >the way to go about implementing a noise-removal filter. You could >instead use an adaptive filter; an LMS filter is easy to implement and >doesn't require much additional computation. > >Jason > >
Hello Jason, thank you for your time. I think my problem is not so much the Wiener Filter, or the estimation of the noise. My problem is when I implement the Wiener Filter as an Spectral Substraction. I do not get good results even when I dont smooth the noise ffts over one block. I mean when I subtract the magnitude of the actual noise, I get equally bad results. For example: S_estimated=abs(Y)-abs(N); gives me totally different results as: S_estimated2=abs(Y-N); I know the phase is different, but isnt this what spectral substraction says or something like this: S_qu = abs(Y).*abs(Y)-abs(N).*abs(N); I think this is where my problem is. The estimation of the clean speech from the estimation of the noise. best regards, Stefan