Skip to content

voxtype: decouple mic capture from decoding (blocking read drops audio during decodes) #169

Description

@pchalasani

Problem

ParakeetEngine._capture_session reads the microphone with PortAudio's blocking API on the same thread that decodes. Any decode therefore pauses capture:

  • MLX engine: take decodes run inline (_enqueue_take -> _deliver_take) because MLX streams are thread-local, and the new keepalive_minutes tick decodes there too.
  • PortAudio's input ring buffer at default latency holds well under a second, so a decode longer than that drops samples.
  • _read_samples discards read()'s overflow flag, so the loss is silent.

Consequence: speech arriving during a decode can be clipped rather than merely delayed. Raised by Codex review on #168 against the keepalive, but it is pre-existing — an ordinary take decode has the same exposure (toggle off, then immediately toggle on and speak).

Fix

Decouple capture from decoding: drive the mic with a sounddevice callback that pushes chunks into a bounded queue, and have the processing loop consume that queue. Capture then continues during any decode, and the queue makes overflow explicit and measurable instead of silent.

Points to settle during design:

  • Bounded queue + an explicit drop policy, reported through _report rather than swallowed.
  • Surface PortAudio's overflow flag (status in the callback) as a warning.
  • Keep the ordering guarantees the command queue relies on (hold_stop delivering before a following hold_start).
  • Both engines and all three modes (toggle/wake/vad) share this loop; hold-mode buffering and the VAD path must behave identically after the change.

Not in scope for #168

#168 documents this as a known limitation (docstring, config sample, docs page, release note) and narrows the keepalive's window with guards. The architectural fix belongs here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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