fpga-open-speech-tools / simulink_models

Simulink models for speech and audio processing
MIT License
4 stars 4 forks source link

Noise suppression model discussion #33

Closed audiologic-vannoy closed 4 years ago

audiologic-vannoy commented 4 years ago

This noise suppression algorithm is based off the following paper: Speech enhancement with an adaptive Wiener filter.

The basic gist of the algorithm is as follows: we assume the statistics of the noise, then we measure the mean and variance of the signal on a sample-by-sample basis using a sliding window; the enhanced signal is a weighted combination, based upon the signal and noise statistics, of the signal and the signal's mean.

Hardware Implementation

The software implementation of the algorithm, found in the MATLAB_scripts folder, is fairly straight-forward. A simple translation to a hardware implementation would use a circular buffer to store a window of incoming samples, then compute the mean and variance on those samples every time a new sample comes in. My initial thoughts were that doing this would require reading the samples out of the circular buffer at a higher clock rate in order to compute the statistics before the next sample comes in, which I didn't want to do.

I ended up implementing exponential moving average/variance, as they can be computed online, require minimal storage, and can be implemented as first-order IIR filters; however, these are approximations to the mean and variance, and I don't know what the error bounds are.

The Simulink version does indeed suppress noise, but it does not match the output of the MATLAB version that implements the algorithm in the paper. The output amplitude of the Simulink model is much smaller; I'm not sure why that is. I wouldn't expect the Simulink and Matlab versions to match perfectly since I'm using approximate calculations for mean and variance in the Simulink model. comparison

Any thoughts on where the amplitude difference might be coming from? I'm not convinced that my Simulink implementation is correct. If either of you have time give the model a quick look, that would be helpful.

I've attached audio files so you can listen to the difference between the Simulink and Matlab versions. noise_suppression_audio.zip

Additional Features/Improvements?

The noise suppression model is quite simple at this point, and doesn't have any control elements besides turning it on an off. It also assumes the noise variance, which is unrealistic in a real-world scenario.

Here are some improvements I'm thinking we could add:

Any other ideas or thoughts on the ideas proposed above?

tvannoy commented 4 years ago

I have fixed the amplitude issue in the previous post. The outputs now match pretty well. The main issue now is that the exponential moving variance seems to overestimate the variance during periods of silence.

The algorithm sets the variance to 0 if it is less than the a priori noise variance. The algorithm is as follows: y[n] = mean + (variance / (variance + noise variance)) * (x[n] - mean) Setting the variance to 0 when it is less than the noise variance makes the estimated signal equal to the mean, which makes sense as that's pretty much the best guess we have when the noise is very high.

The problem here is that the exponential moving variance is often higher than the noise variance during periods of silence because it is an overestimate. This causes excess noise during periods of silence compared to the MATLAB algorithm that uses the normal variance calculation.

I could change the ratio/threshold that sets the variance to 0, e.g. variance < 1.5 * noise variance to solve this, but that seems pretty arbitrary.

Maybe there is still something wrong in my implementation of the exponential moving variance.

audiologic-vannoy commented 4 years ago

Now the model is not meeting timing closure

audiologic-vannoy commented 4 years ago

Issues are all fixed now. Thanks for all the help!!!!!!