diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index e3be42c..04a3524 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -62,6 +62,7 @@ fn default_settings() -> Settings { retention_max_size_gb: None, pst_last_path: None, pst_auto_sync: false, + audio_output_device: None, } } @@ -286,7 +287,12 @@ pub async fn start_recording( // Level updates + device-change notices (FR-CAP-5/6); low-volume, forwarded to events below. let (event_tx, event_rx) = std::sync::mpsc::sync_channel::(8); let capture = WasapiCapture - .start(&wav_path, frame_tx, event_tx) + .start( + &wav_path, + settings.audio_output_device.as_deref(), + frame_tx, + event_tx, + ) .map_err(|e| WaError::new("audio", e.to_string()))?; // Fire-and-forget: exits on its own once `event_tx` drops at capture stop; @@ -905,6 +911,18 @@ pub async fn hardware_status() -> WaResult { })) } +/// Lists active render (playback) devices for the "Audio Devices" picker +/// (Settings ▸ Hardware) — loopback-only, matching the app's only capture +/// path (FR-CAP-1). Runs off the async runtime thread since device +/// enumeration is a blocking COM call. +#[tauri::command] +pub async fn list_audio_devices() -> WaResult> { + tauri::async_runtime::spawn_blocking(crate::audio::list_render_devices) + .await + .map_err(|e| WaError::new("audio", e.to_string()))? + .map_err(|e| WaError::new("audio", e.to_string())) +} + #[derive(Deserialize)] pub struct SetPreferredBackendArgs { pub backend: String, // "auto"|"npu"|"nvidia"|"amd"|"intel"|"cpu"