CNA-BUG-148: DynamicSoundEffectInstance::SubmitFloatBufferEXT accepts empty and non-frame-aligned float buffers
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 c1c316b9; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
SubmitBuffer now refuses partial frames as XNA does, but SubmitFloatBufferEXT still queues an empty buffer or a sample count that is not a whole number of channel frames, which SDL3 audio then drops and CNA's ALSA mixer plays shifted.
- Identifier
CNA-BUG-148- Category
- Bug
- Subsystem
- Audio & media
- Status
- Narrowed (partially fixed; describes only what survives)
- Verified against
- CNA
c1c316b9(c1c316b9c7a846ce8002809c151fcd1af14942c9) - 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
- DynamicSoundEffectInstance::SubmitFloatBufferEXT(const std::vector<float>&[, int offset, int count])
Expected behaviour
XNA 4.0's SubmitBuffer(byte[], int, int) (IL) throws ArgumentException for an empty buffer and for a length, offset or count that is not frame-aligned. SubmitFloatBufferEXT is an FNA extension with no XNA contract, but it feeds the same stream, and CNA's own plan requires the same rule for it: open P0 task AUD-07-006 in plan_audio.md ("Partial multichannel frames are rejected").
Actual behaviour at TARGET
SubmitFloatBufferEXT in DynamicSoundEffectInstance.cpp throws only for a disposed instance, a negative or overrunning offset or count, and the int/float mode guard. An empty buffer, a zero count and a sample count that is not a multiple of the channel count are queued. SDL3 audio refuses the resulting partial frame (SDL_PutAudioStreamData); CNA logs "stream submit failed (N bytes dropped)" and the chunk is lost. CNA's ALSA mixer appends it, shifting every later sample.
Fixed since first recorded: SubmitBuffer refuses an empty buffer, a partial frame and an off-frame offset or count with ArgumentException (KF-12, 49119a34c).
Source locations
modules/audio/src/Xna/DynamicSoundEffectInstance.cpp— DynamicSoundEffectInstance::SubmitFloatBufferEXT: range checks only (SubmitBuffer refuses partial frames since KF-12)plans/plan_audio.md— AUD-07-006: float frame-alignment validation, open
Evidence
Checked by reading at c1c316b9 against the XNA 4.0 IL of DynamicSoundEffectInstance.SubmitBuffer; not executed. CNA's own plan records the SDL3 'Can't add partial sample frames' rejection from a real run.
Re-verified at b0e97bb1: KF-12 (49119a34c) made SubmitBuffer follow XNA (SubmitBufferRefusesPartialFrames, SubmitBufferRefusesPartialFramesWhilePlaying); SubmitFloatBufferEXT still checks only the range, and SubmitFloatBufferWithSampleCountNotDivisibleByChannelCountDoesNotThrow (plan P9-DYNAMIC-009, which matched FNA) pins that acceptance on purpose, so a fix must change it; AUD-07-006 is still open. Not executed.
Focused reproduction
// Illustrative; not compiled or run.
DynamicSoundEffectInstance d(44100, AudioChannels::Stereo);
std::vector<float> odd(4097);
d.SubmitFloatBufferEXT(odd); // half a stereo frame at the end: queued, then dropped (SDL3) or shifted (ALSA)
Current tests
SubmitBufferRefusesPartialFrames and SubmitBufferRefusesPartialFramesWhilePlaying pin the fixed integer path. SubmitFloatBufferWithSampleCountNotDivisibleByChannelCountDoesNotThrow pins the float path's acceptance (P9-DYNAMIC-009).
Regression test
Cases for an empty float buffer, an odd float count on stereo and a zero count, each expecting ArgumentException, replacing the acceptance test.
Blast radius
Streaming audio code that submits float samples with an arithmetic slip: the partial frame is dropped (SDL3) or shifts every later sample (ALSA) instead of failing. Byte submissions through SubmitBuffer are unaffected.
Workaround
Submit whole frames only (a multiple of the channel count of floats).
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- Audio: overview
- Known issues
- Bug index