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