Reused channel slot records the previous occupant's audio
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 82/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- cpp
- Domain
- audio-video-rtc
Research direction
Start in src/server.cpp around the decoder-selection branch at the referenced lines, then trace how vecvecsData is passed to the recorder. Reproduce the client A/client B handover with recording enabled and verify the new client's pre-identification frame is silent while the original tone still records normally.
Written by the indexing model from the issue text.
Description
🤖 AI: A channel slot reused by a new client can have the previous occupant's audio attributed to it. On an -R server the stale frame lands in the new client's own recording, at full amplitude.
Root cause. Between disconnect and the new occupant negotiating transport properties a channel sits at CT_NONE, so decoder selection leaves CurOpusDecoder null. In that window nothing writes the channel's decode buffer: the OPUS decode is skipped for want of a decoder, and bIsRawAudio is false because iCeltNumCodedBytes has been reset to CELT_MINIMUM_NUM_BYTES. vecvecsData is indexed by position in the active-channel list rather than by channel ID, so it still holds the previous occupant's decoded audio — which is then passed to the recorder and read by the mix.
Reproduced 3 of 3 on 5146a072. Client A sends a 440 Hz tone and disconnects; after a gap client B takes the freed slot and sends only silence. B's own pre-identification recording is exactly 128 samples of A's tone — one OPUS frame, DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES — at 440 Hz energy fraction 0.999 or above. A's own stub is silent in the same runs, so this is not a recorder artifact. Reconnect gaps of 100, 250 and 500 ms all reproduce it.
Scope: recordings. vecvecsData also feeds the mix, so the same stale samples are a candidate for the live path — but they do not survive there audibly. On a server run without -R, what a passive listener receives is statistically unchanged by the fix below: the residual artifact at slot handover measures about 59 dB under the source (peak sample 29 of 32767) both with it and without.
Fix — contribute silence in the no-decoder branch:
else
{
CurOpusDecoder = nullptr;
// CT_NONE: nothing else writes this buffer, and it is indexed by position in
// the active-channel list, so it still holds the previous occupant's audio
memset ( &vecvecsData[iChanCnt][0], 0, vecvecsData[iChanCnt].Size() * sizeof ( int16_t ) );
}
With that applied, B's stub reads 0.0 in 3 of 3 runs and A's own tone still records normally.
One subtlety: zero the whole worst-case buffer rather than iClientFrameSizeSamples worth. That variable is still zero in this branch, since it is only set in the CT_OPUS and CT_OPUS64 arms, so a memset scaled by it writes no bytes at all.
🤖 This message was written by AI and reviewed by @mcfnord.
- Dominant language
- C
- Stars
- 1.1k
- Forks
- 248
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 7
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from jamulussoftware/jamulus
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
jamulussoftware/jamulus#3953 · 2 comments ·
-
AI
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
jamulussoftware/jamulus#3846 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 76/100
jamulussoftware/jamulus#3958 ·
-
refactoring
jamulussoftware/jamulus#3955 · 1 comment · 1 assignee ·
-
Difficulty 4/5 3-5 days Newbie friendliness 68/100
jamulussoftware/jamulus#3951 · 1 reaction ·
All issues in jamulussoftware/jamulus
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
level/task module/gcp type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
Difficulty 1/5 Under an hour Newbie friendliness 86/100
hapostgres/pg_auto_failover#1190 ·
-
docs
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
P3 sonic-vpp
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
sonic-net/sonic-buildimage#29662 ·