[真实链路自测]:完成完整流程自测和ACK缓冲修正,包含真实Provider验收、播放回声清理和回归测试
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user