- frontend/wasm/loudness.c → loudness-wasm.js (1.5 KB, base64-embedded; built by scripts/build-loudness-wasm.sh with clang or Zig's clang): K-weighting + 100 ms energy steps. loudness.js does the 400 ms gating (abs -70 LUFS, rel -10 LU) with an identical JS fallback. EBU Tech 3341 sine cases measure -23.0/-33.0 on both engines; a real track reads -21.7 vs ffmpeg ebur128 -21.8. - The device measures from audio it already has (saved copy or the server cache's m4a sidecar, songs up to 12 min, decoded natively at 22.05 kHz) and reports the number to /api/loudness, so each song is measured once for everyone; the server stores numbers only, no audio processing. - The EQ graph gains a level stage (gain -> limiter) that eases each track toward -14 LUFS (-12..+9 dB). Settings -> Playback -> Level volume: on by default on Android/desktop, opt-in on iPhone (Web Audio stops sound when the screen locks there).
7 lines
2.3 KiB
JavaScript
7 lines
2.3 KiB
JavaScript
/* GENERATED by scripts/build-loudness-wasm.sh from frontend/wasm/loudness.c — do not edit.
|
|
* WebAssembly K-weighting + 100 ms energy steps for EBU R128 loudness (see loudness.js). */
|
|
(function (root) {
|
|
root.LOUDNESS_WASM_B64 = 'AGFzbQEAAAABHQRgAX8Bf2AAAX9gDH9/fHx8fHx8fHx8fABgAX8AAwYFAAEBAgMFAwEAQgYIAX8BQYDAAAsHMQYGbWVtb3J5AgAFaW5idWYAAAVzdGVwcwABBWNvdW50AAIFc2V0dXAAAwRmZWVkAAQK2QoFEQBBgMCAgABBgMCQgAAgABsLCABBgMCggAALCwBBACgCgOjjgQAL5wIAQQBCADcDkOjjgQBBACACOQOg6OOBAEEAIAM5A6jo44EAQQAgBDkDsOjjgQBBACAFOQO46OOBAEEAIAY5A8Do44EAQQAgBzkD0OjjgQBBACAIOQPY6OOBAEEAIAk5A+Do44EAQQAgCjkD6OjjgQBBACALOQPw6OOBAEEAQgA3A/jp44EAQQBCADcD8OnjgQBBAEIANwPo6eOBAEEAQgA3A+Dp44EAQQBCADcD2OnjgQBBAEIANwPQ6eOBAEEAQgA3A8jp44EAQQBCADcDwOnjgQBBAEIANwO46eOBAEEAQgA3A7Dp44EAQQBCADcDqOnjgQBBAEIANwOg6eOBAEEAQgA3A5jp44EAQQBCADcDkOnjgQBBAEIANwOI6eOBAEEAQgA3A4Dp44EAQQAgAUEBIAFBAUobNgKI6OOBAEEAQQJBASAAQQFKGzYChOjjgQBBAEEANgKM6OOBAEEAQQA2AoDo44EAC8YHDgN/CHwBfwd8An8EfAJ/BHwCfwF8An8BfAF/A3wCQCAAQQFIDQAgAEGAgAQgAEGAgARIGyEBQQAoAoTo44EAIgJBf2ohA0EAKwO46eOBACEEQQArA7Dp44EAIQVBACsDqOnjgQAhBkEAKwOg6eOBACEHQQArA5jp44EAIQhBACsDkOnjgQAhCUEAKwOI6eOBACEKQQArA4Dp44EAIQtBACgCiOjjgQAhDEEAKwPg6OOBACENQQArA9jo44EAIQ5BACsD0OjjgQAhD0EAKwOw6OOBACEQQQArA6jo44EAIRFBACsDoOjjgQAhEkEAKwOQ6OOBACETQQAoAozo44EAIRRBACgCgOjjgQAhFUEAKwPw6OOBAJohFkEAKwPo6OOBAJohF0EAKwPA6OOBAJohGEEAKwO46OOBAJohGSACQQFIIRpBACEbA0ACQAJAIBpFDQBEAAAAAAAAAAAhHAwBC0EAIAs5A4jp44EAQQAgCTkDmOnjgQBBACAHOQOo6eOBAEEAIAU5A7jp44EAQQAgG0ECdCIAKgKAwJCAALsiHTkDgOnjgQBBACAYIAiiIBkgCaIgECAKoiASIB2iIBEgC6KgoKCgIh45A5Dp44EAQQAgHjkDoOnjgQBBACAWIASiIBcgBaIgDSAGoiAPIB6iIA4gB6KgoKCgIh85A7Dp44EAIB8gH6JEAAAAAAAAAACgIRwCQCACQQFGDQAgACoCgMCAgAC7IQRBgOnjgQAhACADISADQCAAQcgAaiIhKwMAISIgISAAQcAAaiIjKwMAIgY5AwAgAEHYAGoiISsDACEIICEgAEHQAGoiJCsDACIKOQMAICMgBDkDACAAQegAaiIhKwMAISUgISAAQeAAaiImKwMAIic5AwAgAEH4AGoiISsDACEoICEgAEHwAGoiACsDACIpOQMAICQgGCAIoiAZIAqiIBAgIqIgEiAEoiARIAaioKCgoCIiOQMAICYgIjkDACAAIBYgKKIgFyApoiANICWiIA8gIqIgDiAnoqCgoKAiIjkDACAiICKiIBygIRwgIyEAICBBf2oiIA0ACwsgBSEEIB8hBSAHIQYgHiEHIAkhCCAeIQkgCyEKIB0hCwsgHCAToCEiAkACQCAUQQFqIhQgDEYNACAiIRMMAQtEAAAAAAAAAAAhE0EAIRQgFUH/tBhKDQBBACEUQQAgFUEBaiIANgKA6OOBACAVQQN0QYDAoIAAaiAiOQMAIAAhFQsgG0EBaiIbIAFHDQALQQAgFDYCjOjjgQBBACATOQOQ6OOBAAsL';
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = root.LOUDNESS_WASM_B64;
|
|
})(typeof globalThis !== 'undefined' ? globalThis : this);
|