The documentation for Analog Device's sigmastudio shows some of the formulas behind their biquad IIR filter coefficients. The usual suspects (HP, LP, peaking, ...) as described in RBJ's cookbook are all there. A couple more specialised filters (Butterworth & Bessel) are here as well.

However, what really caught my eye was their so called "Tone Control" filter. Contrary to the other filters on the site, there's no explicit transfer function listed. It's a simple biquad filter like others. The implentation reads verbatim:

tb = 10^(Boost_Treble_db / 20.0)
bb = 10^(Boost_Bass_db   / 20.0)
ωT = tan(pi * Freq_Treble / Fs)
ωB = tan(pi * Freq_Bass   / Fs)
Knum_T = 2 / (1 + (1.0 / tb))
Kden_T = 2 / (1 + tb)
Knum_B = 2.0 / (1.0 + (1.0 / bb))
Kden_B = 2.0 / (1.0 + bb)

alpha0 = ωT + Kden_T
beta1  = ωT + Knum_T
alpha1 = ωT - Kden_T
beta2  = ωT - Knum_T

alpha2 = (ωB * Kden_B) + 1
beta3  = (ωB * Knum_B) - 1
alpha3 = (ωB * Kden_B) - 1
beta4  = (ωB * Knum_B) + 1

a0 = alpha0 * alpha2
a1 = (alpha0 * alpha3) + (alpha1 * alpha2)
a2 = alpha1 * alpha3
b0 = beta1 * beta3
b1 = (beta1 * beta4) + (beta2 * beta3)
b2 = beta2 * beta4

I've never encountered a biquad filter like this. This is exactly the response I would expect from a "Tone Control" and from the parameter naming. The response looks like a high and a low shelf combined.

However, traditionally shelving filters as described by RBJ's cookbook are already second order systems. To have to shelves we'd need to cascade two biquads with different coefficients.

How does this filter achieve its response? Does it simply somehow "combine" two filters or is there more going on here? If it does combine two filters, can this be adapted to other combination (e.g. could I combine two peaking filters?)

Examples: (The responses are plotted using Earlevel's Biquad Calculator V3)

Frequency response of the tone control filter Boost_Treble_dB = +6dB, Boost_Bass_dB = +6dB, Freq_Treble = 2000Hz, Freq_Bass = 500Hz.

Frequency response bass = -6dB 100Hz, treble = +6dB 5000Hz Boost_Treble_dB = +6dB, Boost_Bass_dB = -6dB, Freq_Treble = 5000Hz, Freq_Bass = 100Hz.

Frequency response bass = +3dB 100Hz, treble = +6dB 3000Hz Boost_Treble_dB = +6dB, Boost_Bass_dB = +3dB, Freq_Treble = 3000Hz, Freq_Bass = 100Hz.

  • $\begingroup$ You can combine two 1st order filters to get 2nd order filter (though, its possible to build custom response filters through pole/zero placements (an example is a RIAA filter). LS and HS can be implemented as 1st order filter (IIRC peak-notch too). $\endgroup$
    – Juha P
    Dec 28, 2023 at 21:35

1 Answer 1


Cascade of First Order High-shelf and Low-shelf Sections

This implementation is simply the cascade of two first order sections with real coefficients and thus is limited to what can be accomplished with poles and zeros on the real axis as first-order high-shelf and low-shelf sections. It appears this was done by mapping the continuous time transfer function for simple first order high-shelf and low-shelf filters to discrete time using the Bilinear Transform along with prewarping the cutoff frequencies to compensate for the frequency warping that occurs with that mapping technique. The cascade of two first order sections in series can be combined as a single biquad filter as the product of their individual transfer functions. Here we see the resulting first-order filters as:

$$H_L(z) = \frac{\beta_1z+\beta_2}{\alpha_0z+\alpha_1}$$

$$H_H(z) = \frac{\beta_3z+\beta_4}{\alpha_2z+\alpha_3}$$

The cascade would be the product as follows:

$$H_L(z)H_H(z) = \frac{(\beta_1z+\beta_2)(\beta_3z+\beta_4)}{(\alpha_0z+\alpha_1)(\alpha_2z+\alpha_3)}$$

$$= \frac{(\beta_1\beta_3)z^2+(\beta_1 \beta_4 + \beta_2 \beta_3)z + \beta_2 \beta_4}{(\alpha_0\alpha_2) z^2+ (\alpha_0 \alpha_3 + \alpha_1 \alpha_2)z + \alpha_1\alpha_3}$$

And thus the biquad coefficients are given as:

$b_0 = \beta_1\beta_3$
$b_1 = \beta_1 \beta_4 + \beta_2 \beta_3$
$b_2 = \beta_2 \beta_4$
$a_0 = \alpha_0\alpha_2$
$a_1 = \alpha_0 \alpha_3 + \alpha_1 \alpha_2$
$a_2 = \alpha_1\alpha_3$

For example, the low-shelf (boosting the Bass) is accomplished by placing the pole closer to the origin than the zero on the real axis in the S Plane, and the graphic below illustrates how this would map to a pole and zero placement in the z-plane using the Bilinear Transform resulting in a pole at $z=-\alpha_1/\alpha_0$ and a zero at $z=-\beta_2/\beta_1$ where the origin in the s-plane maps to $z=1$, and the zero is now further than the reciprocal distance of the pole from the $z=0$. The high-shelf is similar with the zero closer to the origin than the pole. The implementation posted by the OP was done with the zeros in the right half plane (in the s-plane) or equivalently outside the unit circle in the z-plane as I depict below (as the phase response posted by the OP goes to 180 degrees which tells us there are two zeros overall outside the unit circle). This results in a maximum phase response meaning maximum delay for the given magnitude response. It would likely be an improvement to instead reflect those zeros for each high-shelf and low-shelf section to be inside the unit circle as a minimum phase solution.

Bilinear Transform

Other Approaches With Complex Conjugate Poles and Zeros

Independent control of bass or treble or both as the OP has done can be also be accomplished with a single biquad filter section with complex coefficients providing more control of the overall response. Given the entire phase is going to 180 degrees at Nyquist in all the OP's plots is the hint that suggests that these are all 2nd order systems of two poles and two zeros with all the poles inside the unit circle and all the zeros outside the unit circle.

The first plot looks like what you could achieve by placing the conjugate poles and zeros on the same angle (resonant frequency), with the radius of the pole inside the unit circle and the zero outside, symmetrically at less distance from the unit circle than the reciprocal of the pole. Add a constant gain and the magnitude response shown on the upper left plot (for frequency from $0$ to $2\pi$ or DC to the sampling rate, in contrast to the OP's plots that go from $0$ to $\pi$ or DC to Nyquist) comes close to that as posted by the OP:

pole zero demo

By adjusting the relative pole and zero conjugate locations (radius and angle) with independent angles for the poles and zeros as well as independent radii, we can achieve different balances for the bass and treble with the single second order biquadratic filter, as above a static gain can be added to shift the entire magnitude plot up or down:

Bass Boost

Bass boost

Treble Boost

Treble boost

I detailed the relationship between the poles and zeros and the coefficients / implementations for the 2nd order biquad in this recent post.

Like what you see? I teach online DSP courses where I bring intuition together with the math involved for a deeper and more creative understanding of signal processing concepts. You can find the latest course listings at https://dsprelated.com/courses and https://ieeeboston.org/courses/ Next courses start at the end of Feb 2024, with an early sign-up discount until Feb 15!


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.