Notch Filters


Digital Biquad Filtering

Brief:


A second-order biquad notch filter selectively attenuates a narrow band of frequencies around a specified center while allowing others to pass, using a combination of two poles and two zeros to shape its frequency response. It is implemented with a difference equation employing both feedback and feedforward coefficients, providing precise control over gain, center frequency, and bandwidth (Q factor).

\(f_{0}\) = 1000

\(Q\) = 0.707


Formulae:


In order to construct a biquad notch 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.

Then, the filter coefficients can be calculated:

  • \(b_{0} = 1\)
  • \(b_{1} = -2cos(ω_{0})\)
  • \(b_{2} = 1\)
  • \(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})}}\)