fundsp/
audionode.rs

1//! The central `AudioNode` abstraction and basic components.
2
3use super::buffer::*;
4use super::combinator::*;
5use super::math::*;
6use super::setting::*;
7use super::signal::*;
8use super::*;
9use core::marker::PhantomData;
10use num_complex::Complex64;
11use numeric_array::typenum::*;
12use numeric_array::{ArrayLength, NumericArray};
13
14/// Type-level integer. These are notated as `U0`, `U1`...
15pub trait Size<T>: ArrayLength + Sync + Send + Clone {}
16
17impl<T, A: ArrayLength + Sync + Send + Clone> Size<T> for A {}
18
19/// Frames are arrays with a static size used to transport audio data
20/// between `AudioNode` instances.
21pub type Frame<T, Size> = NumericArray<T, Size>;
22
23/*
24Order of type arguments in nodes:
251. Basic input and output arities excepting filter input selector arities.
262. Processing float type.
273. Unary or binary operation type.
284. Filter input selector arity.
295. Contained node types.
306. The rest in any order.
31*/
32
33/// Generic audio processor.
34/// `AudioNode` has a static number of inputs (`AudioNode::Inputs`) and outputs (`AudioNode::Outputs`).
35pub trait AudioNode: Clone + Sync + Send {
36    /// Unique ID for hashing.
37    const ID: u64;
38    /// Input arity.
39    type Inputs: Size<f32>;
40    /// Output arity.
41    type Outputs: Size<f32>;
42
43    /// Reset the input state of the component and all its children to an initial state
44    /// where it has not processed any samples. In other words, reset time to zero.
45    /// If `allocate` has been called previously, and the sample rate is unchanged,
46    /// then it is expected that no memory allocation or deallocation takes place here.
47    ///
48    /// ### Example
49    /// ```
50    /// use fundsp::hacker::*;
51    /// let mut node = saw_hz(440.0);
52    /// let sample1 = node.get_mono();
53    /// node.reset();
54    /// let sample2 = node.get_mono();
55    /// assert_eq!(sample1, sample2);
56    /// ```
57    #[allow(unused_variables)]
58    fn reset(&mut self) {
59        // The default implementation does nothing.
60    }
61
62    /// Set the sample rate of the node and all its children.
63    /// The default sample rate is 44100 Hz.
64    /// The unit is allowed to reset its state here in response to sample rate changes.
65    /// If the sample rate stays unchanged, then the goal is to maintain current state.
66    ///
67    /// ### Example (Changing The Sample Rate)
68    /// ```
69    /// use fundsp::hacker::*;
70    /// let mut node = saw_hz(440.0);
71    /// node.set_sample_rate(48_000.0);
72    /// ```
73    #[allow(unused_variables)]
74    fn set_sample_rate(&mut self, sample_rate: f64) {
75        // The default implementation does nothing.
76    }
77
78    /// Process one sample.
79    ///
80    /// ### Example
81    /// ```
82    /// use fundsp::hacker::*;
83    /// assert_eq!(pass().tick(&Frame::from([2.0])), Frame::from([2.0]));
84    /// ```
85    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs>;
86
87    /// Process up to 64 (`MAX_BUFFER_SIZE`) samples.
88    /// If `size` is zero then this is a no-op, which is permitted.
89    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
90        // The default implementation is a fallback that calls into `tick`.
91        debug_assert!(size <= MAX_BUFFER_SIZE);
92        debug_assert!(input.channels() == self.inputs());
93        debug_assert!(output.channels() == self.outputs());
94
95        // Note. We could build `tick` inputs from `[f32; 8]` or `f32x8` temporary
96        // values to make index arithmetic easier but according to benchmarks
97        // it doesn't make a difference.
98        let mut input_frame: Frame<f32, Self::Inputs> = Frame::default();
99
100        for i in 0..size {
101            for channel in 0..self.inputs() {
102                input_frame[channel] = input.at_f32(channel, i);
103            }
104            let output_frame = self.tick(&input_frame);
105            for channel in 0..self.outputs() {
106                output.set_f32(channel, i, output_frame[channel]);
107            }
108        }
109    }
110
111    /// Process samples left over using `tick` after processing all full SIMD items.
112    /// This is a convenience method for implementers.
113    #[inline]
114    fn process_remainder(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
115        debug_assert!(size <= MAX_BUFFER_SIZE);
116        debug_assert!(input.channels() == self.inputs());
117        debug_assert!(output.channels() == self.outputs());
118
119        let mut input_frame: Frame<f32, Self::Inputs> = Frame::default();
120
121        for i in (size & !SIMD_M)..size {
122            for channel in 0..self.inputs() {
123                input_frame[channel] = input.at_f32(channel, i);
124            }
125            let output_frame = self.tick(&input_frame);
126            for channel in 0..self.outputs() {
127                output.set_f32(channel, i, output_frame[channel]);
128            }
129        }
130    }
131
132    /// Set a parameter. What formats are recognized depends on the component.
133    #[allow(unused_variables)]
134    fn set(&mut self, setting: Setting) {}
135
136    /// Set node pseudorandom phase hash.
137    /// This is called from `ping` (only). It should not be called by users.
138    /// The node is allowed to reset itself here.
139    #[allow(unused_variables)]
140    fn set_hash(&mut self, hash: u64) {
141        // Override this to use the hash.
142        // The default implementation does nothing.
143    }
144
145    /// Ping contained `AudioNode`s to obtain a deterministic pseudorandom hash.
146    /// The local hash includes children, too.
147    /// Leaf nodes should not need to override this.
148    /// If `probe` is true, then this is a probe for computing the network hash
149    /// and `set_hash` should not be called yet.
150    /// To set a custom hash for a graph, call this method with `probe`
151    /// set to false and `hash` initialized with the custom hash.
152    /// The node is allowed to reset itself here.
153    ///
154    /// ### Example (Setting a Custom Hash)
155    /// ```
156    /// use fundsp::hacker32::*;
157    /// let mut node = square_hz(440.0);
158    /// node.ping(false, AttoHash::new(1));
159    /// ```
160    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
161        if !probe {
162            self.set_hash(hash.state());
163        }
164        hash.hash(Self::ID)
165    }
166
167    /// Preallocate all needed memory.
168    fn allocate(&mut self) {
169        // The default implementation does nothing.
170    }
171
172    /// Route constants, latencies and frequency responses at `frequency` Hz
173    /// from inputs to outputs. Return output signal.
174    /// If there are no frequency responses in `input`, then `frequency` is ignored.
175    #[allow(unused_variables)]
176    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
177        // The default implementation marks all outputs unknown.
178        SignalFrame::new(self.outputs())
179    }
180
181    // End of interface. There is no need to override the following.
182
183    /// Number of inputs.
184    ///
185    /// ### Example
186    /// ```
187    /// use fundsp::hacker::*;
188    /// assert_eq!(sink().inputs(), 1);
189    /// ```
190    #[inline(always)]
191    fn inputs(&self) -> usize {
192        Self::Inputs::USIZE
193    }
194
195    /// Number of outputs.
196    ///
197    /// ### Example
198    /// ```
199    /// use fundsp::hacker::*;
200    /// assert_eq!(zero().outputs(), 1);
201    /// ```
202    #[inline(always)]
203    fn outputs(&self) -> usize {
204        Self::Outputs::USIZE
205    }
206
207    /// Retrieve the next mono sample from a generator.
208    /// The node must have no inputs and 1 or 2 outputs.
209    /// If there are two outputs, average the channels.
210    ///
211    /// ### Example
212    /// ```
213    /// use fundsp::hacker::*;
214    /// assert_eq!(dc(2.0).get_mono(), 2.0);
215    /// assert_eq!(dc((3.0, 4.0)).get_mono(), 3.5);
216    /// ```
217    #[inline]
218    fn get_mono(&mut self) -> f32 {
219        assert!(
220            Self::Inputs::USIZE == 0 && (Self::Outputs::USIZE == 1 || Self::Outputs::USIZE == 2)
221        );
222        let output = self.tick(&Frame::default());
223        if self.outputs() == 1 {
224            output[0]
225        } else {
226            (output[0] + output[1]) / f32::new(2)
227        }
228    }
229
230    /// Retrieve the next stereo sample (left, right) from a generator.
231    /// The node must have no inputs and 1 or 2 outputs.
232    /// If there is just one output, duplicate it.
233    ///
234    /// ### Example
235    /// ```
236    /// use fundsp::hacker::*;
237    /// assert_eq!(dc((5.0, 6.0)).get_stereo(), (5.0, 6.0));
238    /// assert_eq!(dc(7.0).get_stereo(), (7.0, 7.0));
239    /// ```
240    #[inline]
241    fn get_stereo(&mut self) -> (f32, f32) {
242        assert!(
243            Self::Inputs::USIZE == 0 && (Self::Outputs::USIZE == 1 || Self::Outputs::USIZE == 2)
244        );
245        let output = self.tick(&Frame::default());
246        (output[0], output[(Self::Outputs::USIZE > 1) as usize])
247    }
248
249    /// Filter the next mono sample `x`.
250    /// The node must have exactly 1 input and 1 output.
251    ///
252    /// ### Example
253    /// ```
254    /// use fundsp::hacker::*;
255    /// assert_eq!(add(1.0).filter_mono(1.0), 2.0);
256    /// ```
257    #[inline]
258    fn filter_mono(&mut self, x: f32) -> f32 {
259        assert!(Self::Inputs::USIZE == 1 && Self::Outputs::USIZE == 1);
260        let output = self.tick(&Frame::splat(x));
261        output[0]
262    }
263
264    /// Filter the next stereo sample `(x, y)`.
265    /// The node must have exactly 2 inputs and 2 outputs.
266    ///
267    /// ### Example
268    /// ```
269    /// use fundsp::hacker::*;
270    /// assert_eq!(add((2.0, 3.0)).filter_stereo(4.0, 5.0), (6.0, 8.0));
271    /// ```
272    #[inline]
273    fn filter_stereo(&mut self, x: f32, y: f32) -> (f32, f32) {
274        assert!(Self::Inputs::USIZE == 2 && Self::Outputs::USIZE == 2);
275        let output = self.tick(&Frame::generate(|i| if i == 0 { x } else { y }));
276        (output[0], output[1])
277    }
278
279    /// Evaluate frequency response of `output` at `frequency` Hz.
280    /// Any linear response can be composed.
281    /// Return `None` if there is no response or it could not be calculated.
282    ///
283    /// ### Example
284    /// ```
285    /// use fundsp::hacker::*;
286    /// assert_eq!(pass().response(0, 440.0), Some(Complex64::new(1.0, 0.0)));
287    /// ```
288    fn response(&mut self, output: usize, frequency: f64) -> Option<Complex64> {
289        assert!(output < self.outputs());
290        let mut input = SignalFrame::new(self.inputs());
291        for i in 0..self.inputs() {
292            input.set(i, Signal::Response(Complex64::new(1.0, 0.0), 0.0));
293        }
294        let response = self.route(&input, frequency);
295        match response.at(output) {
296            Signal::Response(rx, _) => Some(rx),
297            _ => None,
298        }
299    }
300
301    /// Evaluate frequency response of `output` in dB at `frequency` Hz.
302    /// Any linear response can be composed.
303    /// Return `None` if there is no response or it could not be calculated.
304    ///
305    /// ### Example
306    /// ```
307    /// use fundsp::hacker::*;
308    /// let db = pass().response_db(0, 440.0).unwrap();
309    /// assert!(db < 1.0e-7 && db > -1.0e-7);
310    /// ```
311    fn response_db(&mut self, output: usize, frequency: f64) -> Option<f64> {
312        assert!(output < self.outputs());
313        self.response(output, frequency).map(|r| amp_db(r.norm()))
314    }
315
316    /// Causal latency in (fractional) samples, if any.
317    /// After a reset, we can discard this many samples from the output to avoid incurring a pre-delay.
318    /// The latency may depend on the sample rate.
319    /// Voluntary latencies, such as delays, are not counted as latency.
320    ///
321    /// ### Example
322    /// ```
323    /// use fundsp::hacker::*;
324    /// assert_eq!(pass().latency(), Some(0.0));
325    /// assert_eq!(tick().latency(), Some(0.0));
326    /// assert_eq!(sink().latency(), None);
327    /// assert_eq!(lowpass_hz(440.0, 1.0).latency(), Some(0.0));
328    /// assert_eq!(limiter(0.01, 0.01).latency(), Some(441.0));
329    /// ```
330    fn latency(&mut self) -> Option<f64> {
331        if self.outputs() == 0 {
332            return None;
333        }
334        let mut input = SignalFrame::new(self.inputs());
335        for i in 0..self.inputs() {
336            input.set(i, Signal::Latency(0.0));
337        }
338        // The frequency argument can be anything as there are no responses to propagate,
339        // only latencies. Latencies are never promoted to responses during signal routing.
340        let response = self.route(&input, 1.0);
341        // Return the minimum latency.
342        let mut result: Option<f64> = None;
343        for output in 0..self.outputs() {
344            match (result, response.at(output)) {
345                (None, Signal::Latency(x)) => result = Some(x),
346                (Some(r), Signal::Latency(x)) => result = Some(r.min(x)),
347                _ => (),
348            }
349        }
350        result
351    }
352}
353
354/// Pass through inputs unchanged.
355#[derive(Default, Clone)]
356pub struct MultiPass<N> {
357    _marker: PhantomData<N>,
358}
359
360impl<N: Size<f32>> MultiPass<N> {
361    pub fn new() -> Self {
362        MultiPass::default()
363    }
364}
365
366impl<N: Size<f32>> AudioNode for MultiPass<N> {
367    const ID: u64 = 0;
368    type Inputs = N;
369    type Outputs = N;
370
371    #[inline]
372    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
373        input.clone()
374    }
375    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
376        for channel in 0..self.outputs() {
377            for i in 0..simd_items(size) {
378                output.set(channel, i, input.at(channel, i));
379            }
380        }
381    }
382    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
383        input.clone()
384    }
385}
386
387/// Pass through input unchanged.
388#[derive(Default, Clone)]
389pub struct Pass {}
390
391impl Pass {
392    pub fn new() -> Self {
393        Pass::default()
394    }
395}
396
397// Note. We have separate Pass and MultiPass structs
398// because it helps a little with type inference.
399impl AudioNode for Pass {
400    const ID: u64 = 48;
401    type Inputs = U1;
402    type Outputs = U1;
403
404    #[inline]
405    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
406        *input
407    }
408    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
409        for i in 0..simd_items(size) {
410            output.set(0, i, input.at(0, i));
411        }
412    }
413    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
414        input.clone()
415    }
416}
417
418/// Discard inputs.
419#[derive(Default, Clone)]
420pub struct Sink<N> {
421    _marker: PhantomData<N>,
422}
423
424impl<N: Size<f32>> Sink<N> {
425    pub fn new() -> Self {
426        Sink::default()
427    }
428}
429
430impl<N: Size<f32>> AudioNode for Sink<N> {
431    const ID: u64 = 1;
432    type Inputs = N;
433    type Outputs = U0;
434
435    #[inline]
436    fn tick(&mut self, _input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
437        Frame::default()
438    }
439    fn process(&mut self, _size: usize, _input: &BufferRef, _output: &mut BufferMut) {}
440
441    fn route(&mut self, _input: &SignalFrame, _frequency: f64) -> SignalFrame {
442        SignalFrame::new(self.outputs())
443    }
444}
445
446/// Output a constant value.
447#[derive(Clone)]
448pub struct Constant<N: Size<f32>> {
449    output: Frame<f32, N>,
450}
451
452impl<N: Size<f32>> Constant<N> {
453    /// Construct constant.
454    pub fn new(output: Frame<f32, N>) -> Self {
455        Constant { output }
456    }
457    /// Set the value of the constant.
458    #[inline]
459    pub fn set_value(&mut self, output: Frame<f32, N>) {
460        self.output = output;
461    }
462    /// Get the value of the constant.
463    #[inline]
464    pub fn value(&self) -> Frame<f32, N> {
465        self.output.clone()
466    }
467    /// Set a scalar value on all channels.
468    #[inline]
469    pub fn set_scalar(&mut self, output: f32) {
470        self.output = Frame::splat(output);
471    }
472}
473
474impl<N: Size<f32>> AudioNode for Constant<N> {
475    const ID: u64 = 2;
476    type Inputs = U0;
477    type Outputs = N;
478
479    #[inline]
480    fn tick(&mut self, _input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
481        self.output.clone()
482    }
483
484    fn process(&mut self, size: usize, _input: &BufferRef, output: &mut BufferMut) {
485        for channel in 0..self.outputs() {
486            let channel_value = F32x::splat(self.output[channel].to_f32());
487            for j in 0..simd_items(size) {
488                output.set(channel, j, channel_value);
489            }
490        }
491    }
492
493    fn set(&mut self, setting: Setting) {
494        if let Parameter::Value(value) = setting.parameter() {
495            self.set_scalar(*value);
496        }
497    }
498
499    fn route(&mut self, _input: &SignalFrame, _frequency: f64) -> SignalFrame {
500        let mut output = SignalFrame::new(self.outputs());
501        for i in 0..N::USIZE {
502            output.set(i, Signal::Value(self.output[i].to_f64()));
503        }
504        output
505    }
506}
507
508/// Split input into `N` channels.
509#[derive(Clone)]
510pub struct Split<N> {
511    _marker: PhantomData<N>,
512}
513
514// Note. We have separate split and multisplit (and join and multijoin)
515// implementations because it helps with type inference.
516impl<N> Split<N>
517where
518    N: Size<f32>,
519{
520    #[allow(clippy::new_without_default)]
521    pub fn new() -> Self {
522        Self {
523            _marker: PhantomData,
524        }
525    }
526}
527
528impl<N> AudioNode for Split<N>
529where
530    N: Size<f32>,
531{
532    const ID: u64 = 40;
533    type Inputs = U1;
534    type Outputs = N;
535
536    #[inline]
537    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
538        Frame::splat(input[0])
539    }
540    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
541        for channel in 0..N::USIZE {
542            for i in 0..simd_items(size) {
543                output.set(channel, i, input.at(0, i));
544            }
545        }
546    }
547    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
548        Routing::Split.route(input, self.outputs())
549    }
550}
551
552/// Split `M` inputs into `N` branches, with `M` * `N` outputs.
553#[derive(Clone)]
554pub struct MultiSplit<M, N> {
555    _marker: PhantomData<(M, N)>,
556}
557
558impl<M, N> MultiSplit<M, N>
559where
560    M: Size<f32> + Mul<N>,
561    N: Size<f32>,
562    <M as Mul<N>>::Output: Size<f32>,
563{
564    #[allow(clippy::new_without_default)]
565    pub fn new() -> Self {
566        Self {
567            _marker: PhantomData,
568        }
569    }
570}
571
572impl<M, N> AudioNode for MultiSplit<M, N>
573where
574    M: Size<f32> + Mul<N>,
575    N: Size<f32>,
576    <M as Mul<N>>::Output: Size<f32>,
577{
578    const ID: u64 = 38;
579    type Inputs = M;
580    type Outputs = numeric_array::typenum::Prod<M, N>;
581
582    #[inline]
583    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
584        Frame::generate(|i| input[i % M::USIZE])
585    }
586    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
587        for channel in 0..M::USIZE * N::USIZE {
588            for i in 0..simd_items(size) {
589                output.set(channel, i, input.at(channel % M::USIZE, i));
590            }
591        }
592    }
593    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
594        Routing::Split.route(input, self.outputs())
595    }
596}
597
598/// Join `N` channels into one by averaging. Inverse of `Split<N>`.
599#[derive(Clone)]
600pub struct Join<N> {
601    _marker: PhantomData<N>,
602}
603
604impl<N> Join<N>
605where
606    N: Size<f32>,
607{
608    #[allow(clippy::new_without_default)]
609    pub fn new() -> Self {
610        Self {
611            _marker: PhantomData,
612        }
613    }
614}
615
616impl<N> AudioNode for Join<N>
617where
618    N: Size<f32>,
619{
620    const ID: u64 = 41;
621    type Inputs = N;
622    type Outputs = U1;
623
624    #[inline]
625    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
626        let mut output = input[0];
627        for i in 1..N::USIZE {
628            output += input[i];
629        }
630        [output / N::I64 as f32].into()
631    }
632    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
633        let z = 1.0 / N::U64 as f32;
634        for i in 0..simd_items(size) {
635            output.set(0, i, input.at(0, i) * z);
636        }
637        for channel in 1..N::USIZE {
638            for i in 0..simd_items(size) {
639                output.add(0, i, input.at(channel, i) * z);
640            }
641        }
642    }
643    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
644        Routing::Join.route(input, self.outputs())
645    }
646}
647
648/// Average `N` branches of `M` channels into one branch with `M` channels.
649/// The input has `M` * `N` channels. Inverse of `MultiSplit<M, N>`.
650#[derive(Clone)]
651pub struct MultiJoin<M, N> {
652    _marker: PhantomData<(M, N)>,
653}
654
655impl<M, N> MultiJoin<M, N>
656where
657    M: Size<f32> + Mul<N>,
658    N: Size<f32>,
659    <M as Mul<N>>::Output: Size<f32>,
660{
661    #[allow(clippy::new_without_default)]
662    pub fn new() -> Self {
663        Self {
664            _marker: PhantomData,
665        }
666    }
667}
668
669impl<M, N> AudioNode for MultiJoin<M, N>
670where
671    M: Size<f32> + Mul<N>,
672    N: Size<f32>,
673    <M as Mul<N>>::Output: Size<f32>,
674{
675    const ID: u64 = 39;
676    type Inputs = numeric_array::typenum::Prod<M, N>;
677    type Outputs = M;
678
679    #[inline]
680    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
681        Frame::generate(|j| {
682            let mut output = input[j];
683            for i in 1..N::USIZE {
684                output += input[j + i * M::USIZE];
685            }
686            output / N::I64 as f32
687        })
688    }
689    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
690        let z = 1.0 / N::U64 as f32;
691        for channel in 0..M::USIZE {
692            for i in 0..simd_items(size) {
693                output.set(channel, i, input.at(channel, i) * z);
694            }
695        }
696        for channel in M::USIZE..M::USIZE * N::USIZE {
697            for i in 0..simd_items(size) {
698                output.add(channel % M::USIZE, i, input.at(channel, i) * z);
699            }
700        }
701    }
702    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
703        Routing::Join.route(input, self.outputs())
704    }
705}
706
707/// Provides binary operator implementations to the `Binop` node.
708pub trait FrameBinop<N: Size<f32>>: Clone + Sync + Send {
709    /// Do binary op (`x` op `y`) channelwise.
710    fn binop(&self, x: F32x, y: F32x) -> F32x;
711    /// Do binary op (`x` op `y`) channelwise.
712    fn frame(&self, x: &Frame<f32, N>, y: &Frame<f32, N>) -> Frame<f32, N>;
713    /// Do binary op (`x` op `y`) in-place lengthwise. `size` may be zero.
714    fn assign(&self, size: usize, x: &mut [f32], y: &[f32]);
715    /// Do binary op (`x` op `y`) on signals.
716    fn route(&self, x: Signal, y: Signal) -> Signal;
717}
718
719/// Addition operator.
720#[derive(Default, Clone)]
721pub struct FrameAdd<N: Size<f32>> {
722    _marker: PhantomData<N>,
723}
724
725impl<N: Size<f32>> FrameAdd<N> {
726    pub fn new() -> FrameAdd<N> {
727        FrameAdd::default()
728    }
729}
730
731impl<N: Size<f32>> FrameBinop<N> for FrameAdd<N> {
732    #[inline]
733    fn binop(&self, x: F32x, y: F32x) -> F32x {
734        x + y
735    }
736    #[inline]
737    fn frame(&self, x: &Frame<f32, N>, y: &Frame<f32, N>) -> Frame<f32, N> {
738        x + y
739    }
740    #[inline]
741    fn assign(&self, size: usize, x: &mut [f32], y: &[f32]) {
742        for (o, i) in x[..size].iter_mut().zip(y[..size].iter()) {
743            *o += *i;
744        }
745    }
746    fn route(&self, x: Signal, y: Signal) -> Signal {
747        x.combine_linear(y, 0.0, |x, y| x + y, |x, y| x + y)
748    }
749}
750
751/// Subtraction operator.
752#[derive(Default, Clone)]
753pub struct FrameSub<N: Size<f32>> {
754    _marker: PhantomData<N>,
755}
756
757impl<N: Size<f32>> FrameSub<N> {
758    pub fn new() -> FrameSub<N> {
759        FrameSub::default()
760    }
761}
762
763impl<N: Size<f32>> FrameBinop<N> for FrameSub<N> {
764    #[inline]
765    fn binop(&self, x: F32x, y: F32x) -> F32x {
766        x - y
767    }
768    #[inline]
769    fn frame(&self, x: &Frame<f32, N>, y: &Frame<f32, N>) -> Frame<f32, N> {
770        x - y
771    }
772    #[inline]
773    fn assign(&self, size: usize, x: &mut [f32], y: &[f32]) {
774        for (o, i) in x[..size].iter_mut().zip(y[..size].iter()) {
775            *o -= *i;
776        }
777    }
778    fn route(&self, x: Signal, y: Signal) -> Signal {
779        x.combine_linear(y, 0.0, |x, y| x - y, |x, y| x - y)
780    }
781}
782
783/// Multiplication operator.
784#[derive(Default, Clone)]
785pub struct FrameMul<N: Size<f32>> {
786    _marker: PhantomData<N>,
787}
788
789impl<N: Size<f32>> FrameMul<N> {
790    pub fn new() -> FrameMul<N> {
791        FrameMul::default()
792    }
793}
794
795impl<N: Size<f32>> FrameBinop<N> for FrameMul<N> {
796    #[inline]
797    fn binop(&self, x: F32x, y: F32x) -> F32x {
798        x * y
799    }
800    #[inline]
801    fn frame(&self, x: &Frame<f32, N>, y: &Frame<f32, N>) -> Frame<f32, N> {
802        x * y
803    }
804    #[inline]
805    fn assign(&self, size: usize, x: &mut [f32], y: &[f32]) {
806        for (o, i) in x[..size].iter_mut().zip(y[..size].iter()) {
807            *o *= *i;
808        }
809    }
810    fn route(&self, x: Signal, y: Signal) -> Signal {
811        match (x, y) {
812            (Signal::Value(vx), Signal::Value(vy)) => Signal::Value(vx * vy),
813            (Signal::Latency(lx), Signal::Latency(ly)) => Signal::Latency(min(lx, ly)),
814            (Signal::Response(_, lx), Signal::Response(_, ly)) => Signal::Latency(min(lx, ly)),
815            (Signal::Response(_, lx), Signal::Latency(ly)) => Signal::Latency(min(lx, ly)),
816            (Signal::Latency(lx), Signal::Response(_, ly)) => Signal::Latency(min(lx, ly)),
817            (Signal::Response(rx, lx), Signal::Value(vy)) => {
818                Signal::Response(rx * Complex64::new(vy, 0.0), lx)
819            }
820            (Signal::Value(vx), Signal::Response(ry, ly)) => {
821                Signal::Response(ry * Complex64::new(vx, 0.0), ly)
822            }
823            (Signal::Latency(lx), _) => Signal::Latency(lx),
824            (Signal::Response(_, lx), _) => Signal::Latency(lx),
825            (_, Signal::Latency(ly)) => Signal::Latency(ly),
826            (_, Signal::Response(_, ly)) => Signal::Latency(ly),
827            _ => Signal::Unknown,
828        }
829    }
830}
831
832#[derive(Clone)]
833pub struct Binop<B, X, Y>
834where
835    B: FrameBinop<X::Outputs>,
836    X: AudioNode,
837    Y: AudioNode<Outputs = X::Outputs>,
838    X::Inputs: Add<Y::Inputs>,
839    <X::Inputs as Add<Y::Inputs>>::Output: Size<f32>,
840{
841    x: X,
842    y: Y,
843    binop: B,
844}
845
846impl<B, X, Y> Binop<B, X, Y>
847where
848    B: FrameBinop<X::Outputs>,
849    X: AudioNode,
850    Y: AudioNode<Outputs = X::Outputs>,
851    X::Inputs: Add<Y::Inputs>,
852    <X::Inputs as Add<Y::Inputs>>::Output: Size<f32>,
853{
854    pub fn new(binop: B, x: X, y: Y) -> Self {
855        let mut node = Self { x, y, binop };
856        let hash = node.ping(true, AttoHash::new(Self::ID));
857        node.ping(false, hash);
858        node
859    }
860
861    /// Access the left node of the sum.
862    #[inline]
863    pub fn left_mut(&mut self) -> &mut X {
864        &mut self.x
865    }
866
867    /// Access the left node of the sum.
868    #[inline]
869    pub fn left(&self) -> &X {
870        &self.x
871    }
872
873    /// Access the right node of the sum.
874    #[inline]
875    pub fn right_mut(&mut self) -> &mut Y {
876        &mut self.y
877    }
878
879    /// Access the right node of the sum.
880    #[inline]
881    pub fn right(&self) -> &Y {
882        &self.y
883    }
884}
885
886impl<B, X, Y> AudioNode for Binop<B, X, Y>
887where
888    B: FrameBinop<X::Outputs>,
889    X: AudioNode,
890    Y: AudioNode<Outputs = X::Outputs>,
891    X::Inputs: Add<Y::Inputs>,
892    <X::Inputs as Add<Y::Inputs>>::Output: Size<f32>,
893{
894    const ID: u64 = 3;
895    type Inputs = Sum<X::Inputs, Y::Inputs>;
896    type Outputs = X::Outputs;
897
898    fn reset(&mut self) {
899        self.x.reset();
900        self.y.reset();
901    }
902
903    fn set_sample_rate(&mut self, sample_rate: f64) {
904        self.x.set_sample_rate(sample_rate);
905        self.y.set_sample_rate(sample_rate);
906    }
907
908    #[inline]
909    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
910        let input_x = &input[..X::Inputs::USIZE];
911        let input_y = &input[X::Inputs::USIZE..];
912        self.binop
913            .frame(&self.x.tick(input_x.into()), &self.y.tick(input_y.into()))
914    }
915
916    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
917        let mut buffer = BufferArray::<X::Outputs>::uninitialized();
918        self.x.process(
919            size,
920            &input.subset(0, self.x.inputs()),
921            &mut buffer.buffer_mut(),
922        );
923        self.y.process(
924            size,
925            &input.subset(self.x.inputs(), self.y.inputs()),
926            output,
927        );
928        for channel in 0..self.outputs() {
929            for i in 0..simd_items(size) {
930                output.set(
931                    channel,
932                    i,
933                    self.binop
934                        .binop(buffer.at(channel, i), output.at(channel, i)),
935                );
936            }
937        }
938    }
939
940    fn set(&mut self, setting: Setting) {
941        match setting.direction() {
942            Address::Left => self.x.set(setting.peel()),
943            Address::Right => self.y.set(setting.peel()),
944            _ => (),
945        }
946    }
947
948    #[inline]
949    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
950        self.y.ping(probe, self.x.ping(probe, hash.hash(Self::ID)))
951    }
952
953    fn allocate(&mut self) {
954        self.x.allocate();
955        self.y.allocate();
956    }
957
958    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
959        let mut signal_x = self
960            .x
961            .route(&SignalFrame::copy(input, 0, X::Inputs::USIZE), frequency);
962        let signal_y = self.y.route(
963            &SignalFrame::copy(input, X::Inputs::USIZE, Y::Inputs::USIZE),
964            frequency,
965        );
966        for i in 0..Self::Outputs::USIZE {
967            signal_x.set(i, self.binop.route(signal_x.at(i), signal_y.at(i)));
968        }
969        signal_x
970    }
971}
972
973/// Provides unary operator implementations to the `Unop` node.
974pub trait FrameUnop<N: Size<f32>>: Clone + Sync + Send {
975    /// Do unary op channelwise.
976    fn unop(&self, x: F32x) -> F32x;
977    /// Do unary op channelwise.
978    fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N>;
979    /// Do unary op in-place lengthwise.
980    fn assign(&self, size: usize, x: &mut [f32]);
981    /// Do unary op on signal.
982    fn route(&self, x: Signal) -> Signal;
983}
984
985/// Negation operator.
986#[derive(Default, Clone)]
987pub struct FrameNeg<N: Size<f32>> {
988    _marker: PhantomData<N>,
989}
990
991impl<N: Size<f32>> FrameNeg<N> {
992    pub fn new() -> FrameNeg<N> {
993        FrameNeg::default()
994    }
995}
996
997impl<N: Size<f32>> FrameUnop<N> for FrameNeg<N> {
998    #[inline]
999    fn unop(&self, x: F32x) -> F32x {
1000        -x
1001    }
1002    #[inline]
1003    fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N> {
1004        -x
1005    }
1006    #[inline]
1007    fn assign(&self, size: usize, x: &mut [f32]) {
1008        for o in x[..size].iter_mut() {
1009            *o = -*o;
1010        }
1011    }
1012    fn route(&self, x: Signal) -> Signal {
1013        match x {
1014            Signal::Value(vx) => Signal::Value(-vx),
1015            Signal::Response(rx, lx) => Signal::Response(-rx, lx),
1016            s => s,
1017        }
1018    }
1019}
1020
1021/// Identity op.
1022#[derive(Default, Clone)]
1023pub struct FrameId<N: Size<f32>> {
1024    _marker: PhantomData<N>,
1025}
1026
1027impl<N: Size<f32>> FrameId<N> {
1028    pub fn new() -> FrameId<N> {
1029        FrameId::default()
1030    }
1031}
1032
1033impl<N: Size<f32>> FrameUnop<N> for FrameId<N> {
1034    #[inline]
1035    fn unop(&self, x: F32x) -> F32x {
1036        x
1037    }
1038    #[inline]
1039    fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N> {
1040        x.clone()
1041    }
1042    #[inline]
1043    fn assign(&self, _size: usize, _x: &mut [f32]) {}
1044    fn route(&self, x: Signal) -> Signal {
1045        x
1046    }
1047}
1048
1049/// Add scalar op.
1050#[derive(Default, Clone)]
1051pub struct FrameAddScalar<N: Size<f32>> {
1052    scalar: f32,
1053    splat: F32x,
1054    _marker: PhantomData<N>,
1055}
1056
1057impl<N: Size<f32>> FrameAddScalar<N> {
1058    pub fn new(scalar: f32) -> Self {
1059        Self {
1060            scalar,
1061            splat: F32x::splat(scalar),
1062            _marker: PhantomData,
1063        }
1064    }
1065}
1066
1067impl<N: Size<f32>> FrameUnop<N> for FrameAddScalar<N> {
1068    #[inline]
1069    fn unop(&self, x: F32x) -> F32x {
1070        x + self.splat
1071    }
1072    #[inline]
1073    fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N> {
1074        x + Frame::splat(self.scalar)
1075    }
1076    #[inline]
1077    fn assign(&self, size: usize, x: &mut [f32]) {
1078        for o in x[..size].iter_mut() {
1079            *o += self.scalar;
1080        }
1081    }
1082    fn route(&self, x: Signal) -> Signal {
1083        match x {
1084            Signal::Value(vx) => Signal::Value(vx + self.scalar.to_f64()),
1085            s => s,
1086        }
1087    }
1088}
1089
1090/// Negate and add scalar op.
1091#[derive(Default, Clone)]
1092pub struct FrameNegAddScalar<N: Size<f32>> {
1093    scalar: f32,
1094    splat: F32x,
1095    _marker: PhantomData<N>,
1096}
1097
1098impl<N: Size<f32>> FrameNegAddScalar<N> {
1099    pub fn new(scalar: f32) -> Self {
1100        Self {
1101            scalar,
1102            splat: F32x::splat(scalar),
1103            _marker: PhantomData,
1104        }
1105    }
1106}
1107
1108impl<N: Size<f32>> FrameUnop<N> for FrameNegAddScalar<N> {
1109    #[inline]
1110    fn unop(&self, x: F32x) -> F32x {
1111        -x + self.splat
1112    }
1113    #[inline]
1114    fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N> {
1115        -x + Frame::splat(self.scalar)
1116    }
1117    #[inline]
1118    fn assign(&self, size: usize, x: &mut [f32]) {
1119        for o in x[..size].iter_mut() {
1120            *o = -*o + self.scalar;
1121        }
1122    }
1123    fn route(&self, x: Signal) -> Signal {
1124        match x {
1125            Signal::Value(vx) => Signal::Value(-vx + self.scalar.to_f64()),
1126            Signal::Response(rx, lx) => Signal::Response(-rx, lx),
1127            s => s,
1128        }
1129    }
1130}
1131
1132/// Multiply with scalar op.
1133#[derive(Default, Clone)]
1134pub struct FrameMulScalar<N: Size<f32>> {
1135    scalar: f32,
1136    splat: F32x,
1137    _marker: PhantomData<N>,
1138}
1139
1140impl<N: Size<f32>> FrameMulScalar<N> {
1141    pub fn new(scalar: f32) -> Self {
1142        Self {
1143            scalar,
1144            splat: F32x::splat(scalar),
1145            _marker: PhantomData,
1146        }
1147    }
1148}
1149
1150impl<N: Size<f32>> FrameUnop<N> for FrameMulScalar<N> {
1151    #[inline]
1152    fn unop(&self, x: F32x) -> F32x {
1153        x * self.splat
1154    }
1155    #[inline]
1156    fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N> {
1157        x * Frame::splat(self.scalar)
1158    }
1159    #[inline]
1160    fn assign(&self, size: usize, x: &mut [f32]) {
1161        for o in x[..size].iter_mut() {
1162            *o *= self.scalar;
1163        }
1164    }
1165    fn route(&self, x: Signal) -> Signal {
1166        match x {
1167            Signal::Response(vx, lx) => Signal::Response(vx * self.scalar.to_f64(), lx),
1168            Signal::Value(vx) => Signal::Value(vx * self.scalar.to_f64()),
1169            s => s,
1170        }
1171    }
1172}
1173
1174/// Apply a unary operation to output of contained node.
1175#[derive(Clone)]
1176pub struct Unop<X, U> {
1177    x: X,
1178    u: U,
1179}
1180
1181impl<X, U> Unop<X, U>
1182where
1183    X: AudioNode,
1184    U: FrameUnop<X::Outputs>,
1185{
1186    pub fn new(x: X, u: U) -> Self {
1187        let mut node = Unop { x, u };
1188        let hash = node.ping(true, AttoHash::new(Self::ID));
1189        node.ping(false, hash);
1190        node
1191    }
1192}
1193
1194impl<X, U> AudioNode for Unop<X, U>
1195where
1196    X: AudioNode,
1197    U: FrameUnop<X::Outputs>,
1198{
1199    const ID: u64 = 4;
1200    type Inputs = X::Inputs;
1201    type Outputs = X::Outputs;
1202
1203    fn reset(&mut self) {
1204        self.x.reset();
1205    }
1206
1207    fn set_sample_rate(&mut self, sample_rate: f64) {
1208        self.x.set_sample_rate(sample_rate);
1209    }
1210
1211    #[inline]
1212    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1213        self.u.frame(&self.x.tick(input))
1214    }
1215
1216    #[inline]
1217    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1218        self.x.process(size, input, output);
1219        for channel in 0..self.outputs() {
1220            for i in 0..simd_items(size) {
1221                output.set(channel, i, self.u.unop(output.at(channel, i)));
1222            }
1223        }
1224    }
1225
1226    fn set(&mut self, setting: Setting) {
1227        self.x.set(setting);
1228    }
1229
1230    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1231        self.x.ping(probe, hash.hash(Self::ID))
1232    }
1233
1234    fn allocate(&mut self) {
1235        self.x.allocate();
1236    }
1237
1238    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1239        let mut signal_x = self.x.route(input, frequency);
1240        for i in 0..Self::Outputs::USIZE {
1241            signal_x.set(i, self.u.route(signal_x.at(i)));
1242        }
1243        signal_x
1244    }
1245}
1246
1247/// Map any number of channels.
1248#[derive(Clone)]
1249pub struct Map<M, I, O> {
1250    f: M,
1251    routing: Routing,
1252    _marker: PhantomData<(I, O)>,
1253}
1254
1255impl<M, I, O> Map<M, I, O>
1256where
1257    M: Fn(&Frame<f32, I>) -> O + Clone + Send + Sync,
1258    I: Size<f32>,
1259    O: ConstantFrame<Sample = f32>,
1260    O::Size: Size<f32>,
1261{
1262    pub fn new(f: M, routing: Routing) -> Self {
1263        Self {
1264            f,
1265            routing,
1266            _marker: PhantomData,
1267        }
1268    }
1269}
1270
1271impl<M, I, O> AudioNode for Map<M, I, O>
1272where
1273    M: Fn(&Frame<f32, I>) -> O + Clone + Send + Sync,
1274    I: Size<f32>,
1275    O: ConstantFrame<Sample = f32>,
1276    O::Size: Size<f32>,
1277{
1278    const ID: u64 = 5;
1279    type Inputs = I;
1280    type Outputs = O::Size;
1281
1282    #[inline]
1283    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1284        (self.f)(input).frame()
1285    }
1286
1287    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
1288        self.routing.route(input, O::Size::USIZE)
1289    }
1290}
1291
1292/// Pipe the output of `X` to `Y`.
1293#[derive(Clone)]
1294pub struct Pipe<X, Y>
1295where
1296    X: AudioNode,
1297    Y: AudioNode<Inputs = X::Outputs>,
1298{
1299    x: X,
1300    y: Y,
1301}
1302
1303impl<X, Y> Pipe<X, Y>
1304where
1305    X: AudioNode,
1306    Y: AudioNode<Inputs = X::Outputs>,
1307{
1308    pub fn new(x: X, y: Y) -> Self {
1309        let mut node = Pipe { x, y };
1310        let hash = node.ping(true, AttoHash::new(Self::ID));
1311        node.ping(false, hash);
1312        node
1313    }
1314
1315    /// Access the left node of the pipe.
1316    #[inline]
1317    pub fn left_mut(&mut self) -> &mut X {
1318        &mut self.x
1319    }
1320
1321    /// Access the left node of the pipe.
1322    #[inline]
1323    pub fn left(&self) -> &X {
1324        &self.x
1325    }
1326
1327    /// Access the right node of the pipe.
1328    #[inline]
1329    pub fn right_mut(&mut self) -> &mut Y {
1330        &mut self.y
1331    }
1332
1333    /// Access the right node of the pipe.
1334    #[inline]
1335    pub fn right(&self) -> &Y {
1336        &self.y
1337    }
1338}
1339
1340impl<X, Y> AudioNode for Pipe<X, Y>
1341where
1342    X: AudioNode,
1343    Y: AudioNode<Inputs = X::Outputs>,
1344{
1345    const ID: u64 = 6;
1346    type Inputs = X::Inputs;
1347    type Outputs = Y::Outputs;
1348
1349    fn reset(&mut self) {
1350        self.x.reset();
1351        self.y.reset();
1352    }
1353
1354    fn set_sample_rate(&mut self, sample_rate: f64) {
1355        self.x.set_sample_rate(sample_rate);
1356        self.y.set_sample_rate(sample_rate);
1357    }
1358
1359    #[inline]
1360    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1361        self.y.tick(&self.x.tick(input))
1362    }
1363
1364    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1365        let mut buffer = BufferArray::<X::Outputs>::uninitialized();
1366        self.x.process(size, input, &mut buffer.buffer_mut());
1367        self.y.process(size, &buffer.buffer_ref(), output);
1368    }
1369
1370    fn set(&mut self, setting: Setting) {
1371        match setting.direction() {
1372            Address::Left => self.x.set(setting.peel()),
1373            Address::Right => self.y.set(setting.peel()),
1374            _ => (),
1375        }
1376    }
1377
1378    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1379        self.y.ping(probe, self.x.ping(probe, hash.hash(Self::ID)))
1380    }
1381
1382    fn allocate(&mut self) {
1383        self.x.allocate();
1384        self.y.allocate();
1385    }
1386
1387    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1388        self.y.route(&self.x.route(input, frequency), frequency)
1389    }
1390}
1391
1392/// Stack `X` and `Y` in parallel.
1393#[derive(Clone)]
1394pub struct Stack<X, Y> {
1395    x: X,
1396    y: Y,
1397}
1398
1399impl<X, Y> Stack<X, Y>
1400where
1401    X: AudioNode,
1402    Y: AudioNode,
1403    X::Inputs: Add<Y::Inputs>,
1404    X::Outputs: Add<Y::Outputs>,
1405    <X::Inputs as Add<Y::Inputs>>::Output: Size<f32>,
1406    <X::Outputs as Add<Y::Outputs>>::Output: Size<f32>,
1407{
1408    pub fn new(x: X, y: Y) -> Self {
1409        let mut node = Stack { x, y };
1410        let hash = node.ping(true, AttoHash::new(Self::ID));
1411        node.ping(false, hash);
1412        node
1413    }
1414
1415    /// Access the left node of the stack.
1416    #[inline]
1417    pub fn left_mut(&mut self) -> &mut X {
1418        &mut self.x
1419    }
1420
1421    /// Access the left node of the stack.
1422    #[inline]
1423    pub fn left(&self) -> &X {
1424        &self.x
1425    }
1426
1427    /// Access the right node of the stack.
1428    #[inline]
1429    pub fn right_mut(&mut self) -> &mut Y {
1430        &mut self.y
1431    }
1432
1433    /// Access the right node of the stack.
1434    #[inline]
1435    pub fn right(&self) -> &Y {
1436        &self.y
1437    }
1438}
1439
1440impl<X, Y> AudioNode for Stack<X, Y>
1441where
1442    X: AudioNode,
1443    Y: AudioNode,
1444    X::Inputs: Add<Y::Inputs>,
1445    X::Outputs: Add<Y::Outputs>,
1446    <X::Inputs as Add<Y::Inputs>>::Output: Size<f32>,
1447    <X::Outputs as Add<Y::Outputs>>::Output: Size<f32>,
1448{
1449    const ID: u64 = 7;
1450    type Inputs = Sum<X::Inputs, Y::Inputs>;
1451    type Outputs = Sum<X::Outputs, Y::Outputs>;
1452
1453    fn reset(&mut self) {
1454        self.x.reset();
1455        self.y.reset();
1456    }
1457
1458    fn set_sample_rate(&mut self, sample_rate: f64) {
1459        self.x.set_sample_rate(sample_rate);
1460        self.y.set_sample_rate(sample_rate);
1461    }
1462
1463    #[inline]
1464    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1465        let input_x = &input[..X::Inputs::USIZE];
1466        let input_y = &input[X::Inputs::USIZE..];
1467        let output_x = self.x.tick(input_x.into());
1468        let output_y = self.y.tick(input_y.into());
1469        Frame::generate(|i| {
1470            if i < X::Outputs::USIZE {
1471                output_x[i]
1472            } else {
1473                output_y[i - X::Outputs::USIZE]
1474            }
1475        })
1476    }
1477
1478    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1479        self.x.process(
1480            size,
1481            &input.subset(0, X::Inputs::USIZE),
1482            &mut output.subset(0, X::Outputs::USIZE),
1483        );
1484        self.y.process(
1485            size,
1486            &input.subset(X::Inputs::USIZE, Y::Inputs::USIZE),
1487            &mut output.subset(X::Outputs::USIZE, Y::Outputs::USIZE),
1488        );
1489    }
1490
1491    fn set(&mut self, setting: Setting) {
1492        match setting.direction() {
1493            Address::Left => self.x.set(setting.peel()),
1494            Address::Right => self.y.set(setting.peel()),
1495            _ => (),
1496        }
1497    }
1498
1499    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1500        self.y.ping(probe, self.x.ping(probe, hash.hash(Self::ID)))
1501    }
1502
1503    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1504        let mut signal_x = self
1505            .x
1506            .route(&SignalFrame::copy(input, 0, X::Inputs::USIZE), frequency);
1507        let signal_y = self.y.route(
1508            &SignalFrame::copy(input, X::Inputs::USIZE, Y::Inputs::USIZE),
1509            frequency,
1510        );
1511        signal_x.resize(self.outputs());
1512        for i in 0..Y::Outputs::USIZE {
1513            signal_x.set(X::Outputs::USIZE + i, signal_y.at(i));
1514        }
1515        signal_x
1516    }
1517
1518    fn allocate(&mut self) {
1519        self.x.allocate();
1520        self.y.allocate();
1521    }
1522}
1523
1524/// Send the same input to `X` and `Y`. Concatenate outputs.
1525#[derive(Clone)]
1526pub struct Branch<X, Y> {
1527    x: X,
1528    y: Y,
1529}
1530
1531impl<X, Y> Branch<X, Y>
1532where
1533    X: AudioNode,
1534    Y: AudioNode<Inputs = X::Inputs>,
1535    X::Outputs: Add<Y::Outputs>,
1536    <X::Outputs as Add<Y::Outputs>>::Output: Size<f32>,
1537{
1538    pub fn new(x: X, y: Y) -> Self {
1539        let mut node = Branch { x, y };
1540        let hash = node.ping(true, AttoHash::new(Self::ID));
1541        node.ping(false, hash);
1542        node
1543    }
1544
1545    /// Access the left node of the branch.
1546    #[inline]
1547    pub fn left_mut(&mut self) -> &mut X {
1548        &mut self.x
1549    }
1550
1551    /// Access the left node of the branch.
1552    #[inline]
1553    pub fn left(&self) -> &X {
1554        &self.x
1555    }
1556
1557    /// Access the right node of the branch.
1558    #[inline]
1559    pub fn right_mut(&mut self) -> &mut Y {
1560        &mut self.y
1561    }
1562
1563    /// Access the right node of the branch.
1564    #[inline]
1565    pub fn right(&self) -> &Y {
1566        &self.y
1567    }
1568}
1569
1570impl<X, Y> AudioNode for Branch<X, Y>
1571where
1572    X: AudioNode,
1573    Y: AudioNode<Inputs = X::Inputs>,
1574    X::Outputs: Add<Y::Outputs>,
1575    <X::Outputs as Add<Y::Outputs>>::Output: Size<f32>,
1576{
1577    const ID: u64 = 8;
1578    type Inputs = X::Inputs;
1579    type Outputs = Sum<X::Outputs, Y::Outputs>;
1580
1581    fn reset(&mut self) {
1582        self.x.reset();
1583        self.y.reset();
1584    }
1585
1586    fn set_sample_rate(&mut self, sample_rate: f64) {
1587        self.x.set_sample_rate(sample_rate);
1588        self.y.set_sample_rate(sample_rate);
1589    }
1590
1591    #[inline]
1592    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1593        let output_x = self.x.tick(input);
1594        let output_y = self.y.tick(input);
1595        Frame::generate(|i| {
1596            if i < X::Outputs::USIZE {
1597                output_x[i]
1598            } else {
1599                output_y[i - X::Outputs::USIZE]
1600            }
1601        })
1602    }
1603
1604    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1605        self.x
1606            .process(size, input, &mut output.subset(0, X::Outputs::USIZE));
1607        self.y.process(
1608            size,
1609            input,
1610            &mut output.subset(X::Outputs::USIZE, Y::Outputs::USIZE),
1611        );
1612    }
1613
1614    fn set(&mut self, setting: Setting) {
1615        match setting.direction() {
1616            Address::Left => self.x.set(setting.peel()),
1617            Address::Right => self.y.set(setting.peel()),
1618            _ => (),
1619        }
1620    }
1621
1622    #[inline]
1623    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1624        self.y.ping(probe, self.x.ping(probe, hash.hash(Self::ID)))
1625    }
1626
1627    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1628        let mut signal_x = self.x.route(input, frequency);
1629        let signal_y = self.y.route(input, frequency);
1630        signal_x.resize(self.outputs());
1631        for i in 0..Y::Outputs::USIZE {
1632            signal_x.set(X::Outputs::USIZE + i, signal_y.at(i));
1633        }
1634        signal_x
1635    }
1636
1637    fn allocate(&mut self) {
1638        self.x.allocate();
1639        self.y.allocate();
1640    }
1641}
1642
1643/// Mix together `X` and `Y` sourcing from the same inputs.
1644#[derive(Clone)]
1645pub struct Bus<X, Y>
1646where
1647    X: AudioNode,
1648    Y: AudioNode<Inputs = X::Inputs, Outputs = X::Outputs>,
1649{
1650    x: X,
1651    y: Y,
1652}
1653
1654impl<X, Y> Bus<X, Y>
1655where
1656    X: AudioNode,
1657    Y: AudioNode<Inputs = X::Inputs, Outputs = X::Outputs>,
1658{
1659    pub fn new(x: X, y: Y) -> Self {
1660        let mut node = Bus { x, y };
1661        let hash = node.ping(true, AttoHash::new(Self::ID));
1662        node.ping(false, hash);
1663        node
1664    }
1665
1666    /// Access the left node of the bus.
1667    #[inline]
1668    pub fn left_mut(&mut self) -> &mut X {
1669        &mut self.x
1670    }
1671
1672    /// Access the left node of the bus.
1673    #[inline]
1674    pub fn left(&self) -> &X {
1675        &self.x
1676    }
1677
1678    /// Access the right node of the bus.
1679    #[inline]
1680    pub fn right_mut(&mut self) -> &mut Y {
1681        &mut self.y
1682    }
1683
1684    /// Access the right node of the bus.
1685    #[inline]
1686    pub fn right(&self) -> &Y {
1687        &self.y
1688    }
1689}
1690
1691impl<X, Y> AudioNode for Bus<X, Y>
1692where
1693    X: AudioNode,
1694    Y: AudioNode<Inputs = X::Inputs, Outputs = X::Outputs>,
1695{
1696    const ID: u64 = 10;
1697    type Inputs = X::Inputs;
1698    type Outputs = X::Outputs;
1699
1700    fn reset(&mut self) {
1701        self.x.reset();
1702        self.y.reset();
1703    }
1704
1705    fn set_sample_rate(&mut self, sample_rate: f64) {
1706        self.x.set_sample_rate(sample_rate);
1707        self.y.set_sample_rate(sample_rate);
1708    }
1709
1710    #[inline]
1711    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1712        let output_x = self.x.tick(input);
1713        let output_y = self.y.tick(input);
1714        output_x + output_y
1715    }
1716
1717    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1718        let mut buffer = BufferArray::<X::Outputs>::uninitialized();
1719        self.x.process(size, input, output);
1720        self.y.process(size, input, &mut buffer.buffer_mut());
1721        for channel in 0..self.outputs() {
1722            for i in 0..simd_items(size) {
1723                output.add(channel, i, buffer.at(channel, i));
1724            }
1725        }
1726    }
1727
1728    fn set(&mut self, setting: Setting) {
1729        match setting.direction() {
1730            Address::Left => self.x.set(setting.peel()),
1731            Address::Right => self.y.set(setting.peel()),
1732            _ => (),
1733        }
1734    }
1735
1736    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1737        self.y.ping(probe, self.x.ping(probe, hash.hash(Self::ID)))
1738    }
1739
1740    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1741        let mut signal_x = self.x.route(input, frequency);
1742        let signal_y = self.y.route(input, frequency);
1743        for i in 0..Self::Outputs::USIZE {
1744            signal_x.set(
1745                i,
1746                signal_x
1747                    .at(i)
1748                    .combine_linear(signal_y.at(i), 0.0, |x, y| x + y, |x, y| x + y),
1749            );
1750        }
1751        signal_x
1752    }
1753
1754    fn allocate(&mut self) {
1755        self.x.allocate();
1756        self.y.allocate();
1757    }
1758}
1759
1760/// Pass through inputs without matching outputs.
1761/// Adjusts output arity to match input arity, adapting a filter to a pipeline.
1762#[derive(Clone)]
1763pub struct Thru<X: AudioNode> {
1764    x: X,
1765}
1766
1767impl<X: AudioNode> Thru<X> {
1768    pub fn new(x: X) -> Self {
1769        let mut node = Thru { x };
1770        let hash = node.ping(true, AttoHash::new(Self::ID));
1771        node.ping(false, hash);
1772        node
1773    }
1774}
1775
1776impl<X: AudioNode> AudioNode for Thru<X> {
1777    const ID: u64 = 12;
1778    type Inputs = X::Inputs;
1779    type Outputs = X::Inputs;
1780
1781    fn reset(&mut self) {
1782        self.x.reset();
1783    }
1784
1785    fn set_sample_rate(&mut self, sample_rate: f64) {
1786        self.x.set_sample_rate(sample_rate);
1787    }
1788
1789    #[inline]
1790    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1791        let output = self.x.tick(input);
1792        Frame::generate(|channel| {
1793            if channel < X::Outputs::USIZE {
1794                output[channel]
1795            } else {
1796                input[channel]
1797            }
1798        })
1799    }
1800    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1801        if X::Inputs::USIZE == 0 {
1802            // This is an empty node.
1803            return;
1804        }
1805        if X::Inputs::USIZE < X::Outputs::USIZE {
1806            // An intermediate buffer is only used in this "degenerate" case where
1807            // we are not passing through inputs - we are cutting out some of them.
1808            let mut buffer = BufferArray::<X::Outputs>::uninitialized();
1809            self.x.process(size, input, &mut buffer.buffer_mut());
1810            for channel in 0..X::Inputs::USIZE {
1811                for i in 0..simd_items(size) {
1812                    output.set(channel, i, buffer.at(channel, i));
1813                }
1814            }
1815        } else {
1816            self.x
1817                .process(size, input, &mut output.subset(0, X::Outputs::USIZE));
1818            for channel in X::Outputs::USIZE..X::Inputs::USIZE {
1819                for i in 0..simd_items(size) {
1820                    output.set(channel, i, input.at(channel, i));
1821                }
1822            }
1823        }
1824    }
1825
1826    fn set(&mut self, setting: Setting) {
1827        self.x.set(setting);
1828    }
1829
1830    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1831        self.x.ping(probe, hash.hash(Self::ID))
1832    }
1833
1834    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1835        let mut output = self.x.route(input, frequency);
1836        output.resize(self.outputs());
1837        for i in X::Outputs::USIZE..Self::Outputs::USIZE {
1838            output.set(i, input.at(i));
1839        }
1840        output
1841    }
1842
1843    fn allocate(&mut self) {
1844        self.x.allocate();
1845    }
1846}
1847
1848/// Mix together a bunch of similar nodes sourcing from the same inputs.
1849#[derive(Clone)]
1850pub struct MultiBus<N, X>
1851where
1852    N: Size<f32> + Size<X>,
1853    X: AudioNode,
1854{
1855    x: Frame<X, N>,
1856}
1857
1858impl<N, X> MultiBus<N, X>
1859where
1860    N: Size<f32> + Size<X>,
1861    X: AudioNode,
1862{
1863    pub fn new(x: Frame<X, N>) -> Self {
1864        let mut node = MultiBus { x };
1865        let hash = node.ping(true, AttoHash::new(Self::ID));
1866        node.ping(false, hash);
1867        node
1868    }
1869
1870    /// Access a contained node.
1871    #[inline]
1872    pub fn node_mut(&mut self, index: usize) -> &mut X {
1873        &mut self.x[index]
1874    }
1875
1876    /// Access a contained node.
1877    #[inline]
1878    pub fn node(&self, index: usize) -> &X {
1879        &self.x[index]
1880    }
1881}
1882
1883impl<N, X> AudioNode for MultiBus<N, X>
1884where
1885    N: Size<f32> + Size<X>,
1886    X: AudioNode,
1887{
1888    const ID: u64 = 28;
1889    type Inputs = X::Inputs;
1890    type Outputs = X::Outputs;
1891
1892    fn reset(&mut self) {
1893        self.x.iter_mut().for_each(|node| node.reset());
1894    }
1895
1896    fn set_sample_rate(&mut self, sample_rate: f64) {
1897        self.x
1898            .iter_mut()
1899            .for_each(|node| node.set_sample_rate(sample_rate));
1900    }
1901
1902    #[inline]
1903    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
1904        self.x
1905            .iter_mut()
1906            .fold(Frame::splat(0.0), |acc, x| acc + x.tick(input))
1907    }
1908
1909    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
1910        let mut buffer = BufferArray::<X::Outputs>::uninitialized();
1911        self.x[0].process(size, input, output);
1912        for i in 1..N::USIZE {
1913            self.x[i].process(size, input, &mut buffer.buffer_mut());
1914            for channel in 0..X::Outputs::USIZE {
1915                for j in 0..simd_items(size) {
1916                    output.add(channel, j, buffer.at(channel, j));
1917                }
1918            }
1919        }
1920    }
1921
1922    fn set(&mut self, setting: Setting) {
1923        if let Address::Index(index) = setting.direction() {
1924            self.x[index].set(setting.peel());
1925        }
1926    }
1927
1928    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
1929        let mut hash = hash.hash(Self::ID);
1930        for x in &mut self.x {
1931            hash = x.ping(probe, hash);
1932        }
1933        hash
1934    }
1935
1936    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
1937        let mut output = self.x[0].route(input, frequency);
1938        for i in 1..self.x.len() {
1939            let output_i = self.x[i].route(input, frequency);
1940            for channel in 0..Self::Outputs::USIZE {
1941                output.set(
1942                    channel,
1943                    output.at(channel).combine_linear(
1944                        output_i.at(channel),
1945                        0.0,
1946                        |x, y| x + y,
1947                        |x, y| x + y,
1948                    ),
1949                );
1950            }
1951        }
1952        output
1953    }
1954
1955    fn allocate(&mut self) {
1956        for x in &mut self.x {
1957            x.allocate();
1958        }
1959    }
1960}
1961
1962/// Stack a bunch of similar nodes in parallel.
1963#[derive(Clone)]
1964pub struct MultiStack<N, X>
1965where
1966    N: Size<f32> + Size<X>,
1967    X: AudioNode,
1968    X::Inputs: Size<f32> + Mul<N>,
1969    X::Outputs: Size<f32> + Mul<N>,
1970    <X::Inputs as Mul<N>>::Output: Size<f32>,
1971    <X::Outputs as Mul<N>>::Output: Size<f32>,
1972{
1973    _marker: PhantomData<N>,
1974    x: Frame<X, N>,
1975}
1976
1977impl<N, X> MultiStack<N, X>
1978where
1979    N: Size<f32> + Size<X>,
1980    X: AudioNode,
1981    X::Inputs: Size<f32> + Mul<N>,
1982    X::Outputs: Size<f32> + Mul<N>,
1983    <X::Inputs as Mul<N>>::Output: Size<f32>,
1984    <X::Outputs as Mul<N>>::Output: Size<f32>,
1985{
1986    pub fn new(x: Frame<X, N>) -> Self {
1987        let mut node = MultiStack {
1988            _marker: PhantomData,
1989            x,
1990        };
1991        let hash = node.ping(true, AttoHash::new(Self::ID));
1992        node.ping(false, hash);
1993        node
1994    }
1995
1996    /// Access a contained node.
1997    #[inline]
1998    pub fn node_mut(&mut self, index: usize) -> &mut X {
1999        &mut self.x[index]
2000    }
2001
2002    /// Access a contained node.
2003    #[inline]
2004    pub fn node(&self, index: usize) -> &X {
2005        &self.x[index]
2006    }
2007}
2008
2009impl<N, X> AudioNode for MultiStack<N, X>
2010where
2011    N: Size<f32> + Size<X>,
2012    X: AudioNode,
2013    X::Inputs: Size<f32> + Mul<N>,
2014    X::Outputs: Size<f32> + Mul<N>,
2015    <X::Inputs as Mul<N>>::Output: Size<f32>,
2016    <X::Outputs as Mul<N>>::Output: Size<f32>,
2017{
2018    const ID: u64 = 30;
2019    type Inputs = Prod<X::Inputs, N>;
2020    type Outputs = Prod<X::Outputs, N>;
2021
2022    fn reset(&mut self) {
2023        self.x.iter_mut().for_each(|node| node.reset());
2024    }
2025
2026    fn set_sample_rate(&mut self, sample_rate: f64) {
2027        self.x
2028            .iter_mut()
2029            .for_each(|node| node.set_sample_rate(sample_rate));
2030    }
2031
2032    #[inline]
2033    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
2034        let mut output: Frame<f32, Self::Outputs> = Frame::splat(0.0);
2035        for (i, node) in self.x.iter_mut().enumerate() {
2036            let node_input = &input[i * X::Inputs::USIZE..(i + 1) * X::Inputs::USIZE];
2037            let node_output = node.tick(node_input.into());
2038            output[i * X::Outputs::USIZE..(i + 1) * X::Outputs::USIZE]
2039                .copy_from_slice(node_output.as_slice());
2040        }
2041        output
2042    }
2043
2044    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
2045        let mut in_channel = 0;
2046        let mut out_channel = 0;
2047        for i in 0..N::USIZE {
2048            self.x[i].process(
2049                size,
2050                &input.subset(in_channel, X::Inputs::USIZE),
2051                &mut output.subset(out_channel, X::Outputs::USIZE),
2052            );
2053            in_channel += X::Inputs::USIZE;
2054            out_channel += X::Outputs::USIZE;
2055        }
2056    }
2057
2058    fn set(&mut self, setting: Setting) {
2059        if let Address::Index(index) = setting.direction() {
2060            self.x[index].set(setting.peel());
2061        }
2062    }
2063
2064    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
2065        let mut hash = hash.hash(Self::ID);
2066        for x in self.x.iter_mut() {
2067            hash = x.ping(probe, hash);
2068        }
2069        hash
2070    }
2071
2072    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
2073        if self.x.is_empty() {
2074            return SignalFrame::new(self.outputs());
2075        }
2076        let mut output = self.x[0].route(input, frequency);
2077        output.resize(self.outputs());
2078        for i in 1..N::USIZE {
2079            let output_i = self.x[i].route(
2080                &SignalFrame::copy(input, i * X::Inputs::USIZE, X::Inputs::USIZE),
2081                frequency,
2082            );
2083            for channel in 0..X::Outputs::USIZE {
2084                output.set(channel + i * X::Outputs::USIZE, output_i.at(channel));
2085            }
2086        }
2087        output
2088    }
2089
2090    fn allocate(&mut self) {
2091        for x in &mut self.x {
2092            x.allocate();
2093        }
2094    }
2095}
2096
2097/// Combine outputs of a bunch of similar nodes with a binary operation.
2098/// Inputs are disjoint.
2099/// Outputs are combined channel-wise.
2100#[derive(Clone)]
2101pub struct Reduce<N, X, B>
2102where
2103    N: Size<f32> + Size<X>,
2104    X: AudioNode,
2105    X::Inputs: Mul<N>,
2106    <X::Inputs as Mul<N>>::Output: Size<f32>,
2107    B: FrameBinop<X::Outputs>,
2108{
2109    x: Frame<X, N>,
2110    b: B,
2111}
2112
2113impl<N, X, B> Reduce<N, X, B>
2114where
2115    N: Size<f32> + Size<X>,
2116    X: AudioNode,
2117    X::Inputs: Mul<N>,
2118    <X::Inputs as Mul<N>>::Output: Size<f32>,
2119    B: FrameBinop<X::Outputs>,
2120{
2121    pub fn new(x: Frame<X, N>, b: B) -> Self {
2122        let mut node = Reduce { x, b };
2123        let hash = node.ping(true, AttoHash::new(Self::ID));
2124        node.ping(false, hash);
2125        node
2126    }
2127
2128    /// Access a contained node.
2129    #[inline]
2130    pub fn node_mut(&mut self, index: usize) -> &mut X {
2131        &mut self.x[index]
2132    }
2133
2134    /// Access a contained node.
2135    #[inline]
2136    pub fn node(&self, index: usize) -> &X {
2137        &self.x[index]
2138    }
2139}
2140
2141impl<N, X, B> AudioNode for Reduce<N, X, B>
2142where
2143    N: Size<f32> + Size<X>,
2144    X: AudioNode,
2145    X::Inputs: Mul<N>,
2146    <X::Inputs as Mul<N>>::Output: Size<f32>,
2147    B: FrameBinop<X::Outputs>,
2148{
2149    const ID: u64 = 32;
2150    type Inputs = Prod<X::Inputs, N>;
2151    type Outputs = X::Outputs;
2152
2153    fn reset(&mut self) {
2154        self.x.iter_mut().for_each(|node| node.reset());
2155    }
2156
2157    fn set_sample_rate(&mut self, sample_rate: f64) {
2158        self.x
2159            .iter_mut()
2160            .for_each(|node| node.set_sample_rate(sample_rate));
2161    }
2162
2163    #[inline]
2164    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
2165        let mut output: Frame<f32, Self::Outputs> = Frame::splat(0.0);
2166        for (i, node) in self.x.iter_mut().enumerate() {
2167            let node_input = &input[i * X::Inputs::USIZE..(i + 1) * X::Inputs::USIZE];
2168            let node_output = node.tick(node_input.into());
2169            if i > 0 {
2170                output = self.b.frame(&output, &node_output);
2171            } else {
2172                output = node_output;
2173            }
2174        }
2175        output
2176    }
2177    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
2178        let mut buffer = BufferArray::<X::Outputs>::uninitialized();
2179        self.x[0].process(size, &input.subset(0, X::Inputs::USIZE), output);
2180        let mut in_channel = X::Inputs::USIZE;
2181        for i in 1..N::USIZE {
2182            self.x[i].process(
2183                size,
2184                &input.subset(in_channel, X::Inputs::USIZE),
2185                &mut buffer.buffer_mut(),
2186            );
2187            in_channel += X::Inputs::USIZE;
2188            for channel in 0..X::Outputs::USIZE {
2189                for j in 0..simd_items(size) {
2190                    output.set(
2191                        channel,
2192                        j,
2193                        self.b.binop(output.at(channel, j), buffer.at(channel, j)),
2194                    );
2195                }
2196            }
2197        }
2198    }
2199
2200    fn set(&mut self, setting: Setting) {
2201        if let Address::Index(index) = setting.direction() {
2202            self.x[index].set(setting.peel());
2203        }
2204    }
2205
2206    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
2207        let mut hash = hash.hash(Self::ID);
2208        for x in self.x.iter_mut() {
2209            hash = x.ping(probe, hash);
2210        }
2211        hash
2212    }
2213
2214    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
2215        let mut output = self.x[0].route(input, frequency);
2216        for j in 1..self.x.len() {
2217            let output_j = self.x[j].route(
2218                &SignalFrame::copy(input, j * X::Inputs::USIZE, X::Inputs::USIZE),
2219                frequency,
2220            );
2221            for i in 0..Self::Outputs::USIZE {
2222                output.set(i, self.b.route(output.at(i), output_j.at(i)));
2223            }
2224        }
2225        output
2226    }
2227
2228    fn allocate(&mut self) {
2229        for x in &mut self.x {
2230            x.allocate();
2231        }
2232    }
2233}
2234
2235/// Branch into a bunch of similar nodes in parallel.
2236#[derive(Clone)]
2237pub struct MultiBranch<N, X>
2238where
2239    N: Size<f32> + Size<X>,
2240    X: AudioNode,
2241    X::Outputs: Mul<N>,
2242    <X::Outputs as Mul<N>>::Output: Size<f32>,
2243{
2244    x: Frame<X, N>,
2245}
2246
2247impl<N, X> MultiBranch<N, X>
2248where
2249    N: Size<f32> + Size<X>,
2250    X: AudioNode,
2251    X::Outputs: Mul<N>,
2252    <X::Outputs as Mul<N>>::Output: Size<f32>,
2253{
2254    pub fn new(x: Frame<X, N>) -> Self {
2255        let mut node = MultiBranch { x };
2256        let hash = node.ping(true, AttoHash::new(Self::ID));
2257        node.ping(false, hash);
2258        node
2259    }
2260
2261    /// Access a contained node.
2262    #[inline]
2263    pub fn node_mut(&mut self, index: usize) -> &mut X {
2264        &mut self.x[index]
2265    }
2266
2267    /// Access a contained node.
2268    #[inline]
2269    pub fn node(&self, index: usize) -> &X {
2270        &self.x[index]
2271    }
2272}
2273
2274impl<N, X> AudioNode for MultiBranch<N, X>
2275where
2276    N: Size<f32> + Size<X>,
2277    X: AudioNode,
2278    X::Outputs: Mul<N>,
2279    <X::Outputs as Mul<N>>::Output: Size<f32>,
2280{
2281    const ID: u64 = 33;
2282    type Inputs = X::Inputs;
2283    type Outputs = Prod<X::Outputs, N>;
2284
2285    fn reset(&mut self) {
2286        self.x.iter_mut().for_each(|node| node.reset());
2287    }
2288
2289    fn set_sample_rate(&mut self, sample_rate: f64) {
2290        self.x
2291            .iter_mut()
2292            .for_each(|node| node.set_sample_rate(sample_rate));
2293    }
2294
2295    #[inline]
2296    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
2297        let mut output: Frame<f32, Self::Outputs> = Frame::splat(0.0);
2298        for (i, node) in self.x.iter_mut().enumerate() {
2299            let node_output = node.tick(input);
2300            output[i * X::Outputs::USIZE..(i + 1) * X::Outputs::USIZE]
2301                .copy_from_slice(node_output.as_slice());
2302        }
2303        output
2304    }
2305
2306    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
2307        let mut out_channel = 0;
2308        for i in 0..N::USIZE {
2309            self.x[i].process(
2310                size,
2311                input,
2312                &mut output.subset(out_channel, X::Outputs::USIZE),
2313            );
2314            out_channel += X::Outputs::USIZE;
2315        }
2316    }
2317
2318    fn set(&mut self, setting: Setting) {
2319        if let Address::Index(index) = setting.direction() {
2320            self.x[index].set(setting.peel());
2321        }
2322    }
2323
2324    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
2325        let mut hash = hash.hash(Self::ID);
2326        for x in self.x.iter_mut() {
2327            hash = x.ping(probe, hash);
2328        }
2329        hash
2330    }
2331
2332    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
2333        if self.x.is_empty() {
2334            return SignalFrame::new(self.outputs());
2335        }
2336        let mut output = self.x[0].route(input, frequency);
2337        output.resize(self.outputs());
2338        for i in 1..N::USIZE {
2339            let output_i = self.x[i].route(input, frequency);
2340            for j in 0..X::Outputs::USIZE {
2341                output.set(i * X::Outputs::USIZE + j, output_i.at(j));
2342            }
2343        }
2344        output
2345    }
2346
2347    fn allocate(&mut self) {
2348        for x in &mut self.x {
2349            x.allocate();
2350        }
2351    }
2352}
2353
2354/// A pipeline of multiple nodes.
2355#[derive(Clone)]
2356pub struct Chain<N, X>
2357where
2358    N: Size<f32> + Size<X>,
2359    X: AudioNode,
2360{
2361    x: Frame<X, N>,
2362}
2363
2364impl<N, X> Chain<N, X>
2365where
2366    N: Size<f32> + Size<X>,
2367    X: AudioNode,
2368{
2369    pub fn new(x: Frame<X, N>) -> Self {
2370        // TODO. We'd like to require statically that X::Inputs equals X::Outputs
2371        // but I don't know how to write such a trait bound.
2372        assert_eq!(x[0].inputs(), x[0].outputs());
2373        let mut node = Chain { x };
2374        let hash = node.ping(true, AttoHash::new(Self::ID));
2375        node.ping(false, hash);
2376        node
2377    }
2378
2379    /// Access a contained node.
2380    #[inline]
2381    pub fn node_mut(&mut self, index: usize) -> &mut X {
2382        &mut self.x[index]
2383    }
2384
2385    /// Access a contained node.
2386    #[inline]
2387    pub fn node(&self, index: usize) -> &X {
2388        &self.x[index]
2389    }
2390}
2391
2392impl<N, X> AudioNode for Chain<N, X>
2393where
2394    N: Size<f32> + Size<X>,
2395    X: AudioNode,
2396{
2397    const ID: u64 = 32;
2398    type Inputs = X::Inputs;
2399    type Outputs = X::Outputs;
2400
2401    fn reset(&mut self) {
2402        self.x.iter_mut().for_each(|node| node.reset());
2403    }
2404
2405    fn set_sample_rate(&mut self, sample_rate: f64) {
2406        self.x
2407            .iter_mut()
2408            .for_each(|node| node.set_sample_rate(sample_rate));
2409    }
2410
2411    #[inline]
2412    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
2413        let mut output = self.x[0].tick(input);
2414        for i in 1..N::USIZE {
2415            output = self.x[i].tick(&Frame::generate(|i| output[i]));
2416        }
2417        output
2418    }
2419
2420    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
2421        let mut buffer = BufferArray::<X::Outputs>::uninitialized();
2422        if N::USIZE & 1 > 0 {
2423            self.x[0].process(size, input, output);
2424        } else {
2425            self.x[0].process(size, input, &mut buffer.buffer_mut());
2426        }
2427        for i in 1..N::USIZE {
2428            if (N::USIZE ^ i) & 1 > 0 {
2429                self.x[i].process(size, &buffer.buffer_ref(), output);
2430            } else {
2431                self.x[i].process(size, &output.buffer_ref(), &mut buffer.buffer_mut());
2432            }
2433        }
2434    }
2435
2436    fn set(&mut self, setting: Setting) {
2437        if let Address::Index(index) = setting.direction() {
2438            self.x[index].set(setting.peel());
2439        }
2440    }
2441
2442    fn ping(&mut self, probe: bool, hash: AttoHash) -> AttoHash {
2443        let mut hash = hash.hash(Self::ID);
2444        for x in self.x.iter_mut() {
2445            hash = x.ping(probe, hash);
2446        }
2447        hash
2448    }
2449
2450    fn allocate(&mut self) {
2451        for x in &mut self.x {
2452            x.allocate();
2453        }
2454    }
2455
2456    fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
2457        let mut output = self.x[0].route(input, frequency);
2458        for i in 1..self.x.len() {
2459            output = self.x[i].route(&output, frequency);
2460        }
2461        output
2462    }
2463}
2464
2465/// Reverse channel order.
2466#[derive(Default, Clone)]
2467pub struct Reverse<N> {
2468    _marker: PhantomData<N>,
2469}
2470
2471impl<N: Size<f32>> Reverse<N> {
2472    pub fn new() -> Self {
2473        Reverse::default()
2474    }
2475}
2476
2477impl<N: Size<f32>> AudioNode for Reverse<N> {
2478    const ID: u64 = 45;
2479    type Inputs = N;
2480    type Outputs = N;
2481
2482    #[inline]
2483    fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
2484        Frame::generate(|i| input[N::USIZE - 1 - i])
2485    }
2486    fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
2487        for channel in 0..N::USIZE {
2488            for i in 0..simd_items(size) {
2489                output.set(channel, i, input.at(N::USIZE - 1 - channel, i));
2490            }
2491        }
2492    }
2493    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
2494        Routing::Reverse.route(input, N::USIZE)
2495    }
2496}
2497
2498/// `N`-channel impulse. First sample on each channel is one, the rest are zero.
2499#[derive(Default, Clone)]
2500pub struct Impulse<N: Size<f32>> {
2501    value: f32,
2502    _marker: PhantomData<N>,
2503}
2504
2505impl<N: Size<f32>> Impulse<N> {
2506    pub fn new() -> Self {
2507        Self {
2508            value: 1.0,
2509            _marker: PhantomData,
2510        }
2511    }
2512}
2513
2514impl<N: Size<f32>> AudioNode for Impulse<N> {
2515    const ID: u64 = 81;
2516    type Inputs = U0;
2517    type Outputs = N;
2518
2519    fn reset(&mut self) {
2520        self.value = 1.0;
2521    }
2522
2523    #[inline]
2524    fn tick(&mut self, _input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
2525        let output = Frame::splat(self.value);
2526        self.value = 0.0;
2527        output
2528    }
2529    fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
2530        Routing::Generator(0.0).route(input, N::USIZE)
2531    }
2532}