/ proof-of-concept / steelsim21
Sign in
proof-of-concept / steelsim21
steelsim21 / src / audio / wav.ts
28 lines · 1.0 KBBlameHistoryRaw
1// 16-bit PCM mono WAV encoder.
3export function encodeWav(samples: Float32Array, fs: number, peak = 0.99): Blob {
4 let max = 0;
5 for (let k = 0; k < samples.length; k++) max = Math.max(max, Math.abs(samples[k]));
6 const gain = max > 0 ? peak / max : 0;
7 const buf = new ArrayBuffer(44 + samples.length * 2);
8 const v = new DataView(buf);
9 const str = (o: number, s: string) => { for (let k = 0; k < s.length; k++) v.setUint8(o + k, s.charCodeAt(k)); };
10 str(0, "RIFF");
11 v.setUint32(4, 36 + samples.length * 2, true);
12 str(8, "WAVE");
13 str(12, "fmt ");
14 v.setUint32(16, 16, true);
15 v.setUint16(20, 1, true);
16 v.setUint16(22, 1, true);
17 v.setUint32(24, fs, true);
18 v.setUint32(28, fs * 2, true);
19 v.setUint16(32, 2, true);
20 v.setUint16(34, 16, true);
21 str(36, "data");
22 v.setUint32(40, samples.length * 2, true);
23 for (let k = 0; k < samples.length; k++) {
24 const s = Math.max(-1, Math.min(1, samples[k] * gain));
25 v.setInt16(44 + 2 * k, Math.round(s * 32767), true);
26 }
27 return new Blob([buf], { type: "audio/wav" });
↑↓ move↵openescclose