// Mono 16-bit PCM WAV encoder. /** Encodes the signal as a 16-bit PCM mono WAV file; samples are clamped to [-1, 1]. */ export function encodeWav(samples: Float32Array, fs: number): Blob { const n = samples.length; const dataBytes = n * 2; const buf = new ArrayBuffer(44 + dataBytes); const v = new DataView(buf); const ascii = (offset: number, s: string): void => { for (let k = 0; k < s.length; k++) v.setUint8(offset + k, s.charCodeAt(k)); }; const rate = Math.round(fs); ascii(0, "RIFF"); v.setUint32(4, 36 + dataBytes, true); ascii(8, "WAVE"); ascii(12, "fmt "); v.setUint32(16, 16, true); // fmt chunk size v.setUint16(20, 1, true); // PCM v.setUint16(22, 1, true); // channels v.setUint32(24, rate, true); v.setUint32(28, rate * 2, true); // byte rate v.setUint16(32, 2, true); // block align v.setUint16(34, 16, true); // bits per sample ascii(36, "data"); v.setUint32(40, dataBytes, true); for (let k = 0; k < n; k++) { const x = samples[k]; const s = x > 1 ? 1 : x < -1 ? -1 : x !== x ? 0 : x; v.setInt16(44 + 2 * k, Math.round(s * 32767), true); } return new Blob([buf], { type: "audio/wav" }); }