A biquad calculator

Type:

Plot:
Sample rate (Hz)
Fc (Hz)
Q
Gain (dB)

Something useful: a biquad filter coefficient calculator. Set the filter Type, the Sample rate (or 1.0 for “normalized” frequency), and cutoff of center frequency Fc. You can adjust Q for lowpass, highpass, bandpass, notch, and peak filters (use 0.7071–which is 1 divided by the square root of 2–for Butterworth lowpass and highpass), and Gain for peak and shelving filters. View the frequency response with a linear or log scale. You can copy and past the resulting coefficients into your programs.

More info on biquads in previous posts, here and here.

Note that there is an improved version of this calculator here.

This entry was posted in Biquads, Digital Audio, Filters, IIR Filters, Widgets. Bookmark the permalink.

20 Responses to A biquad calculator

  1. Anita Barteky-Bamford says:

    Hey Nigel…I guess all that competitive math with you in grade school paid off! LOL
    Looks like some cool stuff here.

  2. Erik says:

    I think you have your a and b coefficients labeling swapped in the coefficient output window.

    • Nigel Redmon says:

      Thanks for visiting!

      Actually, I prefer the a’s in the numerator (of the z-domain transfer function), and b’s in the denominator—some folks go the other way. (I did an informal survey of the DSP texts on my book shelf when this sort of discussion came up some years back, and the a’s-on-top were most popular, but some fine authors choose the other way as well.)

      Folks also disagree on the sign of the denominator coefficients (I use a minus sign at the summation for the denominator/feedback coefficients, others negate the coefficients and use all adds.) If you start from the z transform, the a’s on top and minuses for the denominator coefficients are most natural; if you start at the block diagram of a direct form II biquad, then you’ll tend towards the other convention.

      In any case, I’m consistent—check my other articles on biquads and the bilinear transform. But thanks for bringing this up—it reminds me why I need to post some sample code as well.

  3. Paul says:

    Nigel, I’ve really enjoyed your articles and have learned a lot. I have a simple bi-quad filter working fine and I’d like to cascade it. After cascading it appears I’m getting pretty much the same response as not cascading. I’ve defined variables “current_sample” and “filtered_sample” so current_sample is the output of the ADC and filtered_sample is then the value after filtering. Below is the simple bi-quad code. My thoughts were initially that I could simply run the Bi-Quad filter section again changing only the “y” values. I’m not sure it’s that easy and kindly ask your help.

    —————————————————————————————————-

    // Low-pass fc=20, 2000 samples/sec, Q=.707
    a0 = 0.0009446914586925257;
    a1 = 0.0018893829173850513;
    a2 = 0.0009446914586925257;
    b1 = -1.911196288237583;
    b2 = 0.914975054072353;

    b1=b1*-1;
    b2=b2*-1;

    current_sample = SampleADCfloat();

    /* Bi-Quad filter */
    x[2]=x[1];
    x[1]=x[0];
    x[0]=current_sample;
    y[2]=y[1];
    y[1]=y[0];
    filtered_sample= a0*x[0] + a1*x[1] + a2*x[2] + b1*y[1] + b2*y[2];
    y[0]=filtered_sample;

    /* Cascade? */
    y[2]=y[1];
    y[1]=y[0];
    filtered_sample= a0*x[0] + a1*x[1] + a2*x[2] + b1*y[1] + b2*y[2];
    y[0]=filtered_sample;

    .repeat above?
    .repeat above?
    .repeat above?

  4. Nigel Redmon says:

    Hi Paul,

    I see some problems with your code, but since you’re using floating point, I’d go with transposed direct form II anyway, which requires just two saved states per biquad:

    http://www.earlevel.com/main/2003/02/28/biquads/

    I’m sure you can figure it out from there, but for those who need a head start: Looking at the diagram there (let’s call the top delay state z1, and the lower one z2), you’ll see that the output is

    output = input * a0 + z1;

    Now for the new z1 and z2:

    z1 = input * a1 + z2 – b1 * output;
    z2 = input * a2 – b2 * output;

    To cascade, you’d repeat the above, preceded with “input = output;”, and another a new set of delay states (z11, z22). Also note that you’ll need to adjust your filter settings—cascading two filters that are each -3dB at 10 kHz yields a filter with a different -3dB point and shape (it’s now -6dB at 10 kHz). So depending on the exact filter shape you want, you may want to use different frequency and Q setting for each section, or just adjust the Q.

  5. Paul says:

    Thank you Nigel! I’ll give this a try.

    Thanks for being so nice, I definately fit the “need a little head start” category since I’ve never worked with filters like this. Just understanding that the “z” values end up as intermediate values in the calculations is a jump start. As soon as I have time I should start a beginner’s course or read a book that starts with the simple terminology.

    Thanks again!

  6. Hey, Nigel, nice js app! Very handy!
    Calculation of a1 for low shelf seems incorrect though (a1 > 2.0 when all coefficients should have magnitude <= 2). It is probably irrelevant, but anyway I am using the app with Chrome running in Ubuntu.

    • Nigel Redmon says:

      Glad it’s helpful to you, Adriano! Remember, the shelves have gain, so you’ll see the a coefficients go over 2 for the boost case. BTW, the high and low shelves are from Udo Zölzer’s Digital Audio Signal Processing.

      Nigel

  7. Nigel, you are absolutely right. I mistook b’s for a’s and applied the stability triangle rule for the nonrecursive coefficients instead of the recursive ones. Sorry for that.

  8. Hi Nigel!

    I just wanted to thank you for your excellent articles. It seems everything I need is right here! Thanks!

    Fredrik C

  9. Gábor Kakuk says:

    Dear Nigel,

    Is it possible to explain how to add the SLOPE for shelfing filters?
    (In the formulas)

  10. Nigel Redmon says:

    Hi Gábor,

    I did some work on slope, late last year, including Q (it’s useful to allow a dip before the shelf transition, as some vintage analog equalizers). It was educational, but at a certain point I realized that the only real purpose would be to develop a high-quality EQ, and for that I’d want to make other changes as well—and for what, with so many high-quality EQ plug-ins available. So I stopped—it wasn’t something I wanted for myself, and it wasn’t what I wanted to do here in this blog. I might get back to it at another time, but there were so many other things I want to get done first…

    But the basic thing was working out the pole-zero motion in the s-domain, relating to the controls. From there it’s just the bilinear transform. Sorry, I know that’s not very useful information.

    Nigel

  11. Nigel, it would be interesting to highlight that the Q definition implicit in your designer reference the -3 dB points, not the half-gain ones. “One problem with this definition is that complementary equalizers with the same defined bandwidth, boost/cut frequency, and opposite boost/cut gains, do not cancel each other to result in a flat 0 dB overall response.” For instance, a -18 dB peaking EQ do not perfectly cancel two cascaded +9 dB with same frequency and Q. Please refer to the paper where the above quote was extracted for a thorough discussion [1].

    Gábor, please refer to [2] for a second order shelving filters with adjustable slopes.

    [1] Bristow-Johnson, R., “The Equivalence of Various Methods of Computing Biquad Coefficients for Audio Parametric Equalizers” URL: http://thesounddesign.com/MIO/EQ-Coefficients.pdf

    [2] Bristow-Johnson, R., “Cookbook formulae for audio EQ biquad filter coefficients” URL: http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt

    • Nigel Redmon says:

      Thanks for your comments, Adriano.

      True, but that doesn’t mean it’s “wrong”, simple an alternate definition. You can’t cascade two lowpass filters of the same Q and frequency and get a steeper slope with the same frequency and Q specs either (two biquads set to 1 kHz and 0.707Q do not produce a fourth-order 1 kHz filter as defined by -3 dB), yet that’s the standard definition.

      Yes, the variable slope is interesting, but it’s not of the form that’s usually used for audio, and will not sound good at higher Q. It produces both a dip near unit and a peak at the shelf height, while the usual shape for both analog consoles and their digital equivalents is to have the dip at unity by no bump at the shelf gain level.

      Also, note that the rbj shelves are not symmetrical—cut and boost behave differently. The transfer function must be inverted for negative gain, to preserve the same shape on both sides of unity.

  12. Nigel, referencing -3 dB points is indeed pretty standard and surely not “wrong”. In some cases it may even be actually perceptually preferable to use the -3 dB reference points (e.g., MID EQ in mixing consoles), so that the perceptually the bandwidth increases with gain magnitude. I believe it nevertheless relevant to point out that half-logarithm-gain (vs half-linear-gain points) reference points must be used in order to have the perfect-cancelling property in the magnitude frequency response.

    The RBJ formulas for shelves given in [2] actually do have gain symmetry, i.e., cascading a shelf with gain +G with another with gain -G produce unity frequency response. Cascading a shelf with gain +G with two others with gain -G/2 , however, does not produce unity frequency response. Therefore, we have here a weaker perfect cancelling property for shelves than for half-gain peaking EQs.

    Regarding shelves variable slopes, the most useful S range is within 0.33 and 1.0 (slower than first-order to fastest monotonic second order). For faster than 12 dB/oct slopes, higher order shelves must be employed, such as in [3].

    [3] Holters, M. and Zölzer, U., “PARAMETRIC HIGHER-ORDER SHELVING FILTERS”, in Proc. of 14th European Signal Processing Conference (EUSIPCO 2006), Florence, Italy, September 4-8, 2006. URL: http://www.researchgate.net/publication/239734982_Parametric_higher-order_shelving_filters/file/3deec51c2ae3d17210.pdf

    • Nigel Redmon says:

      Hi Adriano,

      Yes, you are correct about rbj’s shelves being symmetrical. I took a look only at the transfer function before, and did not notice that he was calculating his coefficients based on the midpoint of the shelf, not the corner frequency. I think that audio engineers are more familiar with the corner frequency definition, as that’s how hardware EQs work (at least the ones that I’m familiar with). Out of curiosity, I did a quick check with some of my EQ plug-ins, and the old “Q” equalizers from Waves (“The world’s very first paragraphic EQ”, they claim) appear to use that definition, though their newer ones (REQ, etc.) use corner frequency, as do the others that I have (the old Motu PEQ, and newer Oxford-clone MW Equalizer, for instance).

      Yes, with S of 1 or less, slope control is useful for audio. I won’t implement it without a more general Q solution, though. I did take a stab at a general solution, with Q less than 0.7071 reducing the slope, and causing a dip with steeper initial slope when greater than 0.7071. I was successful in general, but need to work out the pole-zero motion so that behaves closer to what I’ve seen for seen for similar EQs, since there doesn’t appear to be an obvious engineering-driven definition. (But maybe there is—I need to play with it in the s-domain and see.)

      Nigel

  13. Nigel, I believe it would be interesting to conclude this thread by presenting the formula to convert between both Q definitions. Let G be the peaking filter absolute gain, let Q_lin be the half-power (-3 dB), aka full width at half maximum (FWHM), referenced quality factor and Q_log be the half-logarithm-gain (G/2 with G in decibels), then the two quantites are related by the following ratio: Q_lin / Q_log = 10^(|G|/40).

    Finally, another interesting (and thorough) reference on the subject is [4], in which it is possible to see that the -3 dB actually references the bandpass from which the peaking filter is derived and that is why for |G| < 6 dB the -3 dB actually does not reference the sign(G)*(|G|-3) dB points.

    [4] Miller, R., ""Why DSP Boxes Set the Same Way Differ"" in RaneNote 167, 2007 Rane Corporation, URL: http://www.rane.com/note167.html

  14. Below I present very accurate approximations in Ruby code for converting between corner (LPF/HPF -3 dB) [5] and midpoint (G/2 in dB) witt S = 1 [2] high/low-shelves cutoff specifications.
    [5] http://www.earlevel.com/main/2011/01/02/biquad-formulas/

    def bw_warp(fc,fs)
      include Math
      w = 2*PI/fs*fc
      w/sin(w)
    end
    
    def r(g)
      10**(g/80.0)
    end
    
    # Midpoint to corner for high-shelves and corner to midpoint for low-shelves.
    #
    def conv_up(fm, g, fs)
      raise RangeError, 'invalid digital frequency' unless fm <= fs*0.5
      fcc = fm * r(g)
      fc = fcc / bw_warp(fcc, fs)**0.25
      raise RangeError, 'frequency-gain pair too high for conversion' unless fc <= fs*0.5
    fc
    end
    
    # Corner to midpoint for high-shelves and midpoint to corner for low-shelves.
    #
    def conv_down(fc, g, fs)
      raise RangeError, 'invalid digital frequency' unless fc <= fs*0.5
      fm = fc / r(g)
      [fm * bw_warp(fc, fs)**0.25, fs*0.5].min
    end
    

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>