55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { describe, it } from "@suaveplan/testing/runner";
|
|
import fc from "fast-check";
|
|
import { LoudnessMeter, samplePeakLinear, truePeakDbtp } from "../src/index.js";
|
|
import { buildDoc, sine } from "./helpers/build-doc.js";
|
|
|
|
describe("LoudnessMeter properties", () => {
|
|
it("LUFS is monotonic with gain on a sine", {
|
|
timeout: 60000,
|
|
}, async () => {
|
|
await fc.assert(
|
|
fc.asyncProperty(
|
|
fc.double({ min: 0.05, max: 0.5, noNaN: true }),
|
|
fc.double({ min: 0.51, max: 0.95, noNaN: true }),
|
|
async (a, b) => {
|
|
const sr = 48000;
|
|
const dur = 3.5;
|
|
const meter = new LoudnessMeter();
|
|
const lo = await meter.analyze(
|
|
buildDoc([sine(a, 1000, sr, dur)], sr)
|
|
);
|
|
const hi = await meter.analyze(
|
|
buildDoc([sine(b, 1000, sr, dur)], sr)
|
|
);
|
|
return hi.lufs >= lo.lufs - 0.5;
|
|
}
|
|
),
|
|
{ numRuns: 6 }
|
|
);
|
|
});
|
|
|
|
it("true peak ≥ sample peak for arbitrary blocks", {
|
|
timeout: 30000,
|
|
}, () => {
|
|
fc.assert(
|
|
fc.property(
|
|
fc.array(fc.double({ min: -1, max: 1, noNaN: true }), {
|
|
minLength: 32,
|
|
maxLength: 4096,
|
|
}),
|
|
(arr) => {
|
|
const ch = Float32Array.from(arr);
|
|
const sp = samplePeakLinear([ch]);
|
|
// Below Float32 quantisation, sample peak cannot be
|
|
// round-trip compared in dB: skip such degenerate inputs.
|
|
if (sp < 1e-6) return true;
|
|
const spDb = 20 * Math.log10(sp);
|
|
const tpDb = truePeakDbtp([ch]);
|
|
return tpDb >= spDb - 0.1;
|
|
}
|
|
),
|
|
{ numRuns: 25 }
|
|
);
|
|
});
|
|
});
|