@audio/dynamics-varimu 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/package.json +44 -0
  2. package/varimu.js +38 -0
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@audio/dynamics-varimu",
3
+ "version": "0.1.0",
4
+ "description": "Vari-Mu compressor model — feedback detection, drive-dependent ratio, soft wide knee (Fairchild class)",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "varimu.js",
8
+ "exports": {
9
+ ".": "./varimu.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "varimu.js"
14
+ ],
15
+ "dependencies": {
16
+ "@audio/dynamics-core": "^0.1.0",
17
+ "@audio/dynamics-envelope": "^0.1.0",
18
+ "@audio/dynamics-compressor": "^0.1.0"
19
+ },
20
+ "keywords": [
21
+ "audio",
22
+ "dsp",
23
+ "dynamics",
24
+ "compressor",
25
+ "varimu"
26
+ ],
27
+ "license": "MIT",
28
+ "author": "Dmitry Iv. <dfcreative@gmail.com>",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/audiojs/dynamics.git",
32
+ "directory": "packages/dynamics-varimu"
33
+ },
34
+ "homepage": "https://github.com/audiojs/dynamics/tree/main/packages/dynamics-varimu",
35
+ "bugs": {
36
+ "url": "https://github.com/audiojs/dynamics/issues"
37
+ },
38
+ "engines": {
39
+ "node": ">=18"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ }
44
+ }
package/varimu.js ADDED
@@ -0,0 +1,38 @@
1
+ // Vari-Mu compressor model (Fairchild class) — feedback topology (detector reads the
2
+ // output), very soft wide knee, slow attack, and ratio that grows with drive (the "mu").
3
+ import { envelope } from '@audio/dynamics-envelope'
4
+ import { compressorGain } from '@audio/dynamics-compressor'
5
+ import { writer, concat, db2lin, lin2db, timeCoef } from '@audio/dynamics-core'
6
+
7
+ export default function varimu (data, opts) {
8
+ if (!(data instanceof Float32Array)) return writer(varimuStream(data))
9
+ let s = varimuStream(opts)
10
+ return concat(s.write(data), s.flush())
11
+ }
12
+
13
+ export function varimuStream (opts = {}) {
14
+ let sr = opts.sampleRate || opts.fs || 44100
15
+ let threshold = opts.threshold ?? -22
16
+ let knee = opts.knee ?? 15
17
+ let makeup = opts.makeup ?? 0
18
+ let env = envelope({ ...opts, sampleRate: sr, detector: 'rms', attack: opts.attack ?? 25, release: 1 })
19
+ let gr = 0
20
+ let aCoef = timeCoef(opts.attack ?? 25, sr)
21
+ let rCoef = timeCoef(opts.release ?? 400, sr)
22
+
23
+ return {
24
+ write (chunk) {
25
+ let out = new Float32Array(chunk.length)
26
+ for (let i = 0; i < chunk.length; i++) {
27
+ let y = chunk[i] * db2lin(gr) // feedback: detect the compressed output
28
+ let over = lin2db(env(y)) - threshold
29
+ let mu = 1.8 + Math.max(0, over) / 5 // ratio grows with drive
30
+ let target = compressorGain(lin2db(env(y)) , threshold, mu, knee)
31
+ gr = target < gr ? target + (gr - target) * aCoef : target + (gr - target) * rCoef
32
+ out[i] = chunk[i] * db2lin(gr + makeup)
33
+ }
34
+ return out
35
+ },
36
+ flush () { return new Float32Array(0) }
37
+ }
38
+ }