cathode/src-tauri/src/audio.rs

71 lines
1.9 KiB
Rust

use std::sync::Arc;
use std::sync::Mutex;
use std::thread::sleep;
use std::time::Duration;
use anyhow::anyhow;
use anyhow::Result;
use cpal::traits::StreamTrait;
use cpal::traits::{DeviceTrait, HostTrait};
use cpal::Device;
use cpal::InputCallbackInfo;
use log::debug;
use tauri::Window;
pub async fn monitor(
window: Window,
threshold: Arc<Mutex<f32>>,
level: Arc<Mutex<f32>>,
sens: Arc<Mutex<f32>>,
) {
let device = initialize().expect("Unable to init audio");
debug!("Using device {}", device.name().unwrap());
let config = device.default_input_config().unwrap();
let stream = device
.build_input_stream(
&config.config(),
move |data: &[f32], _: &InputCallbackInfo| {
if data
.iter()
.any(|e| (e.abs() * *sens.lock().unwrap()) >= *threshold.lock().unwrap())
{
window.emit("mouth-open", "").unwrap();
} else {
window.emit("mouth-close", "").unwrap();
}
*level.lock().unwrap() = data
.iter()
.map(|e| e.abs() * *sens.lock().unwrap())
.max_by(|a, b| a.total_cmp(&b))
.unwrap();
},
move |err| {
println!("Audio error: {:?}", err);
},
)
.unwrap();
stream.play().expect("Error creating input stream");
// The stream will end if it goes out of scope, so just dwell here
loop {
sleep(Duration::from_secs(5000));
}
}
fn initialize() -> Result<Device> {
let host = cpal::default_host();
host.default_input_device()
.ok_or_else(|| anyhow!("No default output device"))
}
#[tauri::command]
pub fn get_devices() -> Vec<String> {
let host = cpal::default_host();
host.input_devices()
.unwrap()
.filter_map(|e| e.name().ok())
.collect()
}