1// 16-bit mono PCM WAV, normalized to the given peak (default -1 dBFS).
2export function encodeWav(x: Float32Array, fs: number, peak = 0.89): Blob {
3 let m = 0;
4 for (let i = 0; i < x.length; i++) m = Math.max(m, Math.abs(x[i]));
5 const g = m > 0 ? peak / m : 0;
6 const buf = new ArrayBuffer(44 + 2 * x.length);
7 const v = new DataView(buf);
8 const str = (o: number, s: string) => {
9 for (let i = 0; i < s.length; i++) v.setUint8(o + i, s.charCodeAt(i));
10 };
11 str(0, 'RIFF');
12 v.setUint32(4, 36 + 2 * x.length, true);
13 str(8, 'WAVE');
14 str(12, 'fmt ');
15 v.setUint32(16, 16, true);
16 v.setUint16(20, 1, true);
17 v.setUint16(22, 1, true);
18 v.setUint32(24, fs, true);
19 v.setUint32(28, fs * 2, true);
20 v.setUint16(32, 2, true);
21 v.setUint16(34, 16, true);
22 str(36, 'data');
23 v.setUint32(40, 2 * x.length, true);
24 for (let i = 0; i < x.length; i++) {
25 const s = Math.max(-1, Math.min(1, x[i] * g));
26 v.setInt16(44 + 2 * i, Math.round(s * 32767), true);
27 }
28 return new Blob([buf], { type: 'audio/wav' });
29}