Skip to content

run_loop: a slow chime-playback failure loses post-wake audio (mic stopped during the failure window) #58

Description

@jamditis

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions