CNA-BUG-222: Audio comments describe behaviour the code does not have: SoundEffect::Play's instance limit, FireAndForgetPanState freeing, the is3D_ latch and SoundEffectReader's WAV route
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
SoundEffect.hpp promises that Play returns false at an instance limit CNA does not implement, and three internal comments in the audio and content modules contradict the code next to them.
- Identifier
CNA-BUG-222- Category
- Bug
- Subsystem
- Documentation & release tooling
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- SoundEffect::Play() and SoundEffect::Play(float, float, float) documentation; maintainer comments in SoundEffect.cpp, SoundEffectInstance.hpp and SoundEffectContentTypeReader.hpp
Expected behaviour
Comments and Doxygen describe what the code does. For SoundEffect::Play the XNA meaning of a false return is specific: XNA 4.0's SoundEffect.Play(float, float, float) returns false when it catches InstancePlayLimitException (decompiled reference, Microsoft.Xna.Framework.Audio/SoundEffect.cs).
Actual behaviour at TARGET
SoundEffect.hppdocuments bothPlayoverloads as returning false “if the instance limit was reached”.SoundEffect::Play(float, float, float)inSoundEffect.cppchecks no limit and CNA has none: it returns false for a disposed effect, a missing native audio handle, a track that cannot be created, bound or started, and always in a build withoutSOUND_ENABLED.- In SoundEffect.cpp the comment above
FireAndForgetPanStatesays it is “freed in OnFireAndForgetStopped”, and the comment atSetMixerTrackStoppedCallbacksays the stopped callback frees it.OnFireAndForgetStoppedonly pushes it ontog_pendingPanStateCleanup; the nextPlayor process exit frees it. The deferral is deliberate (an AddressSanitizer heap-use-after-free, P11-PAN-002), so the stale comment invites reintroducing the bug. - The
is3D_member comment inSoundEffectInstance.hppsayssetPanProperty()keeps updatingPan_but stops writing the track, and that the flag is “never reset back to false once set”.setPanPropertyinSoundEffectInstance.cppclearsis3D_before the firstPlayand throwsInvalidOperationExceptionfor a 3D instance after it (CABI-25). SoundEffectContentTypeReader.hppsays 8-bit PCM, float and ADPCM are wrapped in a synthetic WAV and decoded throughSoundEffect::FromStream.SoundEffectReader::ReadinSoundEffectContentTypeReader.cppconverts every format withConvertXnbSoundToImportedSoundandProcessImportedSoundEffectand constructs through the raw 16-bit PCM buffer constructor.
Source locations
modules/audio/include/Microsoft/Xna/Framework/Audio/SoundEffect.hpp— Play() and Play(float, float, float) return documentationmodules/audio/src/Xna/SoundEffect.cpp— SoundEffect::Play; FireAndForgetPanState comment; OnFireAndForgetStoppedmodules/audio/include/Microsoft/Xna/Framework/Audio/SoundEffectInstance.hpp— is3D_ member commentmodules/audio/src/Xna/SoundEffectInstance.cpp— SoundEffectInstance::setPanProperty (CABI-25 gate)modules/content/include/CNA/Internal/Xnb/SoundEffectContentTypeReader.hpp— SoundEffectReader class commentmodules/content/src/Xnb/SoundEffectContentTypeReader.cpp— SoundEffectReader::Read
Evidence
Checked by reading at 009d40f5; nothing executed. The XNA meaning of the return value was read from the decompiled XNA 4.0 SoundEffect. The behaviours the comments misdescribe are pinned elsewhere: SoundEffectInstanceTest.SetPanBeforePlaybackTakesTheInstanceOutOf3D (whose own comment records that it replaces the older latch-for-life reading). The fire-and-forget pan path is exercised by SoundEffectTest.PlayWithHardPanDoesNotCrash, which does not observe when the pan state is freed.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
Comments are not tested. The code paths are covered by SoundEffectTests.cpp and SoundEffectInstanceTests.cpp (SDL3 audio only).
Regression test
No behavioural test applies: correct the four comments, and document the false-return cases SoundEffect::Play really has (or implement an instance limit and keep the XNA wording).
Blast radius
Readers of the public SoundEffect header, who may code against a limit that never triggers, and maintainers of the fire-and-forget, 3D-pan and XNB sound paths.
Workaround
No workaround is known.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.