Fix audio device selection to show friendly PipeWire names

The previous implementation tried to map ALSA device names (from cpal)
to PipeWire descriptions, but the naming schemes are completely different:
- cpal returns names like "plughw:1,0"
- pactl returns sink names like "alsa_output.usb-Cambridge_Audio_..."

This fix changes the approach:
1. Use PipeWire sinks directly for the device dropdown (already filtered
   to real outputs and have friendly descriptions like "DacMagic Plus")
2. Store the PipeWire sink name when user selects a device
3. Set the PipeWire default sink using pactl when device is selected
4. Use rodio's default device (which follows PipeWire's default)

This ensures users see 4-5 meaningful devices with friendly names
instead of 30+ raw ALSA device names.

Backend changes:
- Add set_pipewire_default_sink command (pactl set-default-sink)
- Register new command in lib.rs

Frontend changes:
- Use pipewireSinks directly for device dropdown
- Display sink description (friendly name)
- Store sink name (for pactl)
- Call set_pipewire_default_sink when device changes
- Remove unused AudioDevice interface and getDevicePrettyName import
This commit is contained in:
vicrodh committed 2026-01-16 19:52:51 -06:00
1 parent eebf440f84
commit 33c5e00da0
3 files changed
+74 -65

No files matched your search

+31
View File
@@ -677,3 +677,34 @@ pub fn get_pipewire_sinks() -> Result<Vec<PipewireSink>, String> {
log::info!("Found {} audio output devices", sinks.len());
Ok(sinks)
}
/// Set the default PipeWire/PulseAudio sink
/// This is used when the user selects an audio device in settings
#[cfg(target_os = "linux")]
#[tauri::command]
pub fn set_pipewire_default_sink(sink_name: String) -> Result<(), String> {
use std::process::Command;
log::info!("Command: set_pipewire_default_sink {}", sink_name);
let output = Command::new("pactl")
.args(["set-default-sink", &sink_name])
.output()
.map_err(|e| format!("Failed to run pactl: {}", e))?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(format!("pactl set-default-sink failed: {}", stderr));
}
log::info!("Set default sink to: {}", sink_name);
Ok(())
}
/// Set the default sink (no-op on non-Linux)
#[cfg(not(target_os = "linux"))]
#[tauri::command]
pub fn set_pipewire_default_sink(_sink_name: String) -> Result<(), String> {
log::info!("Command: set_pipewire_default_sink (no-op on non-Linux)");
Ok(())
}