Are there known issues using a samplesize that is not a power of two? (SDL2)

The documentation for SDL_OpenAudioDevice says:

This number should be a power of two, and may be adjusted by the audio driver to a value more suitable for the hardware.

I have been using a value of 960 (not a power of two). Audio seems to be working fine, but I’ve only been able to test on linux (using some combination of alsa and pulse) and on windows 11. The reason I’m asking when the documentation clearly says not to do it is because the information on SDL_AudioStream suggests that internally, SDL is using an API that shouldn’t care about the size of the queue that I want to work with. I’m wondering if this is something that caused issues in earlier versions of SDL2 but is no longer the case, if there are some less common platforms that will still have issues, or if I might start facing issues once my audio system gets a little bit bigger.


as to why I don’t want to use a power of two, I am using libopus to decompress opus streams. opus streams are split up into frames, whose size is controlled by the encoder (i’m encoding all the streams i want to play, so i can control that size) but is limited to a handful of options, none of which is a power of two. if i can use the same frame size in sdl and opus, then audio playback is greatly simplified. the other option is to use libopus to fill an SDL_AudioStream, then read out of it in my audio callback. But the AudioStream docs lead me to believe that this is what’s happening inside SDL anyway, at least in sufficiently new versions of SDL2.

This restriction has loosened over time, but you take a risk that some platform or another won’t cooperate. In fact, both Windows and Linux are likely not cooperating, but rather buffering on your behalf or just outright overriding your request.

But this is just the size of the buffer going to the hardware at a time; set it to 1024, and fill the audio stream with decoded Opus audio faster than real time, and let it sort out the difference.

The goal is not to match these things exactly, because if you do, you’re going to get skips in the audio output when the system fails to keep up. Better to have at least a small buffer ahead of what you’re playing, and that’s what an SDL_AudioStream is perfect for doing. Heck, if you have the memory to spare, dump the entire decoded audio into the stream upfront. If you don’t have the memory to spare, still keep it filled to way more than 1024 samples at any given time.

you take a risk that some platform or another won’t cooperate. In fact, both Windows and Linux are likely not cooperating, but rather buffering on your behalf

This is the behaviour I’m expecting. The audio is going to a software mixer, not to hardware, so I’m expecting that there is already a small buffer between my SDL audio handler and the actual hardware, whether or not I’m making it work with a buffer that is not a power of two sized.

The goal is not to match these things exactly, because if you do, you’re going to get skips in the audio output when the system fails to keep up.

How much work is it appropriate to do in the audio call back handler? Would you mix multiple SDL_AudioStream in the callback handler, or would you mix-ahead into another SDL_Audiostream?

SDL3_mixer is mixing multiple audiostreams (one for each thing currently playing) in the callback handler, so we know this is a system that works (but as a caution, SDL3’s audio streams are both more flexible and more efficient than SDL2’s, so YMMV).

Generally you just need the audio callback to run faster than the amount of audio the device buffer needs, which is part of why a larger audio buffer makes sense: more time to do fancy audio work, decompress MP3s on-the-fly, whatever.

(Of course, larger device buffer means more latency, but you’d be surprised at what you can get away with.)