Something about juce_IIRFilter


#1

Hi , jules,

void IIRFilter::makeLowPass (const double sampleRate,
                             const double frequency) throw()
{
    jassert (sampleRate > 0);

    const double n = 1.0 / tan (double_Pi * frequency / sampleRate);
    const double nSquared = n * n;
    const double c1 = 1.0 / (1.0 + sqrt (2.0) * n + nSquared);

    setCoefficients (c1,
                     c1 * 2.0f,
                     c1,
                     1.0,
                     c1 * 2.0 * (1.0 - nSquared),
                     c1 * (1.0 - sqrt (2.0) * n + nSquared));
}

I did some calculation with my pen and according to the code above, which is using a 2nd order butterworth, I think the param n has some problem. Param n here is 1/w, and w is nomalized angular frequency.

My question is: shouldn’t the first line of the code be replaced by this:

const double n = 1.0 / tan (0.5 * double_Pi * frequency / sampleRate);

Because the frequency conversion equation(from normalized freq to analog freq) is :
Wa = tan (Wn / 2) * ( 2 / Ts);
where Wa means analog filter frequency, Wn is normalized freq( 2 * pi * fc / fs), and 2/Ts is usually ignored.

Correct me if wrong.

thx


#2

erm… it’s a while since I wrote that!

But if Wn = ( 2 * pi * fc / fs),
and we want Wa = tan (Wn / 2)
then Wa = tan (pi * fc / fs), right?

(Or maybe I’m being thick…?)


#3

yes, pi is right I think.


#4

Well, the current code use double_Pi, so if Pi is right, the code isn’t.


#5

Ah! I understand the confusion now!

double_Pi means “pi, in double-precision”, not “2 x pi”! (There’s also a float_Pi).

I never noticed that it could be misinterpreted like that!


#6

[quote=“jules”]Ah! I understand the confusion now!

double_Pi means “pi, in double-precision”, not “2 x pi”! (There’s also a float_Pi).

I never noticed that it could be misinterpreted like that![/quote]

Wow…I 'm really sorry for that…