Skip to main content

rill_core/traits/
multichannel_algorithm.rs

1use crate::math::Transcendental;
2use crate::traits::ProcessResult;
3
4/// A signal processing algorithm with multiple inputs and outputs.
5///
6/// Unlike `Algorithm<T>` which is strictly single-input/single-output (SISO),
7/// this trait supports N-to-M channel processing in a single call.
8pub trait MultichannelAlgorithm<T: Transcendental>: Send {
9    /// Number of signal input channels.
10    fn num_inputs(&self) -> usize;
11
12    /// Number of signal output channels.
13    fn num_outputs(&self) -> usize;
14
15    /// Process one buffer of samples.
16    ///
17    /// - `inputs.len() == num_inputs()`
18    /// - `outputs.len() == num_outputs()`
19    /// - Each inner slice has exactly BUF_SIZE samples (determined by the caller).
20    fn process(&mut self, inputs: &[&[T]], outputs: &mut [&mut [T]]) -> ProcessResult<()>;
21
22    /// Reset internal state.
23    fn reset(&mut self);
24}
25
26/// Adapter: wrap a SISO Algorithm as a MultichannelAlgorithm.
27///
28/// Useful for mixed graphs where most nodes are SISO but some are multi-IO.
29pub struct SisoAdapter<A, T: Transcendental> {
30    /// The wrapped SISO algorithm.
31    pub inner: A,
32    _phantom: std::marker::PhantomData<T>,
33}
34
35impl<A, T: Transcendental> SisoAdapter<A, T>
36where
37    A: crate::traits::Algorithm<T>,
38{
39    /// Create a new adapter wrapping a SISO algorithm.
40    pub fn new(inner: A) -> Self {
41        Self {
42            inner,
43            _phantom: std::marker::PhantomData,
44        }
45    }
46}
47
48impl<A, T: Transcendental> MultichannelAlgorithm<T> for SisoAdapter<A, T>
49where
50    A: crate::traits::Algorithm<T>,
51{
52    fn num_inputs(&self) -> usize {
53        1
54    }
55
56    fn num_outputs(&self) -> usize {
57        1
58    }
59
60    fn process(&mut self, inputs: &[&[T]], outputs: &mut [&mut [T]]) -> ProcessResult<()> {
61        let input = if inputs.is_empty() {
62            None
63        } else {
64            Some(inputs[0])
65        };
66        crate::traits::Algorithm::process(&mut self.inner, input, outputs[0])
67    }
68
69    fn reset(&mut self) {
70        crate::traits::Algorithm::reset(&mut self.inner);
71    }
72}