Skip to content

Drop mic-track echoes of system audio at transcript merge - #25

Open
jpsrobertson wants to merge 1 commit into
digimata:masterfrom
jpsrobertson:echo-filter
Open

Drop mic-track echoes of system audio at transcript merge#25
jpsrobertson wants to merge 1 commit into
digimata:masterfrom
jpsrobertson:echo-filter

Conversation

@jpsrobertson

Copy link
Copy Markdown

Problem

Recording a meeting played through the speakers with the default raw mic (mic_voice_processing off), the mic hears the speakers. In my test session the leaked far-end audio reached the mic louder than my own voice (-33.9 vs -37.6 dBFS), so Parakeet transcribes it cleanly and every far-end sentence lands twice — once as "them" from the system tap, again as "me" from the mic:

**[0:21] them:** reports, right?
**[0:21] me:** reports, right?

In a real 42-minute meeting, 477 of 641 "me" segments were echo copies of "them" speech.

Fix

Filter the mic-side copies out at transcript-merge time. A me segment whose words are ≥70% contained, in order (word-level LCS on normalized words), in the them speech it overlaps (±400ms pad for the room-path lag and loose VAD boundaries) is the speakers heard twice, not the user talking over them. One/two-word segments ("um", "yeah") only drop on an exact hit so genuine backchannels survive.

  • New config key transcript_echo_filter, default on — costs nothing when there's no echo; false restores raw merge output.
  • Drops are counted in the session's transcribe.log, so nothing disappears silently.
  • mic_voice_processing still prevents the echo at capture when enabled — this pass is the guard for sessions recorded raw (the default) or where the voice unit fell back.

Also corrects the MicRecorder header comment claiming voice processing is on by default (Config defaults it off) and documents the new key in the README.

Validation

  • Thresholds tuned on the echoed session above: all 477 drops spot-checked as echo (including pairs the two tracks transcribed slightly differently — "data map" vs "data mode"); genuine cross-talk over far-end speech ("No, I I I do get you") all kept.
  • End-to-end: re-transcribing that session through the patched daemon produced 1160 → 683 segments with echo filter dropped 477 mic segment(s) duplicating system audio in transcribe.log.

🤖 Generated with Claude Code

A meeting played through the speakers reaches a raw (non-voice-processed)
mic louder than the speaker's own voice, so every far-end sentence is
transcribed twice: once as "them" from the system tap, again as "me"
from the mic. Filter the mic-side copies out at merge time: a me segment
whose words are >=70% contained, in order, in the them speech it overlaps
(+/-400ms) is echo; 1-2 word segments need an exact hit so genuine
backchannels survive. Configurable via transcript_echo_filter (default
on); drops are counted in transcribe.log.

Validated against a real 42-min echoed session: 477/641 mic segments
dropped, all spot-checked as echo; all genuine cross-talk kept. Also
corrects the MicRecorder header claiming voice processing defaults on
(Config defaults it off) and documents the new key in the README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
FernandoGomes83 added a commit to FernandoGomes83/quill that referenced this pull request Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant