fix: 优化唤醒词音频采集

This commit is contained in:
3030332422
2026-04-22 11:42:22 +08:00
parent db73faeec4
commit 44587985dd
@@ -1,6 +1,4 @@
import logging import logging
import threading
from collections import deque
from typing import Protocol from typing import Protocol
import numpy as np import numpy as np
@@ -16,7 +14,6 @@ class AudioListener(Protocol):
class MicrophoneListener: class MicrophoneListener:
_MAX_QUEUE_SIZE = 10
def __init__(self, config: RuntimeConfig) -> None: def __init__(self, config: RuntimeConfig) -> None:
self.config = config self.config = config
@@ -26,11 +23,8 @@ class MicrophoneListener:
self._sample_rate = self.config.audio.sample_rate self._sample_rate = self.config.audio.sample_rate
self._channels = self.config.audio.channels self._channels = self.config.audio.channels
self._device = self.config.audio.input_device self._device = self.config.audio.input_device
self._block_duration_ms = 100 self._block_duration_ms = 30
self._block_size = int(self._sample_rate * (self._block_duration_ms / 1000)) self._block_size = int(self._sample_rate * (self._block_duration_ms / 1000))
self._audio_queue: deque = deque(maxlen=self._MAX_QUEUE_SIZE)
self._queue_event = threading.Event()
self._consumer_thread = None
def add_audio_listener(self, listener: AudioListener) -> None: def add_audio_listener(self, listener: AudioListener) -> None:
if listener not in self._listeners: if listener not in self._listeners:
@@ -48,13 +42,6 @@ class MicrophoneListener:
"Missing dependency: sounddevice. Install runtime dependencies before starting microphone listener." "Missing dependency: sounddevice. Install runtime dependencies before starting microphone listener."
) from exc ) from exc
self._running = True
self._audio_queue.clear()
self._consumer_thread = threading.Thread(
target=self._consume_loop, daemon=True, name="mic-consumer"
)
self._consumer_thread.start()
self._stream = sd.InputStream( self._stream = sd.InputStream(
device=self._device, device=self._device,
samplerate=self._sample_rate, samplerate=self._sample_rate,
@@ -65,6 +52,7 @@ class MicrophoneListener:
latency="low", latency="low",
) )
self._stream.start() self._stream.start()
self._running = True
logger.info("microphone listener started") logger.info("microphone listener started")
logger.info("microphone sample rate: %s", self._sample_rate) logger.info("microphone sample rate: %s", self._sample_rate)
@@ -77,10 +65,6 @@ class MicrophoneListener:
return return
self._running = False self._running = False
self._queue_event.set()
if self._consumer_thread is not None:
self._consumer_thread.join(timeout=2)
self._consumer_thread = None
if self._stream is not None: if self._stream is not None:
try: try:
self._stream.stop() self._stream.stop()
@@ -91,7 +75,7 @@ class MicrophoneListener:
def _input_callback(self, indata, frames, time_info, status) -> None: def _input_callback(self, indata, frames, time_info, status) -> None:
_ = frames, time_info _ = frames, time_info
if status: if status and "overflow" not in str(status).lower():
logger.warning("microphone status: %s", status) logger.warning("microphone status: %s", status)
audio = np.copy(indata) audio = np.copy(indata)
@@ -100,17 +84,8 @@ class MicrophoneListener:
else: else:
audio = audio.reshape(-1) audio = audio.reshape(-1)
self._audio_queue.append(audio) for listener in list(self._listeners):
self._queue_event.set() try:
listener.on_audio_data(audio)
def _consume_loop(self) -> None: except Exception:
while self._running: logger.exception("audio listener callback failed")
self._queue_event.wait(timeout=0.5)
self._queue_event.clear()
while self._audio_queue:
audio = self._audio_queue.popleft()
for listener in list(self._listeners):
try:
listener.on_audio_data(audio)
except Exception:
logger.exception("audio listener callback failed")