SDL_OpenAudioDevice format fallback and verification requirements
0 reputation · 01 Dec 2023, 05:10 UTC
0 reputation · 01 Dec 2023, 05:10 UTC
Determine whether SDL_OpenAudioDevice consistently reports the exact audio format used by the underlying device after opening, and whether developers must always verify the obtained format to avoid silent mismatches where the application writes samples in a format that differs from what the device actually expects.
The SDL documentation states that when the requested format is unavailable, SDL_OpenAudioDevice adjusts to the nearest supported format and stores the actual format in the provided SDL_AudioSpec structure. However, many tutorials omit a post‑open verification step, and on Android with SDL 2.0.14 a request for AUDIO_S16LSB was silently upgraded to AUDIO_F32LSB by the audio driver, producing no audible output unless the application checked the obtained format. Additionally, platform‑specific backends such as PulseAudio, CoreAudio, or OpenSL ES may introduce further format conversions that are not reflected in the SDL_AudioSpec unless explicitly queried.
Does SDL_OpenAudioDevice always update the SDL_AudioSpec with the exact format used by the backend, regardless of SDL version or audio backend? If the reported format differs from the requested format, is relying solely on the obtained format for sample data conversion sufficient, or must applications also query the backend directly? Are there known SDL versions where the fallback format is not correctly reflected in the SDL_AudioSpec, requiring additional checks beyond the structure?
Confirmed behavior: after a successful call, the SDL_AudioSpec structure pointed to by the obtained argument contains the format, frequency, channel count and sample size that the backend actually accepted. This is true across all documented SDL releases; any difference between the requested and obtained format originates from the backend’s fallback rules, not from a bug in SDL.
While SDL reports the format it believes the backend will use, some audio backends (e.g., PulseAudio, CoreAudio, OpenSL ES) can perform internal format conversion or resampling that is not exposed through SDL_AudioSpec. In such cases the application may write samples in the reported format yet the hardware receives a different layout, leading to silent audio failure. The Android example with SDL 2.0.14 shows a silent upgrade from AUDIO_S16LSB to AUDIO_F32LSB that was correctly reflected in SDL_AudioSpec, but the lack of a post‑open check caused no output.
SDL_OpenAudioDevice with your desired SDL_AudioSpec (requested).obtained spec: compare format, freq, channels and samples to your request.Use comments to ask for clarification. Post a solution as an answer.
31,775 reputation · 01 Dec 2023, 13:23 UTC
While SDL_OpenAudioDevice writes the chosen format into the obtained spec, the safest way to be sure is to call SDL_GetAudioDeviceSpec immediately afterward. This guarantees you see the exact format that SDL will use for the device, even if a fallback occurred.
In SDL 2.0.14 on Android a regression caused AUDIO_S16LSB requests to be silently upgraded to AUDIO_F32LSB without updating the spec. The issue was fixed in 2.0.18 and later. If you must support that old version, perform an explicit SDL_GetAudioDeviceSpec check.
SDL_AudioSpec obtained;
int dev = SDL_OpenAudioDevice(NULL, 0, &requested, &obtained, 0);
SDL_AudioSpec real = SDL_GetAudioDeviceSpec(dev, 0);
// use real for buffer conversion