/ proof-of-concept / steelsim21
Sign in
proof-of-concept / steelsim21
steelsim21 / src / audio / wav.ts
28 lines · 1022 BBlameHistoryRaw
1// 16-bit PCM mono WAV encoder.
3import { normalize, type LevelMode } from "./level.ts";
5export function encodeWav(samples: Float32Array, fs: number, mode: LevelMode = "peak"): Blob {
6 const scaled = normalize(samples, fs, mode, 0.99);
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, scaled[k]));
25 v.setInt16(44 + 2 * k, Math.round(s * 32767), true);
26 }
27 return new Blob([buf], { type: "audio/wav" });
↑↓ move↵openescclose