[本地语音降噪]:完成本地语音链路和噪音过滤,包含降噪模型、本地ASR和实时字幕稳定策略

This commit is contained in:
mkbk
2026-06-17 22:55:33 +08:00
parent a77a172412
commit 8c75fc5baf
22 changed files with 803 additions and 64 deletions
+13
View File
@@ -3,6 +3,7 @@ from __future__ import annotations
from dataclasses import dataclass, field
from typing import Protocol
from .audio_preprocess import NoopAudioPreprocessor
from .config import AppConfig
from .conversation import ConversationContext
from .events import (
@@ -28,6 +29,7 @@ from .events import (
)
from .models import AudioFrame, AudioSegment, ErrorCode, PipelineState, ProviderError
from .protocols import (
AudioPreprocessor,
AudioTransport,
LlmProvider,
RealtimeSttProvider,
@@ -77,6 +79,7 @@ class TurnController:
transport: AudioTransport,
wakeword: WakeWordProvider,
vad_recorder: VadRecorder,
audio_preprocessor: AudioPreprocessor,
stt: SttProvider,
realtime_stt: RealtimeSttProvider | None,
llm: LlmProvider,
@@ -90,6 +93,7 @@ class TurnController:
self.transport = transport
self.wakeword = wakeword
self.vad_recorder = vad_recorder
self.audio_preprocessor = audio_preprocessor
self.stt = stt
self.realtime_stt = realtime_stt
self.llm = llm
@@ -157,6 +161,7 @@ class TurnController:
def _capture_segment(self, turn_id: int, *, state_message: str) -> AudioSegment | ProviderError:
self.vad_recorder.reset()
self.vad_recorder.provider.reset()
self.audio_preprocessor.reset()
realtime_session = self._start_realtime_transcript()
self._event(CAPTURE_STARTED, PipelineState.RECORDING, state_message, turn_id=turn_id)
while True:
@@ -164,6 +169,10 @@ class TurnController:
if not frames:
continue
for frame in frames:
try:
frame = self.audio_preprocessor.process_frame(frame)
except ProviderError as exc:
return exc
was_started = self.vad_recorder.started
result = self.vad_recorder.feed(frame)
if not was_started and self.vad_recorder.started:
@@ -310,6 +319,7 @@ class VoiceAssistantPipeline:
llm: LlmProvider,
tts: TtsProvider,
context: ConversationContext,
audio_preprocessor: AudioPreprocessor | None = None,
realtime_stt: RealtimeSttProvider | None = None,
ack_tts: TtsProvider | None = None,
reporter: RuntimeReporter | None = None,
@@ -320,6 +330,7 @@ class VoiceAssistantPipeline:
self.transport = transport
self.wakeword = wakeword
self.vad_recorder = vad_recorder
self.audio_preprocessor = audio_preprocessor or NoopAudioPreprocessor()
self.stt = stt
self.realtime_stt = realtime_stt
self.llm = llm
@@ -336,6 +347,7 @@ class VoiceAssistantPipeline:
transport=transport,
wakeword=wakeword,
vad_recorder=vad_recorder,
audio_preprocessor=self.audio_preprocessor,
stt=stt,
realtime_stt=realtime_stt,
llm=llm,
@@ -349,6 +361,7 @@ class VoiceAssistantPipeline:
def load(self) -> None:
self.wakeword.load()
self.vad_recorder.provider.load()
self.audio_preprocessor.load()
self.stt.load()
if self.realtime_stt is not None and self.realtime_stt is not self.stt:
self.realtime_stt.load()