From cd641358dbdd30014094d284174f3b4b23a0829a Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Tue, 5 Jul 2022 23:58:32 +0200 Subject: [PATCH 1/2] Add --listen-timeout-secs --- pulseaudio-control.bash | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pulseaudio-control.bash b/pulseaudio-control.bash index 7ac9193..27c5cc0 100755 --- a/pulseaudio-control.bash +++ b/pulseaudio-control.bash @@ -22,6 +22,7 @@ OSD="no" NODE_NICKNAMES_PROP= VOLUME_STEP=2 VOLUME_MAX=130 +LISTEN_TIMEOUT=0.1 # shellcheck disable=SC2016 FORMAT='$VOL_ICON ${VOL_LEVEL}% $ICON_NODE $NODE_NICKNAME' declare -A NODE_NICKNAMES @@ -348,7 +349,7 @@ function listen() { # Read all stdin to flush unwanted pending events, i.e. if there are # 15 events at the same time (100ms window), output is only called # twice. - read -r -d '' -t 0.1 -n 10000 + read -r -d '' -t "$LISTEN_TIMEOUT" -n 10000 # After the 100ms waiting time, output again the state, as it may # have changed if the user did an action during the 100ms window. @@ -466,6 +467,17 @@ Options: Exact matches are prioritized. Don't forget to quote the string when using globs, to avoid unwanted shell glob extension. Default: none + --listen-timeout-secs + The listen command updates the output as soon as it receives an event + from PulseAudio. However, events are often accompanied by many other + useless ones, which may result in unnecessary consecutive output + updates. This script buffers the following events until a timeout is + reached to avoid this scenario, which lessens the CPU load on events. + However, this may result in noticeable latency when performing many + actions quickly (e.g., updating the volume with the mouse wheel). You + can specify what timeout to use to control the responsiveness, in + seconds. + Default: \"$LISTEN_TIMEOUT\" Actions: help display this message and exit @@ -570,6 +582,10 @@ while [[ "$1" = --* ]]; do NODE_TYPE="$val" SINK_OR_SOURCE=$([ "$NODE_TYPE" == "output" ] && echo "ink" || echo "ource") ;; + --listen-timeout-secs) + if getOptVal "$@"; then shift; fi + LISTEN_TIMEOUT="$val" + ;; # Deprecated options, to be removed in a next release --icon-sink) echo "Replaced by --icon-node, see https://github.com/marioortizmanero/polybar-pulseaudio-control/releases/tag/v3.0.0" >&2 From 9eeb5f816b610940c78694b642a5d8a654c18504 Mon Sep 17 00:00:00 2001 From: Mario Ortiz Manero Date: Wed, 13 Jul 2022 14:14:08 +0200 Subject: [PATCH 2/2] Add a FAQ --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++ pulseaudio-control.bash | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fcc3e1d..7ec4cce 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,55 @@ font-Y = Font Awesome 5 Brands: pixelsize=11 font-Z = Material Icons: style=Regular: pixelsize=13; 2 ``` +## FAQ + +### Can I use this with a status bar other than Polybar? + +The only part of this script that's tied to Polybar is the color formatting. +When muted, the dimmed color will probably not work. Please [let us know in this +issue](https://github.com/marioortizmanero/polybar-pulseaudio-control/issues/36) +if you want support for a new status bar. I'd strongly recommend you to open a +PR yourself, as it should be relatively easy! + +### Does this work with PipeWire? + +Yes! You only need to install the pulseaudio client on your machine. On Arch +Linux, that's +[`pipewire-pulse`](https://archlinux.org/packages/extra/x86_64/pipewire-pulse/), +for example. + +It won't work with other audio servers like JACK, though. + +### This script uses too much CPU + +We use the `pactl subscribe` command to get notified of new events that may +occur in order to refresh the output. However, the command often outputs *a lot* +of events for a simple action, like increasing the volume. Instead of refreshing +for every single line it prints, we: + +1. Wait for one event +2. Update the output first +3. Continue to listen for events until a timeout ends, or until we reach a large + enough number of them +4. Update the output again +5. Go back to step 1 + +This way, the first event will update quickly, and the following ones, which are +most likely unnecessary, will be ignored until some time passes. This reduces +the CPU usage, but it's not really perfect, as everyone percieves latency +differently, and it depends on the use-case. + +The timer can be configured with `--listen-timeout-secs`, which has a default +value of `0.05` (50 ms). If you want less CPU usage, i.e., ignore more duplicate +events, you can bump it to, for example, `0.1` (100 ms). Or for faster refreshes +when performing multiple actions quickly, e.g., updating the volume with your +mousewheel, you can even use a smaller value. + +### This script feels laggy when performing multiple actions quickly + +Please refer to the previous question, as you can fix this by setting a smaller +refresh delay with `--listen-timeout-secs`. + ## Sources Part of the script and of this README's info was taken from [customlinux.blogspot.com](http://customlinux.blogspot.com/2013/02/pavolumesh-control-active-sink-volume.html), the creator. It was later adapted to fit polybar. It is also mixed with [the ArcoLinux version](https://github.com/arcolinux/arcolinux-polybar/blob/master/etc/skel/.config/polybar/scripts/pavolume.sh), which implemented the `listen` action to use less resources. diff --git a/pulseaudio-control.bash b/pulseaudio-control.bash index 27c5cc0..3b68dcc 100755 --- a/pulseaudio-control.bash +++ b/pulseaudio-control.bash @@ -22,7 +22,7 @@ OSD="no" NODE_NICKNAMES_PROP= VOLUME_STEP=2 VOLUME_MAX=130 -LISTEN_TIMEOUT=0.1 +LISTEN_TIMEOUT=0.05 # shellcheck disable=SC2016 FORMAT='$VOL_ICON ${VOL_LEVEL}% $ICON_NODE $NODE_NICKNAME' declare -A NODE_NICKNAMES