1use 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
14pub trait Size<T>: ArrayLength + Sync + Send + Clone {}
16
17impl<T, A: ArrayLength + Sync + Send + Clone> Size<T> for A {}
18
19pub type Frame<T, Size> = NumericArray<T, Size>;
22
23pub trait AudioNode: Clone + Sync + Send {
36 const ID: u64;
38 type Inputs: Size<f32>;
40 type Outputs: Size<f32>;
42
43 #[allow(unused_variables)]
58 fn reset(&mut self) {
59 }
61
62 #[allow(unused_variables)]
74 fn set_sample_rate(&mut self, sample_rate: f64) {
75 }
77
78 fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs>;
86
87 fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
90 debug_assert!(size <= MAX_BUFFER_SIZE);
92 debug_assert!(input.channels() == self.inputs());
93 debug_assert!(output.channels() == self.outputs());
94
95 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 #[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 #[allow(unused_variables)]
134 fn set(&mut self, setting: Setting) {}
135
136 #[allow(unused_variables)]
140 fn set_hash(&mut self, hash: u64) {
141 }
144
145 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 fn allocate(&mut self) {
169 }
171
172 #[allow(unused_variables)]
176 fn route(&mut self, input: &SignalFrame, frequency: f64) -> SignalFrame {
177 SignalFrame::new(self.outputs())
179 }
180
181 #[inline(always)]
191 fn inputs(&self) -> usize {
192 Self::Inputs::USIZE
193 }
194
195 #[inline(always)]
203 fn outputs(&self) -> usize {
204 Self::Outputs::USIZE
205 }
206
207 #[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 #[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 #[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 #[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 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 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 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 let response = self.route(&input, 1.0);
341 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#[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#[derive(Default, Clone)]
389pub struct Pass {}
390
391impl Pass {
392 pub fn new() -> Self {
393 Pass::default()
394 }
395}
396
397impl 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#[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#[derive(Clone)]
448pub struct Constant<N: Size<f32>> {
449 output: Frame<f32, N>,
450}
451
452impl<N: Size<f32>> Constant<N> {
453 pub fn new(output: Frame<f32, N>) -> Self {
455 Constant { output }
456 }
457 #[inline]
459 pub fn set_value(&mut self, output: Frame<f32, N>) {
460 self.output = output;
461 }
462 #[inline]
464 pub fn value(&self) -> Frame<f32, N> {
465 self.output.clone()
466 }
467 #[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#[derive(Clone)]
510pub struct Split<N> {
511 _marker: PhantomData<N>,
512}
513
514impl<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#[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#[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#[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
707pub trait FrameBinop<N: Size<f32>>: Clone + Sync + Send {
709 fn binop(&self, x: F32x, y: F32x) -> F32x;
711 fn frame(&self, x: &Frame<f32, N>, y: &Frame<f32, N>) -> Frame<f32, N>;
713 fn assign(&self, size: usize, x: &mut [f32], y: &[f32]);
715 fn route(&self, x: Signal, y: Signal) -> Signal;
717}
718
719#[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#[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#[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 #[inline]
863 pub fn left_mut(&mut self) -> &mut X {
864 &mut self.x
865 }
866
867 #[inline]
869 pub fn left(&self) -> &X {
870 &self.x
871 }
872
873 #[inline]
875 pub fn right_mut(&mut self) -> &mut Y {
876 &mut self.y
877 }
878
879 #[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
973pub trait FrameUnop<N: Size<f32>>: Clone + Sync + Send {
975 fn unop(&self, x: F32x) -> F32x;
977 fn frame(&self, x: &Frame<f32, N>) -> Frame<f32, N>;
979 fn assign(&self, size: usize, x: &mut [f32]);
981 fn route(&self, x: Signal) -> Signal;
983}
984
985#[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#[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#[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#[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#[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#[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#[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#[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 #[inline]
1317 pub fn left_mut(&mut self) -> &mut X {
1318 &mut self.x
1319 }
1320
1321 #[inline]
1323 pub fn left(&self) -> &X {
1324 &self.x
1325 }
1326
1327 #[inline]
1329 pub fn right_mut(&mut self) -> &mut Y {
1330 &mut self.y
1331 }
1332
1333 #[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#[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 #[inline]
1417 pub fn left_mut(&mut self) -> &mut X {
1418 &mut self.x
1419 }
1420
1421 #[inline]
1423 pub fn left(&self) -> &X {
1424 &self.x
1425 }
1426
1427 #[inline]
1429 pub fn right_mut(&mut self) -> &mut Y {
1430 &mut self.y
1431 }
1432
1433 #[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#[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 #[inline]
1547 pub fn left_mut(&mut self) -> &mut X {
1548 &mut self.x
1549 }
1550
1551 #[inline]
1553 pub fn left(&self) -> &X {
1554 &self.x
1555 }
1556
1557 #[inline]
1559 pub fn right_mut(&mut self) -> &mut Y {
1560 &mut self.y
1561 }
1562
1563 #[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#[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 #[inline]
1668 pub fn left_mut(&mut self) -> &mut X {
1669 &mut self.x
1670 }
1671
1672 #[inline]
1674 pub fn left(&self) -> &X {
1675 &self.x
1676 }
1677
1678 #[inline]
1680 pub fn right_mut(&mut self) -> &mut Y {
1681 &mut self.y
1682 }
1683
1684 #[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#[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 return;
1804 }
1805 if X::Inputs::USIZE < X::Outputs::USIZE {
1806 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#[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 #[inline]
1872 pub fn node_mut(&mut self, index: usize) -> &mut X {
1873 &mut self.x[index]
1874 }
1875
1876 #[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#[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 #[inline]
1998 pub fn node_mut(&mut self, index: usize) -> &mut X {
1999 &mut self.x[index]
2000 }
2001
2002 #[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#[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 #[inline]
2130 pub fn node_mut(&mut self, index: usize) -> &mut X {
2131 &mut self.x[index]
2132 }
2133
2134 #[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#[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 #[inline]
2263 pub fn node_mut(&mut self, index: usize) -> &mut X {
2264 &mut self.x[index]
2265 }
2266
2267 #[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#[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 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 #[inline]
2381 pub fn node_mut(&mut self, index: usize) -> &mut X {
2382 &mut self.x[index]
2383 }
2384
2385 #[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#[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#[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}