in client/src/util/audio.ts [158:193]
function audioBuffersToWAV(sampleBuffer: Float32Array, sampleRate: number): Blob {
const sampleCount = sampleBuffer.length;
const buffer = new ArrayBuffer(44 + sampleCount * 2);
const view = new DataView(buffer);
writeWAVString(view, 0, 'RIFF');
// file length
view.setUint32(4, 32 + sampleCount * 2, true);
writeWAVString(view, 8, 'WAVE');
writeWAVString(view, 12, 'fmt ');
// chunk length
view.setUint32(16, 16, true);
// sample format
view.setUint16(20, 1, true);
// channel count
view.setUint16(22, 1, true);
// sample rate
view.setUint32(24, sampleRate, true);
// byte rate
view.setUint32(28, sampleRate * 4, true);
// block align
view.setUint16(32, 4, true);
// bits per sample
view.setUint16(34, 16, true);
// data chunk identifier
writeWAVString(view, 36, 'data');
// data length
view.setUint32(40, sampleCount * 2, true);
// data
let offset = 44;
for (const spl of sampleBuffer) {
const s = Math.max(-1, Math.min(1, spl));
view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
offset += 2;
}
return new Blob([buffer], { type: 'audio/wav' });
}