jamulussoftware / jamulussoftware/jamulus
Reused channel slot records the previous occupant's audio
Personne n'a encore pris cette issue.
- Langage dominant
- C
- Ătoiles
- 1.1k
- Forks
- 248
- Merge moyen
- 2 j 3 h
- PR mergées (30 j)
- 9
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](https://github.com/jamulussoftware/jamulus/blob/5146a072ee15425564b0d7845cd7616a24a271b1/src/server.cpp#L894-L897) leaves `CurOpusDecoder` null. In that window nothing writes the channel's decode buffer: [the OPUS decode](https://github.com/jamulussoftware/jamulus/blob/5146a072ee15425564b0d7845cd7616a24a271b1/src/server.cpp#L981-L992) 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](https://github.com/jamulussoftware/jamulus/blob/5146a072ee15425564b0d7845cd7616a24a271b1/src/server.cpp#L754-L758) 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](https://github.com/jamulussoftware/jamulus/blob/5146a072ee15425564b0d7845cd7616a24a271b1/src/server.cpp#L1099), 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:
```cpp
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](https://github.com/jamulussoftware/jamulus/blob/5146a072ee15425564b0d7845cd7616a24a271b1/src/server.cpp#L837) 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.*
Guide de contribution
Ouvrir le guide de contribution
Par oĂč commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez â cela Ă©vite que deux personnes fassent le mĂȘme travail.
- Forkez le dépÎt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez dans src/server.cpp, autour de la branche de sĂ©lection du dĂ©codeur aux lignes indiquĂ©es, puis suivez la maniĂšre dont vecvecsData est transmis Ă lâenregistreur. Reproduisez le transfert de client A/client B avec lâenregistrement activĂ© et vĂ©rifiez que la trame prĂ©cĂ©dant lâidentification du nouveau client est silencieuse, tandis que la tonalitĂ© dâorigine continue dâĂȘtre enregistrĂ©e normalement.
Rédigé par le modÚle d'indexation à partir du texte de l'issue.
Ăvaluation
- Stack technique
- cpp
- Domaine
- audio-video-rtc
- Type d'issue
- Bug
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Activité
- Active
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 82/100