Fix G.722 ADPCM state reset causing robotic/truncated echo audio#43
Fix G.722 ADPCM state reset causing robotic/truncated echo audio#43
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #43 +/- ##
==========================================
+ Coverage 94.13% 94.25% +0.11%
==========================================
Files 24 24
Lines 1723 1759 +36
==========================================
+ Hits 1622 1658 +36
Misses 101 101 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Co-authored-by: codingjoe <[email protected]>
Co-authored-by: codingjoe <[email protected]>
There was a problem hiding this comment.
Pull request overview
Adds per-call, stateful G.722 decoding to preserve ADPCM predictor state across RTP packets, fixing truncated/robotic audio in echo/VAD flows.
Changes:
- Introduce
PayloadDecoder+RTPCodec.create_decoder()and aPerPacketDecoderdefault to support per-call decoder instances. - Add
G722Decoderdataclass holding a persistent PyAV codec context, and overrideG722.create_decoder()to return it. - Update
AudioCallto instantiate and use a per-callpayload_decoder; extend tests and docs accordingly.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
voip/codecs/g722.py |
Adds G722Decoder and G722.create_decoder() for stateful per-call decode. |
voip/codecs/base.py |
Adds decoder protocol + default per-packet decoder factory infrastructure. |
voip/audio.py |
Switches payload decoding to a per-call decoder instance (payload_decoder). |
tests/test_audio.py |
Updates/extends AudioCall.decode_payload tests for decoder routing. |
tests/codecs/test_g722.py |
Adds tests validating stateful decoding and documenting the original bug. |
tests/codecs/test_base.py |
Adds tests for RTPCodec.create_decoder() / PerPacketDecoder. |
docs/codecs.md |
Documents new decoder types in API docs. |
You can also share your feedback on Copilot code review. Take the survey.
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
|
@copilot this worked for the echo call, but the agent suffers from the same strange sound. Open a new PR against main and check if the TTS output is correctly send via G.722 |
G722.decodecreated a newav.open()context per RTP packet, resetting the ADPCM predictor to zero every 20 ms. Since the remote encoder accumulates predictor state across packets, only packet 0 decoded correctly — packets 1+ decoded to near-silence. The VAD discarded these silent frames, so the speech buffer collected ≈20 ms of audio regardless of utterance length, producing a truncated, robotic echo.Changes
voip/codecs/g722.py—G722Decoder: stateful decoder dataclass that holds a single persistentav.CodecContext(sample_rate=16000)for the call lifetime; each packet is fed into the same context, preserving predictor state across boundaries.voip/codecs/g722.py—G722.create_decoder: factory classmethod returning aG722Decoderfor per-call use.voip/codecs/base.py— decoder infrastructure:PayloadDecoderProtocol — common interface (decode(bytes) → np.ndarray)PerPacketDecoder— stateless wrapper for PCMA/PCMU/Opus; delegates toRTPCodec.decodeper packet (preserves existing behavior)RTPCodec.create_decoder()— default factory, returnsPerPacketDecoder; overridden byG722voip/audio.py—AudioCall:__post_init__now callscodec.create_decoder()and stores the result aspayload_decoder;decode_payloaddelegates toself.payload_decoder.decode(payload).Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
releases.astral.sh/home/REDACTED/.local/bin/uv /home/REDACTED/.local/bin/uv run --extra=audio --extra=hd-audio pytest tests/codecs/test_g722.py tests/test_audio.py -x -q(dns block)stun.cloudflare.com/home/REDACTED/work/VoIP/VoIP/.venv/bin/pytest pytest -q(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.