I’m not a filter expert so this is mostly out of curiosity. I was comparing the juce::dsp::IIR peak filter with the corresponding filter presented at Earlevel and according to the details the juce::IIR is a Transposed Direct Form II. So I would guess this is the same thing as the biquad Transposed Direct Form II presented at the Earlevel page.
From the code I see that the Juce implementation calculates six coefficients, an extra (non trivial) coefficient compared to as presented on Earlevel and other places. So normally it seems this biquad design only uses five coefficients. Seems to me it’s the same with other responses like SHelving e.t.c.
Is the Juce-implementation a different design than the “ordinary” Transposed Direct Form II Biquad or is this only a matter of implementation differences further down the line in the Juce version? It’s quite hard to follow all the steps in the Juce implementation so I thought I’d ask instead.
Technically speaking, the biquad does have 6 coefficients: b0, b1, b2 for the numerator, a0, a1, a2 for the denominator. However, often a0 is set to be 1.0. This is done by dividing the five other coefficients by a0. In juce_IIRFilter_Impl.h, in the function
assignImpl you can see that the coefficients are multiplied by 1 / a0.
If you see an implementation that used only 5 coefficients, then a0 is not provided and is assumed to be 1.
(Note: sometimes the names a and b are switched and a0-a2 are for the numerator while b0-b2 are for the denominator.)
OK, I see. That probably explains why there’s a variable called “norm” in the Earlevel implementation.
Will there be any differences in calculation (rounding errors etc) by postponing this division by a0? Or can I assume the filter’s to be practically identical?
Mathematically they are identical, but I’m sure there are tiny rounding errors since that’s just the nature of floating point numbers.