Windows port Phase 2: cpal device enumeration
Give the Windows device pickers a real device list (Phase 0/1 left pw_cli returning nothing off-Linux) and generalize enumeration into a platform-neutral interface. - audio/mod.rs: move AudioDevice here (neutral home), gate pw_cli to cfg(unix), and re-export enumerate_audio_devices per-platform (pw_cli on unix, cpal_impl on windows). Also drop a now-stale "no-op stub" doc note. - cpal_impl.rs: add enumerate_audio_devices() — iterate the cpal host's input + output devices into AudioDevice (name == description == the cpal friendly name, which is what resolve() matches target_node against, so a saved selection round-trips), sorted by description. - pw_cli.rs: use super::AudioDevice instead of a local copy; parsing + tests unchanged. - app/mod.rs: one-line import change; the device-picker logic is untouched. Verified: shipped Linux state green (build --locked, clippy, 316/316, pw_cli parse tests 6/6); the cpal enumerator compiles against real cpal via the Linux/ALSA toggle. Runtime device listing on Windows is pending a real host (M2/M3). WASAPI names are less stable than PipeWire node names, so a saved device may not always round-trip (falls back to default). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+27
-2
@@ -66,9 +66,35 @@ pub mod pan;
|
||||
pub mod pipewire_impl;
|
||||
#[cfg(windows)]
|
||||
pub mod cpal_impl;
|
||||
#[cfg(unix)]
|
||||
pub mod pw_cli;
|
||||
pub mod recorder;
|
||||
|
||||
/// A selectable audio device for the input/output pickers. `name` is the stable
|
||||
/// identifier the backend uses to request the device (`target_node`);
|
||||
/// `description` is the human-facing label shown in the UI. The two may be equal
|
||||
/// (cpal/WASAPI) or differ (PipeWire node name vs. description).
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AudioDevice {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub is_input: bool,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AudioDevice {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.description)
|
||||
}
|
||||
}
|
||||
|
||||
// Enumerate audio input/output devices for the pickers (sorted by description),
|
||||
// returning the same `AudioDevice` shape regardless of platform: PipeWire
|
||||
// (`pw-cli`) on Linux, cpal/WASAPI on Windows.
|
||||
#[cfg(unix)]
|
||||
pub use pw_cli::enumerate_audio_devices;
|
||||
#[cfg(windows)]
|
||||
pub use cpal_impl::enumerate_audio_devices;
|
||||
|
||||
/// The audio backend implementation for the current platform.
|
||||
///
|
||||
/// The whole app constructs and threads this alias (via
|
||||
@@ -77,8 +103,7 @@ pub mod recorder;
|
||||
/// [`AudioBackend`] trait, which is the only interface the core talks to.
|
||||
///
|
||||
/// - Linux/Unix → PipeWire ([`pipewire_impl::PipeWireBackend`]).
|
||||
/// - Windows → cpal/WASAPI ([`cpal_impl::CpalBackend`]); a no-op stub until the
|
||||
/// Phase 1 capture/playback implementation lands.
|
||||
/// - Windows → cpal/WASAPI ([`cpal_impl::CpalBackend`]).
|
||||
#[cfg(unix)]
|
||||
pub type PlatformAudioBackend = pipewire_impl::PipeWireBackend;
|
||||
#[cfg(windows)]
|
||||
|
||||
Reference in New Issue
Block a user