Band Pass Filters


Digital Biquad Filtering

Brief:


A second-order biquad band-pass filter allows frequencies around a specified center frequency to pass through while attenuating frequencies outside this range, using a combination of two poles and two zeros to shape the frequency response. It is implemented using a difference equation with feedback and feedforward coefficients, offering precise control over gain, center frequency, and bandwidth or resonance (Q factor). This makes it ideal for isolating specific frequency bands in audio and signal processing applications.

\(f_{0}\) = 1000

\(Q\) = 0.707


Formulae:


In order to construct a biquad band-pass filter, the sample rate, cutoff frequency, and Q-factor need to be provided. From those, the coefficients for the underlying filter can be calculated:

First, some intermediate values are calculated:

  • \(ω_{0} = 2π{f_{0} \over F_{s}}\)
  • \(α = {sin(ω_{0}) \over {2Q}}\)

Where \(f_{0}\) is the cutoff frequency, \(F_{s}\) is the sample rate, and \(Q\) is the Q-factor.

There is also an option of configuring the band-pass filter to use constant skirt gain, in which the peak linear gain is equal to the Q-factor. Otherwise, the peak gain will be 0dB.

Then, the filter coefficients can be calculated:

For constant skirt gain:

  • \(b_{0} = Qα\)
  • \(b_{1} = 0\)
  • \(b_{2} = -Qα\)
  • \(a_{0} = 1 + α\)
  • \(a_{1} = -2cos(ω_{0})\)
  • \(a_{2} = 1 - α\)

For 0dB peak gain:

  • \(b_{0} = α\)
  • \(b_{1} = 0\)
  • \(b_{2} = -α\)
  • \(a_{0} = 1 + α\)
  • \(a_{1} = -2cos(ω_{0})\)
  • \(a_{2} = 1 - α\)

Implementation


You can find a C++ and Rust implementation of this and other biquad filters on my GitHub page:

Repo card

Notes:


Since Q-factor is a unit-less value and is a little hard to quantify, sometimes it is easier to provide bandwidth instead. Bandwidth can be converted to the Q-factor by using the formula:

\(Q = {1 \over {2sinh(BW ⋅ {log_{10}(2) \over 2})}}\)