@audio/filter-spectral-tilt 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.
Files changed (2) hide show
  1. package/package.json +38 -0
  2. package/spectral-tilt.js +48 -0
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@audio/filter-spectral-tilt",
3
+ "version": "1.0.0",
4
+ "description": "Spectral tilt filter: apply a constant dB/octave slope to the spectrum",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "spectral-tilt.js",
8
+ "exports": {
9
+ ".": "./spectral-tilt.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "spectral-tilt.js"
14
+ ],
15
+ "keywords": [
16
+ "audio",
17
+ "dsp",
18
+ "filter",
19
+ "spectral-tilt"
20
+ ],
21
+ "license": "MIT",
22
+ "author": "Dmitry Iv. <dfcreative@gmail.com>",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/audiojs/filter.git",
26
+ "directory": "packages/filter-spectral-tilt"
27
+ },
28
+ "homepage": "https://github.com/audiojs/filter/tree/main/packages/filter-spectral-tilt",
29
+ "bugs": {
30
+ "url": "https://github.com/audiojs/filter/issues"
31
+ },
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ }
38
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Spectral tilt filter: apply a constant dB/octave slope to the spectrum.
3
+ * Implemented as a cascade of first-order shelving sections.
4
+ *
5
+ * @module audio-filter/effect/spectral-tilt
6
+ */
7
+
8
+ /**
9
+ * @param {Float64Array} data - Input (modified in-place)
10
+ * @param {object} params - { slope: dB per octave (positive = boost high), fs }
11
+ */
12
+ export default function spectralTilt (data, params) {
13
+ let slope = params.slope || 0 // dB/octave
14
+ let fs = params.fs || 44100
15
+
16
+ if (slope === 0) return data
17
+
18
+ // Use a cascade of first-order filters at octave-spaced frequencies
19
+ if (!params._coefs || params._slope !== slope || params._fs !== fs) {
20
+ let nStages = 8
21
+ params._slope = slope
22
+ params._fs = fs
23
+ if (!params._s) params._s = new Float64Array(nStages)
24
+ params._coefs = []
25
+ for (let j = 0; j < nStages; j++) {
26
+ let fc = 62.5 * Math.pow(2, j) // 62.5, 125, 250, ... 8kHz
27
+ if (fc >= fs / 2) continue
28
+ let a = Math.exp(-2 * Math.PI * fc / fs)
29
+ let gain = Math.pow(10, slope / 20) // gain per octave
30
+ params._coefs.push({ a, gain })
31
+ }
32
+ }
33
+
34
+ let s = params._s
35
+ let coefs = params._coefs
36
+
37
+ for (let i = 0, n = data.length; i < n; i++) {
38
+ let x = data[i]
39
+ for (let j = 0; j < coefs.length; j++) {
40
+ let c = coefs[j]
41
+ s[j] = c.a * s[j] + (1 - c.a) * x
42
+ x = s[j] + (x - s[j]) * c.gain
43
+ }
44
+ data[i] = x
45
+ }
46
+
47
+ return data
48
+ }