mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
fix(linux): prefer pipewire/pulse over raw ALSA default for audio output (#288)
On PipeWire-based distros (Debian 13, Ubuntu 22+, Gnome-on-PipeWire, and similar), cpal's default_output_device() resolves to the raw ALSA `default` alias. During early app-start that alias sometimes routes to a null sink: the stream opens without error, progress ticks run, but nothing reaches the user. Closes #234. Prefer the pipewire-alsa / pulse-alsa aliases explicitly before falling back to cpal's default, but only on Linux — macOS / Windows paths are untouched. Systems that don't expose either alias (pure ALSA, no PipeWire) fall through to the original default-device path. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
ea01470df4
commit
ce8d389070
+21
-3
@@ -2076,10 +2076,28 @@ fn open_stream_for_device_and_rate(device_name: Option<&str>, desired_rate: u32)
|
||||
|
||||
let host = rodio::cpal::default_host();
|
||||
|
||||
// Resolve the target device: named device first, fall back to system default.
|
||||
let device = device_name.and_then(|name| {
|
||||
// Resolve the target device: explicit name first, then (on Linux) prefer
|
||||
// a "pipewire" or "pulse" ALSA alias before falling back to cpal's system
|
||||
// default. On PipeWire-based distros the raw ALSA `default` alias can
|
||||
// route to a null sink at app-start (issue #234 on Debian 13): the stream
|
||||
// opens cleanly, progress ticks run, no audio reaches the user. The
|
||||
// named-alias path goes through pipewire-alsa's real sink and just works.
|
||||
// On systems where neither alias exists (pure ALSA, macOS, Windows),
|
||||
// `find_by_name` returns None and we drop through to `default_output_device`
|
||||
// unchanged — no regression.
|
||||
let find_by_name = |name: &str| -> Option<_> {
|
||||
host.output_devices().ok()?.find(|d| d.name().ok().as_deref() == Some(name))
|
||||
}).or_else(|| host.default_output_device());
|
||||
};
|
||||
|
||||
let device = device_name
|
||||
.and_then(find_by_name)
|
||||
.or_else(|| {
|
||||
#[cfg(target_os = "linux")]
|
||||
{ find_by_name("pipewire").or_else(|| find_by_name("pulse")) }
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
{ None }
|
||||
})
|
||||
.or_else(|| host.default_output_device());
|
||||
|
||||
if let Some(device) = device {
|
||||
if desired_rate > 0 {
|
||||
|
||||
Reference in New Issue
Block a user