Perf: reduce sink usage to improve idle CPU usage
This PR tries to address the high idle cpu usage discussed in #1500.
By closing the sink when not in use and opening it when streaming, the idle CPU usage should decrease.
Additionally this should also resolve a bug where disconnection a device on windows results in loosing the output sink and having to restart librespot as result. Tho I didn't verify that yet.
Sadly that issue isn't resolved by that, so might be rather related to the mixer instead of the sink
Good point. But usually you only encounter a stop when you reach the end of a context, which usually doesn't happen as often. I would think that you want to reduce the idle usage even when you pause.
A delay after which we close the sink might be the desired behavior So that it isn't closed immediatly but will be closed even if paused. We could make that configurable, so that you can set it to zero or never, however you would want it to behave.
I think a default of maybe 10-30 sec might be a good delay?
I have to admit that I'm not a big fan.
When I read #1500 then this CPU usage is on PipeWire, but not on plain bare metal ALSA? Further, the hw-top suggests 0.02% CPU load for alsa_output.platform-es8388-sound.stereo-fallback and 0.00% average, 0.01% peak for + ALSA plug-in [librespot], which is kinda negligible.
From the traces it seems that not librespot but PipeWire-Pulse is the culprit with high-frequency epoll_ctl, epoll_pwait, and sendto loops. I wouldn't want to work around an upstream issue in a way that impairs the bare-metal ALSA experience, which I do believe represents the majority of users and downstream audio distros.
How about:
- setting
pulse.idle.timeout = 0in the PipeWire-Pulse configuration? - if that doesn't work, enable the behavior only on "broken" backends?
Hmm, I have mixed feelings on the topic. On the one hand I can understand from where you are coming from. On the other hand, it looks like we do behave differently then other players (referring to spotify desktop or firefox). Where those seem to timeout the sink after the playback is pause and then construct/create a new sink when playing again, where we keep the sink all the time open.
For now we could close the PR as I'm not so fond of the current implementation myself. But a solution that would close the sink or bring it an idle state would be probably the way to go. Maybe on the Sink trait level and as optional implementation?