mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-28 22:23:51 +08:00
update:恢复vad判断
This commit is contained in:
@@ -454,7 +454,7 @@ VAD:
|
|||||||
threshold: 0.5
|
threshold: 0.5
|
||||||
threshold_low: 0.3
|
threshold_low: 0.3
|
||||||
model_dir: models/snakers4_silero-vad
|
model_dir: models/snakers4_silero-vad
|
||||||
min_silence_duration_ms: 200 # 如果说话停顿比较长,可以把这个值设置大一些,实际延迟为:min_silence_duration_ms // 32 * 32ms
|
min_silence_duration_ms: 200 # 如果说话停顿比较长,可以把这个值设置大一些
|
||||||
|
|
||||||
LLM:
|
LLM:
|
||||||
# 所有openai类型均可以修改超参,以AliLLM为例
|
# 所有openai类型均可以修改超参,以AliLLM为例
|
||||||
|
|||||||
@@ -115,10 +115,10 @@ class ConnectionHandler:
|
|||||||
# vad相关变量
|
# vad相关变量
|
||||||
self.client_audio_buffer = bytearray()
|
self.client_audio_buffer = bytearray()
|
||||||
self.client_have_voice = False
|
self.client_have_voice = False
|
||||||
|
self.client_voice_window = deque(maxlen=5)
|
||||||
self.last_activity_time = 0.0 # 统一的活动时间戳(毫秒)
|
self.last_activity_time = 0.0 # 统一的活动时间戳(毫秒)
|
||||||
self.client_voice_stop = False
|
self.client_voice_stop = False
|
||||||
self.last_is_voice = False
|
self.last_is_voice = False
|
||||||
self.continuous_false_count = 0
|
|
||||||
|
|
||||||
# asr相关变量
|
# asr相关变量
|
||||||
# 因为实际部署时可能会用到公共的本地ASR,不能把变量暴露给公共ASR
|
# 因为实际部署时可能会用到公共的本地ASR,不能把变量暴露给公共ASR
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import time
|
import time
|
||||||
import torch
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import torch
|
||||||
import opuslib_next
|
import opuslib_next
|
||||||
from config.logger import setup_logging
|
from config.logger import setup_logging
|
||||||
from core.providers.vad.base import VADProviderBase
|
from core.providers.vad.base import VADProviderBase
|
||||||
@@ -26,12 +26,15 @@ class VADProvider(VADProviderBase):
|
|||||||
threshold_low = config.get("threshold_low", "0.2")
|
threshold_low = config.get("threshold_low", "0.2")
|
||||||
min_silence_duration_ms = config.get("min_silence_duration_ms", "1000")
|
min_silence_duration_ms = config.get("min_silence_duration_ms", "1000")
|
||||||
|
|
||||||
# 双阈值判断参数
|
|
||||||
self.vad_threshold = float(threshold) if threshold else 0.5
|
self.vad_threshold = float(threshold) if threshold else 0.5
|
||||||
self.vad_threshold_low = float(threshold_low) if threshold_low else 0.2
|
self.vad_threshold_low = float(threshold_low) if threshold_low else 0.2
|
||||||
|
|
||||||
# 静默阈值,连续多少帧低于最低值才判断为静音
|
self.silence_threshold_ms = (
|
||||||
self.stop_false_count = int(min_silence_duration_ms) // 32 if min_silence_duration_ms else 31
|
int(min_silence_duration_ms) if min_silence_duration_ms else 1000
|
||||||
|
)
|
||||||
|
|
||||||
|
# 至少要多少帧才算有语音
|
||||||
|
self.frame_window_threshold = 3
|
||||||
|
|
||||||
def is_vad(self, conn, opus_packet):
|
def is_vad(self, conn, opus_packet):
|
||||||
try:
|
try:
|
||||||
@@ -56,24 +59,26 @@ class VADProvider(VADProviderBase):
|
|||||||
|
|
||||||
# 双阈值判断
|
# 双阈值判断
|
||||||
if speech_prob >= self.vad_threshold:
|
if speech_prob >= self.vad_threshold:
|
||||||
client_have_voice = True
|
is_voice = True
|
||||||
elif speech_prob <= self.vad_threshold_low:
|
elif speech_prob <= self.vad_threshold_low:
|
||||||
client_have_voice = False
|
is_voice = False
|
||||||
else:
|
else:
|
||||||
client_have_voice = conn.last_is_voice
|
is_voice = conn.last_is_voice
|
||||||
|
|
||||||
if not client_have_voice:
|
|
||||||
conn.continuous_false_count += 1
|
|
||||||
else:
|
|
||||||
conn.continuous_false_count = 0
|
|
||||||
|
|
||||||
# 声音没低于最低值则延续前一个状态,判断为有声音
|
# 声音没低于最低值则延续前一个状态,判断为有声音
|
||||||
conn.last_is_voice = client_have_voice
|
conn.last_is_voice = is_voice
|
||||||
|
|
||||||
# 如果之前有声音,且连续为静音帧,达到静默阈值要求帧数,则认为已经说完一句话
|
# 更新滑动窗口
|
||||||
if conn.client_have_voice and conn.continuous_false_count >= self.stop_false_count:
|
conn.client_voice_window.append(is_voice)
|
||||||
conn.client_voice_stop = True
|
client_have_voice = (
|
||||||
|
conn.client_voice_window.count(True) >= self.frame_window_threshold
|
||||||
|
)
|
||||||
|
|
||||||
|
# 如果之前有声音,但本次没有声音,且与上次有声音的时间差已经超过了静默阈值,则认为已经说完一句话
|
||||||
|
if conn.client_have_voice and not client_have_voice:
|
||||||
|
stop_duration = time.time() * 1000 - conn.last_activity_time
|
||||||
|
if stop_duration >= self.silence_threshold_ms:
|
||||||
|
conn.client_voice_stop = True
|
||||||
if client_have_voice:
|
if client_have_voice:
|
||||||
conn.client_have_voice = True
|
conn.client_have_voice = True
|
||||||
conn.last_activity_time = time.time() * 1000
|
conn.last_activity_time = time.time() * 1000
|
||||||
|
|||||||
Reference in New Issue
Block a user