import { test, expect } from "bun:test"; import { mixStemsScaled } from "../../src/audio/mix.ts"; import type { Audio } from "../../src/core/types.ts"; test("mixStemsScaled: scaled stems sum to mix; scale is the normalisation factor", () => { const mk = (n: number, amp: number): Audio => { const x = Float32Array.from({ length: n }, (_, i) => amp * Math.sin(i / 7)); return { sampleRate: 44100, channels: [x, x.slice()] }; }; const a = mk(1000, 0.9), b = mk(700, 0.8); const { mix, scaled, scale } = mixStemsScaled([{ audio: a, gainDb: 0 }, { audio: b, gainDb: -3 }]); // unnormalised peak const gb = Math.pow(10, -3 / 20); let peak = 0; for (let i = 0; i < 1000; i++) peak = Math.max(peak, Math.abs(a.channels[0]![i]! + (i < 700 ? b.channels[0]![i]! * gb : 0))); expect(peak).toBeGreaterThan(1); expect(Math.abs(scale - Math.pow(10, -1 / 20) / peak)).toBeLessThan(1e-6); expect(scaled.length).toBe(2); let maxDiff = 0; for (let c = 0; c < 2; c++) for (let i = 0; i < 1000; i++) { const s = scaled[0]!.channels[c]![i]! + scaled[1]!.channels[c]![i]!; maxDiff = Math.max(maxDiff, Math.abs(s - mix.channels[c]![i]!)); } expect(maxDiff).toBeLessThan(1e-6); });