wx-web/utils/audioUtil.js

58 lines
2.0 KiB
JavaScript
Raw Normal View History

2024-05-22 10:14:19 +08:00
"use strict";
const savePCMBuffer = async (pcmArrayBuffer, voiceList) => {
const sampleRate = 16e3;
const channels = 1;
const bitDepth = 16;
const wavArrayBuffer = pcmToWav(pcmArrayBuffer, sampleRate, channels, bitDepth);
const FileSystemManager = wx.getFileSystemManager();
const dateNow = Date.now();
const savePath = `${wx.env.USER_DATA_PATH}/${dateNow}.wav`;
try {
await new Promise((resolve, reject) => {
FileSystemManager.writeFile({
data: wavArrayBuffer,
filePath: savePath,
success: resolve,
fail: reject
});
});
if (voiceList) {
voiceList.push(savePath);
}
} catch (error) {
console.error("Failed to save WAV file:", error);
}
};
const pcmToWav = (pcmArrayBuffer, sampleRate, channels, bitDepth) => {
const chunkSize = 36 + pcmArrayBuffer.byteLength;
const subChunk1Size = 16;
const audioFormat = 1;
const byteRate = sampleRate * channels * (bitDepth / 8);
const blockAlign = channels * (bitDepth / 8);
const wavArrayBuffer = new ArrayBuffer(chunkSize + 8 + pcmArrayBuffer.byteLength);
const wavView = new DataView(wavArrayBuffer);
writeString(wavView, 0, "RIFF");
wavView.setUint32(4, chunkSize, true);
writeString(wavView, 8, "WAVE");
writeString(wavView, 12, "fmt ");
wavView.setUint32(16, subChunk1Size, true);
wavView.setUint16(20, audioFormat, true);
wavView.setUint16(22, channels, true);
wavView.setUint32(24, sampleRate, true);
wavView.setUint32(28, byteRate, true);
wavView.setUint16(32, blockAlign, true);
wavView.setUint16(34, bitDepth, true);
writeString(wavView, 36, "data");
wavView.setUint32(40, pcmArrayBuffer.byteLength, true);
const pcmView = new Uint8Array(pcmArrayBuffer);
const wavPcmView = new Uint8Array(wavArrayBuffer, 44);
wavPcmView.set(pcmView);
return wavArrayBuffer;
};
const writeString = (view, offset, string) => {
for (let i = 0; i < string.length; i++) {
view.setUint8(offset + i, string.charCodeAt(i));
}
};
exports.savePCMBuffer = savePCMBuffer;