fix audio chop#176
Draft
raghavm243512 wants to merge 2 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix choppy recorded audio in voice-agent benchmark runs
Problem
Under concurrency, recorded conversation audio (
audio_user.wav/audio_mixed.wav) developed audible "chops" — hard-cut silence gaps in the middle of speech. It worsened with load and was most severe with the ElevenLabs user simulator. The live conversation and STT were unaffected (transcripts are coherent); the corruption was purely in the recording.Root cause
The assistant servers reconstruct each channel's timeline by padding buffers with silence to match wall-clock time, read at frame-processing time (
_pad_buffer_to_walltimeinelevenlabs_server; pipecat 1.x's_fill_buffer_silence_gap;sync_buffer_to_positionin the realtime/gemini servers). EVA's audio streams are already continuous (real audio + paced silence), so any wall-clock gap the recorder sees is event-loop jitter, not real silence. Under concurrency the loop stalls, frames are processed late and bunched, and the recorder inserts silence between frames whose audio is all present → a hard-cut chop.This regressed recently via two changes that introduced wall-clock anchoring into the recording path: the pipecat 0.0.104 → 1.x upgrade (2026-06-01) and PR #154's per-frame
_pad_buffer_to_walltime.Fix (per backend, same principle: never fabricate silence from processing-time jitter)
elevenlabs_server— pad the user track to wall-clock only at the start of a user turn, then append contiguously within the turn (mirrors the assistant pacer, which was already correct and never chopped).openai_realtime_server,gemini_live_server— guard the cross-track sync-pad: skip it when real user audio arrived within 300ms (the speaking-state flag goes stale under jitter). Safe-by-construction — only ever skips a pad, never adds silence.pipecat_server—ContiguousAudioBufferProcessordisables pipecat 1.x's wall-clock silence fill; byte-count track alignment is retained.Diagnostic tooling
scripts/analyze_chops.py— detects chops (hard-cut digital-silence runs), separates LONG (≥150ms, audible) from short (~20ms single-frame, benign/pre-existing), and reports cross-channel overlap. Calibrated against labeled recordings (0 false positives on a clean file). Kept as a regression check; LONG chops is the metric that tracks audible quality.Results
Account conc = ElevenLabs account load = concurrency × sides using ElevenLabs. "In-limit" ≈ ≤ ~30.
Updated takeaways:
sync_buffer_to_positionpattern but was near-clean at baseline. The fix is validated (3 → 0) and consistent with the other backends; worth including so the known-vulnerable pattern isn't left in place.Takeaways: