audio youhua
This commit is contained in:
parent
0a7b2124a8
commit
fe2876f09c
@ -8,12 +8,20 @@ class AudioProcessor {
|
||||
|
||||
// VAD相关属性
|
||||
this.isSpeaking = false;
|
||||
this.silenceThreshold = options.silenceThreshold || 0.01;
|
||||
this.silenceThreshold = options.silenceThreshold || 0.03;
|
||||
this.silenceTimeout = options.silenceTimeout || 1000;
|
||||
this.minSpeechDuration = options.minSpeechDuration || 300;
|
||||
this.silenceTimer = null;
|
||||
this.speechStartTime = null;
|
||||
this.audioBuffer = [];
|
||||
this.backgroundNoiseLevel = 0;
|
||||
// 添加连续性检测参数
|
||||
this.consecutiveFramesRequired = 3;
|
||||
this.consecutiveFramesCount = 0; // 当前连续帧计数
|
||||
this.frameBuffer = []; // 帧缓冲区
|
||||
this.adaptiveThreshold = options.adaptiveThreshold !== false;
|
||||
this.noiseCalibrationSamples = [];
|
||||
this.isCalibrated = false; // 添加校准状态标志
|
||||
|
||||
// API配置
|
||||
this.apiConfig = {
|
||||
@ -36,6 +44,49 @@ class AudioProcessor {
|
||||
this.onStatusUpdate = options.onStatusUpdate || (() => {});
|
||||
}
|
||||
|
||||
// 添加背景噪音校准方法
|
||||
// 改进背景噪音校准方法,添加更多日志
|
||||
calibrateBackgroundNoise(audioData) {
|
||||
const audioLevel = this.calculateAudioLevel(audioData);
|
||||
this.noiseCalibrationSamples.push(audioLevel);
|
||||
|
||||
if (this.noiseCalibrationSamples.length >= 100) {
|
||||
this.backgroundNoiseLevel = this.noiseCalibrationSamples.reduce((a, b) => a + b) / this.noiseCalibrationSamples.length;
|
||||
const oldThreshold = this.silenceThreshold;
|
||||
this.silenceThreshold = Math.max(this.backgroundNoiseLevel * 2.5, 0.005); // 设置最小阈值
|
||||
|
||||
console.log(`背景噪音校准完成:`);
|
||||
console.log(`- 平均背景噪音: ${this.backgroundNoiseLevel.toFixed(4)}`);
|
||||
console.log(`- 旧阈值: ${oldThreshold.toFixed(4)}`);
|
||||
console.log(`- 新阈值: ${this.silenceThreshold.toFixed(4)}`);
|
||||
|
||||
this.noiseCalibrationSamples = [];
|
||||
this.onStatusUpdate('背景噪音校准完成,等待语音输入...', 'ready');
|
||||
}
|
||||
}
|
||||
|
||||
// 改进音频能量计算
|
||||
calculateAudioLevel(audioData) {
|
||||
let sum = 0;
|
||||
let peak = 0;
|
||||
for (let i = 0; i < audioData.length; i++) {
|
||||
const sample = Math.abs(audioData[i]);
|
||||
sum += sample * sample;
|
||||
peak = Math.max(peak, sample);
|
||||
}
|
||||
const rms = Math.sqrt(sum / audioData.length);
|
||||
// 结合RMS和峰值进行更准确的检测
|
||||
return rms * 0.7 + peak * 0.3;
|
||||
}
|
||||
|
||||
// 重新校准背景噪音
|
||||
recalibrateBackground() {
|
||||
this.noiseCalibrationSamples = [];
|
||||
this.isCalibrated = false;
|
||||
this.onStatusUpdate('开始重新校准背景噪音...', 'calibrating');
|
||||
console.log('开始重新校准背景噪音');
|
||||
}
|
||||
|
||||
// 生成UUID
|
||||
generateUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
@ -46,27 +97,33 @@ class AudioProcessor {
|
||||
}
|
||||
|
||||
// 计算音频能量(音量)
|
||||
calculateAudioLevel(audioData) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < audioData.length; i++) {
|
||||
sum += audioData[i] * audioData[i];
|
||||
}
|
||||
return Math.sqrt(sum / audioData.length);
|
||||
}
|
||||
// calculateAudioLevel(audioData) {
|
||||
// let sum = 0;
|
||||
// for (let i = 0; i < audioData.length; i++) {
|
||||
// sum += audioData[i] * audioData[i];
|
||||
// }
|
||||
// return Math.sqrt(sum / audioData.length);
|
||||
// }
|
||||
|
||||
// 语音活动检测
|
||||
// 修改语音活动检测方法
|
||||
// 改进语音活动检测
|
||||
detectVoiceActivity(audioData) {
|
||||
const audioLevel = this.calculateAudioLevel(audioData);
|
||||
const currentTime = Date.now();
|
||||
|
||||
// 连续性检测
|
||||
if (audioLevel > this.silenceThreshold) {
|
||||
this.consecutiveFramesCount++;
|
||||
|
||||
// 需要连续几帧都超过阈值才开始录音
|
||||
if (this.consecutiveFramesCount >= this.consecutiveFramesRequired) {
|
||||
if (!this.isSpeaking) {
|
||||
this.isSpeaking = true;
|
||||
this.speechStartTime = currentTime;
|
||||
this.audioBuffer = [];
|
||||
this.audioBuffer = [...this.frameBuffer]; // 包含之前的帧
|
||||
this.onSpeechStart();
|
||||
this.onStatusUpdate('检测到语音,开始录音...', 'speaking');
|
||||
console.log('开始说话');
|
||||
console.log(`开始说话 - 音量: ${audioLevel.toFixed(4)}, 连续帧: ${this.consecutiveFramesCount}`);
|
||||
}
|
||||
|
||||
if (this.silenceTimer) {
|
||||
@ -76,6 +133,18 @@ class AudioProcessor {
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// 还未达到连续帧要求,缓存音频数据
|
||||
this.frameBuffer.push(new Float32Array(audioData));
|
||||
if (this.frameBuffer.length > this.consecutiveFramesRequired) {
|
||||
this.frameBuffer.shift(); // 保持缓冲区大小
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// 重置连续帧计数
|
||||
this.consecutiveFramesCount = 0;
|
||||
this.frameBuffer = [];
|
||||
|
||||
if (this.isSpeaking && !this.silenceTimer) {
|
||||
this.silenceTimer = setTimeout(() => {
|
||||
this.handleSpeechEnd();
|
||||
@ -277,6 +346,11 @@ class AudioProcessor {
|
||||
this.isRecording = true;
|
||||
this.onStatusUpdate('等待语音输入...', 'ready');
|
||||
|
||||
// 在startRecording方法的最后添加
|
||||
if (this.adaptiveThreshold && this.noiseCalibrationSamples.length === 0) {
|
||||
this.onStatusUpdate('正在校准背景噪音,请保持安静...', 'calibrating');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user