7
$\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$
  • 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 '12 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 '12 at 3:11
4
$\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;

Solved my problem.

$\endgroup$
  • $\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$ – robert bristow-johnson May 28 '16 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.