Relation of queued audio and audio buffer size?

I use an audio stream (Audio_Output_Stream) for sound output.

After initialisation my application sends samples to the stream using

SDL_PutAudioStreamData(Audio_Output_Stream, data, len);

For the purpose of syncing my audio source with playback I only send new samples to the stream if queued audio is below a certain threshold. Therefore I check for queued audio size using

SDL_GetAudioStreamQueued(Audio_Output_Stream);

Now to my question:

The SDL audio system uses an output buffer internally. Its size is accessible through SDL_GetAudioDeviceFormat (sample_frames). Do I need to take care of this?

e.g.

My application only sends new samples if the size of the buffer is <= 4096 byte (1024 samples of 4 byte each). Is this safe if sample_frames is for example 2048 samples?

It seems to work on my system but is somehow confusing me. I would expect the queued data to never make it to the larger internal buffer or cause padding to be inserted because it is not able to fill the entire buffer.

(I answered this on GitHub, too, but for everyone’s benefit…)

Generally the best plan is not to worry about the internal buffer size, and I fought for a long time to not present this information to apps at all.

The buffer size represents the number of samples that each push to the hardware will need, but (especially if you need to resample) this gets complicated quickly.

Generally it’s better to think in terms of time: I am feeding the stream X milliseconds of audio in whatever format, and even if it has to resample it, we’ll still be ahead of what the hardware needs by a little.

Failing that, using the stream’s audio callback works a lot like SDL2, and also guarantees you feed the hardware exactly what it needs on demand, without having to worry about buffering ahead of time. This is also a good option.

I am afraid I have to worry about buffer size. To avoid lags or stuttering I need to know if more data is required or syncing is neccessary. This only works if buffer size is known.

The callback is useful if an arbitrary size of data can be provided immediately. For an emulator this is not always the case. I need to signal the guest system that more data is required and wait for it to make it available. To avoid blocking an intermediate buffer is required even in the case of using the callback method and determining its minimum size is the quest in both variants (poll from callback or push to queue).

Obviously with current SDL3 there is no simple way to do this. This is the link to the discussion on GitHub with code examples: https://github.com/libsdl-org/SDL/issues/15764