9
$\begingroup$

I've put together a multi-band audio EQ using biquad filters. I'm getting the coefficients using the methods from the RBJ cookbook.

Now I want to plot the curve showing the magnitude response. I'm using an equation from this source

Here is my function to get the coefficients and get the magnitude response at points of interest.

void GetCoefficients (double samplerate = 44100.0) {

    //from the rbj biquad coefficient cookbook by Robert Bristow-Johnson
    long double SR = (long double)samplerate;
    long double A = powl(10.0L, dBGain/40.0L);
    long double W0 = 2.0L * PI * Center / SR;
    long double alpha = sinl(W0)*sinhl( LN2/2.0L * WidthInOctaves * W0/sinl(W0));

    if (Type == "peaking") {
        b0 = 1.0L + alpha * A;
        b1 = -2.0L * cosl(W0);
        b2 = 1.0L - alpha * A;
        a0 = 1.0L + alpha / A;
        a1 = -2.0L * cosl(W0);
        a2 = 1.0L - alpha / A;
    }
    
    long double w;
    long double numerator;
    long double denominator;
    long double magnitude;

    for (int i = 0; i < 59; ++ i) {
        w = 2.0L*PI*FreqPoints[i] / SR;  
        numerator = b0*b0 + b1*b1 + b2*b2 + 2.0L*(b0*b1 + b1*b2)*cosl(w) + 2.0L*b0*b2*cosl(2.0L*w);
        denominator = 1.0L + a1*a1 + a2*a2 + 2.0L*(a1 + a1*a2)*cosl(w) + 2.0L*a2*cosl(2.0L*w);
        magnitude = sqrtl(numerator / denominator);
        FrequencyResponse[i] = magnitude;   
    }
}

My filters sound correct, but my plot seams way wrong. For example, when I have calculated the coefficients for a peaking filter with a width of $2$ octaves, centered at $4398\textrm{ Hz}$, with $3\textrm{ dB}$ gain; my magnitude response using those coefficients at $349\textrm{ Hz}$ is about $12$.

I must be doing something wrong, but I can't quite figure it out.

$\endgroup$
2
  • 1
    $\begingroup$ That looks correct to me. There is nothing obviously wrong. Debug hint: try an allpass filter, numerator and denominator should come out to be the same and the a & b's should be fipped, i.e. b2 = a0, b1 = a1, b0 = a2 $\endgroup$
    – Hilmar
    Aug 12, 2012 at 0:44
  • 1
    $\begingroup$ It would be best if you showed a complete, compilable example. It's possible that you could have a problem initializing the FreqPoints array or the PI constant, for example. $\endgroup$
    – Jason R
    Aug 12, 2012 at 3:11

1 Answer 1

5
$\begingroup$

Someone over at the KRV forum pointed out that I need to normalize my coefficients so that a0 = 1.

b0 /= a0;
b1 /= a0;
b2 /= a0;
a1 /= a0;
a2 /= a0;
a0 = 1;
$\endgroup$
2
  • 1
    $\begingroup$ hey take a look at this answer. it shows a numerically better way to plot the magnitude response if you're stuck with using single-precision floats. $\endgroup$ May 28, 2016 at 15:39
  • $\begingroup$ I'm seeing at this old post, and I'm looking for a similar solution, to implement in C#, to plot a curve that represent a parametric filter. I have 10 bands, frequencies and bandwidth for each one, and I need to calc the coordinates (x, y), to add the correct points to draw an accurate curve. Just in case, and seeing at this resolution, Do you have a complete example, including the drawing side, that you could share with me? Thanks! $\endgroup$ May 26 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.