Biquad calculator v2


Sample rate (Hz)
Fc (Hz)
Gain (dB)

Here’s an update of the biquad calculator. It adds one-pole highpass and lowpass filters, and frequency, Q, and gain sliders. The sliders cover the range of typical audio settings, and are valuable for getting a quick feel for how the filters respond. But for precise settings and a wider range of parameters, type settings into the edit fields. (For this reason, the connection between sliders and edit fields are one-way—sliders update the edit fields, but changing the fields does not change the sliders positions accordingly.)

Review the biquad direct forms here; direct form I is best for fixed point processors, while direct for II transposed is best for floating point implementations.

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

96 Responses to Biquad calculator v2

  1. Rob says:

    I can’t see the sliders, I have extra text boxes instead – Firefox 20 for Ubuntu Canonical 1.0

    Freescale SGTL5000 is a pain in the neck. Freescale representatives tell me that their PEQ uses IIR Biquad digital filter and 20 bit number is all fractions with one sign bit and 19 bits after the decimal point so only able to represent -1 to 0.99997; Then they tell me to find a 3rd party tool and their help is vacuous thereafter.

    Your Biquad Calculator V2 seems pretty cool but keeps giving me figures above 0.99997 and/or below -1

    Please help me.

    • Nigel Redmon says:

      To the slider issue, Firefox doesn’t support HTML 5 “range” (slider) controls before release 23. I make no attempt to support anything that’s not HTML 5 compliant, at this point. It’s not worth the effort.

      OK, it looks like you’re saying that at the filter settings you want (low frequency, apparently), the 20-bit fixed point coefficients don’t have sufficient resolution. This is always an issue with direct form biquads, as the poles are very sensitive to quantization at the angles of zero and pi. There are other filter forms that work better in that area. The state variable form is quite good for low frequencies.

    • David says:

      I know it’s way after the fact, but in case it’s helpful for future people: the chip I’ve been working with takes a1 and b1 at half-scale (because those are the coefficients most likely to be larger than 1), so their usable range is -2 to 2-ish.

  2. Carl says:

    Excellent work. This page and the whole website is useful.

  3. miK says:

    Great web site! However, I was also stumped on why b0 was missing until I read the comments section from your old calculator. Maybe it’ll help if there’s big bold disclaimer at the beginning letting folks know your a are for numerator and b are for denominator and that could be different from what others are using?

  4. MikeH says:


    I left an early message about coefficient scaling, and here are the coefficients in question. I am using a high shelf filter.
    a0 = 2.1711322014279757
    a1 = -4.073744433313715
    a2 = 1.9182767385279291
    b1 = -1.8153410827045682
    b2 = 0.8310055893467576

    I am trying to scale these to be between +-2 as my processor requires numbers in that range. 2 of the above are outside that.

    • Nigel Redmon says:

      The most convenient method depends on the processor, but the way that this is usually handled is to halve the particular coefficient, then multiply-accumulate it twice:

      mac -x0,y1,a
      mac -x0,y1,a

      Similarly, you could quarter the coefficient and repeat it four times. Those are simply the sort of tradeoffs that you have with fixed-point processors.

    • I had been succesful in just scaling down a0,a1,a2 using a constant factor, in your case you may just divide all of them by (-a1/2) so a1=-2.0 and all others scale down accordingly.
      b1 and b2 remain the same.

      It will result in the output being scaled down accordingly, in this case slightly more than 6 dB.

  5. MikeH says:

    Thanks for the response Nigel.

    Unfortunately, I do not have the ability to multiply and accumulate. I am trying to use a biquad on a Blutetooth chip and all I have access to is the coefficients – I cannot program anything else. Their structure is fixed in silicon. If it is not possible to scale them and still keep the b0 coefficient as unity, I will have to adjust the parameters (like gain, etc) until they are are all under 2 for magnitude.


  6. Just discovered this website.. very helpful! .. thanks a lot!


    Only the gain slider doesn’t work for me (Firefox 29 on Mac OSx)

    • Nigel Redmon says:

      Hi Luca—I’m glad you like the site, thanks for saying so!

      Note that the gain slider affects only peak and shelf filters. Notice that the gain field is disabled for others (try to change it). In most browsers, you’ll see that the gain field is dimmed for the other filters, but for some reason Firefox does not dim the field when disabled. Also, under Safari and Opera, the sliders update in real time as they move, not just upon release of the mouse button, making the experience a lot better than in Firefox or Chrome at this time.


      PS—Sliders updating on drag should now work on all browsers.

  7. Burns Fisher says:

    Really helpful! Thanks! The coordinates work great in the CMSIS library for ARM. A couple questions, though: 1) The gain slider seems to have no effect either on the graph or the output. The output seems to have 0 gain (which is really what I wanted) despite saying 6db in the slider.

    2) If I wanted to implement two stages of biquad, would I just use the same coefficients again? I don’t see anywhere a way to calculate biquad coefficients beyond the first stage.

    Thanks again for such a useful page!

    • Nigel Redmon says:

      1) Try a newer browser—it’s an html5 feature, so it won’t work in old browsers, and I know that previous versions of Firefox didn’t have them working right either.

      2) No, because the corner will have a 6 dB rolloff instead of 3 dB, for a Butterworth (Q = 0.7071) lowpass. Do a search on cascading biquads, or factoring higher order filters into biquads. Basically, for a fourth-order Butterworth lowpass made from biquads, the Q settings will be different for each section in order to form the intended corner. But, if your application is not so picking about the definition of the corner, then maybe identical settings are fine.

    • Can you be more specific on how you get up the co-efficents in CMSIS, I am trying and it seems the A and B terms are reversed. ARM says {b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, …}
      seems b10 would be a0
      seems b11 would be a1
      seems b12 would be a2
      seems a11 would be b1
      seems a12 would be b2

      • Nigel Redmon says:

        You are correct—as I said, there is no standard for A and B, but the dead giveaway is that in a normalized filter, it’s easy to tell which are which. (The output index-0 coefficient is normalized to 1, and is left out—in my case b0, in their’s a0.)

  8. LH says:

    This is a great tool. Would it be possible to add group delay calculation to this, please?

  9. CK says:

    So useful. Any plans for butterworth filters?

    • Nigel Redmon says:

      Easy—just use 0.7071 (1 divided by the square root of 2) for Q! The calculator defaults to that setting when it opens.

      • CK says:

        Thanks for the response. I mean higher order Butterworth filters to get those really sharp corners.

        • Nigel Redmon says:

          You can convert a higher-order Butterworth prototype with the inverse z transform. Higher orders are increasingly more sensitive to numerical errors, though, so you’d have to evaluate numerical properties for a given filter setting, at a given numerical precision (64-bit floating point, for instance). To avoid that, you can cascade multiple lower-order filters, such as first and second order. You can find a helpful table in wikipedia by searching for “Butterworth filter”. For instance, it lists (s^2 + 0.7654s + 1)(s^2 + 1.8478s + 1) for fourth-order. That means that you need one biquad with a Q of 1/0.7654, followed by another with Q 1/1.8478.

          • Joe P says:

            Hi Nigel,

            Thanks for sharing your work. One thing I don’t understand is the definition of Q, which seems to vary with the type of filter. The specs I get from control engineers define notch (and bandpass) filters in terms of a sample frequency, notch center frequency, and bandwidth, defined as the difference between -3dB frequencies. For example, fs = 200, fc = 3.3, bw = 1, all in Hz. Can you explain how to computer Q for a Butterworth filter with these specs?


          • Nigel Redmon says:

            Joe, there are definitely different interpretations for Q, especially for bandpass, peak, and shelving filters. And note that many of the classic analog EQs deviate from engineering-type definitions. Refer to Robert Bristow-Johnson’s well-know biquad reference, “Cookbook formulae for audio EQ biquad filter coefficients” for comments on bandpass. (Note that despite different formulas, most of his filters are mathematically identical with mine, with the same approach but different factoring; I think the main exception is our shelving implementations.)

  10. florian says:

    Is there any workaround so that I could use the following settings:
    Sample Rate: 12kHz
    FC: 7kHz
    with the peak filter?

    • Nigel Redmon says:

      7kHz is more than half the sample rate of 12kHz—it’s above the highest frequency you could play back. (Of course, you could say that setting an Fc of 5kHz would be the same as 7kHz, since the response is mirrored around half the sample rate.)

  11. Roger Jonsson says:

    Thank you for a very useful and informative page.

    However the one pole hp does not seem to behave like a normal one pole hp filter…

    • Nigel Redmon says:

      Glad you like it, Roger. The hp works correctly, but it’s simply a one-pole (no zero). That makes it of limited value, and is only here for illustration and completeness. I included it because I commented on it in the one-pole article. But for a DC blocker, for instance, a better solution is to subtract the one-pole lp from its input.

  12. Oleg Naumenko says:

    Overall fantastic tool to study filters!
    However, looks like lowshelf ans highshelf responses are not precise – or am I missing something? As far as I know, with this type of filter, the Fc (center frequency) is a point of half the magnitude swing of the filter, however, it’s not the case on this plot.

    If You set Fc at 1391 Hz (so it is right at the corresponding vertical grid line), and apply – 6 dB gain, You clearly see that it’s shifted in frequency – so that 1391 Hz is not at -3 dB.

    What is wrong in my assumptions?

    … and it’s worth mentioning I meant using log scale for better clarity

    • Nigel Redmon says:

      Hi Oleg—thanks, and good points. First, the Fc definition of shelves depends on the implementation. Digital Performer’s Master Works EQs behave exactly as mine do. At a glance, Waves’ REQ works that way too. But their (very old) Q seems to use mid-point (as do rbj’s cookbook shelves). But I don’t think mid is the norm—I think it’s corner for analog EQs, and most modern digital EQs emulate them. Lastly, it make sense logically, as the pole-zero angles remain constant at the frequency for any gain value—the same as if you were mixing a lowpass filter with variable gain with the direct signal (ignoring phase issues). The only advantage to picking the middle is that you can get by with a single equation.

      But I don’t see the shift you mention. For instance, set Fc to 1391.3 Hz, and set Gain to any multiple of 10, plus 3—positive or negative, high or low shelf (-43, -33, -23…); you’ll see the plot cross at 3 dB closer to unity (-40, -30, -20).

      • André says:

        Hello Nigel,

        When zooming in (using Matlab), I do see an offset in the cutoff frequencies for the shelf filters; for example, configuring a low shelf filter with Fc = 1391.3 and G=13dB, the frequency response crosses 10dB at f=1426Hz. I see something similar for high shelf filters, but then I measure Fc=1357Hz. How can this be fixed?

        • Nigel Redmon says:

          Without checking, that’s probably about right. It’s the nature of a shelving filter, if you set the shelf to +3 dB, obviously it won’t drop 3 dB by the requested corner frequency because the slope is limited to 6 dB per octave. It’s closer at +13 dB, but there is no expectation that the response will be down 3 dB at the corner frequency. Unlike lowpass and highpass, which have well-accepted definitions, there are many ways to define shelves. If you have a lot of EQ plugins, play with the shapes of each—you’ll be surprised how many different ways they are implemented. My shelves keep the shelf frequencies constant (as does MOTU’s MW EQ; I don’t know for sure, but I’d guess most analog shelving filters work this way too, as they’re often a lowpass with gain, summed with the direct signal), which means the top corner of a shelf boost will remain in the same place as you change gain, and the corner near the 0 dB baseline will move. Some keep the baseline corner constant (I’ve seen in before, don’t recall who—worst musical choice, in my opinion), with the boost corner moving, some define the frequency to be the center of the slope (Waves Q, Izotope Neutron EQ).

  13. Oleg Naumenko says:

    Thank You for Explanations… Now clear …

  14. Tom Andersen says:

    Thanks for the site.

    It would be great if one could form a URL that would be for a certain filter: EG

    That way one could send filters to other people, etc..

    Thanks again,


  15. Mark Hudson says:

    Great site to have stumbled across! Loads of good reading and well written explanations, as I tread slowly to some understanding of audio DSP!

    I have some working biquads based on the RBJ cookbook and am now trying to produce visuals/graphs of frequency response like the ones shown on this calculator, and like the ones you get in VST EQ plugins etc. Any chance of a head start in what I should be plotting and a few lines of code to show me how it was achieved here? I think I should be plotting 20Log|H(z)| as y axis data but I can’t get it to work.

    Yours hopefully

    • Nigel Redmon says:

      Hi Mark…There is more than one way to do it, but a fairly simple one if you are starting from pole/zero coordinates is to walk around the unit circle (from 0 to pi is sufficient, since the other half is symmetrical) and for each point, take the products of the lengths of the vectors drawn from each zero to that point, divided by the product of the lengths of vectors from the poles (two of each for a biquad).

      Of course you get there directly from coefficients with some manipulation…looking at my Java code on this webpage, that’s what I’m doing. I’m reluctant to google and put up a link to somewhere else here, but I have no control over the link becoming obsolete later, but just do a search on magnitude response of a biquad. Remember that my “a” coefficients are on top of the transfer function, possible reverse of what you might find elsewhere.


      • Mark Hudson says:

        Hi Nigel

        Thanks for your reply. I have been trying with the 2nd approach i.e working from the coefficients using RBJ’s comments and manipulations from here :!topic/comp.dsp/jA-o05autEQ

        but I am going wrong somewhere. I will carry on trying though, as I do get something vaguely resembling the curves I expect but I know they’re not right!

        As well as your a’s and b’s being swapped I also noticed in one article that you comment that your implementations for low & high shelf are more symmetric for boost/gain than RBJ’s so I am trying them now.

        Great site to read/learn from so far but I still have some way to go! 🙂


        • Nigel Redmon says:

          Hi Mark,

          OK, it’s looks like you’re doing the same thing I’m doing—take a look at the source of this page. It depends on the browser, but for Safari, for instance, right click on the page and Inspect Element (maybe this needs the developer menu enabled?), and look at biquad2.js. Look for the look that calculates phi. It seems the only change is swap a for b, the signs look the same at a glance.

          As far as the shelves…I recall looking again, and concluding that Robert’s shelves and mine (after Zölzer) behaved the same. Robert added a Q control, but it’s not a musically desirable one. I did some work on a more desirable Q control (one that doesn’t peak on the shelf), but didn’t completely work out the control details. I decided I probably needed to make a tool that let me play around in the s domain to figure out the interaction I wanted—left for when I have more time, or actually need such a shelf.

          For the other filters, the only difference between Robert’s and mine are factoring (sin/cos instead of tan).


        • Nigel Redmon says:

          BTW, you can also do it with FFT. First, it should be obvious that you can plot the FFT (magnitude) of an FIR filter, since it’s equivalent to the impulse response—just zero pad it to the length you want. For a biquad (or higher order IIR), you can take the magnitude of an FFT of the numerator (a) coefficient, divided by the magnitude of an FFT of the denominator coefficients (b—but don’t forget to include b0=1.0, since we’ve normalized the coefficients), similarly padded. Anyway, I think that’s right, but check it in case I’m forgetting a detail.

          • Mark Hudson says:

            Many thanks Nigel for taking time to help me!

            I have looked at your biquads2.js script and it seems as I have a very similar approach, but my plots are just wrong for some reason. I am using plain java (actually “Processing” if you have ever used that as it’s great for visual and GUI things as well as being an easy IDE to use and code with for non-experts like me!), so some of the Javascript commands are unfamiliar. I will spend a few hours learning and see how it goes, as although the equations and maths used seem the same as yours, my plots are just wrong.

            I will get there:) and once done will have a look at the FFT route. which is on my list of things to do anyway at some time.

            Best regards

  16. Mark Hudson says:

    Got it! A few issues inc doing normalizing twice for coefficients and not properly using a log scale for plotting. Many thanks for all your help


  17. Olteanu Ramona says:

    It is a great site indeed, but there is something that i’ve stumbled on. For the bandpass filter, there is only one frequency instead of two. Then, i discovered that, the bandpass limits are F1=Fc/2 and F2=2*Fc, which means that F2=4*F1. Is there a solution to this problem? I think that the limits shouldn’t be calculated but instead, to be specified by the user.

  18. Kiran Ramsaroop says:


    Great blog – it’s coming in very useful for my home project. I’m currently trying to do some pipe cleaning exercises, then plan to try and implement a H-infinity optimisation process to tune the gains according to some objective function.

    However, I’m having a bit of difficulty getting off the ground with my Matlab simulation – I’ve implemented the biquad in Direct Form I and copied your filter coefficients from a highpass filter with fc=5kHz and Q=0.7071. My cut off is in roughly the right place, I’ve normalised with a gain of 2=6dB on the output and am using a discrete solver. However, my Bode has the wrong slope! Whilst your’s is around +25dB/decade, mine is around half of that. At the Nyquist/1000 breakpoint I still have -44.9dB.

    I reckon I’ve implemented it correctly as per

    But what could I have messed up to give me half the slope?! Thanks in advance…

    • Nigel Redmon says:

      Sorry, Kiran, this came in when I was away for the year end, and just realized I hadn’t answered. I don’t know, without seeing exactly what you’re doing, and don’t want to guess. I hope you’ve sorted it out by now.

      • Kiran Ramsaroop says:

        No Problem – I actually went away and came back to the problem, so it’s just resurfaced… But the plot thickens. I’m sure I’m just doing something daft.

        The coefficients from your calculator are:

        a0 = 0.600716795914846;
        a1 = -1.201433591829692;
        a2 = 0.600716795914846;
        b1 = -1.035121791879154;
        b2 = 0.36774539178022964;

        I’m using a normalising Gain of sqrt(2). I’ve set up a Simulink model (discrete) with a sample time of 44.1khz, and have drawn it in direct form I with the normalising gain stuck right on the output.

        But then I use your equations to get the gains, as referenced in the source code. I expected them to come out with what your calculator gives me, but instead I get:

        fc = 5000;
        K = tand(pi*f/fc);
        Q = 1/sqrt(2);

        norm = 1 / (1 + K / Q + K * K);
        a0 = 1 * norm;
        a1 = -2 * a0;
        a2 = a0;
        b1 = 2 * (K * K – 1) * norm;
        b2 = (1 – K / Q + K * K) * norm;
        G = sqrt(2);

        a1 = -0.9908
        a2 = 0.4954
        b1 = -0.7175
        b2 = 0.2641
        G = 1.4142

        So… the outputs and the gains appear different! The gradients of the slope are the same, but the coefficients from the calculator give me a Fc of around 2500Hz, whether when I use your equations and calculate, they look pretty much around 5kHz as requested.

        Any ideas?!

        • Nigel Redmon says:

          I put the parameters in another biquad calculator on the web, and it came up with the same results as mine.

          But I see “tand” in your code, instead of “tan”—isn’t that tangent in degrees in matlab? Or a typo?

      • Kiran Ramsaroop says:

        Aha – I’ve made an arithmetic error and matched the output from the two methods… However, the slope and values from the Highpass just above is a bit different to what I have for the two methods in Matlab – it’s as though your x-axis has the wrong scale?

  19. James says:

    I’d like to transpose the biquad designer from js (actually into C++).

    I’d keep your copyright – but there is no license in the js file, and I’d like to play fair.

    Also – if you ever feel a need to do something more, a Linkwitz Transform calculator would be really helpful.

    In an answer above, you mention using a subtractive filter with input-lowpass. Under what circumstances is a subtractive approach a good one to use?

    Thanks for a great site.

    • Nigel Redmon says:

      Please feel free to do so. My C++ filter code is the same (I translated it to js for the widget). The graphing code would be totally different, but the fft and magnitude calculations are pretty much the same in C or js.

      As for subtracting, I assume you’re referring to my comment about a DC blocker? In general, subtracting (or adding) a filter’s output to the input signal will not give you the sum of magnitudes, due to phase shift induced by the filter around the cutoff. That’s especially evident in second-order and higher order filters. But it’s inconsequential in a DC blocker because it’s sub-audio.

  20. Rev. Hector Forbes says:

    Amazing: your calculator’s 5 numbers plug straight into the biquad filter module in SynthMaker, even that free v1.0.5 from Computer Music magazine! Can’t use 6 coefficients see, no “b0” pin! & my maths is the worst of anyone here! They plug right in & they work! Now I can make that bank of resonant (Q≈100) bandpass filters I need for the core of my audio to midi Vst plugin! I’m going to be rich… But don’t worry, I’m giving it all to my local donkey sanctuary!

  21. Couple things…. I want to use this in ARM CMSIS biquad library and it seems the A and B terms are reversed? also would love a single pole bandpass option! 🙂 I need high, and low, and BP for a small audio app I am doing on an M3

    • Nigel Redmon says:

      See my comments about A and B elsewhere, but the gist is that I use A on top of the transfer function, as many classic texts do. But there is no standard, so it varies. Watch out for signs of the numerator coefficients too, as some folks roll the subtraction into an addition and sign flip. Sorry about that, it’s just the way it is.

      And there is no one-pole bandpass. It requires a complex pole, and that means you’ll have a pair.

      • So I did learn the hard way about the +- of the coefficients … 🙂 Someone pointed out to me that the last 2 when used in the ARM CMSIS DSP libs, would need a sign change.

        a0 = 0.9733553098104358
        a1 = -1.9467106196208717
        a2 = 0.9733553098104358
        b1 = -1.9447880283614938
        b2 = 0.9486332108802497

        a0 = 0.9733553098104358
        a1 = -1.9467106196208717
        a2 = 0.9733553098104358
        b1 = 1.9447880283614938
        b2 = -0.9486332108802497

        and it seems to work. If the signs were left alone the data output “ran away to infinity” 🙂


  22. Richard says:

    Hello, I want draw this Q- Factor graph.

    Could you please share code?


    • Nigel Redmon says:

      You can view javascript from any site, depending on your browser (for instance, enable the Develop menu in Safari via Preferences/Advanced). But here’s a direct link.

  23. Mikhail says:

    Nigel thanks a lot for a useful tool, and a great site overall!

    For anyone who wants to make a frequency response plot for the filter with calculated coefficients in MATLAB / Octave, here is how to use them with `freqz’ function to get a graph in Hz:

    freqz([a0, a1, a2], [1, b1, b2], , 0, );

    should be a power of 2, e.g. 512
    `0′ is to get a graph with frequencies up to / 2 Hz

  24. KH says:

    Hi Nigel,

    I just wanted to pop in for a second and thank you for your detailed and helpful explanations/examples for making biquad filters. I’ve been hopping around online for a few weeks trying to understand how to make a basic audio filter, and your site was easily the most helpful. Specifically, this biquad calculator is an excellent tool. Beforehand, I was just guessing-and-testing different values without any understanding of what they were actually doing. Your biquad filter class in C was also incredibly helpful to get myself up and running in implementing a working filter. I absolutely have a much better understanding of how this stuff works thanks to your help.


  25. Cleric says:

    This is very useful tool. Please add Phase response also, just like at
    Now I have to copy-paste the coefficients there to see the phase response.

  26. der says:

    If we wish to handle a wave the fundamental frequency of which is a4 (440hZ), which frequency we can choose (Fc- Hz)? I would want to use the filter biquad-lowpass.
    For the parameter “Q”, I do not know what to choose. I would want to use a biquad filter in Nyquist prompt of the software Audacity 2.
    Thank you.

    • Nigel Redmon says:

      I’m not sure what you’re looking for. Do you intend to remove frequencies other than the 440 Hz fundamental?

      • der says:

        Let us imagine a sound with harmonics sounds. This sound has a fundamental frequency of 440 hz. Can we eliminate the fundamental frequency not to hear more than the harmonious sounds? Is it necessary to use the notch filter?

        • Nigel Redmon says:

          That is correct—you’d use a notch filter to remove a specific frequency.

          • der says:

            Thank you.
            But: Can we act on the opening of the bandwidth ? Apparently, on the page, ” cascading filters “, we can fix the parameter Q for filters highpass and lowpass only).

          • Nigel Redmon says:

            A notch filter is a different animal. A second order notch has perfect rejection at the center frequency (which is subject to numerical precision). In addition, the Q factor moves the poles closer to the unit circle, essentially sharpening the notch as you can see by playing with it. Cascading with different Qs can affect that rolloff somewhat, but probably not the degree of control you’d want for musical purposes (say, if you wanted to reject a range of frequencies). If you do want more control, you’ll do better with following cascaded lowpass biquads with cascade highpass, letting you control the width of the notch.

  27. Skyler says:

    I am currently translating the highself to c++. I have seen success, However, I am curious to the difference in coefficients when log is selected verses linear.

    I was not able to find a difference in the javascript, you posted earlier in the thread!

  28. John Mulcahy says:

    Bit dubious about the first order filter implementations – are they missing BLT by any chance? The first order high pass in particular leaves a little to be desired as implemented, only a few dB of attenuation at DC per the plot 🙂

    • Nigel Redmon says:

      Hi John—they aren’t “first order” filters, they are “one-pole” filters (that is, the corresponding zero is at the origin, no degree of freedom). I do mention the limitations with trying to make a highpass from a one-pole, in my source code article—it’s mainly here for completeness (but you can subtract a lowpass one-pole from the input for a better one, suitable for a DC blocker).

      • John Mulcahy says:

        If they are included to use in cascades with biquads for odd order filters don’t they really need to be first order filters, BLTs of the real pole of the odd order function?

        • Nigel Redmon says:

          The only features we’re concerned with are filter order, frequency, and Q. As first order, Q is always 0.5, and it doesn’t matter what method (BLT or otherwise) we use. The difference between a one-pole and first-order lowpass is that the latter has a zero at the Nyquist frequency to give it a null there in the frequency response.

          • John Mulcahy says:

            Perhaps there is some difference in our use of terminology, but the BLT of a real s-plane pole does not produce the biquad coefficients your calculator produces. I don’t think I’m alone in thinking that, here is someone else’s take on it, with an option to calculate for 1st order Butterworth low pass so a single real s-plane pole: Perhaps you are referring to z-plane poles? The odd orders of filter transfer functions are due to real s-plane poles, however. We may well be simply talking at cross purposes and I have simply misunderstood what your calculator is trying to convey, but using your coefficients in implementing an odd order filter using cascaded biquads would not produce the transfer function one might expect.

          • Nigel Redmon says:

            We’re talking about two different things. I’m not sure you understood what I was getting at in my last post, so I may overdo it here, bear with me. Yes, this is a biquad (as in biquadratic) filter coefficient calculator. For the second order filters, the calculator uses the BLT of standard s-plane filters. But for the one-pole (1p) filters, it does not. The other calculator you link to does not calculate one-pole filters for its 6 dB/oct choice, it calculates one-pole, one-zero (1p1z) filters.

            Neither is ideal—the 1p response doesn’t dip enough as its nears the Nyquist frequency, the 1p1z dips too much. I don’t have a 1p1z, but you can get the idea by looking at the one-pole lowpass on a log scale at 1k/48k, noting that it flatness out, then switching to the (second order) lowpass and see it dive with the zeros at Nyquist.

            So which is better? The 1p requires fewer operations to calculate. This makes it a great choice for a lightweight smoothing filter (for parameters, for building blocks of other low-frequency components such as noice gates). I haven’t had the motivation to develop a 1p1z filter in these pages—I don’t think I’ve ever needed a plain 1p1z lowpass in my own work (1p1z with freedom of both pole and zero, yes, but with zero fixed at Nyquist, no).

            As for using a 1p along with BLT-derived biquads in order to make an odd order filter, what are we giving up? The 1p doesn’t dip enough near Nyquist…but the biquads all dip too much. Put another way, you already have plenty of zeros at Nyquist (two per BLT-biquad), why do you need one more? But I’m not implying that you need to use my one-pole when cascading, just that I present no other choice at this website.

  29. John Mulcahy says:

    The extra zero is kind of the point of the BLT though, a little inconsistent to use BLT for the 2nd order sections and not for the first. Your article on cascaded biquads does refer folk here so they might imagine that in using the biquad coefficients for the sections of an odd order filter they are getting the BLT of the whole filter transfer function, not just the even orders. I’m sure the world will keep turning either way though 🙂

    • Nigel Redmon says:

      I think you’re conflating filter order with how such filters are derived in the digital domain. The BLT is one compromise—spectacularly far from the ideal response as Fc nears Nyquist. But you can make these cascades from all-pole filters such as the state-variable structure, or from two pole, one zero direct forms. I don’t know why you think it’s important to have exact BLT response, but I don’t consider it an inconsistency on my part, I think I’ve been clear.

  30. Andy Piper says:

    Hi Nigel, thanks for this tool – it’s great.
    Do you happen to know the equations for an IIR notch with variable gain? I have been having back and forth discussions with different experts in the flight controller community who all use notch filters with different implementations and I am struggling to reconcile the differences. I have noticed that the peaking EQ filter with negative gain sort of works with very high Q – but I’m not sure that’s exactly what I want.

    • Nigel Redmon says:

      Notch with variable gain…to me, a notch filter has the zeros on the unit circle—that’s complete attenuation at that point—and the sharpness is determined by how close the corresponding (same angle) poles are inside the unit circle. There is no actual gain, that would be more like a peaking filter with negative gain, as you said.

  31. Marc says:

    Hey Nigel. I’ve been trying to generate these filter plots in Excel, but have hit an impasse. I figured your tool here and this bode plot generator would be good place to start . I’ve had zero luck getting any plot resembling anything close to a peak filter.
    I thought the corresponding coefficients would be (right=your coefficient, left= excel coefficient). I suspect I’m making some fundamental error. Do you have any idea on where I’m going wrong? Any assistance would be much appreciated.


    • Nigel Redmon says:

      Hi Marc. The Excel calculator is plotting in the s-domain, not the z-domain. See my article on evaluating filter frequency response for z-domain.

      • Marc says:

        Thanks Nigel. With the help of that article, I eventually got my Excel program working.
        I noticed that your coefficient equations for the Peak filter differs from the RBJ equations. Do you happen to know which is more commonly used in music focused EQ programs? (such as EqualizerAPO)

  32. Fredrik says:

    I made a script derived from

    and I don’t get the same values from this site.

    With these arguments:
    f0 = 10000.0
    fs = 44100.0
    q = 1
    bq_type = “BQ_LP_E”

    My script yields:
    a0 = 0.427240
    a1 = 0.854481
    a2 = 0.427240
    b0 = 1.494678
    b1 = -0.291038
    b2 = 0.505322

    This site:
    a0 = 0.28584114740229055
    a1 = 0.5716822948045811
    a2 = 0.28584114740229055
    b1 = -0.1947165117031973
    b2 = 0.33808110131235947

    Here’s the script…

    • Nigel Redmon says:

      They are the same. We typically normalize the response to unity gain, which means scaling coefficients by b0, the output gain. Your coefficients are the same as mine once you divide by b0. Also, you can see the response is the same by checking with my frequency response grapher.

      • Fredrik says:

        Thank you! Aha, I see now. If I’d look more carefully I could have realized that. I do this in hardware, an FPGA, I might have to do this, too, else I might get an overflow if I have no more bits left. ^^

  33. markzzz says:

    Hi Nigel,

    shouldn’t the Q factor be set as “log” scale?
    I notice that shape between [0.0, 1.0] values are faster in change…

    Than from [1.0, 10.0] the change is slower.
    Shouldn’t be better set the whole range in log scale? For a “smooth” change?

    Any tips?

    • Nigel Redmon says:

      Maybe. But the slider is just a convenience for playing with the graph, to get accustomed to the frequency response of various filters at difference settings and view points (log, linear). For instance, the slider only goes to 10, but you can type in a Q of 100.

      • markzzz says:

        Yes. What I mean is: I’d like to scale the whole range. So “middle” of the slider would be lower value than 5.0. As a freq know would do it. Exp scale? Make it sense for a Res setting in a real audio plugin?

        • Nigel Redmon says:

          Sure, that’s reasonable. You could do curve or piecewise linear (audio “log” taper potentiometers are typically just two linear segments, but you have more). Some of my plugins have eight linear segments for each control (table of nine endpoints), to shape the response to whatever feels good. It doesn’t need to be a mathematically simple curve, just a practical one.

          • markzzz says:

            Nice. Example of “table with 9 endpoints”? What do you mean with it? Linear scale that change “rope” due to the position?

          • Nigel Redmon says:

            First, if you do want a smooth curve that can be adjusted between log, linear, and exponential, you can: min + pow(normalizedValue, shape) * (max – min). Normalized means the control is 0-1, when shape is 1 it’s linear, above is degree of exponential.

            But here’s what I mean piecewise linear from a table; let’s say you a control for delay time from 1 ms to 10 sec. Linear would be a disaster, because the low end wouldn’t have enough resolution, while the high end would have too much. The control produces 0 to 1, the normalized value, and you want time in seconds, for instance. I’ll give an example with four segments (five endpoints), for brevity. You might have a table 0.001, 0.05, 0.12, 0.6, 10.0. So, you can think of the control as halving four zones. If the control value is between 0 and 1/4, then its value is used to interpolate between 1 and 50 milliseconds, linearly. So, essentially lowerIdx = int(controlVal * 5) gives you the index to the min value, lowerIdx + 1 for the max (but limit to 5), and controlVal – lowerIdx gives you a number between 0-1 to interpolated between min and max.

  34. markzzz says:

    hi master,

    what’s the fastest way to “invert” q?
    min q value = narrow shape
    max q value = wide shape

    for each filter which use q (peak, bandpass, etc)


Leave a Reply to Nigel Redmon Cancel reply

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