[真实链路自测]:完成完整流程自测和ACK缓冲修正,包含真实Provider验收、播放回声清理和回归测试

This commit is contained in:
mkbk
2026-06-17 23:47:21 +08:00
parent b3566c2424
commit b2822dc1af
10 changed files with 121 additions and 7 deletions
+1 -2
View File
@@ -227,7 +227,6 @@ class TurnController:
def _acknowledge_wake(self, turn_id: int) -> ProviderError | None:
text = self.config.wake_ack_text.strip()
if not text:
self._drain_input_after_playback()
return None
try:
self._event(ACK_STARTED, PipelineState.SPEAKING, f"应答中:{text}", turn_id=turn_id)
@@ -278,9 +277,9 @@ class TurnController:
self._drain_input_after_playback()
def _drain_input_after_playback(self) -> None:
self.transport.flush_input()
if self.config.post_playback_drain_ms <= 0:
return
self.transport.flush_input()
remaining_ms = self.config.post_playback_drain_ms
while remaining_ms > 0:
timeout_ms = min(50, remaining_ms)
+1 -2
View File
@@ -240,7 +240,6 @@ class LiveVoiceRuntime:
def _acknowledge_wake(self, turn_id: int) -> ProviderError | None:
text = self.config.wake_ack_text.strip()
if not text:
self._drain_input_after_playback()
return None
try:
self._event(ACK_STARTED, PipelineState.SPEAKING, f"应答中:{text}", turn_id=turn_id)
@@ -254,9 +253,9 @@ class LiveVoiceRuntime:
return exc
def _drain_input_after_playback(self) -> None:
self.transport.flush_input()
if self.config.post_playback_drain_ms <= 0:
return
self.transport.flush_input()
remaining_ms = self.config.post_playback_drain_ms
while remaining_ms > 0:
timeout_ms = min(50, remaining_ms)
+1 -1
View File
@@ -55,7 +55,7 @@ class SimulationReporter:
class BoundedMemoryAudioTransport(MemoryAudioTransport):
def __init__(self, frames: list[AudioFrame], *, max_empty_reads: int = 5) -> None:
super().__init__(frames)
super().__init__(frames, flush_clears_input=False)
self.max_empty_reads = max_empty_reads
self.empty_reads = 0
+6
View File
@@ -58,12 +58,15 @@ class MemoryAudioTransport:
frames: list[AudioFrame] | None = None,
input_available: bool = True,
output_available: bool = True,
flush_clears_input: bool = True,
) -> None:
self._frames: deque[AudioFrame] = deque(frames or [])
self.played_segments: list[AudioSegment] = []
self.flush_count = 0
self.started = False
self._input_available = input_available
self._output_available = output_available
self._flush_clears_input = flush_clears_input
def start_input(
self, device_id: str | None = None, sample_rate: int = 16000, channels: int = 1
@@ -104,6 +107,9 @@ class MemoryAudioTransport:
return PlaybackResult(True, segment.duration_ms)
def flush_input(self) -> int:
self.flush_count += 1
if not self._flush_clears_input:
return 0
count = len(self._frames)
self._frames.clear()
return count