JavaScript - AudioBuffer to Wav
發文於 2024-10-08 由 JTH
async function audioBufferToWav2(audioBuffer) {
const numChannels = audioBuffer.numberOfChannels;
const sampleRate = audioBuffer.sampleRate;
const numSamples = audioBuffer.length;
// 計算 WAV 檔案的總字節長度
const byteLength = 44 + numSamples * numChannels * 2; // 44 bytes for header and 16-bit samples
const buffer = new ArrayBuffer(byteLength);
const view = new DataView(buffer);
// 寫入 WAV 頭部
writeString(view, 0, "RIFF");
view.setUint32(4, byteLength - 8, true); // 4 bytes for 'RIFF' + file size
writeString(view, 8, "WAVE");
writeString(view, 12, "fmt ");
view.setUint32(16, 16, true); // Subchunk1Size for PCM
view.setUint16(20, 1, true); // AudioFormat (PCM)
view.setUint16(22, numChannels, true); // Number of Channels
view.setUint32(24, sampleRate, true); // SampleRate
view.setUint32(28, sampleRate * numChannels * 2, true); // ByteRate
view.setUint16(32, numChannels * 2, true); // BlockAlign
view.setUint16(34, 16, true); // BitsPerSample
writeString(view, 36, "data");
view.setUint32(40, numSamples * numChannels * 2, true); // Subchunk2Size
// 寫入音頻數據
for (let i = 0; i < numChannels; i++) {
const channelData = audioBuffer.getChannelData(i);
for (let j = 0; j < numSamples; j++) {
// 格式轉換:將浮點值(-1.0 到 1.0)轉換為 16 位整數
view.setInt16(44 + j * numChannels * 2 + i * 2, channelData[j] * 0x7fff, true);
}
}
return new Blob([view], { type: 'audio/wav' });
}