use async_trait::async_trait;
use crate::error::AudioResult;
use crate::frame::AudioFrame;
#[async_trait]
pub trait AudioProcessor: Send + Sync {
async fn process(&self, frame: &AudioFrame) -> AudioResult<AudioFrame>;
}
pub struct FxChain {
stages: Vec<Box<dyn AudioProcessor>>,
}
impl FxChain {
pub fn new() -> Self {
Self { stages: Vec::new() }
}
pub fn push(mut self, processor: impl AudioProcessor + 'static) -> Self {
self.stages.push(Box::new(processor));
self
}
pub fn len(&self) -> usize {
self.stages.len()
}
pub fn is_empty(&self) -> bool {
self.stages.is_empty()
}
}
impl Default for FxChain {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl AudioProcessor for FxChain {
async fn process(&self, frame: &AudioFrame) -> AudioResult<AudioFrame> {
let mut current = frame.clone();
for stage in &self.stages {
current = stage.process(¤t).await?;
}
Ok(current)
}
}