From ce8514cc39557000fbf0d82a6bef31b4741b7313 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 4 Jun 2024 11:25:14 +0800 Subject: [PATCH] =?UTF-8?q?Feat:=20floatTo16BitPCM=20=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 4 ++-- src/utils/audio.ts | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8bfe50c..eb0ae67 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import viteLogo from "/vite.svg"; import "./App.css"; import { client, start } from "./utils/mqtt"; import { startAudio, stopAudio, context } from "./utils/microphone"; -import { arrayBufferToBase64, downSampleAudioFrame, getMergedPCMData } from "./utils/audio"; +import { arrayBufferToBase64, downSampleAudioFrame, floatTo16BitPCM, getMergedPCMData } from "./utils/audio"; let mqttData; @@ -17,7 +17,7 @@ const getAudio = () => { // 降比特率到 16000 const downedFloat32Arr = downSampleAudioFrame(float32Arr, context.sampleRate, 16000); // 转 base64 打包给后端 - const sendItem = arrayBufferToBase64(downedFloat32Arr.buffer); + const sendItem = arrayBufferToBase64(floatTo16BitPCM(downedFloat32Arr)); // 存储一遍压缩后的音频 buffers.push(downedFloat32Arr); diff --git a/src/utils/audio.ts b/src/utils/audio.ts index 1117717..5060579 100644 --- a/src/utils/audio.ts +++ b/src/utils/audio.ts @@ -61,3 +61,22 @@ export const arrayBufferToBase64 = (buffer: ArrayBuffer) => { } return window.btoa(binary); } + +// Float32 转 16 Bit PCM +export const floatTo16BitPCM = (input: Float32Array) => { + const audioLength = input.length * 2; + + // 新开一个对象 + const buffer = new ArrayBuffer(audioLength); + const view = new DataView(buffer); + + // 写入 input 的数据到 buffer 里面(view 理解成只是一个操作手段) + let offset = 0; + + for (let i = 0; i < input.length; i++ , offset += 2) { + const s = Math.max(-1, Math.min(1, input[i])); + view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); + } + + return buffer; +}