@audio/auditory-gammatone 1.0.0
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.
- package/gammatone.js +76 -0
- package/package.json +30 -0
package/gammatone.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gammatone auditory filter (cochlear model).
|
|
3
|
+
* Cascade of complex one-pole filters (4th-order by default).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let { cos, sin, exp, PI } = Math
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Apply gammatone filter in-place.
|
|
10
|
+
* @param {Float32Array|Float64Array|Array<number>} data - Input/output buffer, filtered in-place
|
|
11
|
+
* @param {object} params - { fc: 1000, fs: 44100, order: 4 }, plus persisted `_`-prefixed cache/state
|
|
12
|
+
* @param {number} params.fc - Center frequency in Hz (default 1000)
|
|
13
|
+
* @param {number} params.fs - Sample rate in Hz (default 44100)
|
|
14
|
+
* @param {number} params.order - Cascade order, i.e. number of one-pole stages (default 4)
|
|
15
|
+
* @returns {Float32Array|Float64Array|Array<number>} data, filtered in-place
|
|
16
|
+
*/
|
|
17
|
+
export default function gammatone (data, params) {
|
|
18
|
+
let fc = params.fc || 1000
|
|
19
|
+
let fs = params.fs || 44100
|
|
20
|
+
let order = params.order || 4
|
|
21
|
+
|
|
22
|
+
// ERB bandwidth
|
|
23
|
+
let erb = 24.7 * (4.37 * fc / 1000 + 1)
|
|
24
|
+
let b = 2 * PI * 1.019 * erb
|
|
25
|
+
|
|
26
|
+
let T = 1 / fs
|
|
27
|
+
let w = 2 * PI * fc * T
|
|
28
|
+
let a = exp(-b * T)
|
|
29
|
+
let cosW = a * cos(w), sinW = a * sin(w)
|
|
30
|
+
|
|
31
|
+
// Gain normalization: compute frequency-domain peak (at fc) from a test impulse,
|
|
32
|
+
// then scale so the filter has 0 dB at its center frequency.
|
|
33
|
+
let gain = 1
|
|
34
|
+
if (params._gain == null || params._fc !== fc || params._order !== order || params._fs !== fs) {
|
|
35
|
+
let ts = new Float64Array(order * 2)
|
|
36
|
+
let irLen = Math.max(4096, Math.round(fs / erb * 10)) // enough cycles to capture the ringing
|
|
37
|
+
// Sum impulse response at center frequency (= DFT at fc = sum of h[n]*e^(-j*w*n))
|
|
38
|
+
let re = 0, im = 0
|
|
39
|
+
for (let i = 0; i < irLen; i++) {
|
|
40
|
+
let v = i === 0 ? 1 : 0
|
|
41
|
+
for (let j = 0; j < order; j++) {
|
|
42
|
+
let sre = ts[j*2], sim = ts[j*2+1]
|
|
43
|
+
ts[j*2] = cosW * sre - sinW * sim + v
|
|
44
|
+
ts[j*2+1] = sinW * sre + cosW * sim
|
|
45
|
+
v = ts[j*2]
|
|
46
|
+
}
|
|
47
|
+
let phase = w * i
|
|
48
|
+
re += v * cos(phase)
|
|
49
|
+
im -= v * sin(phase)
|
|
50
|
+
}
|
|
51
|
+
let mag = Math.sqrt(re * re + im * im)
|
|
52
|
+
params._gain = mag > 0 ? 1 / mag : 1
|
|
53
|
+
params._fc = fc; params._order = order; params._fs = fs
|
|
54
|
+
}
|
|
55
|
+
gain = params._gain
|
|
56
|
+
|
|
57
|
+
if (!params._s || params._s.length !== order * 2) params._s = new Float64Array(order * 2)
|
|
58
|
+
let s = params._s
|
|
59
|
+
|
|
60
|
+
for (let i = 0, n = data.length; i < n; i++) {
|
|
61
|
+
let x = data[i] * gain
|
|
62
|
+
|
|
63
|
+
for (let j = 0; j < order; j++) {
|
|
64
|
+
let re = s[j * 2], im = s[j * 2 + 1]
|
|
65
|
+
let newRe = cosW * re - sinW * im + x
|
|
66
|
+
let newIm = sinW * re + cosW * im
|
|
67
|
+
s[j * 2] = newRe
|
|
68
|
+
s[j * 2 + 1] = newIm
|
|
69
|
+
x = newRe
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
data[i] = x
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return data
|
|
76
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@audio/auditory-gammatone",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Gammatone auditory filter (cochlear model)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "gammatone.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./gammatone.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"gammatone.js"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"audio",
|
|
17
|
+
"dsp",
|
|
18
|
+
"auditory",
|
|
19
|
+
"filterbank",
|
|
20
|
+
"gammatone"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"author": "Dmitry Iv. <dfcreative@gmail.com>",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
}
|
|
30
|
+
}
|