@audio/denoise-deesser 0.1.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/deesser.js +68 -0
  2. package/package.json +42 -0
package/deesser.js ADDED
@@ -0,0 +1,68 @@
1
+ // De-esser — dynamic peaking EQ centred on the sibilance band.
2
+ //
3
+ // Detection runs on a HP-filtered side-chain (above `freq`); when the envelope
4
+ // exceeds threshold, a peaking EQ at `freq` with negative gain is engaged on
5
+ // the audio path. EQ gain follows the envelope continuously — recomputed every
6
+ // `block` samples for smoothness without per-sample coef cost.
7
+ //
8
+ // Standard for voice post-production. Unlike a static shelf, the cut only engages
9
+ // on loud 's' / 'sh' events, so dark consonants aren't thinned.
10
+
11
+ import { biquad, highpassCoefs, peakingCoefs, db2lin, lin2db } from '@audio/denoise-core'
12
+
13
+ export default function deesser(data, params = {}) {
14
+ let fs = params.fs || 44100
15
+ let freq = params.freq ?? 6000
16
+ let threshold = params.threshold ?? -30
17
+ let ratio = params.ratio ?? 4
18
+ let attack = params.attack ?? 0.001
19
+ let release = params.release ?? 0.05
20
+ let Q = params.Q ?? 1.4 // peaking EQ Q (narrower than 0.707)
21
+ let block = params.block ?? 64 // coef update interval
22
+
23
+ if (!params._init) {
24
+ params._init = true
25
+ params._scC = highpassCoefs(freq, 0.707, fs)
26
+ params._scS = [0, 0]
27
+ params._eqS = [0, 0]
28
+ params._env = 0
29
+ params._eqGainDb = 0
30
+ }
31
+
32
+ let aA = Math.exp(-1 / (attack * fs))
33
+ let aR = Math.exp(-1 / (release * fs))
34
+ let aBlk = Math.exp(-block / (release * fs)) // EQ-gain smoothing across blocks
35
+ let thLin = db2lin(threshold)
36
+
37
+ // Sidechain: HP copy for detection
38
+ let sc = new Float32Array(data.length)
39
+ for (let i = 0; i < data.length; i++) sc[i] = data[i]
40
+ biquad(sc, params._scC.b0, params._scC.b1, params._scC.b2, params._scC.a1, params._scC.a2, params._scS)
41
+
42
+ let env = params._env
43
+ let eqDb = params._eqGainDb
44
+
45
+ for (let pos = 0; pos < data.length; pos += block) {
46
+ let end = Math.min(data.length, pos + block)
47
+ // update envelope across block, take peak
48
+ let peakEnv = env
49
+ for (let i = pos; i < end; i++) {
50
+ let x = Math.abs(sc[i])
51
+ env = x > env ? aA * env + (1 - aA) * x : aR * env + (1 - aR) * x
52
+ if (env > peakEnv) peakEnv = env
53
+ }
54
+ let target = 0
55
+ if (peakEnv > thLin) {
56
+ let over = lin2db(peakEnv / thLin)
57
+ target = -over * (1 - 1 / ratio) // negative dB cut
58
+ }
59
+ eqDb = target < eqDb ? aBlk * eqDb + (1 - aBlk) * target : aR * eqDb + (1 - aR) * target
60
+
61
+ let coef = peakingCoefs(freq, Q, eqDb, fs)
62
+ let blk = data.subarray(pos, end)
63
+ biquad(blk, coef.b0, coef.b1, coef.b2, coef.a1, coef.a2, params._eqS)
64
+ }
65
+ params._env = env
66
+ params._eqGainDb = eqDb
67
+ return data
68
+ }
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@audio/denoise-deesser",
3
+ "version": "0.1.0",
4
+ "description": "De-esser — dynamic peaking EQ centred on the sibilance band",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "deesser.js",
8
+ "exports": {
9
+ ".": "./deesser.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "deesser.js"
14
+ ],
15
+ "dependencies": {
16
+ "@audio/denoise-core": "^0.1.0"
17
+ },
18
+ "keywords": [
19
+ "audio",
20
+ "dsp",
21
+ "denoise",
22
+ "restoration",
23
+ "deesser"
24
+ ],
25
+ "license": "MIT",
26
+ "author": "Dmitry Iv. <dfcreative@gmail.com>",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/audiojs/denoise.git",
30
+ "directory": "packages/denoise-deesser"
31
+ },
32
+ "homepage": "https://github.com/audiojs/denoise/tree/main/packages/denoise-deesser",
33
+ "bugs": {
34
+ "url": "https://github.com/audiojs/denoise/issues"
35
+ },
36
+ "engines": {
37
+ "node": ">=18"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ }
42
+ }