CNA-BUG-052: SongTypeReader and MediaLibraryIndex offer song formats (.opus, .aac, .wma) that no CNA-configured mixer decodes
Evidence basis: source-verified at the pinned commit; inferred from the source (the behaviour was not run); 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.
Load<Song> resolves .opus, .aac and .wma files and the media library indexes .opus, but neither the vendored SDL3_mixer build nor CNA's ALSA mixer decodes them, so such songs load and then silently fail to play.
- Identifier
CNA-BUG-052- Category
- Bug
- Subsystem
- Audio & media
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Inferred (strong): follows from the code, but the behaviour was not run
- Tests touching this area
- Yes: see Current tests
- Affected contract
- ContentManager::Load<Media::Song> (loose-file tier, SongTypeReader::GetExtensions) and MediaLibrary::getSongsProperty (MediaLibraryIndex scan)
Expected behaviour
A loose-file extension list and a library scan should offer only formats the build can play. MediaLibraryIndex.cpp states that rule for itself (“Only formats this project's selected mixer decoder can genuinely PLAY are indexed”) and leaves out .m4a/.aac for exactly that reason. XNA's contract for Load<T> is a usable asset or a ContentLoadException, so a format the build cannot decode should either not be resolved or be refused at load time.
Actual behaviour at TARGET
SongTypeReader::GetExtensions in ContentManager.cpp returns .mp3 .ogg .wav .flac .opus .aac .wma, and SongTypeReader::Read constructs Media::Song(path, stem), which only checks that the file exists. What can actually be decoded:
- SDL3 audio (the default):
ThirdPartySDL.cmakebuilds the vendored SDL3_mixer (pinned at 3075d3ed, version 3.3.0) withSDLMIXER_OPUS=OFFand the mpg123, vorbisfile, tremor, WavPack, libFLAC, GME, libxmp and FluidSynth back ends off, which leaves dr_mp3, stb_vorbis, dr_flac, WAV/AIFF/VOC/AU and Timidity. SDL3_mixer has no AAC or WMA decoder in any configuration. - ALSA audio:
DecodeMixerAudioinCnaMixerDecoders.cppplays WAV, Ogg Vorbis, MP3 and FLAC and refuses Ogg Opus by name.
So a song whose only file is theme.opus, theme.aac or theme.wma loads successfully; MediaPlayer::Play then reaches PlaySong, LoadMixerAudioFile returns nothing, and PlaySong returns without an error (the consequences are described in the entry on MediaPlayer::Play's failure handling). The resolution order puts these three after .mp3, .ogg, .wav and .flac, so a playable sibling of the same name wins.
The media library repeats the mismatch: HasSupportedAudioExtension indexes .opus and names “decoder_opus (.opus)” as part of the bundled decoder set, which the vendored build disables, and the class comment in MediaLibraryIndex.hpp still lists only .ogg/.oga/.mp3/.wav while the scan indexes six extensions. With CNA_USE_SYSTEM_SDL=ON the host's SDL3_mixer is linked instead and may include Opus; .aac and .wma stay undecodable.
Source locations
modules/content/src/Xna/ContentManager.cpp— SongTypeReader::GetExtensions and SongTypeReader::Readcmake/ThirdPartySDL.cmake— cna_configure_vendored_sdl: the SDL3_mixer configure arguments (SDLMIXER_OPUS=OFF and the other decoder switches)modules/audio/src/Backend/CnaMixer/CnaMixerDecoders.cpp— DecodeMixerAudio: WAV, Ogg Vorbis, MP3, FLAC; Ogg Opus refusedmodules/audio/src/Backend/Sdl3Mixer/MixerEngine.cpp— LoadMixerAudioFile / FinalizeAudioLoad return an empty pointer on a decode failuremodules/media/src/Xna/MediaPlayer.cpp— MediaPlayer::PlaySong returns silently when LoadMixerAudioFile failsmodules/media/src/Internal/MediaLibraryIndex.cpp— HasSupportedAudioExtension: indexes .opusmodules/media/include/CNA/Internal/Media/MediaLibraryIndex.hpp— class comment listing four extensionsmodules/audio/tests/Microsoft/Xna/Framework/Audio/CnaMixerXnaTests.cpp— WavOggMp3AndFlacFilesLoadAndOtherFormatsAreRefusedByNamemodules/media/tests/Microsoft/Xna/Framework/Media/MediaLibraryTests.cpp— LibraryIndexesFlacAndOpusFilesWithTheirRealTags
Evidence
Checked by reading at 009d40f5; not executed. The decoder set of the pinned SDL_mixer commit (3075d3ed) was read with git from a clone that contains that commit (its src/ decoder files and CMakeLists.txt options), because third_party/ is a submodule. ThirdPartySDL.cmake changed after an earlier review (a build manifest and an SDL patch series), but the SDL3_mixer decoder switches are identical. The ALSA refusal of Opus is pinned by a test; the SDL3 refusal follows from the configure switch and was not run. Not checked: what a host SDL3_mixer decodes under CNA_USE_SYSTEM_SDL=ON.
Focused reproduction
Illustrative; not compiled or run.
// Content/theme.opus is the only file named "theme"; default SDL3 audio with the vendored SDL3_mixer
Media::Song song = content.Load<Media::Song>("theme"); // succeeds
Media::MediaPlayer::Play(&song); // no sound and no exception
// MediaPlayer::getStateProperty() is still Stopped
Current tests
CnaMixerXnaTests.cpp pins the ALSA mixer's Opus refusal for a SoundEffect. MediaLibraryTests.cpp pins that an .opus file is indexed with its tags, not that it plays. ContentManagerSongXnbTests.cpp covers the .xnb tier. No test loads an .opus, .aac or .wma file through Load<Song> and plays it.
Regression test
A content test with a directory holding only theme.aac that requires Load<Song>("theme") to throw ContentLoadException (or not to resolve it, if the list is trimmed); and a media test that the library index lists .opus only when the build has an Opus decoder, driven by a compile definition set from the same switch in ThirdPartySDL.cmake.
Blast radius
Loose-file songs in .opus, .aac or .wma with no playable sibling of the same name, and media libraries containing .opus files, on the SDL3 and ALSA audio selections. Compiled .xnb and .cnb songs, the four decodable formats, and SoundEffect loading are not affected.
Workaround
Ship music as .ogg, .mp3, .flac or .wav.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Known issues
- Bug index