biquad 0.4__py3-none-any.whl → 0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- biquad/__init__.py +55 -55
- biquad/biquad.py +268 -270
- biquad/highshelf.py +115 -115
- biquad/lowshelf.py +115 -115
- {biquad-0.4.dist-info → biquad-0.5.dist-info}/METADATA +103 -102
- biquad-0.5.dist-info/RECORD +15 -0
- {biquad-0.4.dist-info → biquad-0.5.dist-info}/WHEEL +1 -1
- {biquad-0.4.dist-info → biquad-0.5.dist-info/licenses}/LICENSE +21 -21
- biquad-0.4.dist-info/RECORD +0 -15
- {biquad-0.4.dist-info → biquad-0.5.dist-info}/top_level.txt +0 -0
biquad/highshelf.py
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Copyright (c) 2023 Juergen Hock
|
|
3
|
-
|
|
4
|
-
SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
Source: https://github.com/jurihock/biquad
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from .biquad import biquad, __df1__, __gain__, __resize__
|
|
10
|
-
|
|
11
|
-
import numba
|
|
12
|
-
import numpy
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class highshelf(biquad):
|
|
16
|
-
"""
|
|
17
|
-
Highshelf filter (HSF).
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def __init__(self, sr, f=None, g=6, q=1):
|
|
21
|
-
"""
|
|
22
|
-
Create a new filter instance.
|
|
23
|
-
|
|
24
|
-
Parameters
|
|
25
|
-
----------
|
|
26
|
-
sr : int or float
|
|
27
|
-
Sample rate in hertz.
|
|
28
|
-
f : int or float, optional
|
|
29
|
-
Persistent filter frequency parameter in hertz.
|
|
30
|
-
g : int or float, optional
|
|
31
|
-
Persistent filter gain parameter in decibel.
|
|
32
|
-
q : int or float, optional
|
|
33
|
-
Persistent filter quality parameter.
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
super().__init__(sr=sr, f=f, g=0, q=q)
|
|
37
|
-
|
|
38
|
-
self.g = __gain__(g, 40)
|
|
39
|
-
|
|
40
|
-
self.__call__(0) # warmup numba
|
|
41
|
-
|
|
42
|
-
def __call__(self, x, f=None, g=None, q=None):
|
|
43
|
-
"""
|
|
44
|
-
Process single or multiple contiguous signal values at once.
|
|
45
|
-
|
|
46
|
-
Parameters
|
|
47
|
-
----------
|
|
48
|
-
x : scalar or array like
|
|
49
|
-
Filter input data.
|
|
50
|
-
f : scalar or array like, optional
|
|
51
|
-
Instantaneous filter frequency parameter in hertz.
|
|
52
|
-
g : scalar or array like, optional
|
|
53
|
-
Instantaneous filter gain parameter in decibel.
|
|
54
|
-
q : scalar or array like, optional
|
|
55
|
-
Instantaneous filter quality parameter.
|
|
56
|
-
|
|
57
|
-
Returns
|
|
58
|
-
-------
|
|
59
|
-
y : scalar or ndarray
|
|
60
|
-
Filter output data of the same shape and dtype as the input x.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
scalar = numpy.isscalar(x)
|
|
64
|
-
|
|
65
|
-
ba = self.ba
|
|
66
|
-
xy = self.xy
|
|
67
|
-
|
|
68
|
-
x = numpy.atleast_1d(x)
|
|
69
|
-
y = numpy.zeros(x.shape, x.dtype)
|
|
70
|
-
|
|
71
|
-
f = __resize__(self.f if f is None else f, x.shape)
|
|
72
|
-
g = __resize__(self.g if g is None else __gain__(g, 40), x.shape)
|
|
73
|
-
q = __resize__(self.q if q is None else q, x.shape)
|
|
74
|
-
|
|
75
|
-
sr = self.sr
|
|
76
|
-
|
|
77
|
-
self.__filter__(ba, xy, x, y, f, g, q, sr)
|
|
78
|
-
|
|
79
|
-
self.f = f[-1]
|
|
80
|
-
self.g = g[-1]
|
|
81
|
-
self.q = q[-1]
|
|
82
|
-
|
|
83
|
-
return y[0] if scalar else y
|
|
84
|
-
|
|
85
|
-
@staticmethod
|
|
86
|
-
@numba.jit(nopython=True, fastmath=True)
|
|
87
|
-
def __filter__(ba, xy, x, y, f, g, q, sr):
|
|
88
|
-
|
|
89
|
-
rs = 2 * numpy.pi / sr
|
|
90
|
-
|
|
91
|
-
for i in range(x.size):
|
|
92
|
-
|
|
93
|
-
w = f[i] * rs
|
|
94
|
-
|
|
95
|
-
cosw = numpy.cos(w)
|
|
96
|
-
sinw = numpy.sin(w)
|
|
97
|
-
|
|
98
|
-
alpha = sinw / (2 * q[i])
|
|
99
|
-
alpha *= 2 * numpy.sqrt(g[i])
|
|
100
|
-
|
|
101
|
-
plus = g[i] + 1
|
|
102
|
-
minus = g[i] - 1
|
|
103
|
-
|
|
104
|
-
# update b
|
|
105
|
-
ba[0, 0] = (plus + minus * cosw + alpha)
|
|
106
|
-
ba[0, 1] = (minus + plus * cosw) * -2
|
|
107
|
-
ba[0, 2] = (plus + minus * cosw - alpha)
|
|
108
|
-
|
|
109
|
-
# update a
|
|
110
|
-
ba[1, 0] = (plus - minus * cosw + alpha)
|
|
111
|
-
ba[1, 1] = (minus - plus * cosw) * +2
|
|
112
|
-
ba[1, 2] = (plus - minus * cosw - alpha)
|
|
113
|
-
|
|
114
|
-
# update y
|
|
115
|
-
__df1__(g[i], ba, xy, x, y, i)
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) 2023 Juergen Hock
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: MIT
|
|
5
|
+
|
|
6
|
+
Source: https://github.com/jurihock/biquad
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .biquad import biquad, __df1__, __gain__, __resize__
|
|
10
|
+
|
|
11
|
+
import numba
|
|
12
|
+
import numpy
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class highshelf(biquad):
|
|
16
|
+
"""
|
|
17
|
+
Highshelf filter (HSF).
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, sr, f=None, g=6, q=1):
|
|
21
|
+
"""
|
|
22
|
+
Create a new filter instance.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
sr : int or float
|
|
27
|
+
Sample rate in hertz.
|
|
28
|
+
f : int or float, optional
|
|
29
|
+
Persistent filter frequency parameter in hertz.
|
|
30
|
+
g : int or float, optional
|
|
31
|
+
Persistent filter gain parameter in decibel.
|
|
32
|
+
q : int or float, optional
|
|
33
|
+
Persistent filter quality parameter.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
super().__init__(sr=sr, f=f, g=0, q=q)
|
|
37
|
+
|
|
38
|
+
self.g = __gain__(g, 40)
|
|
39
|
+
|
|
40
|
+
self.__call__(0) # warmup numba
|
|
41
|
+
|
|
42
|
+
def __call__(self, x, f=None, g=None, q=None):
|
|
43
|
+
"""
|
|
44
|
+
Process single or multiple contiguous signal values at once.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
x : scalar or array like
|
|
49
|
+
Filter input data.
|
|
50
|
+
f : scalar or array like, optional
|
|
51
|
+
Instantaneous filter frequency parameter in hertz.
|
|
52
|
+
g : scalar or array like, optional
|
|
53
|
+
Instantaneous filter gain parameter in decibel.
|
|
54
|
+
q : scalar or array like, optional
|
|
55
|
+
Instantaneous filter quality parameter.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
y : scalar or ndarray
|
|
60
|
+
Filter output data of the same shape and dtype as the input x.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
scalar = numpy.isscalar(x)
|
|
64
|
+
|
|
65
|
+
ba = self.ba
|
|
66
|
+
xy = self.xy
|
|
67
|
+
|
|
68
|
+
x = numpy.atleast_1d(x)
|
|
69
|
+
y = numpy.zeros(x.shape, x.dtype)
|
|
70
|
+
|
|
71
|
+
f = __resize__(self.f if f is None else f, x.shape)
|
|
72
|
+
g = __resize__(self.g if g is None else __gain__(g, 40), x.shape)
|
|
73
|
+
q = __resize__(self.q if q is None else q, x.shape)
|
|
74
|
+
|
|
75
|
+
sr = self.sr
|
|
76
|
+
|
|
77
|
+
self.__filter__(ba, xy, x, y, f, g, q, sr)
|
|
78
|
+
|
|
79
|
+
self.f = f[-1]
|
|
80
|
+
self.g = g[-1]
|
|
81
|
+
self.q = q[-1]
|
|
82
|
+
|
|
83
|
+
return y[0] if scalar else y
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
@numba.jit(nopython=True, fastmath=True)
|
|
87
|
+
def __filter__(ba, xy, x, y, f, g, q, sr):
|
|
88
|
+
|
|
89
|
+
rs = 2 * numpy.pi / sr
|
|
90
|
+
|
|
91
|
+
for i in range(x.size):
|
|
92
|
+
|
|
93
|
+
w = f[i] * rs
|
|
94
|
+
|
|
95
|
+
cosw = numpy.cos(w)
|
|
96
|
+
sinw = numpy.sin(w)
|
|
97
|
+
|
|
98
|
+
alpha = sinw / (2 * q[i])
|
|
99
|
+
alpha *= 2 * numpy.sqrt(g[i])
|
|
100
|
+
|
|
101
|
+
plus = g[i] + 1
|
|
102
|
+
minus = g[i] - 1
|
|
103
|
+
|
|
104
|
+
# update b
|
|
105
|
+
ba[0, 0] = (plus + minus * cosw + alpha)
|
|
106
|
+
ba[0, 1] = (minus + plus * cosw) * -2
|
|
107
|
+
ba[0, 2] = (plus + minus * cosw - alpha)
|
|
108
|
+
|
|
109
|
+
# update a
|
|
110
|
+
ba[1, 0] = (plus - minus * cosw + alpha)
|
|
111
|
+
ba[1, 1] = (minus - plus * cosw) * +2
|
|
112
|
+
ba[1, 2] = (plus - minus * cosw - alpha)
|
|
113
|
+
|
|
114
|
+
# update y
|
|
115
|
+
__df1__(g[i], ba, xy, x, y, i)
|
biquad/lowshelf.py
CHANGED
|
@@ -1,115 +1,115 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Copyright (c) 2023 Juergen Hock
|
|
3
|
-
|
|
4
|
-
SPDX-License-Identifier: MIT
|
|
5
|
-
|
|
6
|
-
Source: https://github.com/jurihock/biquad
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from .biquad import biquad, __df1__, __gain__, __resize__
|
|
10
|
-
|
|
11
|
-
import numba
|
|
12
|
-
import numpy
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class lowshelf(biquad):
|
|
16
|
-
"""
|
|
17
|
-
Lowshelf filter (LSF).
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def __init__(self, sr, f=None, g=6, q=1):
|
|
21
|
-
"""
|
|
22
|
-
Create a new filter instance.
|
|
23
|
-
|
|
24
|
-
Parameters
|
|
25
|
-
----------
|
|
26
|
-
sr : int or float
|
|
27
|
-
Sample rate in hertz.
|
|
28
|
-
f : int or float, optional
|
|
29
|
-
Persistent filter frequency parameter in hertz.
|
|
30
|
-
g : int or float, optional
|
|
31
|
-
Persistent filter gain parameter in decibel.
|
|
32
|
-
q : int or float, optional
|
|
33
|
-
Persistent filter quality parameter.
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
super().__init__(sr=sr, f=f, g=0, q=q)
|
|
37
|
-
|
|
38
|
-
self.g = __gain__(g, 40)
|
|
39
|
-
|
|
40
|
-
self.__call__(0) # warmup numba
|
|
41
|
-
|
|
42
|
-
def __call__(self, x, f=None, g=None, q=None):
|
|
43
|
-
"""
|
|
44
|
-
Process single or multiple contiguous signal values at once.
|
|
45
|
-
|
|
46
|
-
Parameters
|
|
47
|
-
----------
|
|
48
|
-
x : scalar or array like
|
|
49
|
-
Filter input data.
|
|
50
|
-
f : scalar or array like, optional
|
|
51
|
-
Instantaneous filter frequency parameter in hertz.
|
|
52
|
-
g : scalar or array like, optional
|
|
53
|
-
Instantaneous filter gain parameter in decibel.
|
|
54
|
-
q : scalar or array like, optional
|
|
55
|
-
Instantaneous filter quality parameter.
|
|
56
|
-
|
|
57
|
-
Returns
|
|
58
|
-
-------
|
|
59
|
-
y : scalar or ndarray
|
|
60
|
-
Filter output data of the same shape and dtype as the input x.
|
|
61
|
-
"""
|
|
62
|
-
|
|
63
|
-
scalar = numpy.isscalar(x)
|
|
64
|
-
|
|
65
|
-
ba = self.ba
|
|
66
|
-
xy = self.xy
|
|
67
|
-
|
|
68
|
-
x = numpy.atleast_1d(x)
|
|
69
|
-
y = numpy.zeros(x.shape, x.dtype)
|
|
70
|
-
|
|
71
|
-
f = __resize__(self.f if f is None else f, x.shape)
|
|
72
|
-
g = __resize__(self.g if g is None else __gain__(g, 40), x.shape)
|
|
73
|
-
q = __resize__(self.q if q is None else q, x.shape)
|
|
74
|
-
|
|
75
|
-
sr = self.sr
|
|
76
|
-
|
|
77
|
-
self.__filter__(ba, xy, x, y, f, g, q, sr)
|
|
78
|
-
|
|
79
|
-
self.f = f[-1]
|
|
80
|
-
self.g = g[-1]
|
|
81
|
-
self.q = q[-1]
|
|
82
|
-
|
|
83
|
-
return y[0] if scalar else y
|
|
84
|
-
|
|
85
|
-
@staticmethod
|
|
86
|
-
@numba.jit(nopython=True, fastmath=True)
|
|
87
|
-
def __filter__(ba, xy, x, y, f, g, q, sr):
|
|
88
|
-
|
|
89
|
-
rs = 2 * numpy.pi / sr
|
|
90
|
-
|
|
91
|
-
for i in range(x.size):
|
|
92
|
-
|
|
93
|
-
w = f[i] * rs
|
|
94
|
-
|
|
95
|
-
cosw = numpy.cos(w)
|
|
96
|
-
sinw = numpy.sin(w)
|
|
97
|
-
|
|
98
|
-
alpha = sinw / (2 * q[i])
|
|
99
|
-
alpha *= 2 * numpy.sqrt(g[i])
|
|
100
|
-
|
|
101
|
-
plus = g[i] + 1
|
|
102
|
-
minus = g[i] - 1
|
|
103
|
-
|
|
104
|
-
# update b
|
|
105
|
-
ba[0, 0] = (plus - minus * cosw + alpha)
|
|
106
|
-
ba[0, 1] = (minus - plus * cosw) * +2
|
|
107
|
-
ba[0, 2] = (plus - minus * cosw - alpha)
|
|
108
|
-
|
|
109
|
-
# update a
|
|
110
|
-
ba[1, 0] = (plus + minus * cosw + alpha)
|
|
111
|
-
ba[1, 1] = (minus + plus * cosw) * -2
|
|
112
|
-
ba[1, 2] = (plus + minus * cosw - alpha)
|
|
113
|
-
|
|
114
|
-
# update y
|
|
115
|
-
__df1__(g[i], ba, xy, x, y, i)
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) 2023 Juergen Hock
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: MIT
|
|
5
|
+
|
|
6
|
+
Source: https://github.com/jurihock/biquad
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .biquad import biquad, __df1__, __gain__, __resize__
|
|
10
|
+
|
|
11
|
+
import numba
|
|
12
|
+
import numpy
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class lowshelf(biquad):
|
|
16
|
+
"""
|
|
17
|
+
Lowshelf filter (LSF).
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, sr, f=None, g=6, q=1):
|
|
21
|
+
"""
|
|
22
|
+
Create a new filter instance.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
sr : int or float
|
|
27
|
+
Sample rate in hertz.
|
|
28
|
+
f : int or float, optional
|
|
29
|
+
Persistent filter frequency parameter in hertz.
|
|
30
|
+
g : int or float, optional
|
|
31
|
+
Persistent filter gain parameter in decibel.
|
|
32
|
+
q : int or float, optional
|
|
33
|
+
Persistent filter quality parameter.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
super().__init__(sr=sr, f=f, g=0, q=q)
|
|
37
|
+
|
|
38
|
+
self.g = __gain__(g, 40)
|
|
39
|
+
|
|
40
|
+
self.__call__(0) # warmup numba
|
|
41
|
+
|
|
42
|
+
def __call__(self, x, f=None, g=None, q=None):
|
|
43
|
+
"""
|
|
44
|
+
Process single or multiple contiguous signal values at once.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
x : scalar or array like
|
|
49
|
+
Filter input data.
|
|
50
|
+
f : scalar or array like, optional
|
|
51
|
+
Instantaneous filter frequency parameter in hertz.
|
|
52
|
+
g : scalar or array like, optional
|
|
53
|
+
Instantaneous filter gain parameter in decibel.
|
|
54
|
+
q : scalar or array like, optional
|
|
55
|
+
Instantaneous filter quality parameter.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
y : scalar or ndarray
|
|
60
|
+
Filter output data of the same shape and dtype as the input x.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
scalar = numpy.isscalar(x)
|
|
64
|
+
|
|
65
|
+
ba = self.ba
|
|
66
|
+
xy = self.xy
|
|
67
|
+
|
|
68
|
+
x = numpy.atleast_1d(x)
|
|
69
|
+
y = numpy.zeros(x.shape, x.dtype)
|
|
70
|
+
|
|
71
|
+
f = __resize__(self.f if f is None else f, x.shape)
|
|
72
|
+
g = __resize__(self.g if g is None else __gain__(g, 40), x.shape)
|
|
73
|
+
q = __resize__(self.q if q is None else q, x.shape)
|
|
74
|
+
|
|
75
|
+
sr = self.sr
|
|
76
|
+
|
|
77
|
+
self.__filter__(ba, xy, x, y, f, g, q, sr)
|
|
78
|
+
|
|
79
|
+
self.f = f[-1]
|
|
80
|
+
self.g = g[-1]
|
|
81
|
+
self.q = q[-1]
|
|
82
|
+
|
|
83
|
+
return y[0] if scalar else y
|
|
84
|
+
|
|
85
|
+
@staticmethod
|
|
86
|
+
@numba.jit(nopython=True, fastmath=True)
|
|
87
|
+
def __filter__(ba, xy, x, y, f, g, q, sr):
|
|
88
|
+
|
|
89
|
+
rs = 2 * numpy.pi / sr
|
|
90
|
+
|
|
91
|
+
for i in range(x.size):
|
|
92
|
+
|
|
93
|
+
w = f[i] * rs
|
|
94
|
+
|
|
95
|
+
cosw = numpy.cos(w)
|
|
96
|
+
sinw = numpy.sin(w)
|
|
97
|
+
|
|
98
|
+
alpha = sinw / (2 * q[i])
|
|
99
|
+
alpha *= 2 * numpy.sqrt(g[i])
|
|
100
|
+
|
|
101
|
+
plus = g[i] + 1
|
|
102
|
+
minus = g[i] - 1
|
|
103
|
+
|
|
104
|
+
# update b
|
|
105
|
+
ba[0, 0] = (plus - minus * cosw + alpha)
|
|
106
|
+
ba[0, 1] = (minus - plus * cosw) * +2
|
|
107
|
+
ba[0, 2] = (plus - minus * cosw - alpha)
|
|
108
|
+
|
|
109
|
+
# update a
|
|
110
|
+
ba[1, 0] = (plus + minus * cosw + alpha)
|
|
111
|
+
ba[1, 1] = (minus + plus * cosw) * -2
|
|
112
|
+
ba[1, 2] = (plus + minus * cosw - alpha)
|
|
113
|
+
|
|
114
|
+
# update y
|
|
115
|
+
__df1__(g[i], ba, xy, x, y, i)
|
|
@@ -1,102 +1,103 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
2
|
-
Name: biquad
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Collection of alterable digital biquad filters for dynamic audio effect creation
|
|
5
|
-
Home-page: https://github.com/jurihock/biquad
|
|
6
|
-
Author: Juergen Hock
|
|
7
|
-
Author-email: juergen.hock@jurihock.de
|
|
8
|
-
License: MIT
|
|
9
|
-
Keywords: digital,audio,signal,processing,dasp,dafx,effects,filter,equalizer,eq,biquad,frequency,phase,spectrum,algorithms,analysis,synthesis,c,cpp,python
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: Intended Audience :: Education
|
|
12
|
-
Classifier: Intended Audience :: Other Audience
|
|
13
|
-
Classifier: Intended Audience :: Science/Research
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
-
Classifier: Programming Language :: C
|
|
16
|
-
Classifier: Programming Language :: C++
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Topic :: Artistic Software
|
|
19
|
-
Classifier: Topic :: Education
|
|
20
|
-
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
21
|
-
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
22
|
-
Classifier: Topic :: Multimedia :: Sound/Audio :: Sound Synthesis
|
|
23
|
-
Classifier: Topic :: Scientific/Engineering
|
|
24
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
-
Requires-Python: >=3
|
|
26
|
-
Description-Content-Type: text/markdown
|
|
27
|
-
License-File: LICENSE
|
|
28
|
-
Requires-Dist: numba
|
|
29
|
-
Requires-Dist: numpy
|
|
30
|
-
Provides-Extra: plot
|
|
31
|
-
Requires-Dist: matplotlib
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-

|
|
37
|
+

|
|
38
|
+

|
|
39
|
+
|
|
40
|
+
This is a collection of [digital biquad filters](https://webaudio.github.io/Audio-EQ-Cookbook/audio-eq-cookbook.html) whose parameters `f` (frequency in *Hz*), `g` (gain in *dB*) and `q` (quality) can be varied at runtime. Following [DF1](https://ccrma.stanford.edu/~jos/fp/Direct_Form_I.html) filter implementations are available:
|
|
41
|
+
|
|
42
|
+
- Allpass
|
|
43
|
+
- Bandpass
|
|
44
|
+
- Highpass
|
|
45
|
+
- Lowpass
|
|
46
|
+
- Highshelf
|
|
47
|
+
- Lowshelf
|
|
48
|
+
- Notch
|
|
49
|
+
- Peak
|
|
50
|
+
|
|
51
|
+
## Basic usage
|
|
52
|
+
|
|
53
|
+
Filter with static configuration:
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import biquad
|
|
57
|
+
import numpy as np
|
|
58
|
+
|
|
59
|
+
# load audio samples somehow
|
|
60
|
+
x, sr = np.zeros(...), 44100
|
|
61
|
+
|
|
62
|
+
# create a filter of your choice
|
|
63
|
+
f = biquad.bandpass(sr, f=sr/4, q=1)
|
|
64
|
+
|
|
65
|
+
# process all audio samples
|
|
66
|
+
y = f(x)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Filter with dynamic configuration:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import biquad
|
|
73
|
+
import numpy as np
|
|
74
|
+
|
|
75
|
+
# load audio samples somehow
|
|
76
|
+
x, sr = np.zeros(...), 44100
|
|
77
|
+
|
|
78
|
+
# create a filter of your choice
|
|
79
|
+
f = biquad.bandpass(sr)
|
|
80
|
+
|
|
81
|
+
# create parameter modifications as you like
|
|
82
|
+
myf = np.linspace(1, sr/4, len(x))
|
|
83
|
+
myq = np.linspace(2, 1/2, len(x))
|
|
84
|
+
|
|
85
|
+
# process all audio samples
|
|
86
|
+
y = f(x, f=myf, q=myq)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Keep in mind:
|
|
90
|
+
|
|
91
|
+
- All filters have a default value for the persistent parameters `g` and `q`, which is set in the particular `__init__` method.
|
|
92
|
+
- Parameter `f` must be set either in the `__init__` or in the `__call__` method.
|
|
93
|
+
- The optional instantaneous parameters `f`, `g` and `q`, if specified in the `__call__` method, override the persistent ones.
|
|
94
|
+
|
|
95
|
+
## References
|
|
96
|
+
|
|
97
|
+
1. <span id="1">[Cookbook formulae for audio EQ biquad filter coefficients](https://webaudio.github.io/Audio-EQ-Cookbook/audio-eq-cookbook.html) by Robert Bristow-Johnson</span>
|
|
98
|
+
2. <span id="2">[Introduction to Digital Filters with Audio Applications](https://ccrma.stanford.edu/~jos/filters/filters.html) by Julius O. Smith III</span>
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
[github.com/jurihock/biquad](https://github.com/jurihock/biquad) is licensed under the terms of the MIT license.
|
|
103
|
+
For details please refer to the accompanying [LICENSE](https://github.com/jurihock/biquad/raw/main/LICENSE) file distributed with it.
|