@audio/dynamics-vca 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/vca.js +36 -0
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@audio/dynamics-vca",
3
+ "version": "0.1.0",
4
+ "description": "VCA compressor model — clean feed-forward, near-hard knee (dbx/SSL bus class)",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "vca.js",
8
+ "exports": {
9
+ ".": "./vca.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "vca.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
+ "vca"
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-vca"
33
+ },
34
+ "homepage": "https://github.com/audiojs/dynamics/tree/main/packages/dynamics-vca",
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/vca.js ADDED
@@ -0,0 +1,36 @@
1
+ // VCA compressor model (dbx/SSL-bus class) — clean feed-forward peak detection,
2
+ // near-hard knee, precise dB-linear gain computation. The transparent workhorse.
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 vca (data, opts) {
8
+ if (!(data instanceof Float32Array)) return writer(vcaStream(data))
9
+ let s = vcaStream(opts)
10
+ return concat(s.write(data), s.flush())
11
+ }
12
+
13
+ export function vcaStream (opts = {}) {
14
+ let sr = opts.sampleRate || opts.fs || 44100
15
+ let threshold = opts.threshold ?? -20
16
+ let ratio = opts.ratio ?? 4
17
+ let knee = opts.knee ?? 1
18
+ let makeup = opts.makeup ?? 0
19
+ let env = envelope({ ...opts, sampleRate: sr, detector: 'peak', attack: opts.attack ?? 1, release: 1 })
20
+ let gr = 0
21
+ let aCoef = timeCoef(opts.attack ?? 1, sr)
22
+ let rCoef = timeCoef(opts.release ?? 150, sr)
23
+
24
+ return {
25
+ write (chunk) {
26
+ let out = new Float32Array(chunk.length)
27
+ for (let i = 0; i < chunk.length; i++) {
28
+ let target = compressorGain(lin2db(env(chunk[i])), threshold, ratio, knee)
29
+ gr = target < gr ? target + (gr - target) * aCoef : target + (gr - target) * rCoef
30
+ out[i] = chunk[i] * db2lin(gr + makeup)
31
+ }
32
+ return out
33
+ },
34
+ flush () { return new Float32Array(0) }
35
+ }
36
+ }