/** * Small pure helpers for combining traces from different renderers at * different rates. Resampling is linear interpolation, which is adequate * here because the instrawave traces arrive oversampled (the solver rate, * around 114 kHz) and the content sits far below either rate. */ export function resampleLinear(x: Float32Array, srFrom: number, srTo: number): Float32Array { if (x.length === 0) return new Float32Array(0); const n = Math.max(1, Math.round((x.length * srTo) / srFrom)); const out = new Float32Array(n); for (let i = 0; i < n; i++) { const s = (i * srFrom) / srTo; const k = Math.min(x.length - 2, Math.floor(s)); const f = Math.min(1, Math.max(0, s - k)); out[i] = (1 - f) * x[k] + f * x[Math.min(x.length - 1, k + 1)]; } return out; } export function peak(x: Float32Array): number { let p = 0; for (let i = 0; i < x.length; i++) { const a = Math.abs(x[i]); if (a > p) p = a; } return p; } /** dst += src * gain, clipped to dst's length. */ export function mixInto(dst: Float32Array, src: Float32Array, gain = 1): void { const n = Math.min(dst.length, src.length); for (let i = 0; i < n; i++) dst[i] += src[i] * gain; }