Skip to main content

voice_bird_cli/audio/loopback/
mod.rs

1//! System-audio loopback capture.
2//!
3//! Exposes the same [`crate::audio::capture::CaptureHandle`] shape as the
4//! mic path so the rest of the pipeline (resampler → engine) is agnostic.
5//!
6//! - macOS: ScreenCaptureKit audio-only capture (see `loopback_macos`).
7//! - Windows / Linux: not yet wired — returns an explanatory error so the
8//!   UI can surface it as a banner.
9
10#[cfg(not(target_os = "macos"))]
11use anyhow::anyhow;
12use anyhow::Result;
13
14use crate::audio::capture::CaptureHandle;
15
16#[cfg(target_os = "macos")]
17pub mod loopback_macos;
18
19#[cfg(target_os = "windows")]
20pub mod loopback_windows;
21
22/// Capture system audio playing on the output device `name`. If `name` is
23/// `None`, captures the default output.
24pub fn capture_loopback(name: Option<&str>) -> Result<CaptureHandle> {
25    #[cfg(target_os = "macos")]
26    {
27        loopback_macos::capture(name)
28    }
29    #[cfg(not(target_os = "macos"))]
30    {
31        let _ = name;
32        Err(anyhow!("loopback capture not yet wired on this platform"))
33    }
34}
35
36/// Capture audio produced by a single application, identified by bundle
37/// identifier on macOS or PID on Windows. Returns the same
38/// [`CaptureHandle`] shape as the mic and system loopback paths so the
39/// rest of the pipeline (resampler → engine) is agnostic.
40pub fn capture_app(identifier: &str) -> Result<CaptureHandle> {
41    #[cfg(target_os = "macos")]
42    {
43        loopback_macos::capture_app(identifier)
44    }
45    #[cfg(target_os = "windows")]
46    {
47        loopback_windows::capture_app(identifier)
48    }
49    #[cfg(not(any(target_os = "macos", target_os = "windows")))]
50    {
51        let _ = identifier;
52        Err(anyhow!("per-app capture not yet wired on this platform"))
53    }
54}