LASP 1.0
Library for Acoustic Signal Processing
Loading...
Searching...
No Matches
biquad.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""!
4Author: J.A. de Jong - ASCEE V.O.F.
5
6Description: Filter design implementation of common biquad filters that are
7often used in parametric equalizers.
8
9Major source is Audio EQ Cookbook:
10 https://archive.is/20121220231853/http://www.musicdsp.org/
11 files/Audio-EQ-Cookbook.txt
12
13The definition of the BiQuad filter coefficients as coming out of these
14functions defines the filter as:
15
16y[n] = 1/ba[3] * ( ba[0] * x[n] + ba[1] * x[n-1] + ba[2] * x[n-2] +
17 + ba[4] * y[n-1] + ba[5] * y[n-2]
18 )
19
20*Note that all filters are normalized such that ba[3] is by definition equal to
211.0!*
22
23
24"""
25__all__ = ['peaking', 'biquadTF', 'notch', 'lowpass', 'highpass',
26 'highshelf', 'lowshelf', 'LP1compensator', 'LP2compensator',
27 'HP1compensator', 'HP2compensator']
28
29from numpy import array, cos, pi, sin, sqrt
30from scipy.interpolate import interp1d
31from scipy.signal import sosfreqz, bilinear_zpk, zpk2sos
32
33
34def peaking(fs, f0, Q, gain):
35 """
36 Design of peaking biquad filter
37
38 Args:
39 fs: Sampling frequency [Hz]
40 f0: Center frequency
41 Q: Quality factor (~ inverse of bandwidth)
42 gain: Increase in level at the center frequency [dB]
43 """
44 A = sqrt(10**(gain/20))
45 omg0 = 2*pi*f0/fs
46 alpha = sin(omg0)/Q/2
47 b0 = 1+alpha*A
48 b1 = -2*cos(omg0)
49 b2 = 1-alpha*A
50 a0 = 1 + alpha/A
51 a1 = -2*cos(omg0)
52 a2 = 1-alpha/A
53
54 return array([b0/a0, b1/a0, b2/a0, a0/a0, a1/a0, a2/a0])
55
56
57def notch(fs, f0, Q, gain=None):
58 """
59 Notch filter, parameter gain not used
60
61 Args:
62 fs: Sampling frequency [Hz]
63 f0: Center frequency [Hz]
64 Q: Quality factor (~ inverse of bandwidth)
65 """
66 omg0 = 2*pi*f0/fs
67 alpha = sin(omg0)/Q/2
68 b0 = 1
69 b1 = -2*cos(omg0)
70 b2 = 1
71 a0 = 1 + alpha
72 a1 = -2*cos(omg0)
73 a2 = 1 - alpha
74 return array([b0/a0, b1/a0, b2/a0, a0/a0, a1/a0, a2/a0])
75
76
77def lowpass(fs, f0, Q, gain=None):
78 """
79 Second order low pass filter, parameter gain not used
80
81 Args:
82 fs: Sampling frequency [Hz]
83 f0: Cut-off frequency [Hz]
84 Q: Quality factor (~ inverse of bandwidth)
85 """
86 w0 = 2*pi*f0/fs
87 alpha = sin(w0)/Q/2
88 b0 = (1 - cos(w0))/2
89 b1 = 1 - cos(w0)
90 b2 = (1 - cos(w0))/2
91 a0 = 1 + alpha
92 a1 = -2*cos(w0)
93 a2 = 1 - alpha
94 return array([b0/a0, b1/a0, b2/a0, a0/a0, a1/a0, a2/a0])
95
96
97def highpass(fs, f0, Q, gain=None):
98 """
99 Second order high pass filter, parameter gain not used
100
101 Args:
102 fs: Sampling frequency [Hz]
103 f0: Cut-on frequency [Hz]
104 Q: Quality factor (~ inverse of bandwidth)
105 """
106 w0 = 2*pi*f0/fs
107 alpha = sin(w0)/Q/2
108
109 b0 = (1 + cos(w0))/2
110 b1 = -(1 + cos(w0))
111 b2 = (1 + cos(w0))/2
112 a0 = 1 + alpha
113 a1 = -2*cos(w0)
114 a2 = 1 - alpha
115 return array([b0/a0, b1/a0, b2/a0, a0/a0, a1/a0, a2/a0])
116
117
118def highshelf(fs, f0, Q, gain):
119 """
120 High shelving filter
121
122 Args:
123 fs: Sampling frequency [Hz]
124 f0: Cut-on frequency [Hz]
125 Q: Quality factor (~ inverse of bandwidth)
126 gain: Increase in level w.r.t. "wire" [dB]
127 """
128 w0 = 2*pi*f0/fs
129 alpha = sin(w0)/Q/2
130 A = 10**(gain/40)
131 b0 = A*((A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha)
132 b1 = -2*A*((A-1) + (A+1)*cos(w0))
133 b2 = A*((A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha)
134 a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha
135 a1 = 2*((A-1) - (A+1)*cos(w0))
136 a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha
137 return array([b0/a0, b1/a0, b2/a0, a0/a0, a1/a0, a2/a0])
138
139
140def lowshelf(fs, f0, Q, gain):
141 """
142 Low shelving filter
143
144 Args:
145 fs: Sampling frequency [Hz]
146 f0: Cut-on frequency [Hz]
147 Q: Quality factor (~ inverse of bandwidth)
148 gain: Increase in level w.r.t. "wire" [dB]
149 """
150 w0 = 2*pi*f0/fs
151 alpha = sin(w0)/Q/2
152 A = 10**(gain/40)
153 b0 = A*((A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha)
154 b1 = 2*A*((A-1) - (A+1)*cos(w0))
155 b2 = A*((A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha)
156 a0 = (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha
157 a1 = -2*((A-1) + (A+1)*cos(w0))
158 a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha
159 return array([b0/a0, b1/a0, b2/a0, a0/a0, a1/a0, a2/a0])
160
161def LP1compensator(fs, f0o, f0n):
162 """
163 Shelving type filter that, when multiplied with a first-order low-pass
164 filter, alters the response of that filter to a different first-order
165 low-pass filter.
166
167 Args:
168 fs: Sampling frequency [Hz]
169 f0o: Cut-off frequency of the original filter [Hz]
170 f0n: Desired cut-off frequency [Hz]
171 """
172
173 omg0o = 2*pi*f0o
174 omg0n = 2*pi*f0n
175
176 z = -omg0o
177 p = -omg0n
178 k = p/z
179
180 zd, pd, kd = bilinear_zpk(z, p, k, fs)
181
182 sos = zpk2sos(zd,pd,kd)
183
184 return sos[0]
185
186def LP2compensator(fs, f0o, Qo, f0n, Qn):
187 """
188 Shelving type filter that, when multiplied with a second-order low-pass
189 filter, alters the response of that filter to a different second-order
190 low-pass filter.
191
192 Args:
193 fs: Sampling frequency [Hz]
194 f0o: Cut-off frequency of the original filter [Hz]
195 Qo: Quality factor of the original filter (~inverse of bandwidth)
196 f0n: Desired cut-off frequency [Hz]
197 Qn: Desired quality factor(~inverse of bandwidth)
198 """
199
200 omg0o = 2*pi*f0o
201 omg0n = 2*pi*f0n
202
203 zRe = omg0o/(2*Qo)
204 zIm = omg0o*sqrt(1-1/(4*Qo**2))
205 z1 = -zRe + zIm*1j
206 z2 = -zRe - zIm*1j
207
208 pRe = omg0n/(2*Qn)
209 pIm = omg0n*sqrt(1-1/(4*Qn**2))
210 p1 = -pRe + pIm*1j
211 p2 = -pRe - pIm*1j
212
213 z= [z1, z2]
214 p = [p1, p2]
215 k = (pRe**2 + pIm**2)/(zRe**2 + zIm**2)
216
217 zd, pd, kd = bilinear_zpk(z, p, k, fs)
218
219 sos = zpk2sos(zd,pd,kd)
220
221 return sos[0]
222
223def HP1compensator(fs, f0o, f0n):
224 """
225 Shelving type filter that, when multiplied with a first-order high-pass
226 filter, alters the response of that filter to a different first-order
227 high-pass filter.
228
229 Args:
230 fs: Sampling frequency [Hz]
231 f0o: Cut-on frequency of the original filter [Hz]
232 f0n: Desired cut-on frequency [Hz]
233 """
234
235 omg0o = 2*pi*f0o
236 omg0n = 2*pi*f0n
237
238 z = -omg0o
239 p = -omg0n
240 k = 1
241
242 zd, pd, kd = bilinear_zpk(z, p, k, fs)
243
244 sos = zpk2sos(zd,pd,kd)
245
246 return sos[0]
247
248def HP2compensator(fs, f0o, Qo, f0n, Qn):
249 """
250 Shelving type filter that, when multiplied with a second-order high-pass
251 filter, alters the response of that filter to a different second-order
252 high-pass filter.
253
254 Args:
255 fs: Sampling frequency [Hz]
256 f0o: Cut-on frequency of the original filter [Hz]
257 Qo: Quality factor of the original filter (~inverse of bandwidth)
258 f0n: Desired cut-on frequency [Hz]
259 Qn: Desired quality factor(~inverse of bandwidth)
260 """
261
262 omg0o = 2*pi*f0o
263 omg0n = 2*pi*f0n
264
265 zRe = omg0o/(2*Qo)
266 zIm = omg0o*sqrt(1-1/(4*Qo**2))
267 z1 = -zRe + zIm*1j
268 z2 = -zRe - zIm*1j
269
270 pRe = omg0n/(2*Qn)
271 pIm = omg0n*sqrt(1-1/(4*Qn**2))
272 p1 = -pRe + pIm*1j
273 p2 = -pRe - pIm*1j
274
275 z= [z1, z2]
276 p = [p1, p2]
277 k = 1
278
279 zd, pd, kd = bilinear_zpk(z, p, k, fs)
280
281 sos = zpk2sos(zd,pd,kd)
282
283 return sos[0]
284
285def biquadTF(fs, freq, sos):
286 """
287 Computes the transfer function of the biquad.
288
289 Interpolates the frequency response to `freq`
290
291 Args:
292 fs: Sampling frequency [Hz]
293 freq: Frequency array to compute the
294 ba: Biquad filter coefficients in common form.
295
296 TODO: This code is not yet tested
297 """
298 freq2, h = sosfreqz(sos, worN=freq.size, fs=fs)
299 interpolator = interp1d(freq2, h, kind='quadratic')
300 return interpolator(freq)
biquadTF(fs, freq, sos)
Computes the transfer function of the biquad.
Definition biquad.py:285
lowshelf(fs, f0, Q, gain)
Low shelving filter.
Definition biquad.py:140
LP2compensator(fs, f0o, Qo, f0n, Qn)
Shelving type filter that, when multiplied with a second-order low-pass filter, alters the response o...
Definition biquad.py:186
notch(fs, f0, Q, gain=None)
Notch filter, parameter gain not used.
Definition biquad.py:57
HP1compensator(fs, f0o, f0n)
Shelving type filter that, when multiplied with a first-order high-pass filter, alters the response o...
Definition biquad.py:223
LP1compensator(fs, f0o, f0n)
Shelving type filter that, when multiplied with a first-order low-pass filter, alters the response of...
Definition biquad.py:161
highshelf(fs, f0, Q, gain)
High shelving filter.
Definition biquad.py:118
lowpass(fs, f0, Q, gain=None)
Second order low pass filter, parameter gain not used.
Definition biquad.py:77
peaking(fs, f0, Q, gain)
Design of peaking biquad filter.
Definition biquad.py:34
highpass(fs, f0, Q, gain=None)
Second order high pass filter, parameter gain not used.
Definition biquad.py:97
HP2compensator(fs, f0o, Qo, f0n, Qn)
Shelving type filter that, when multiplied with a second-order high-pass filter, alters the response ...
Definition biquad.py:248