I’m using SDL in a music player use-case, so more of a normal desktop app rather than a game. But one issue I’d like to resolve, that probably applies to some games, is that setting the gain in SDL does not affect the app-specific volume slider that’s standard on the Linux desktop (and probably elsewhere).
So in practice that means the volume slider in the app and the volume slider on the desktop widget are impossible to sync up. And you could get a confusing situation where the user lowers the app volume with the desktop widget on Monday and is confused on Friday why the app is so quiet when the in-app volume slider is at 100% (especially as PipeWire is helpfully saving this state).
I actually have a working implementation of SDL_SetAudioDeviceGain that actually changes the per-app volume slider for PulseAudio and PipeWire audio backends (~85 LOC for just PipeWire). And a new SDL_EVENT_AUDIO_DEVICE_GAIN_CHANGED event to let the app know about volume changes made via a desktop widget/pavucontrol (~90 LOC).
While cleaning up my commit to prepare a PR I reread the docs:
Physical devices may not have their gain changed, only logical devices, and this function will always return false when used on physical devices. While it might seem attractive to adjust several logical devices at once in this way, it would allow an app or library to interfere with another portion of the program’s otherwise-isolated devices.
When I read this the first time I was like “oh no problem, a PipeWire stream isn’t a physical device”. But while making this patch I learned this physical vs logical distinction is a SDL specific concept so I thought I would discuss the issue here first, since the docs make clear that not supporting this is intentional. But I also think my use-case here is quite valid so something should be figured out.
One possible solution would be for each logical audio device to represent an actual PipeWire stream. So more closely map SDL’s internal concept of audio streams to what PipeWire is actually doing - so with the PipeWire backend, the physical SDL device would represent a literal soundcard, each logical device a PipeWire stream.