diff --git a/crates/chanora_audio/src/linux_pipewire_input.rs b/crates/chanora_audio/src/linux_pipewire_input.rs index 5924662..e9e921a 100644 --- a/crates/chanora_audio/src/linux_pipewire_input.rs +++ b/crates/chanora_audio/src/linux_pipewire_input.rs @@ -124,14 +124,14 @@ fn pulse_output_name_from_id(id: &str) -> Option<&str> { } pub(crate) fn list_input_devices(default_label: Option<&str>) -> Vec { - visible_devices(list_devices(LinuxDirection::Input)) + list_devices(LinuxDirection::Input) .iter() .map(|device| device.to_audio_device_info(default_label)) .collect() } pub(crate) fn list_output_devices(default_label: Option<&str>) -> Vec { - visible_devices(list_devices(LinuxDirection::Output)) + list_devices(LinuxDirection::Output) .iter() .map(|device| device.to_audio_device_info(default_label)) .collect() @@ -237,39 +237,22 @@ fn select_device( } fn list_devices(direction: LinuxDirection) -> Vec { - let mut devices = Vec::new(); match list_pipewire_nodes(direction) { - Ok(mut pipewire) => devices.append(&mut pipewire), + Ok(pipewire) if !pipewire.is_empty() => return pipewire, + Ok(_) => { + warn!(target: "chanora_audio", "PipeWire device enumeration returned no devices; trying PulseAudio fallback") + } Err(error) => { warn!(target: "chanora_audio", error = %error, "PipeWire device enumeration failed") } } match list_pulse_devices(direction) { - Ok(mut pulse) => devices.append(&mut pulse), + Ok(pulse) => pulse, Err(error) => { - warn!(target: "chanora_audio", error = %error, "PulseAudio device enumeration failed") + warn!(target: "chanora_audio", error = %error, "PulseAudio device enumeration failed"); + Vec::new() } } - devices -} - -fn visible_devices(devices: Vec) -> Vec { - let pipewire_labels = devices - .iter() - .filter(|device| device.backend == LinuxBackend::PipeWire) - .map(|device| normalized_device_label(&device.label)) - .collect::>(); - devices - .into_iter() - .filter(|device| { - device.backend == LinuxBackend::PipeWire - || !pipewire_labels.contains(&normalized_device_label(&device.label)) - }) - .collect() -} - -fn normalized_device_label(label: &str) -> String { - label.split_whitespace().collect::>().join(" ").to_lowercase() } fn list_pipewire_nodes(direction: LinuxDirection) -> Result, String> { @@ -951,8 +934,7 @@ mod tests { use super::{ input_device_id, input_device_node_id_from_id, output_device_id, output_device_node_id_from_id, pulse_input_device_id, pulse_input_name_from_id, - pulse_output_device_id, pulse_output_name_from_id, visible_devices, LinuxBackend, - LinuxDevice, LinuxDirection, + pulse_output_device_id, pulse_output_name_from_id, }; #[test] @@ -982,32 +964,4 @@ mod tests { Some("alsa_output.pci-0000_00_1f.3") ); } - - #[test] - fn visible_devices_hides_pulse_duplicates_when_pipewire_matches() { - let devices = visible_devices(vec![ - LinuxDevice { - backend: LinuxBackend::PipeWire, - direction: LinuxDirection::Output, - raw_id: "42".to_string(), - label: "Built-in Audio Analog Stereo".to_string(), - }, - LinuxDevice { - backend: LinuxBackend::PulseAudio, - direction: LinuxDirection::Output, - raw_id: "alsa_output.pci-0000".to_string(), - label: " built-in audio analog stereo ".to_string(), - }, - LinuxDevice { - backend: LinuxBackend::PulseAudio, - direction: LinuxDirection::Output, - raw_id: "bluez_output.headset".to_string(), - label: "Headset".to_string(), - }, - ]); - - assert_eq!(devices.len(), 2); - assert!(devices.iter().any(|device| device.backend == LinuxBackend::PipeWire)); - assert!(devices.iter().any(|device| device.label == "Headset")); - } }