Removing noise from audio using Fourier transform in Matlab

I'm trying to remove noise from an audio file. This audio file contains speech as well as constant pink noise. I know that I have to use the Fourier transform to convert to the frequency domain then use a filter to filter out the frequencies of the pink noise, but I really don't know where to start with that. It also seems that the noise covers many more frequencies than the speech file (I have the speech and noise files separately) by looking at the plots in the frequency domain.

Doesn't that mean that if I filter out the frequencies of the noise it'll remove all the speech as well?

The plot of the speech audio in the frequency domain displays that the frequencies are mostly between -450 and 450.

The plot of the noise alone in the frequency domain displays that the frequencies are between -2000 and 2000. This clearly covers a much wider range of frequencies than the speech audio.

Does this mean I can't remove it from the noisy speech audio without removing the speech too? Or can I remove the frequencies outside of -450 and 450 and that would remove much of the noise? If so, how do I compute the range of frequencies instead of looking at plots myself to see the range?

• You don't really need to do this in the frequency domain. The information-carrying parts of speech are typically in the range 100 Hz - 3 kHz so you could just implement a simple bandpass filter. May 8, 2013 at 15:31

From my experience, your best bet is spectral subtraction. You can find a lot of literature about it on the web. Here just a quick overview of what you need to do. You take overlapping windowed blocks of your time domain signal and transform them to the frequency domain using an FFT. Then for each frequency bin you need to estimate the signal-to-noise ratio. There are several simple noise tracking algorithms that perform well if the noise is relatively stationary. Based on the estimated SNR per frequency bin you mulitply each bin with a gain constant between 0 (terrible SNR) and 1 (no noise). Note that you only deal with magnitudes, the phase of the FFT is left unchanged. After modifying the FFT bins with the gain factors, you combine the processed bins back to the time domain using the phase of the original noisy signal.

Here is a classic paper on this subject. It goes a bit further than pure spectral subtraction but the overall system is the same. Don't worry too much about the math involved to derive the optimal gain function.

You can filter out everything that's below a certain threshold.

Here's a quick approach (I didn't test the code):

1. Calculate the FFT of the samples:

 fft_values = fft(samples); 

1. Get the mean value and calculate a threshold:

 mean_value = mean(abs(fft)); threshold = 1.1*mean_value; % Fine-tune this 

1. Remove everything that's below the threshold (we assume that it corresponds to noise):

 fft_values[abs(fft_values) < threshold] = 0; 

1. Get the filtered samples:

 filtered_samples = ifft(fft_values); 

That's a starting point. You could use sliding windows for better filtering.

• Thanks that does help in learning how remove frequencies outside thresholds. I made a few changes to this but unfortunately it doesn't help much in terms of removing the noise and making the speech easier to hear. Is this just because the noise is too loud and covers too many frequencies and in actual fact noise like this can't really be removed easily? May 8, 2013 at 16:45
• See this answer as to why it is not generally advisable to filter a signal by simply zeroing its FFT bins. dsp.stackexchange.com/questions/6220/… May 8, 2013 at 20:23
• @user2362591: I can't say for sure but I think it is really hard to make speech clearer as in more intelligible. I don't think there is any published techniques (if such even exists). You can improve the quality of the speech by e.g. spectral subtraction (I don't recommend the bandpass filter suggested unless MIPS is crucial). However, because you can work offline and you know that noise is stationary and pink it may be possible to come up with something that works better than the plain spectral subtraction. May 9, 2013 at 19:10