Bladeren bron

兼容火狐浏览器采集率使用线性插值算法将不同采样率的音频数据转换为16000Hz

liyanbo 1 maand geleden
bovenliggende
commit
31def19da0
1 gewijzigde bestanden met toevoegingen van 35 en 2 verwijderingen
  1. 35 2
      src/components/ai/voice/VoiceInput2.vue

+ 35 - 2
src/components/ai/voice/VoiceInput2.vue

@@ -271,6 +271,35 @@ const stopResultPolling = () => {
   }
 };
 
+// 音频重采样函数
+const resampleAudio = (arrayBuffer, inputSampleRate, outputSampleRate) => {
+  // 如果采样率相同,直接返回
+  if (inputSampleRate === outputSampleRate) {
+    return arrayBuffer;
+  }
+  
+  // 转换为Int16Array
+  const inputData = new Int16Array(arrayBuffer);
+  const inputLength = inputData.length;
+  
+  // 计算输出长度
+  const outputLength = Math.floor(inputLength * outputSampleRate / inputSampleRate);
+  const outputData = new Int16Array(outputLength);
+  
+  // 线性插值重采样
+  for (let i = 0; i < outputLength; i++) {
+    const inputIndex = i * inputSampleRate / outputSampleRate;
+    const index1 = Math.floor(inputIndex);
+    const index2 = Math.min(index1 + 1, inputLength - 1);
+    const fraction = inputIndex - index1;
+    
+    // 线性插值
+    outputData[i] = Math.round(inputData[index1] * (1 - fraction) + inputData[index2] * fraction);
+  }
+  
+  return outputData.buffer;
+};
+
 // 记录录音开始时的输入框状态
 const recordInputState = () => {
   const input = document.querySelector(props.inputSelector)
@@ -391,7 +420,9 @@ const toggleSpeechInput = async () => {
           // 处理来自工作线程的消息
           scriptProcessor.value.port.onmessage = async (event) => {
             if (event.data.pcmData) {
-              await sendAudioData(event.data.pcmData);
+              // 重采样到16000Hz
+              const resampledData = resampleAudio(event.data.pcmData, audioContext.value.sampleRate, 16000);
+              await sendAudioData(resampledData);
             }
           };
         } catch (error) {
@@ -405,8 +436,10 @@ const toggleSpeechInput = async () => {
             for (let i = 0; i < inputData.length; i++) {
               pcmData[i] = inputData[i] * 32768;
             }
+            // 重采样到16000Hz
+            const resampledData = resampleAudio(pcmData.buffer, audioContext.value.sampleRate, 16000);
             // 发送到后端
-            await sendAudioData(pcmData.buffer);
+            await sendAudioData(resampledData);
           };
         }
       } else {