fix(audio): cap pipewire-alsa client latency on Linux (#862) (#990)

* fix(audio): cap pipewire-alsa client latency on Linux (#862)

On some Linux setups the pipewire-alsa bridge negotiates a multi-second
output buffer, so play/pause/seek/volume only take effect once it drains
(~10-20 s). cpal's buffer-size clamp is ignored by those bridges. Set
PIPEWIRE_LATENCY=256/48000 before the audio stream opens to cap the client
node latency — the reporter confirmed this makes the controls instant.
Linux-only, no-op without PipeWire, and a user-set value is left untouched.

* docs: changelog for pipewire latency fix (#990)
This commit is contained in:
Frank Stellmacher
2026-06-04 21:56:15 +02:00
committed by GitHub
parent ca502ad833
commit ec2bee1400
2 changed files with 26 additions and 0 deletions
+7
View File
@@ -988,6 +988,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* **Show remaining time** no longer reticks the seekbar width every second — fixed-width playbar clocks stop `WaveformSeek` resize/redraw jitter; clocks sit tighter against the waveform with an inline duration toggle icon. * **Show remaining time** no longer reticks the seekbar width every second — fixed-width playbar clocks stop `WaveformSeek` resize/redraw jitter; clocks sit tighter against the waveform with an inline duration toggle icon.
### Linux — instant play/pause/seek/volume on PipeWire
**By [@Psychotoxical](https://github.com/Psychotoxical), reported by PHLAK, PR [#990](https://github.com/Psychotoxical/psysonic/pull/990)**
* On some PipeWire setups, play, pause, seek and volume changes only took effect after a long delay (10+ seconds). Root cause: the PipeWire ALSA bridge negotiated a multi-second audio buffer, so changes were only heard once it drained. Psysonic now caps that buffer, so the controls respond immediately.
## [1.46.0] - 2026-05-18 ## [1.46.0] - 2026-05-18
> **🙏 Special thanks to [@zz5zz](https://github.com/zz5zz)** for his tireless quirk-spotting and bug reports on the [Psysonic Discord](https://discord.gg/AMnDRErm4u) — several of the polish fixes in this release landed directly off the back of his messages. > **🙏 Special thanks to [@zz5zz](https://github.com/zz5zz)** for his tireless quirk-spotting and bug reports on the [Psysonic Discord](https://discord.gg/AMnDRErm4u) — several of the polish fixes in this release landed directly off the back of his messages.
+19
View File
@@ -32,7 +32,26 @@ fn apply_linux_webkit_nvidia_quirk() {
} }
} }
#[cfg(target_os = "linux")]
fn apply_pipewire_latency() {
// Linux audio output goes through the pipewire-alsa bridge, which on some
// setups negotiates a huge default buffer (~1M frames ≈ 1020 s); play/pause/
// seek/volume then lag until it drains (issue #862). cpal's buffer-size clamp
// is ignored by those bridges. Setting the client-node latency via
// `PIPEWIRE_LATENCY` caps it — the reporter confirmed `256/48000` makes
// play/pause/volume instant. No-op on non-PipeWire Linux (var is ignored).
// A user-provided value is left untouched.
if std::env::var_os("PIPEWIRE_LATENCY").is_none() {
std::env::set_var("PIPEWIRE_LATENCY", "256/48000");
}
}
fn main() { fn main() {
// Linux audio: cap the pipewire-alsa client latency so play/pause/seek/volume
// respond promptly (issue #862). Must run before any audio stream is opened.
#[cfg(target_os = "linux")]
apply_pipewire_latency();
// Linux GTK/WebKit: `webkit2gtk-nvidia-quirk` (skipped when `PSYSONIC_WEBKIT_GPU_ACCEL` is set). // Linux GTK/WebKit: `webkit2gtk-nvidia-quirk` (skipped when `PSYSONIC_WEBKIT_GPU_ACCEL` is set).
// Forced `GDK_BACKEND=x11` uses the X11-only mitigation path — see `apply_linux_webkit_nvidia_quirk`. // Forced `GDK_BACKEND=x11` uses the X11-only mitigation path — see `apply_linux_webkit_nvidia_quirk`.
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]