use crate::{
AicError, Model, OtelConfig, ProcessorConfig, Vad, VadContext,
processor_async::get_global_thread_pool,
};
use async_lock::Mutex;
use futures_channel::oneshot;
use std::sync::Arc;
pub struct VadAsync {
inner: Arc<Mutex<Vad<'static>>>,
}
impl VadAsync {
pub fn new(model: &Model<'static>, license_key: &str) -> Result<Self, AicError> {
let vad = Vad::new(model, license_key)?;
Ok(Self {
inner: Arc::new(Mutex::new(vad)),
})
}
pub fn with_otel_config(
model: &Model<'static>,
license_key: &str,
otel_config: &OtelConfig,
) -> Result<Self, AicError> {
let vad = Vad::with_otel_config(model, license_key, otel_config)?;
Ok(Self {
inner: Arc::new(Mutex::new(vad)),
})
}
pub async fn with_config(self, config: &ProcessorConfig) -> Result<Self, AicError> {
self.initialize(config).await?;
Ok(self)
}
pub async fn initialize(&self, config: &ProcessorConfig) -> Result<(), AicError> {
let config = config.clone();
let (tx, rx) = oneshot::channel();
let mut vad = self.inner.lock_arc().await;
get_global_thread_pool().spawn(move || {
let _ = tx.send(vad.initialize(&config));
});
rx.await.expect("Rayon worker dropped")
}
pub async fn process(&self, audio: Vec<f32>) -> Result<Vec<f32>, AicError> {
let (tx, rx) = oneshot::channel();
let mut vad = self.inner.lock_arc().await;
get_global_thread_pool().spawn(move || {
let result = vad.process(&audio).map(|_| audio);
let _ = tx.send(result);
});
rx.await.expect("Rayon worker dropped")
}
pub async fn terminate_session(&self) -> Result<(), AicError> {
let (tx, rx) = oneshot::channel();
let mut vad = self.inner.lock_arc().await;
get_global_thread_pool().spawn(move || {
let _ = tx.send(vad.terminate_session());
});
rx.await.expect("Rayon worker dropped")
}
pub async fn context(&self) -> VadContext {
self.inner.lock().await.context()
}
}