[SDL3 Mixer] Reading audio properties of background music track

From the wiki[1], it mentions using MIX_SetTrackIOStream when you have a large file to play through. I’m guessing using MIX_Audio fully loads the audio into memory (optionally still encoded though).

If my goal is to play a music track in the background and keep memory usage low then is MIX_SetTrackIOStream the best option?

If so, is there a way to obtain the audio file’s metadata similar to MIX_GetAudioProperties?

Thanks

1: https://wiki.libsdl.org/SDL3_mixer/MIX_SetTrackIOStream

MIX_SetTrackIOStream will read the file from disk (or wherever) as needed. We added this because one of the game consoles has huge problems reading large files in one chunk, but was better able to stream it from disk a little bit every frame. On most computers, disks are fast and don’t generally fail, but if the mixer needs data and the disk disappoints in some way, there’s nothing you can do about it.

MIX_LoadAudio() will read the whole file from disk, long before you need it, and keeps it compressed in RAM (so an MP3 file is still in MP3 format in memory here). In this case, as the track needs it, it’ll decompress just enough audio to feed the hardware when needed. This is often a good compromise, but if you’re playing the same MP3 to five different tracks at the same time, it’s going to be decompressing the same MP3 data five times.

You can get around this by setting the third parameter of MIX_LoadAudio, predecode, to true. Then it will keep the uncompressed audio in memory instead of the MP3 data. This can take an absurd amount of RAM, but any playing track basically just have to memcpy() the data instead of decompress it.

So, to answer the question: there are tradeoffs to all these options, depending on your needs. If keeping RAM usage low is the most important thing, and you trust your disks to be fast and reliable, then you can totally use MIX_SetTrackIOStream. If you have more RAM, MIX_LoadAudio() is probably better, and if you have short sounds that are played a lot, MIX_LoadAudio() with predecoding enabled is often a good idea.

Depending on the game, a mix of these techniques can make sense (the background music gets pulled in from SetTrackIOStream, the boss fight intro sound gets MIX_LoadAudio’d, the laser shot sound that gets played a million times gets predecoded).

2 Likes

Not with MIX_SetTrackIOStream, but you could, at some earlier time, call MIX_CreateAudioDecoder, then pull the metadata out with MIX_GetAudioDecoderProperties, and then just throw the thing away with MIX_DestroyAudioDecoder without actually decoding any of it.

Thank you for the detailed response! MIX_GetAudioDecoderProperties worked like a charm and your breakdown of the techniques (when to use what) really helped to clear up my mental picture.

1 Like