Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/detect/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
mod app;
mod browser;
mod mic;
mod utils;

pub use app::*;
pub use browser::*;
pub use mic::*;

use utils::*;

pub type DetectCallback = std::sync::Arc<dyn Fn(String) + Send + Sync + 'static>;
Expand All @@ -24,6 +27,7 @@ trait Observer: Send + Sync {
pub struct Detector {
app_detector: AppDetector,
browser_detector: BrowserDetector,
mic_detector: MicDetector,
}

impl Detector {
Expand Down
54 changes: 54 additions & 0 deletions crates/detect/src/mic/macos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use cidre::{core_audio as ca, io, os};

#[derive(Default)]
pub struct Detector {}

const DEVICE_IS_RUNNING_SOMEWHERE: ca::PropAddr = ca::PropAddr {
selector: ca::PropSelector::DEVICE_IS_RUNNING_SOMEWHERE,
scope: ca::PropScope::GLOBAL,
element: ca::PropElement::MAIN,
};

impl crate::Observer for Detector {
fn start(&mut self, f: crate::DetectCallback) {
extern "C-unwind" fn listener(
_obj_id: ca::Obj,
number_addresses: u32,
addresses: *const ca::PropAddr,
_client_data: *mut (),
) -> os::Status {
let addresses =
unsafe { std::slice::from_raw_parts(addresses, number_addresses as usize) };

for addr in addresses {
match addr.selector {
ca::PropSelector::HW_DEFAULT_INPUT_DEVICE => {
println!("default input device changed");
let device = ca::System::default_input_device().unwrap();

let is_running = device.prop::<u8>(&DEVICE_IS_RUNNING_SOMEWHERE).unwrap();
println!("is_running: {is_running}");
}
ca::PropSelector::HW_DEFAULT_OUTPUT_DEVICE => {
println!("default output device changed");
let device = ca::System::default_output_device().unwrap();

let streams = device.streams().unwrap();
let headphones = streams
.iter()
.find(|s| {
let term_type = s.terminal_type().unwrap();
term_type.0 == io::audio::output_term::HEADPHONES
|| term_type == ca::StreamTerminalType::HEADPHONES
})
.is_some();
println!("headphones connected {headphones}");
}
_ => panic!("unregistered selector"),
}
}
os::Status::NO_ERR
}
}
fn stop(&mut self) {}
}
23 changes: 23 additions & 0 deletions crates/detect/src/mic/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "macos")]
type PlatformDetector = macos::Detector;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
type PlatformDetector = windows::Detector;

#[derive(Default)]
pub struct MicDetector {
inner: PlatformDetector,
}

impl crate::Observer for MicDetector {
fn start(&mut self, f: crate::DetectCallback) {
self.inner.start(f);
}
fn stop(&mut self) {
self.inner.stop();
}
}
7 changes: 7 additions & 0 deletions crates/detect/src/mic/windows.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[derive(Default)]
pub struct Detector {}

impl crate::Observer for Detector {
fn start(&mut self, f: crate::DetectCallback) {}
fn stop(&mut self) {}
}
Loading