From ba828b782d83690d0429e4d5025e1848aec6fb3a Mon Sep 17 00:00:00 2001 From: Del Wang Date: Mon, 26 May 2025 23:12:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=20VAD=20=E8=AF=AD?= =?UTF-8?q?=E9=9F=B3=E7=89=87=E6=AE=B5=E6=94=B6=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/xiaozhi/xiaozhi/event.py | 6 +--- .../xiaozhi/services/audio/vad/__init__.py | 29 ++++++++++++++----- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/examples/xiaozhi/xiaozhi/event.py b/examples/xiaozhi/xiaozhi/event.py index f10eafd..88ea0e2 100644 --- a/examples/xiaozhi/xiaozhi/event.py +++ b/examples/xiaozhi/xiaozhi/event.py @@ -27,7 +27,6 @@ class __EventManager: self.session_id = 0 self.current_step = Step.idle self.next_step_future = None - self.tts_session_id = "" def update_step(self, step: Step, step_data=None): if get_xiaoai().mode == "xiaozhi": @@ -80,12 +79,9 @@ class __EventManager: def on_tts_end(self, session_id): """TTS结束""" - if self.current_step == Step.on_interrupt: + if self.current_step in [Step.on_interrupt, Step.on_tts_end]: # 当前 session 已经被打断了,不再处理 return - if self.tts_session_id == session_id: - return - self.tts_session_id = session_id self.session_id = self.session_id + 1 self.update_step(Step.on_tts_end) self.start_session() diff --git a/examples/xiaozhi/xiaozhi/services/audio/vad/__init__.py b/examples/xiaozhi/xiaozhi/services/audio/vad/__init__.py index 8738391..4613cff 100644 --- a/examples/xiaozhi/xiaozhi/services/audio/vad/__init__.py +++ b/examples/xiaozhi/xiaozhi/services/audio/vad/__init__.py @@ -33,16 +33,16 @@ class _VAD: self.stream = None # 暂存的语音片段 - self.temp_frames = [] - self.speech_buffer = [] + self.silence_frames = [] # 静音片段 + self.speech_frames = [] # 语音片段 self.target = None # 检测目标 speech/silence def _reset_state(self): """重置状态""" self.speech_count = 0 self.silence_count = 0 - self.speech_buffer = [] - self.temp_frames = [] + self.speech_frames = [] + self.silence_frames = [] def start(self): """启动VAD检测器""" @@ -78,22 +78,37 @@ class _VAD: """处理语音帧""" self.speech_count += len(frames) self.silence_count = 0 - self.speech_buffer.extend(frames) - speech_bytes = bytes(self.speech_buffer) + if not self.speech_frames: + # 加入静音片段(潜在的语音片段) + self.speech_frames.extend(self.silence_frames) + + # 加入语音片段 + self.speech_frames.extend(frames) + + speech_bytes = bytes(self.speech_frames) if ( self.target == "speech" and self.speech_count > self.min_speech_duration * self.sample_rate / 1000 ): self.pause() + # !FIXME: 需要保证音频流的连续性(在发消息期间) EventManager.on_speech(speech_bytes) def _handle_silence_frame(self, frames): """处理静音帧""" self.silence_count += len(frames) self.speech_count = 0 - self.speech_buffer = [] + + if not self.speech_frames: + # 如果之前没有语音片段,则将当前帧加入静音片段 + self.silence_frames.extend(frames) + # 确保静音片段长度不超过 3s + self.silence_frames = self.silence_frames[: 3 * self.sample_rate] + else: + # 如果之前有语音片段,则将当前帧加入语音片段 + self.speech_frames.extend(frames) if ( self.target == "silence"