ALSA Mixer doesn't reflect changed volume from ALSA in librespot
Look for similar bugs
I have checked existing issues and found no similar reports about ALSA mixer volume synchronization problems.
Description
ALSA Mixer volume changes made through alsamixer or etc are not being reflected in librespot playback volume. When adjusting the volume using alsamixer, librespot maintains its previously set volume level instead of respecting the system's ALSA mixer volume settings.
Version
- librespot v0.6.0
How to reproduce
- Launch librespot with ALSA audio backend and ALSA audio mixer:
librespot --mixer alsa - Connect and start playing audio through Spotify
- Open terminal and run
alsamixer - Change volume level in alsamixer for the output device being used by librespot
- Observe that librespot playback volume remains unchanged and does not reflect the new alsamixer volume level
Log
Host
- OS: Linux
- Platform: armhf
Additional context
I am not a Rust developer but after a quick look into mixer code, it seems there is no API to notify librespot when mixer value changes apart from polling via fn volume(&self) -> u16. It would be great to extend the Mixer trait and then use ALSA's snd_ctl_subscribe_events to subscribe to events - when a volume event is received, we could notify librespot about the change.
Do you mean volume in the Spotify UI? Or really that the volume level remains the same?
For the former, as far as I know there is no way to report volume to Spotify.
For the latter, are you sure that the same hardware mixer control is:
a) being used by librespot
b) being controlled through alsamixer?
Other way around; when you control ALSA volume through Spotify and have alsamixer open, do you see the volume in alsamixer going up and down? If not, it is a configuration issue and you are not using the same hardware volume control.
Yes, I'm referring to the volume display in the Spotify UI. The issue is one-directional:
- When adjusting volume through
Spotify UI-> The volume changes are reflected inalsamixer - When adjusting volume through
alsamixer-> The volume level remains unchanged inSpotify UI
Regarding the possibility of reporting volume to Spotify - this should be feasible, as hardware speakers with physical volume controls are able to report their volume changes back to the Spotify UI. This suggests there is a mechanism for external volume changes to be communicated back to Spotify's interface.
This issue becomes particularly problematic when running multiple audio applications that use the same ALSA mixer - when any of these apps change the volume through the mixer (aslamixer volume changed), the Spotify UI remains stuck showing its previous volume value, leading to inconsistent volume indication.
Regarding the possibility of reporting volume to Spotify - this should be feasible, as hardware speakers with physical volume controls are able to report their volume changes back to the
Spotify UI. This suggests there is a mechanism for external volume changes to be communicated back to Spotify's interface.
That's interesting. @photovoltex you know if the dealer offers that option?
After some research, I found potentially relevant Spotify documentation that might help implement volume reporting:
- The
SPPlaybackUpdateVolumefunction seems to be designed for exactly this purpose: reporting volume changes back to Spotify - Documentation page about hardware button implementation suggests this is a supported use case
I'm not sure if these commercial hardware APIs are directly applicable to librespot's implementation, but they indicate that Spotify's protocol does support receiving external volume updates. This could provide guidance on how to implement similar functionality in librespot.
I also found this notify_volume_changed in code base
Spot on. The dealer has the option to send the volume update to the server. The whole logic can be found in the main loop of the spirc (https://github.com/librespot-org/librespot/blob/dev/connect/src/spirc.rs#L430). The issue is that we currently don't react on volume changes from the mixer/player in the spirc. I don't think we did that with mercury before as far as I'm aware of.
So if we implement that communication, it could be easily communicated to the server :)
Cool. Sketching that out, there'd be two parts to this:
- Changing the communication between the
player/mixerandspircfrom function-calling to message-sending over the already existing command channels. - Subscribing to ALSA events probably in a separate thread.
Any takers for a PR please mention so here.