mirror of
https://github.com/devgianlu/go-librespot.git
synced 2026-04-26 05:15:49 +03:00
[GH-ISSUE #176] Changing the volume is slow when using external volume control #114
Labels
No labels
bug
enhancement
pull-request
spotify-side
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/go-librespot#114
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @blamphos on GitHub (Mar 14, 2025).
Original GitHub issue: https://github.com/devgianlu/go-librespot/issues/176
I think this "feature" was introduced in commit
eab244b. My suggestion is that timers etc. delays should be always bypassed for volume update event originating from Spotify client when using the external volume control (it can be easily controlled on the other end). Now the volume update from the Spotify client is non-responsive and the user experience is reduced compared to previous functionality before these fixes to relative volume changes.@aykevl commented on GitHub (Mar 17, 2025):
I don't understand what you're reporting exactly.
This should work the same with external volume control, but I haven't tested it since I don't use external volume control.
@blamphos commented on GitHub (Apr 14, 2025):
As background, I have two Raspberry Pi 3B+ based Volumio setups. The second setup is intentionally not updated to the latest Spotify plugin version. On both setups, I'm using a custom plugin that acts as a system controller to override ALSA volume control. This redirects volume change commands to an external system, which is a combination of a Genelec GLM adapter and a SAM speaker network that I can control directly via USB.
This setup allows me to control the system volume in a unique way directly from the Spotify application. The goal is to avoid any digital attenuation of audio samples before they reach the active speakers’ DSP stage. This ensures that room correction can be processed using the full dynamic range, and the final volume level is adjusted only at the very last stage — just before the DAC and power amplifier. That’s why I originally contacted @devgianlu to request support for external volume control in go-librespot (#10).
This setup worked perfectly for my use case until I updated setup 1 to Spotify plugin version 4.1.2 (librespot-go 0.1.3), where I encountered an issue with delayed volume control. Unfortunately, updating further to version 4.1.4 (librespot-go 0.2.0) did not resolve the issue.
Setup 2 was using Spotify plugin version 4.1.0 (librespot-go 0.0.17), and volume changes triggered from the Spotify mobile app (or from Volumio) were applied instantly. However, after updating this setup to version 4.1.4, it also started experiencing the same delayed volume changes as setup 1.
I believe it should still work as it did before, but there have been so many changes in the source code related to volume control that I haven’t been able to track all of them — especially since I'm not familiar with Go. My conclusion is that the behavior of external volume control has changed since version 4.1.0, and the delay in applying volume changes is quite frustrating and reminds me similar delay like in #10 when processing audio samples with the large output buffer (which should not happen in this case).
As you can see in the log below there is slightly over 1 second delay seen in go-librespot debug messages:
Here is setup 2 downgraded from Spotify 4.1.4 to 4.1.1 (go-librespot 0.2.0 --> 0.0.17.1 respectively) and the delay is only ~150 ms between first two debug messages:
@blamphos commented on GitHub (May 8, 2025):
I took the liberty of investigating this issue myself, assuming you likely have more pressing tasks. With the following fixes, my system began functioning correctly with the latest versions when using external volume control.
These fixes will also improve the behavior between go-librespot and the Volumio Spotify plugin. During my investigation, I discovered that the plugin includes a 1.5-second debounce timer and additional logic to determine whether a volume change is significant enough to apply. This is a classic case of treating the symptoms rather than the root cause—which, in this case, was improper rounding when converting floating-point volume values to integers (regression?).
@devgianlu: In my opinion, the debounce timer in the Spotify plugin is now redundant, and the logic for detecting significant changes is also unnecessary if you found out that these corrections are good.
@MarcoTinn commented on GitHub (Jul 24, 2025):
Hi @blamphos
I'm getting exactly this issue, and had also spotted the debug output being delayed about 1 second (which is how I then found this update from you).
I've edited the code as you have above, and recompiled go-librespot, but It's not having any effect.
Could you give me some guidance on what you did, and if there's anything other than the above?
Thanks
Marco
@blamphos commented on GitHub (Jul 25, 2025):
Hi Marco,
There was some other changes as well in deed. Please check all changes from my fork:
github.com/blamphos/go-librespot@079b88f72bI also edited index.js on Volumio Spotify plugin:
As I understand it, in the original scenario, a volume change event originating from the Spotify app combined with rounding errors in go-librespot—when converting a decimal value to an integer—caused non-linear behavior in volume adjustment when stepping the level up or down. For example, instead of a linear progression like 19, 20, 21, 22, 23, the rounding bug could result in a sequence like 19, 20, 20, 21, 22, 23.
The additional sluggishness (poor response) in volume changes was due to a 1-second debounce timeout used in go-librespot, and an attempted fix for the rounding issue between go-librespot and the Volumio Spotify plugin. This fix involved a deltaVolumeThreshold variable (defaulted to 2 steps) combined with a 1.5-second debounce timeout. As a result, a single step change could cause up to ~2.5 seconds of delay. After my fixes, the response time when changing the volume—using an external volume control—is now around ~1 second.
You're most likely referring to the fix where I prevent the volume update event coming from Spotify from writing the same value back to itself by using extra boolean in update function. This allows the debounce timeout to be safely reduced from 1 second to, for example, 150 ms
@MarcoTinn commented on GitHub (Jul 25, 2025):
@blamphos, thanks for that. I'm not that experienced, so will slowly look through it and work out what you've done.
In the meantime, I managed to work out that commenting out these two lines in player.go worked. It removes the 1 second timer/buffer. I suspect that's not ideal, but so far so good, and maybe I'll recompile a new version based on your changes if I hit any issues with my crude fix.
Don't know how to show you GitHub-style my changes, but the two lines I commented out are lines 615 and 616 in cmd.daemon/player.go:
// volumeTimer.Reset(time.Second)
// case <-volumeTimer.C:
Thanks again for taking the time to reply.
Marco.
@blamphos commented on GitHub (Jul 25, 2025):
I recommend adopting my changes. As I already mentioned in my very first message, the change introduced in
github.com/devgianlu/go-librespot@eab244b12dechoes the volume value originated from Spotify back to Spotify itself, and rapid consecutive updates will cause the error 'HTTP error 429: Too many requests for user', which is why the 1-second timeout was added.I understand the intention was to handle volume updates uniformly regardless of where the change originates. However, with a relatively simple fix, I was able to address this: when a volume change originates from Spotify, I set a boolean flag in the handler function to indicate it (true), and the value is not echoed back. If the update comes from Volumio (or elsewhere), it is sent to Spotify—but with a much shorter timeout.
@devgianlu commented on GitHub (Jul 26, 2025):
Thank you to everybody for your contribution to solving this issue. I have revised the approach for volume handling and it feels more responsive now.
Can you give it a try and let me know if you experience the same?
@blamphos commented on GitHub (Jul 27, 2025):
Hi @devgianlu, I can confirm that with these changes, the response is better, but the non-linearity in volume stepping caused by rounding errors results in a sequence where some steps are effectively "skipped." This is noticeable, for example, when using Spotify mobile app and volume buttons —sometimes a single press changes the volume, while at other times two presses are needed. As a result, not all volume levels can be set. However, the logs clearly show that Spotify sends a message for every volume step at regular intervals. I kindly suggest revisiting the corrections related to rounding errors that I mentioned my earlier post.
@devgianlu commented on GitHub (Jul 27, 2025):
That should be fixed as well now.
@blamphos commented on GitHub (Jul 27, 2025):
Thank you @devgianlu - the volume works now as expected: responsively and regular interval (1 step).