4
$\begingroup$

I'm new to DSP and I'm interested primarily in the implementation of audio filters. I've been reading about FIR filters as they seemed like a good place to start but now I'm stuck. I've written some code that implements a basic FIR filter and to test it I've tried out a low-pass filter. As far as I can tell it works but much of the higher frequencies seem to get through. It seems to me like the only way to solve this problem would be to use a higher-order filter but the higher I go the larger the CPU load.

This leads me to my problem:

Most of my experience with filters thus far has been via premade plugins in DAWs. Those filters sound significantly better than mine with a fraction of the CPU load. I feel like I'm missing something. Do those types of filters usually use FIR filters? Are they simply optimized better? How can I get an output similar to those "standard" audio filters?

$\endgroup$
1
  • 1
    $\begingroup$ If you're still interested in answers after finding out you probably want to use IIR filters anyway, please edit your question with (A) what order of filters are you talking about, and (B) how are you actually implementing them. There's more slow ways of implementing filters than there are fast ways; you could just be using a very inefficient implementation. $\endgroup$
    – TimWescott
    Dec 12, 2022 at 16:47

2 Answers 2

9
$\begingroup$

Do those types of filters usually use FIR filters?

No. Most "standard" filter types are IIR filters. For the design of single biquads Robert Bristow Johnson's EQ Cookup is an excellent resource: https://www.w3.org/TR/audio-eq-cookbook/

There are also standard topologies for high order low and high pass filters (Butterworth, Chebyshev, Elliptic, etc)

Are they simply optimized better? How can I get an output similar to those "standard" audio filters?

By using the right filter for the specific job: sometimes it's an FIR sometimes it's single a biquad, sometimes it's a more complicated IIR contraption.

Filter design is mathematically challenging and I recommend taking a class if you want to do a lot of it. It requires complicated trade offs between amplitude, phase, steepness, transient response or ringing, causality, latency, CPU and memory, etc.

$\endgroup$
1
  • 1
    $\begingroup$ This is exactly what I was looking for, thank you. I've tried out an IIR filter and it is much closer to what I was looking for. I had no idea that filter topology was so important so that's my next step. Thanks for the answer and the helpful resources! $\endgroup$ Dec 12, 2022 at 17:41
6
$\begingroup$

As far as I can tell it works but much of the higher frequencies seem to get through

This can have multiple reasons. The obvious one is that a FIR with a window length of $t$ can have at most a frequency resolution of $\tfrac1t$, which means it is impossible to have a strong lowpass with a low-order FIR. But also, most impulse responses you can implement won't have the maximum HF rejection possible with that size. A common cause for leakiness is if the IR doesn't go smoothly to zero on both sides. Try a Lanzcos window or similar to avoid this.

But yeah, mainly you just need a large enough convolution. There is two ways in which good FIR implementations make these happen quickly:

  • For relatively small ones (up to 64-ish samples), you can just brute-force the integral. But modern processors can do this a lot quicker than what you get with a naïve loop implementation, through the use of unrolling, SIMD instructions and other tricks. Many commercial plugins probably have the inner loops written in assembly, or at least they make heavy use of architecture-specific compiler optimizations.
    Looking even further, you may notice that machine learning systems carry out an insane number of (small) convolutions. They manage to do this quickly by running on GPUs instead of CPUs, calculating hundreds of integrals in parallel.
  • For any convolution larger than 256 samples, you definitely want a fast convolution algorithm. This means at its most basic just taking the Fourier transform of your signal, multiplying it with the filter kernel in frequency space (complex multiplication), and taking the inverse Fourier transform. Done. It's faster because FFT is only $O(n\cdot \log n)$, whereas brute-force convolution is $O(n^2)$.

Of course, IIR filters avoid the whole problem, by never explicitly carrying out any convolution but instead just updating the filter state in a way that can generate much longer impulse responses than you have variables in the state. They also generally have far fewer parameters than an IIR of the same effective size, which makes it easier to design them towards certain desired properties.

$\endgroup$
1
  • 1
    $\begingroup$ That was another thing I was wondering about but didn't want to include it in my original question to avoid clutter. Is it common to use an FFT algorithm for filtering? It seems like this method would make it easier to adjust the filter parameters. I thought about trying it out at the beginning but it felt like too much "brute force". $\endgroup$ Dec 13, 2022 at 2:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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