@audio/loudness-dr 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/dr.js +40 -0
  2. package/package.json +29 -0
package/dr.js ADDED
@@ -0,0 +1,40 @@
1
+ // DR value — crest-factor dynamic range meter (TT/dr14 method):
2
+ // per-channel 3 s blocks → block RMS with the ×2 sine convention (full-scale sine → 0 dB)
3
+ // and block peak; DR_ch = 20·log10(secondHighestPeak / rms of loudest 20% blocks); average channels.
4
+
5
+ /**
6
+ * @param {Float32Array|Float32Array[]} channels
7
+ * @param {object} opts — { fs=48000, blockSeconds=3 }
8
+ * @returns {number|null} DR value in dB
9
+ */
10
+ export default function dr (channels, { fs = 48000, blockSeconds = 3 } = {}) {
11
+ if (channels[0]?.length === undefined) channels = [channels]
12
+ let win = Math.round(blockSeconds * fs)
13
+ let drs = []
14
+
15
+ for (let ch of channels) {
16
+ if (ch.length < win * 2) win = Math.max(1, Math.floor(ch.length / 2))
17
+ let rms = [], peaks = []
18
+ for (let i = 0; i + win <= ch.length; i += win) {
19
+ let e = 0, p = 0
20
+ for (let j = i; j < i + win; j++) {
21
+ let v = ch[j]
22
+ e += v * v
23
+ let a = Math.abs(v)
24
+ if (a > p) p = a
25
+ }
26
+ rms.push(Math.sqrt(2 * e / win))
27
+ peaks.push(p)
28
+ }
29
+ if (rms.length < 2) continue
30
+ peaks.sort((a, b) => b - a)
31
+ rms.sort((a, b) => b - a)
32
+ let top = Math.max(1, Math.round(rms.length * 0.2))
33
+ let e20 = 0
34
+ for (let i = 0; i < top; i++) e20 += rms[i] * rms[i]
35
+ let r = Math.sqrt(e20 / top)
36
+ let p2 = peaks[1]
37
+ if (r > 0 && p2 > 0) drs.push(20 * Math.log10(p2 / r))
38
+ }
39
+ return drs.length ? drs.reduce((a, b) => a + b, 0) / drs.length : null
40
+ }
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@audio/loudness-dr",
3
+ "version": "1.0.0",
4
+ "description": "DR value — TT/dr14 crest-factor dynamic range meter",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "dr.js",
8
+ "exports": {
9
+ ".": "./dr.js",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "dr.js"
14
+ ],
15
+ "keywords": [
16
+ "audio",
17
+ "dsp",
18
+ "loudness",
19
+ "dr"
20
+ ],
21
+ "license": "MIT",
22
+ "author": "Dmitry Iv. <dfcreative@gmail.com>",
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ }
29
+ }