File size: 1,583 Bytes
9dfbb06 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
export function audioBufferToWav(audioBuffer: AudioBuffer): Uint8Array {
const numOfChan = audioBuffer.numberOfChannels;
const length = audioBuffer.length * numOfChan * 2 + 44;
const buffer = new ArrayBuffer(length);
const view = new DataView(buffer);
let offset = 0;
// Write WAV header
const writeString = function (
view: DataView,
offset: number,
string: string
): void {
for (let i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
};
writeString(view, offset, "RIFF");
offset += 4;
view.setUint32(offset, length - 8, true);
offset += 4;
writeString(view, offset, "WAVE");
offset += 4;
writeString(view, offset, "fmt ");
offset += 4;
view.setUint32(offset, 16, true);
offset += 4; // Sub-chunk size, 16 for PCM
view.setUint16(offset, 1, true);
offset += 2; // PCM format
view.setUint16(offset, numOfChan, true);
offset += 2;
view.setUint32(offset, audioBuffer.sampleRate, true);
offset += 4;
view.setUint32(offset, audioBuffer.sampleRate * 2 * numOfChan, true);
offset += 4;
view.setUint16(offset, numOfChan * 2, true);
offset += 2;
view.setUint16(offset, 16, true);
offset += 2;
writeString(view, offset, "data");
offset += 4;
view.setUint32(offset, audioBuffer.length * numOfChan * 2, true);
offset += 4;
// Write PCM audio data
for (let i = 0; i < audioBuffer.numberOfChannels; i++) {
const channel = audioBuffer.getChannelData(i);
for (let j = 0; j < channel.length; j++) {
view.setInt16(offset, channel[j] * 0xffff, true);
offset += 2;
}
}
return new Uint8Array(buffer);
}
|