With an audio .wav file (sampled at 44.1 or 96 Khz), I would like to filter out everything outside the 20 - 20000 Hz range.

I tried a Butterworth bandpass filter and there were unstability issues, but the choice of a Butterworth was completely random among lots of filtering methods:

  • we could also use a Butterworth low-pass filter at 20000hz, followed by another Butterworth high-pass filter at 20hz

  • we could choose other IIR filters (Chebyshev, etc.)

  • or FIR filters, etc.

So many solutions!

What would you choose to filter out everything outside the 20 - 20000 Hz range of an audio file? (Python code welcome)

Additional notes about transition bandwidth: on the 20 Hz side, I would like no low-frequency rumble, so having some 18 Hz component is ok, but having DC component or 5 Hz rumble is unwanted. On the 20000 Hz side, idem: having 20.1 Khz component is ok, but there should be very few left at 21 Khz.

       ______________________                 0 dB
      /                      \
     /                        \
 ___/                          \______     -100 dB
 0  10 20                   20k 21k
  • $\begingroup$ Can you please edit your question because at the moment it is too broad. Could you please, for example, mention how quickly do you want the components to diminish outside of your limit frequencies? That is, what is the transition bandwidth? How much suppression is required? These are parameters that will constrain the design to something more specific and have nothing to do with "Python" (at this point) $\endgroup$ – A_A Dec 29 '16 at 10:25
  • $\begingroup$ If your signal is sampled at 44.1kHz, and you still have significant components near 22050Hz (half Fs), then I strongly doubt the antialiasing filter previous to sampling was good enough; in which case you'd also expect significant aliasing present in your samples, which you cannot remove once there. $\endgroup$ – Juancho Dec 29 '16 at 12:52
  • $\begingroup$ How much attenuation do yo need? Do you allow for signigicant phase distortion near the cutoff frequencies? Can you include a full spectrum plot of your signal? $\endgroup$ – Juancho Dec 29 '16 at 13:40
  • $\begingroup$ 150dB is a lot of attenuation. It means 10^7.5 attenuation in amplitude. $\endgroup$ – Juancho Dec 29 '16 at 15:25
  • $\begingroup$ Have you tried a simple high-order filter designed with Matlab's fir1? And, why do you need so much attenuation? If you intend the signal for listening, I doubt anything above 50dB will make much difference. Note that the loudspeakers themselves will act as a filter too. $\endgroup$ – MBaz Dec 29 '16 at 16:51

This can be done, but it involves a number of trade offs.

  1. Filtering comes at a cost: CPU cycles, memory, latency, time smear, responsiveness, pre-ringing etc.
  2. The more aggressive the filter, the higher the cost
  3. The filters that you are asking for are extremely aggressive, so I recommend to revisit your requirements

The trickier filter is the high pass at 20 Hz. You can't do an FIR since the length would be prohibitive. A 10th order Butterworth at 20 Hz (-3dB) will give you about -120 dB at 5 Hz. The impulse response of the filter is more than a second long, in a sense that truncating at less than that would results in a attenuation of less than 120 dB. So it takes more than a second for the filter to do it's job.

This filter has poles very close to the unit circle, so it can create stability problems. The best implementation would be cascaded second order sections with proper section ordering and each section implemented in either Direct Form I or Transposed Form II. Double precision wouldn't harm either.

The filter will also introduce lots of phase distortion in the signal. The maximum group delay is about 0.1 seconds. That means signal components at 20 Hz will be delayed by about one tenths of a second as compared to signal components at, say, 200 Hz.

There is no easy way around this: any aggressive filter will results in some significant changes to the time domain wave form. You need to be sure that the problem you want to solve is worth the damage. Most audio application are fine with a mild high pass at the low end (DC blocker) and the high end is rarely a problem since there is almost no signal energy there to start with.

| improve this answer | |
  • $\begingroup$ Thanks @Hilmar. I think you're right (and other comments too): my requirement was too high. I'm working on a instrument sample-set, and I wanted to clean samples. Following your advice, it seems that -100dB or -80dB or even maybe -60dB would already be good at 5Hz for the high-pass / 21 khz for the low-pass. In short, it should be just a casual "outside of 20-20000 hz cleaning" process, more than a surgical procedure. signal components at 20 Hz will be delayed by about one tenths of a second: thanks for pointing this, I would like to avoid such high damage; I'd prefer a milder filter $\endgroup$ – Basj Dec 29 '16 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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