Problem
run_loop's chime_for_turn (pipeline.py) pauses the mic before playing the
wake cue, half-duplex:
mic.pause() # audio.Microphone.pause() -> stream.stop(): capture halts
flushed = False
try:
audio.play_wav(cue_wav, output_name)
except Exception:
print(...) # failure: skip the flush
else:
mic.flush()
flushed = True
mic.resume()
return flushed
mic.pause() calls self._stream.stop() (audio.py:198), so the input callback
stops firing and no audio is captured during the pause. If audio.play_wav
blocks (device open, partial playback) and then raises, the mic was stopped for
that whole span. Any command audio the user speaks during the failed-cue window
is never captured. Returning False preserves only the pre-wake detection
pre-roll; the post-wake audio lost during the pause is unrecoverable. So the
failure path can clip or drop the command instead of degrading to the no-chime
behavior, where the mic is never paused and the command is captured.
Severity
Narrow. Requires wake_chime enabled + a slow-then-fail playback + the user
speaking during the failure window. A clipped/lost command lowers STT confidence,
so guard_transcript likely re-prompts rather than dispatching a wrong action --
degraded UX, not a wrong-action path. The default flow (chime off) is unaffected.
Direction
The audio dropped while the stream is stopped cannot be recovered after the fact,
so the fix is about bounding and handling the failure window:
- Keep the failure window minimal: the cue file is pre-rendered once at loop
start, so the in-loop failure is a playback/device error -- detect a fast-fail
path where possible before committing to the pause.
- On failure, degrade explicitly to no-chime semantics for the rest of the turn
(resume without flush, which the code already does) and document that the
window's audio is lost.
- Full-duplex capture during the cue (capturing through the cue and subtracting
its known waveform) is out of scope and device-dependent.
The chime is opt-in and default off, so this is a robustness item for the
experimental path, not a blocker for the default flow.
Related
Problem
run_loop'schime_for_turn(pipeline.py) pauses the mic before playing thewake cue, half-duplex:
mic.pause()callsself._stream.stop()(audio.py:198), so the input callbackstops firing and no audio is captured during the pause. If
audio.play_wavblocks (device open, partial playback) and then raises, the mic was stopped for
that whole span. Any command audio the user speaks during the failed-cue window
is never captured. Returning
Falsepreserves only the pre-wake detectionpre-roll; the post-wake audio lost during the pause is unrecoverable. So the
failure path can clip or drop the command instead of degrading to the no-chime
behavior, where the mic is never paused and the command is captured.
Severity
Narrow. Requires
wake_chimeenabled + a slow-then-fail playback + the userspeaking during the failure window. A clipped/lost command lowers STT confidence,
so
guard_transcriptlikely re-prompts rather than dispatching a wrong action --degraded UX, not a wrong-action path. The default flow (chime off) is unaffected.
Direction
The audio dropped while the stream is stopped cannot be recovered after the fact,
so the fix is about bounding and handling the failure window:
start, so the in-loop failure is a playback/device error -- detect a fast-fail
path where possible before committing to the pause.
(resume without flush, which the code already does) and document that the
window's audio is lost.
its known waveform) is out of scope and device-dependent.
The chime is opt-in and default off, so this is a robustness item for the
experimental path, not a blocker for the default flow.
Related
live_driverpost-cue drain counterpart of the same half-duplexchime tension.