1use crate::types::{q15, DspSample};
7
8pub trait DspNode<T: Copy> {
10 fn process_sample(&mut self, input: T) -> T;
12
13 #[inline]
15 fn process_block(&mut self, in_buf: &[T], out_buf: &mut [T]) {
16 let len = in_buf.len().min(out_buf.len());
17 for i in 0..len {
18 out_buf[i] = self.process_sample(in_buf[i]);
19 }
20 }
21
22 #[inline]
24 fn process_in_place(&mut self, buf: &mut [T]) {
25 for sample in buf.iter_mut() {
26 *sample = self.process_sample(*sample);
27 }
28 }
29
30 #[inline]
32 fn then<Next>(self, next: Next) -> Chain<Self, Next>
33 where
34 Self: Sized,
35 Next: DspNode<T>,
36 {
37 Chain {
38 first: self,
39 second: next,
40 }
41 }
42}
43
44#[derive(Debug, Clone, Copy, Default)]
46pub struct Chain<A, B> {
47 pub first: A,
48 pub second: B,
49}
50
51impl<T: Copy, A: DspNode<T>, B: DspNode<T>> DspNode<T> for Chain<A, B> {
52 #[inline(always)]
53 fn process_sample(&mut self, input: T) -> T {
54 let intermediate = self.first.process_sample(input);
55 self.second.process_sample(intermediate)
56 }
57}
58
59#[derive(Debug, Clone, Copy, Default)]
61pub struct Gain<T> {
62 pub gain: T,
63}
64
65impl<T> Gain<T> {
66 #[inline(always)]
67 pub const fn new(gain: T) -> Self {
68 Self { gain }
69 }
70}
71
72impl<T: DspSample> DspNode<T> for Gain<T> {
73 #[inline(always)]
74 fn process_sample(&mut self, input: T) -> T {
75 input.sat_mul(self.gain)
76 }
77}
78
79impl DspNode<i16> for Gain<i16> {
80 #[inline(always)]
81 fn process_sample(&mut self, input: i16) -> i16 {
82 crate::types::q15_mult(input, self.gain)
83 }
84}
85
86impl DspNode<i32> for Gain<i32> {
87 #[inline(always)]
88 fn process_sample(&mut self, input: i32) -> i32 {
89 let prod = (input as i64 * self.gain as i64) >> 31;
90 prod.clamp(i32::MIN as i64, i32::MAX as i64) as i32
91 }
92}
93
94#[derive(Debug, Clone, Copy, Default)]
96pub struct Limiter<T> {
97 pub min: T,
98 pub max: T,
99}
100
101impl<T> Limiter<T> {
102 #[inline(always)]
103 pub const fn new(min: T, max: T) -> Self {
104 Self { min, max }
105 }
106}
107
108impl<T: PartialOrd + Copy> DspNode<T> for Limiter<T> {
109 #[inline(always)]
110 fn process_sample(&mut self, input: T) -> T {
111 if input < self.min {
112 self.min
113 } else if input > self.max {
114 self.max
115 } else {
116 input
117 }
118 }
119}
120
121#[cfg(feature = "controller")]
126impl DspNode<f32> for crate::controller::PidInstanceF32 {
127 #[inline(always)]
128 fn process_sample(&mut self, input: f32) -> f32 {
129 self.process(input)
130 }
131}
132
133#[cfg(feature = "controller")]
134impl DspNode<q15> for crate::controller::PidInstanceQ15 {
135 #[inline(always)]
136 fn process_sample(&mut self, input: q15) -> q15 {
137 self.process(input)
138 }
139}
140
141#[cfg(feature = "filtering")]
142impl DspNode<f32> for crate::filtering::SinglePoleFilter {
143 #[inline(always)]
144 fn process_sample(&mut self, input: f32) -> f32 {
145 self.process(input)
146 }
147}
148
149#[cfg(feature = "filtering")]
150impl DspNode<q15> for crate::filtering::SinglePoleFilterQ15 {
151 #[inline(always)]
152 fn process_sample(&mut self, input: q15) -> q15 {
153 self.process(input)
154 }
155}
156
157#[cfg(feature = "filtering")]
158impl DspNode<q15> for crate::filtering::DcBlockerQ15 {
159 #[inline(always)]
160 fn process_sample(&mut self, input: q15) -> q15 {
161 self.process(input)
162 }
163}