1use crate::prelude::*;
2
3macro_rules! tertiary {
4 ($(#[doc = $doc:literal])* $id:literal, $name:ident, | $a:ident, $b:ident, $c:ident | $value:expr) => {
5 #[derive(Debug, Clone, Copy, Default, Node)]
6 #[node(id = $id, module = "tertiary")]
7 #[input($a)]
8 #[input($b)]
9 #[input($c)]
10 $(#[doc = $doc])*
11 pub struct $name;
12
13 impl $name {
14 fn render(&mut self, a: Input, b: Input, c: Input, output: &mut [Sample]) {
15 match (a, b, c) {
16 (Input::Constant($a), Input::Constant($b), Input::Constant($c)) => {
17 let v = $value;
18 for sample in output.iter_mut() {
19 *sample = v;
20 }
21 }
22 (Input::Constant($a), Input::Constant($b), Input::Buffer(c)) => {
23 for (sample, $c) in output.iter_mut().zip(c.iter().copied()) {
24 *sample = $value;
25 }
26 }
27 (Input::Constant($a), Input::Buffer(b), Input::Constant($c)) => {
28 for (sample, $b) in output.iter_mut().zip(b.iter().copied()) {
29 *sample = $value;
30 }
31 }
32 (Input::Constant($a), Input::Buffer(b), Input::Buffer(c)) => {
33 for (sample, ($b, $c)) in output.iter_mut().zip(b.iter().copied().zip(c.iter().copied())) {
34 *sample = $value;
35 }
36 }
37 (Input::Buffer(a), Input::Constant($b), Input::Constant($c)) => {
38 for (sample, $a) in output.iter_mut().zip(a.iter().copied()) {
39 *sample = $value;
40 }
41 }
42 (Input::Buffer(a), Input::Constant($b), Input::Buffer(c)) => {
43 for (sample, ($a, $c)) in output.iter_mut().zip(a.iter().copied().zip(c.iter().copied())) {
44 *sample = $value;
45 }
46 }
47 (Input::Buffer(a), Input::Buffer(b), Input::Constant($c)) => {
48 for (sample, ($a, $b)) in output.iter_mut().zip(a.iter().copied().zip(b.iter().copied())) {
49 *sample = $value;
50 }
51 }
52 (Input::Buffer(a), Input::Buffer(b), Input::Buffer(c)) => {
53 unsafe {
54 unsafe_assert!(a.len() == b.len());
55 unsafe_assert!(a.len() == c.len());
56 }
57
58 let a = a.iter().copied();
59 let b = b.iter().copied();
60 let c = c.iter().copied();
61
62 for (sample, ($a, ($b, $c))) in output.iter_mut().zip(a.zip(b.zip(c))) {
63 *sample = $value;
64 }
65 }
66 }
67 }
68 }
69 };
70}
71
72tertiary!(
73 75,
76 AddMul,
77 |input, add, mul| (input + add) * mul
78);
79tertiary!(
80 76,
88 Clamp,
89 |input, min, max| {
90 if min <= max {
91 input.clamp(min, max)
92 } else {
93 f64::NAN
94 }
95 }
96);
97tertiary!(
98 77,
101 MulAdd,
102 |input, mul, add| input.mul_add(mul, add)
103);
104tertiary!(
105 78,
108 Select,
109 |cond, positive, negative| if cond.is_sign_positive() {
110 positive
111 } else {
112 negative
113 }
114);