use std::{collections::VecDeque, sync::Arc, thread::{sleep, JoinHandle}, time::Duration};
use cpal::{
traits::{DeviceTrait, StreamTrait},
StreamConfig, StreamError,
};
use parking_lot::Mutex;
use super::InputDevice;
pub fn record_audio_with_interrupt<E>(
input_device: InputDevice,
interrupt: tokio::sync::oneshot::Receiver<()>,
err_callback: E,
config: StreamConfig,
) -> anyhow::Result<Arc<Mutex<VecDeque<f32>>>>
where
E: FnMut(StreamError) + Send + 'static,
{
let buffer_handle: Arc<parking_lot::lock_api::Mutex<parking_lot::RawMutex, VecDeque<f32>>> =
Arc::new(parking_lot::Mutex::new(VecDeque::new()));
let buffer_handle_clone = buffer_handle.clone();
let _: JoinHandle<anyhow::Result<()>> = std::thread::spawn(move || {
let stream: cpal::Stream = input_device.build_input_stream(
&config,
move |data: &[f32], _info: &cpal::InputCallbackInfo| {
let mut buffer_handle = buffer_handle_clone.lock();
for sample in data.iter() {
buffer_handle.push_back(*sample);
}
},
err_callback,
None,
)?;
stream.play()?;
interrupt.blocking_recv()?;
Ok(())
});
Ok(buffer_handle)
}
pub fn record_audio_with_duration<E>(
input_device: InputDevice,
duration: Duration,
err_callback: E,
config: StreamConfig,
) -> anyhow::Result<Arc<Mutex<Vec<f32>>>>
where
E: FnMut(StreamError) + Send + 'static,
{
let buffer_handle: Arc<parking_lot::lock_api::Mutex<parking_lot::RawMutex, Vec<f32>>> =
Arc::new(parking_lot::Mutex::new(Vec::new()));
let buffer_handle_clone = buffer_handle.clone();
let _: JoinHandle<anyhow::Result<()>> = std::thread::spawn(move || {
let stream: cpal::Stream = input_device.build_input_stream(
&config,
move |data: &[f32], _info: &cpal::InputCallbackInfo| {
let mut buffer_handle = buffer_handle_clone.lock();
for sample in data.iter() {
buffer_handle.push(*sample);
}
},
err_callback,
None,
)?;
stream.play()?;
sleep(duration);
Ok(())
});
Ok(buffer_handle)
}