cathode/src-tauri/src/audio.rs

55 lines
1.6 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>>) {
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() >= *threshold.lock().unwrap()) {
window.emit("mouth-open", "").unwrap();
} else {
window.emit("mouth-close", "").unwrap();
}
*level.lock().unwrap() = data
.iter()
.map(|e| e.abs())
.max_by(|a, b| a.total_cmp(&b))
.unwrap()
.clone();
},
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(60));
}
}
fn initialize() -> Result<Device> {
let host = cpal::default_host();
host.default_input_device()
.ok_or_else(|| anyhow!("No default output device"))
}