support applications having a volume slider in-sync with the system's provided app audio slider#15731
support applications having a volume slider in-sync with the system's provided app audio slider#15731eean wants to merge 3 commits into
Conversation
this allows system per-app volume sliders to work as expected
…o physical device ids
|
I dunno, I don't think I want this API. It's not clear to me what lower-level APIs will allow for this access in the first place, but even in the PipeWire case, there's two separate volume controls: one for the app (and maybe for each stream in the app?), and the master gain slider (and maybe others, if they decide there should be a global master gain vs device vs app. |
|
It's just unnecessarily confusing if the in-app volume slider, controlling the SDL gain, does not affect the application volume slider. PipeWire is keeping and saving the latter between sessions even. So your in-app volume slider could be at 100% while the app is 50% quieter than other applications, that's the main disconnect. With the actual system device volume it's not confusing since it affects all applications at once. (And luckily there isn't both a master and a device volume, just device volumes.) |
Description
The PR is three commits -
SDL_SetAudioDeviceGainsupporting physical devices, a new system audio gain changed event, and a newSDL_GetPhysicalAudioDevice method- that together allow a SDL application to have a volume slider stay in sync with the system audio slider.This enables an application volume slider to work in the expected way:
Screencast_20260531_131712.webm
This PR has the PipeWire backend implementation. I have a PulseAudio implementation that works, but needs to be cleaned up and tested more. I've tested that it has no regressions for PulseAudio and ALSA backends.
All three commits are needed to support the volume slider, but they each are doing a different part, probably easiest to review this PR by each commit.
37515a9 adds the
SetDeviceGainandGetDeviceGainmethods for the backends to implement. A complication here is that in the PipeWire backend the sample_frames and buffer_size manipulation was moved from stream_add_buffer_callback toPIPEWIRE_GetDeviceBuf. This is to avoid having a PipeWire callback locking device->lock, this would've caused a ABBA deadlock with thepw_thread_loop_lockinPIPEWIRE_SetDeviceGain/PIPEWIRE_GetDeviceGain.a5a0667 adds the
SDL_EVENT_AUDIO_DEVICE_GAIN_CHANGEDevent.SDL_AudioDeviceGainChanged_OnMainThreadis modeled after, and is a lot of copy & paste fromSDL_AudioDeviceDisconnected_OnMainThread. A little functional decomposition could fix this, I could do that here or in a separate refactor-only PR.6cba251 is strictly speaking optional for the above screencast, but it would require some hacks to get there otherwise. Previously the API mostly just expected the logical device IDs, so there was no reason for a
SDL_GetPhysicalAudioDevicethat looks up the physical device id for a logical device. But now there's a reason to use physical device id forSDL_SetAudioDeviceGainandSDL_GetAudioDeviceGain.