Does anyone know of a filter to attenuate non-speech? I am writing speech recognition software and would like to filter out everything but human speech. This would include background noise, noise produced by a crappy microphone, or even background music. I have already implemented a first order filter that compensates for the 6 dB roll-off of the power spectrum, but I'm still hearing noise (though the speech sounds a lot clearer). I have thought to use a low-pass filter, but I am iffy about doing that for two reasons:

  1. I don't know whether or not a low-pass pre-filter will interfere with the rest of the speech processing. Even though the human ear can only detect sounds lower than 20 kHz, I don't want to risk eliminating any higher order harmonics that might be necessary to process the speech (though I don't know if this is the case or not. But I don't want to take any chances).

  2. I understand that the excitation of certain consonants (such as f, h, and s) are almost entirely white noise. I don't want to implement a noise filter that will eliminate good noise, so to speak.

Ideally, I would like to be left with only the speech of the person speaking into the microphone. If you have any ideas, or there is something that I'm missing, please let me know. Much appreciated!

migrated from stackoverflow.com Jul 30 '12 at 18:59

This question came from our site for professional and enthusiast programmers.

  • I suppose. I'll leave it open though, simply because I've seen similar questions (filters and acoustic processing) here that were answered well. – Zetta Suro Jul 30 '12 at 18:06
  • Such as this one: stackoverflow.com/questions/6452926/… – Zetta Suro Jul 30 '12 at 18:11
  • Rule of thumb: if you want to know how to implement a given DSP algorithm e.g. in a particular language or on a particular platform, then it's on-topic for SO. If it's a question about DSP algorithms/techniques with no specific programming angle then it almost certainly belongs on DSP.SE (where it will also tend to get better quality answers). – Paul R Jul 30 '12 at 18:48
  • Gotcha. Did you migrate it over here? If so thanks. I couldn't figure out how to migrate it, so I just ended up re-asking it here. – Zetta Suro Jul 30 '12 at 19:12
  • Not me - I did flag it and ask if a moderator could move it so I guess one of TPTB did it (thanks to whoever that was !). – Paul R Jul 30 '12 at 20:28
up vote 6 down vote accepted

A speech communication channel as used in telephony typically has a frequency response of 300 Hz to 3 kHz. Although this rejects a lot of the energy in normal speech, intelligibility is still quite good - the main problem seems to be that certain plosive consonants, e.g. "p" and "t", can be a little hard to discriminate without the higher frequency components.

So you're probably looking for a "sweet spot" somewhere between using the full 20 Hz - 20 kHz bandwidth typically found in consumer audio and the most aggressive filtering used for voice comms (see above). I would suggest starting with a bandpass filter from say 50 Hz to 8 kHz. It will probably only improve SNR by a few dB at best, but it may help, particularly if you have a lot of high frequency background noise.

  • Thanks! A friend of mine actually suggested the voice channel, but I suspected that it would attenuate too much of the energy in some of the consonants. I'll try 50 Hz to 8 kHz and see how that works! – Zetta Suro Jul 31 '12 at 14:50
  • 1
    Choosing this answer simply because it's the "quick" solution that I was looking for. The rest of the answers will require a lot more research that I will definitely look into, as they will be helpful in the long run, but this is a simple filter solution that I was originally looking for. – Zetta Suro Aug 2 '12 at 23:11

Using a pass band filter matching the bandwidth of speech will help.

If you have several microphones (as is now the case on cellphones), there is a trove of ICA-like methods which can take advantage of that - but your question hints me that you have only one input.

What you want to do is "one-microphone source separation" (name taken from Roweis' groundbreaking paper), also called "single-sensor". Warning: this is far from being a solved problem, and all research in this field is very recent, with no algorithm or approach being a "clear winner" (unlike gaussian mixture models + FST have been for speech recognition).

A good framework to do that is through Wiener filtering. See Benaroya et al. "Single Sensor Source separation based on Wiener filtering and multiple window STFT" (Read section 1 & 2, don't bother with the multiresolution thing unless you really need it). In short, you compute the STFT of your signal, and for each STFT frame, you try to get estimates of the voice spectrum and of the noise spectrum, and you use Wiener filtering to recover the best estimate of the voice spectrum from that (this is akin to "soft-masking" the spectrum).

Your problem is now the following: given a STFT frame, estimate the speech and the noise component from it. The simpler approach described in the paper by Benaroya is through Vector-quantization - take several hours of speech by many speakers, compute the STFT, run LBG on it to find a codebook of 512 or 1024 typical speech frames ; do the same thing for noise. Now, given a frame of your input signal, project it non-negatively (a multiplicative gradient update procedure is described in the paper) onto the speech and noise bases, and you get your speech and noise estimates. If you don't want to deal with the non-negative projection thing, just use the nearest neighbor. This is really the simplest thing that could possibly work in the "single-sensor source separation" department.

Note that a speech recognition system could indeed provide some input for a separation system. Do a first pass of decoding using your speech recognition system. For each frame, take the mean MFCC vector from the gaussian that got the best score. Invert that back into a spectrum. Boom, you have a mask giving you the most likely spectral location of the speech-like bits, and you can use it as an input for Wiener filtering. This sounds a bit like hand-waving, but the geist is that to separate a source you need a good model for it, and a speech recognition system taken backwards is a hell of a good generative model for speech signals.

You should probably look at doing Independent Component Analysis (ICA) as your problem is very similar to the "cocktail party" problem that's often used to describe ICA. In short ICA finds the components of your signal that are independent from each other. This presumes that other noise in the environment (dishwasher, white noise, fan whirr) will be independent from the signal source of the voice and can be separated.

ICA is similar to PCA (principle component analysis) but instead of maximizing the variance on the principle axes, it maximizes the independence. There are many implementations of ICA that should plug into whatever coding environment you're using.

  • 4
    ICA requires as many input signals as there are sources to separate. In speech denoising, we are left with only one signal and ICA is thus of no help. – pichenettes Aug 1 '12 at 14:36

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.