Type:lowpasshighpassbandpassnotchpeaklow shelfhigh shelf Plot:linearlog
 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.

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

There is an even more improved version here.

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

### 37 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.

• Nigel Redmon says:

😉

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;

x=x;
x=x;
x=current_sample;
y=y;
y=y;
filtered_sample= a0*x + a1*x + a2*x + b1*y + b2*y;
y=filtered_sample;

y=y;
y=y;
filtered_sample= a0*x + a1*x + a2*x + b1*y + b2*y;
y=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:

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. Adriano Mitre says:

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. Adriano Mitre says:

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. Fredrik Carlqvist says:

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. Adriano Mitre says:

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 .

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

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

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

• Nigel Redmon says:

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. Adriano Mitre says:

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  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 .

 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:

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. Adriano Mitre says:

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 , 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.

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

• Nigel Redmon says:

14. Adriano Mitre says:

Below I present very accurate approximations in Ruby code for converting between corner (LPF/HPF -3 dB)  and midpoint (G/2 in dB) witt S = 1  high/low-shelves cutoff specifications.

```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
```
15. Akshay says:

Hi, I am experimenting with IIR’s and very new to it. Is it possible to design 1st and 2nd order phase filters? I tune cars and there is normally a phase mismatch between transducers in the 100-250Hz range and then again from 500-750Hz. I normally use a Petroff or Phase changer. Thanks, Akshay

• Nigel Redmon says:

Hi Akshay—I think you’re interested in allpass filters, which don’t affect frequency response, but shift phase in a frequency-dependent manner.

16. fde says:

hello. I trie to use a biquad-m Nyquist filter. There are 6 parameters. In particular, parametrize b0. How do we calculate it?

• Nigel Redmon says:

There are six parameters in a biquadratic equation, but we usually normalize the output for unity gain, by dividing all parameters by the output gain parameter so that it becomes 1.0 and no multiplication is needed. See The bilinear z transform.

17. Richard Hodges says:

Could you please share code, or just math formulas, for calculating biquad coefficients a0 a1 a2 b1 b2 from Fs Fc Q and Gain, as in your biquad calculator?

Thanks,
Richard

• Nigel Redmon says:

Hi Richard,

You can find the formulas in Javascript here, Biquad formulas, and C++ source here, Biquad C++ source code. One tip I can give you is to scroll down on the right-hand column to a topic, and click—biquads for instance—to get related articles.

Nigel

18. Park Ik Soon says:

Hello, I want draw this this Q- Factor graph

Thanks

• Nigel Redmon says:

Use you browser’s debugging feature to look at or download the javascript files and see the html code.

19. vcelkamaja says:

Hello, is it possible to use biquad IIR filter to realize phase inversion? Rather than switching speaker terminals to invert the phase in a crossover, I would like to do it in biquad. Is it possible?

• Nigel Redmon says:

Sure, you can invert the signal by multiplying by -1, of course. But looking at the flow of the direct form I biquad, you can see that flipping the sign of the three input coefficients (a0, a1, a2) does the same thing.

• vcelkamaja says:

Yes, this was also my thought process – to multiply it by -1. Unfortunately I can’t do it as my biquads are “hard-coded” in a specific IC (Texas Instruments TAS5518) where I can only setup coefficients by setting up numbers into specific registers – there are registers for b0, b1, a0, a1, a2 coefficients (check page 19: http://www.ti.com/lit/ds/symlink/tas5518.pdf).
Based on your previous recommendation – should I change the sign (multiply all a0, a1 and a2 by -1) to invert the phase?

• vcelkamaja says:

Actually in my case (TAS5518 datasheet, page 19) it seems they call the input coefficients b0, b1, b2 (on your web page you call them a0, a1, a2). So I guess I should multiply all three of them by -1, right?

• Nigel Redmon says:

That’s right. The filter is linear, so inverting the output is the same as inverting the input, and as the direct form I diagram makes clear, inverting the input multipliers (coefficients—b0, b1, b2 in your case) is the same as inverting the input.

20. vcelkamaja says:

Great, it works – multiplying all b0, b1 and b2 coefficients by -1. Thanks a lot for your help

21. Justin Cao says:

One of my project needs high Q negative gain peak filter. Filter coefficient generated by your code differs to RBJ’s.
I use following parameter for test:
Fs = 48000Hz
Fc = 1000Hz
Gain = -10dB
Q = 5

Original C code:
} else { /* Gain < 0 */
V0=pow(10.0,-G/20);
b0=(1+K/Q + K*K)/(1+V0/Q*K+K*K);
b1=2*(K*K-1)/(1+V0/Q*K+K*K);
b2=(1-K/Q + K*K)/(1+V0/Q*K+K*K);
a1= b1;
a2=(1-V0/Q*K+K*K)/(1+V0/Q*K+K*K);
}

Change to:
} else { /* Gain < 0 */
V0=pow(10.0,-G/40);
b0=(1+K/(Q*pow(10.0,-G/40)) + K*K)/(1+V0/Q*K+K*K);
b1=2*(K*K-1)/(1+V0/Q*K+K*K);
b2=(1-K/(Q*pow(10.0,-G/40)) + K*K)/(1+V0/Q*K+K*K);
a1= b1;
a2=(1-V0/Q*K+K*K)/(1+V0/Q*K+K*K);
}

By the above change, It seems I can get the same coefficient as RBJs:
http://shepazu.github.io/Audio-EQ-Cookbook/audio-eq-cookbook.html
There is an online calculator here:
• Nigel Redmon says:
22. Anuj Bij says: