-
Notifications
You must be signed in to change notification settings - Fork 22
/
audio-eq-cookbook.html
512 lines (507 loc) · 17.4 KB
/
audio-eq-cookbook.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cookbook formulae for audio EQ biquad filter coefficients</title>
<script>
MathJax = {
tex: {
tags: 'ams'
}
};
</script>
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js">
</script>
<style media="screen">
body {
width: 45em;
margin-left: auto;
margin-right: auto;
}
.label {
font-style: italic;
color: gray;
}
dl {
margin: 2em 0;
padding: 0;
font-family: georgia, times, serif;
}
dt {
position: relative;
left: 0;
top: 1.1em;
width: 10em;
font-weight: bold;
}
dd {
border-left: 1px solid gray;
margin: 0 0 0 11em;
padding: 0 0 .5em .5em;
}
</style>
</head>
<body>
<h1>Cookbook formulae for audio equalizer biquad filter coefficients</h1>
<dl>
<dt>Author</dt>
<dd>
<a href="mailto:[email protected]">Robert Bristow-Johnson</a>
</dd>
<dt>Editor</dt>
<dd>
<a href="mailto:[email protected]">Doug Schepers (W3C)</a>
</dd>
</dl>
<p>Adapted from <a href=
"https://webaudio.github.io/Audio-EQ-Cookbook/Audio-EQ-Cookbook.txt">Audio-EQ-Cookbook.txt</a>,
by Robert Bristow, with permission.</p>
<section>
<h2>Biquad Filter Formulae</h2>
<p>All filter transfer functions were derived from analog prototypes (that
are shown below for each equalizer (EQ) filter type) and had been digitized
using the Bilinear Transform (BLT). BLT frequency warping has been taken
into account for both significant frequency relocation (this is the normal
"prewarping" that is necessary when using the BLT) and for bandwidth
readjustment (since the bandwidth is compressed when mapped from analog to
digital using the BLT).</p>
<p>First, given a biquad transfer function defined as:</p>
<!-- displayed-eqn is just a random tag to keep html tidy from indenting the
contents which could mangle the equations. It's not used for anything else, and
it's not a custom element.
-->
<displayed-eqn> $$
\begin{equation}
H(z) = \frac{b_0 + b_1z^{-1}+b_2z^{-2}}{a_0 + a_1z^{-1}+a_2z^{-2}}
\end{equation}
$$
</displayed-eqn>
<p>This shows 6 coefficients instead of 5 so, depending on your
architecture, you will likely normalize \( a_0 \) to be 1 and perhaps also
\(b_0\) to 1 (and collect that into an overall gain coefficient). Then your
transfer function would look like:</p>
<displayed-eqn> $$
\begin{equation}
H(z) = \frac{\left(\displaystyle\frac{b_0}{a_0}\right) + \left(\displaystyle\frac{b_1}{a_0}\right)z^{-1}+\left(\displaystyle\frac{b_2}{a_0}\right)z^{-2}}{1 + \left(\displaystyle\frac{a_1}{a_0}\right)z^{-1}+\left(\displaystyle\frac{a_2}{a_0}\right)z^{-2}}
\label{direct-form-1}
\end{equation}
$$
</displayed-eqn>
<p>or:</p>
<displayed-eqn> $$
\begin{equation}
H(z) = \left(\frac{b_0}{a_0}\right) \frac{1 + \left(\displaystyle\frac{b_1}{b_0}\right)z^{-1}+\left(\displaystyle\frac{b_2}{b_0}\right)z^{-2}}{1 + \left(\displaystyle\frac{a_1}{a_0}\right)z^{-1}+\left(\displaystyle\frac{a_2}{a_0}\right)z^{-2}}
\end{equation}
$$
</displayed-eqn>
<p>The most straight forward implementation would be the "Direct Form 1"
(\(eq. \ref{direct-form-1}\)):</p>
<displayed-eqn> $$
\begin{align}
y[n] = \left(\frac{b_0}{a_0}\right)x[n] & +
\left(\frac{b_1}{a_0}\right)x[n-1] + \left(\frac{b_2}{a_0}\right)x[n-2]
\nonumber \\
&-\left(\frac{a_1}{a_0}\right)y[n-1] - \left(\frac{a_2}{a_0}\right)y[n-2]
\end{align}
$$
</displayed-eqn>
<p>This is probably both the best and the easiest method to implement in
the 56K and other fixed-point or floating-point architectures with a double
wide accumulator.</p>
<p>Begin with these user defined parameters:</p>
<dl>
<dt>\(F_s\)</dt>
<dd>the sampling frequency</dd>
<dt>\(f_0\)</dt>
<dd>Center Frequency or Corner Frequency, or shelf midpoint frequency,
depending on which filter type. The "significant frequency". "wherever
it's happenin', man."</dd>
<dt>\(\mathrm{dBgain}\)</dt>
<dd>used only for peaking and shelving filters</dd>
<dt>\(Q\) or \(\mathrm{BW}\) or \(S\)</dt>
<dd>
<dl>
<dt>\(Q\)</dt>
<dd>the EE kind of definition, except for peakingEQ in which A*Q is
the classic EE Q. That adjustment in definition was made so that a
boost of N dB followed by a cut of N dB for identical Q and f0/Fs
results in a precisely flat unity gain filter or "wire".</dd>
<dt>\(\mathrm{BW}\)</dt>
<dd>the bandwidth in octaves (between -3 dB frequencies for BPF and
notch or between midpoint (dBgain/2) gain frequencies for peaking
EQ)</dd>
<dt>\(S\)</dt>
<dd>a "shelf slope" parameter (for shelving EQ only). When S = 1, the
shelf slope is as steep as it can be and remain monotonically
increasing or decreasing gain with frequency. The shelf slope, in
dB/octave, remains proportional to S for all other values for a fixed
f0/Fs and dBgain</dd>
</dl>
</dd>
</dl>
<p>Then compute a few intermediate variables:</p>
<ol>
<li>
<displayed-eqn> $$
\begin{align*}
A &= \sqrt{10^{\mathrm{dBgain}/20}} & \\
& = 10^{\mathrm{dBgain}/40} & \textrm{(for peaking and shelving EQ filters only)}
\end{align*}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
\omega_0 = 2 \pi \frac{f_0}{F_s}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
\begin{align*}
& \cos \omega_0 \\
& \sin \omega_0
\end{align*}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
\begin{align*}
\alpha &= \frac{\sin \omega_0}{2 Q} & \textrm{(case: Q)} \\
&= \sin \omega_0 \, \sinh\left(\frac{\log 2}{2} \cdot
\mathrm{BW} \cdot
\frac{\omega_0}{\sin \omega_0}\right) & \textrm{(case: BW)} \\
&= \frac{\sin \omega_0}{2} \sqrt{\left(A +
\frac{1}{A}\right) \left(\frac{1}{S} - 1\right) + 2} & \textrm{(case: S)}
\end{align*}
$$
</displayed-eqn>
</li>
</ol>
<p>FYI: The relationship between bandwidth and Q is</p>
<p class="label">digital filter with BLT</p>
<displayed-eqn> $$
\frac{1}{Q} = 2\sinh\left(\frac{\log 2}{2} \cdot \mathrm{BW} \cdot
\frac{\omega_0}{\sin \omega_0}\right)
$$
</displayed-eqn>
<p>or</p>
<p class="label">analog filter prototype</p>
<displayed-eqn> $$
\frac{1}{Q} = 2 \sinh\left(\frac{\log 2}{2} \cdot \mathrm{BW}\right)
$$
</displayed-eqn>
<p>The relationship between shelf slope and Q is</p>
<displayed-eqn> $$
\frac{1}{Q} = \sqrt{\left(A + \frac{1}{A}\right) \left(\frac{1}{S} -
1\right) + 2}
$$
</displayed-eqn>
<displayed-eqn> $$
2\sqrt{A}\,\alpha = (\sin \omega_0)\, \sqrt{\left(A^2 +
1\right)\left(\frac{1}{S}-1\right) + 2A}
$$
</displayed-eqn>
<p>is a handy intermediate variable for shelving EQ filters.</p>
<p>Finally, compute the coefficients for whichever filter type you
want:</p>
<p>(The analog prototypes, H(s), are shown for each filter type for
normalized frequency.)</p>
<dl>
<dt>LPF</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{1}{s^2 + \displaystyle\frac{s}{Q} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= \frac{1-\cos\omega_0}{2} \\
b_1 &= 1-\cos\omega_0 \\
b_2 &= \frac{1-\cos\omega_0}{2} \\
a_0 &= 1 + \alpha \\
a_1 &= -2\cos\omega_0 \\
a_2 &= 1 - \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>HPF</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{s^2}{s^2 + \displaystyle\frac{s}{Q} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= \frac{1 + \cos \omega_0}{2} \\
b_1 &= -(1 + \cos \omega_0) \\
b_2 &= \frac{1 + \cos \omega_0}{2} \\
a_0 &= 1 + \alpha \\
a_1 &= -2\cos \omega_0 \\
a_2 &= 1 - \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>BPF<br>
(constant skirt gain,<br>
peak gain = Q)</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{s}{s^2 + \displaystyle\frac{s}{Q} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b0 &= \frac{\sin\omega_0}{2} = Q \alpha \\
b1 &= 0 \\
b2 &= -\frac{\sin\omega_0}{2} = -Q \alpha \\
a0 &= 1 + \alpha \\
a1 &= -2\cos\omega_0 \\
a2 &= 1 - \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>BPF<br>
(constant 0 dB peak gain)</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{\displaystyle\frac{s}{Q}}{s^2 + \displaystyle\frac{s}{Q} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= \alpha \\
b_1 &= 0 \\
b_2 &= -\alpha \\
a_0 &= 1 + \alpha \\
a_1 &= -2\cos \omega_0 \\
a_2 &= 1 - \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>notch</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{s^2 + 1}{s^2 + \displaystyle\frac{s}{Q} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= 1 \\
b_1 &= -2\cos \omega_0 \\
b_2 &= 1 \\
a_0 &= 1 + \alpha \\
a_1 &= -2\cos \omega_0 \\
a_2 &= 1 - \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>APF</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{s^2 - \displaystyle\frac{s}{Q} + 1}{s^2 + \displaystyle\frac{s}{Q} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= 1 - \alpha \\
b_1 &= -2\cos\omega_0 \\
b_2 &= 1 + \alpha \\
a_0 &= 1 + \alpha \\
a_1 &= -2\cos\omega_0 \\
a_2 &= 1 - \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>peakingEQ</dt>
<dd>
<displayed-eqn> $$
H(s) = \frac{s^2 + s\displaystyle\frac{A}{Q} + 1}{s^2 + \displaystyle\frac{s}{AQ} + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= 1 + \alpha A \\
b_1 &= -2\cos\omega_0 \\
b_2 &= 1 - \alpha A \\
a_0 &= 1 + \frac{\alpha}{A} \\
a_1 &= -2\cos\omega_0 \\
a_2 &= 1 - \frac{\alpha}{A}
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>lowShelf</dt>
<dd>
<displayed-eqn> $$
H(s) = A \frac{s^2 + \displaystyle\frac{\sqrt{A}}{Q} s + A}
{A*s^2 + \displaystyle\frac{\sqrt{A}}{Q} s + 1}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= A\left( (A+1) - (A-1)\cos\omega_0 + 2\sqrt{A}\, \alpha \right) \\
b_1 &= 2A\left( (A-1) - (A+1)\cos\omega_0 \right) \\
b_2 &= A\left( (A+1) - (A-1)\cos\omega_0 - 2\sqrt{A}\, \alpha \right) \\
a_0 &= (A+1) + (A-1)\cos\omega_0 + 2\sqrt{A}\, \alpha \\
a_1 &= -2\left( (A-1) + (A+1)\cos\omega_0 \right) \\
a_2 &= (A+1) + (A-1)\cos\omega_0 - 2\sqrt{A}\, \alpha
\end{align*}
$$
</displayed-eqn>
</dd>
<dt>highShelf</dt>
<dd>
<displayed-eqn> $$
H(s) = A \frac{As^2 + \displaystyle\frac{\sqrt{A}}{Q}s + 1}
{s^2 + \displaystyle\frac{\sqrt{A}}{Q} s + A}
$$
</displayed-eqn>
<displayed-eqn> $$
\begin{align*}
b_0 &= A\left( (A+1) + (A-1)\cos\omega_0 + 2\sqrt{A}\alpha \right) \\
b_1 &= -2A\left( (A-1) + (A+1)\cos\omega_0 \right) \\
b_2 &= A\left( (A+1) + (A-1)\cos\omega_0 - 2\sqrt{A}\alpha \right) \\
a_0 &= (A+1) - (A-1)\cos\omega_0 + 2\sqrt{A}\alpha \\
a_1 &= 2\left( (A-1) - (A+1)\cos\omega_0 \right) \\
a_2 &= (A+1) - (A-1)\cos\omega_0 - 2\sqrt{A}\alpha
\end{align*}
$$
</displayed-eqn>
</dd>
</dl>
<p>FYI: The bilinear transform (with compensation for frequency warping)
substitutes:</p>
<p class="label">(normalized)</p>
<displayed-eqn> $$
s \leftarrow \frac{1}{\tan\displaystyle\frac{\omega_0}{2}} \frac{1-z^{-1}}{1+z^{-1}}
$$
</displayed-eqn>
<p>and makes use of these trig identities:</p>
<ol>
<li>
<displayed-eqn> $$
\tan\frac{\omega_0}{2} = \frac{\sin\omega_0}{1+\cos\omega_0}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
\left(\tan\frac{\omega_0}{2}\right)^2 = \frac{1-\cos\omega_0}{1+\cos\omega_0}
$$
</displayed-eqn>
</li>
</ol>
<p>resulting in these substitutions:</p>
<ol>
<li>
<displayed-eqn> $$
1 \leftarrow \frac{1+\cos\omega_0}{1+\cos\omega_0}\frac{1+2z^{-1}+z^{-2}}{1+2z^{-1}+z^{-2}}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
\begin{align*}
s \leftarrow & \frac{1+\cos\omega_0}{\sin\omega_0}
\frac{1-z^{-1}}{1+z^{-1}} \\
& = \frac{1+\cos\omega_0}{\sin\omega_0} \frac{1-z^{-2}}{1+2z^{-1}+z^{-2}}
\end{align*}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
s^2 \leftarrow \frac{1+\cos\omega_0}{1-\cos\omega_0} \frac{1-2z^{-1}+z^{-2}}{1+2z^{-1}+z^{-2}}
$$
</displayed-eqn>
</li>
</ol>
<p>The factor:</p>
<displayed-eqn> $$
\frac{1+\cos\omega_0}{1+2z^{-1}+z^{-2}}
$$
</displayed-eqn>
<p>is common to all terms in both numerator and denominator, can be
factored out, and thus be left out in the substitutions above resulting
in:</p>
<ol>
<li>
<displayed-eqn> $$
1 \leftarrow \frac{1+2z^{-1}+z^{-2}}{1+\cos\omega_0}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
s \leftarrow \frac{1-z^{-2}}{\sin\omega_0}
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
s^2 \leftarrow \frac{1-2z^{-1}+z^{-2}}{1-\cos\omega_0}
$$
</displayed-eqn>
</li>
</ol>
<p>In addition, all terms, numerator and denominator, can be multiplied by
a common</p>
<displayed-eqn> $$
\sin^2\omega_0
$$
</displayed-eqn>factor, finally resulting in these substitutions:
<ol>
<li>
<displayed-eqn> $$
1 \leftarrow (1 + 2z^{-1} + z^{-2}) (1 - \cos\omega_0)
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
s \leftarrow (1-z^{-2})\sin\omega_0
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
s^2 \leftarrow (1 - 2z^{-1} + z^{-2}) (1 + \cos\omega_0)
$$
</displayed-eqn>
</li>
<li>
<displayed-eqn> $$
1 + s^2 \leftarrow 2\, (1 - 2\cos\omega_0\,z^{-1} + z^{-2})
$$
</displayed-eqn>
</li>
</ol>
<p>The biquad coefficient formulae above come out after a little
simplification.</p>
</section>
<section id="acknowledgements">
<h2>Acknowledgements</h2>
<p>Special thanks to <a href="mailto:[email protected]">Robert
Bristow-Johnson</a> for creating the Audio EQ Cookbook and permitting its
adaption and use for the Web Audio API.</p>
<p>Thanks to <a href="mailto:[email protected]">Peter
Krautzberger</a> for help in adapting these mathematical formulae to
MathML, and to the whole <a href="https://www.mathjax.org/">MathJax</a>
team for making the JavaScript extension that makes the use of math on the
web possible.</p>
<p>Thanks to Peter Jipsen, creator of <a href=
"http://www1.chapman.edu/~jipsen/mathml/asciimath.html">ASCIIMathML</a>,
for making it easier to convert ASCII math notation to MathML.</p>
<p>Converted to using TeX formulas instead of MathML by <a href=
"mailto:[email protected]">Raymond Toy</a>.</p>
</section>
</body>
</html>