# How to de-noise raw sound data

What techniques/algorithms can I use to remove noise from a raw recording of sound (voice)?

The purpose is to get a smoother graph (removing the "jaggedness"). What I have tried was to average-out small deviations by using the surrounding two values to either side, but ended up with distorted sound. What better way is there to "smooth-out" the graph?

• So is your goal in all this to simply produce a graphic representation of the sound, or do you have some other purpose in mind? Aug 19, 2012 at 14:10
• @DanielRHicks: ambitious goal is to isolate phonetic-sounds for home-grown voice-recognition exercise ... Aug 19, 2012 at 17:07
• In that case going directly to an FFT may be the simplest approach. You can then just ignore FFT bands outside of your range of interest. Aug 19, 2012 at 23:55

For what you intend to do, a low-pass filter is the way to go. Your statement about filtering frequencies vs filtering amplitudes is incorrect. Your signal contains many components at many frequencies, the amplitude of which varies in time, and the high frequency components are those causing the "jaggedness" and you want to get rid of them. Not sure why you say your signal is "constant frequency" - maybe you are getting confused by the sample rate?

What you have tried (averaging) is indeed a special case of low-pass filtering, but one with a frequency response far from being ideal. You should try a properly designed IIR or FIR filter. In particular, the FIR filter is not very different from what you tried - this is just a weighted combination of the samples neighboring each sample. But the choice of the coefficients is important and ensures that only unwanted components are eliminated. Note that an FFT is not the way to go. This question crops up here quite frequently under different forms, but in short - FFT, messing with coefficients, IFFT - is a bad idea.

By design, the output of a moving average filter (what you implemented) has less energy than the input. It is thus impossible for a moving average filter to cause distortion. If the input signal is in the [-1, 1] range, there is no way for an averaging filter to yield values outside this range. The "distorted sound" you observed was probably due to an implementation error on your side (overflow / clipping of integer values, signed values treated as unsigned value, or maybe incorrect in-place processing)...

EDIT: one thing worth mentioning is that there are situations in which a speech signal actually has high frequency components (appears "jagged", is noisy) - for example during a sss or shhh ; and removing those with a low-pass filter will affect its brilliance. Ideally, you'll want your low-pass filter to be active only when you detect that your speech signal is voiced - and inhibit it when you detect an unvoiced, noisy consonant.

• What filter bandwidth would you use for American English in the presence of AWGN, with no consonant detection? Aug 18, 2012 at 17:20
• Also, a wide averaging filter (i.e. low cut-off frequency) would distort the sound. Doesn't have to be clipping. Aug 18, 2012 at 17:21
• Using the phone bandwidth (cutoff at 4kHz) would be a good start if intelligibility is the sole goal. I wouldn't use 4kHz to clean up recordings of vocals on a studio production though :) From the original post, it's not clear what is the application. Aug 18, 2012 at 17:34
• I take distortion in the sense: the input is a sine wave but the output is not (added harmonics), not in the sense "output signal will sound unintelligible". The only way for a digital filter to exhibit this behavior would be if it has gain for some input frequencies, causing the signal to clip. Aug 18, 2012 at 17:39
• @JimClay I think it depends on what the definition if distortion is. :-) Personally I am not clear in this, there seems to be a colloquial meaning (ANY change in intelligibility) VS a more rigorous definition (non-linear operations that give rise to additional frequencies). Aug 19, 2012 at 15:32

Another interesting audio denoising technique exploits the fact that many sound recordings contain silent time intervals that contain only noise. Such sections can be chopped out of the recording to obtain a noise spectrum and then spectral gating can be applied to suppress noise. Take a look at the following links for detailed discussion on this technique:

Noise gate: http://en.wikipedia.org/wiki/Noise_gate

Noise removal in Audacity (an open source audio editing tool): http://wiki.audacityteam.org/wiki/Noise_Removal

Of course, this method rests on the assumption that the same noise source'' persists throughout the duration of the audio.

You should apply a low-pass filter on your signal. Look for such an algorithm. Hope this helps... Voice is low frequencies and usually noise is high frequencies.

• The recording I work with is just an array of byte-values, effectively constant frequency, just amplitude differences, where low-pass filters works with differences in the frequencies. Aug 18, 2012 at 10:08
• @slashmais - an array of values still contains many frequencies. just because the samples are regular in time doesn't mean that the signal as a whole cannot have many frequencies. even what you tried - averaging with values either side - can be thought of as a (rather poor) low pass filter. Aug 18, 2012 at 12:55
• @slashmais : if your data are discrete values, then you should probably do a FFT in order to apply a low-pass filter. Interesting math ahead ;-) but I would bet you can find some already well written/tested libs out there.
– Sun Wukong
Aug 18, 2012 at 13:32
• you don't need to do an fft. a simple finite impulse response filter is simpler. for example here en.wikipedia.org/wiki/… is the average of three points as the op tried (if i understood right). Aug 18, 2012 at 13:56