1use crate::{Inplace, Process, SplitInplace, SplitProcess};
2
3#[derive(Debug, Copy, Clone, Default)]
12pub struct Add;
13impl<X: Copy, Y: core::iter::Sum<X>, const N: usize> Process<[X; N], Y> for Add {
14 fn process(&mut self, x: [X; N]) -> Y {
15 x.into_iter().sum()
16 }
17}
18impl<X0: Copy + core::ops::Add<X1, Output = Y>, X1: Copy, Y> Process<(X0, X1), Y> for Add {
19 fn process(&mut self, x: (X0, X1)) -> Y {
20 x.0 + x.1
21 }
22}
23impl<X: Copy> Inplace<X> for Add where Self: Process<X> {}
24
25#[derive(Debug, Copy, Clone, Default)]
29pub struct Mul;
30impl<X: Copy, Y: core::iter::Product<X>, const N: usize> Process<[X; N], Y> for Mul {
31 fn process(&mut self, x: [X; N]) -> Y {
32 x.into_iter().product()
33 }
34}
35impl<X0: Copy + core::ops::Mul<X1, Output = Y>, X1: Copy, Y> Process<(X0, X1), Y> for Mul {
36 fn process(&mut self, x: (X0, X1)) -> Y {
37 x.0 * x.1
38 }
39}
40impl<X: Copy> Inplace<X> for Mul where Self: Process<X> {}
41
42#[derive(Debug, Copy, Clone, Default)]
46pub struct Sub;
47impl<X: Copy + core::ops::Sub<Output = Y>, Y> Process<[X; 2], Y> for Sub {
48 fn process(&mut self, x: [X; 2]) -> Y {
49 x[0] - x[1]
50 }
51}
52impl<X0: Copy + core::ops::Sub<X1, Output = Y>, X1: Copy, Y> Process<(X0, X1), Y> for Sub {
53 fn process(&mut self, x: (X0, X1)) -> Y {
54 x.0 - x.1
55 }
56}
57impl<X: Copy> Inplace<X> for Sub where Self: Process<X> {}
58
59#[derive(Debug, Copy, Clone, Default)]
74pub struct Butterfly;
75impl<X: Copy + core::ops::Add<Output = Y> + core::ops::Sub<Output = Y>, Y> Process<[X; 2], [Y; 2]>
76 for Butterfly
77{
78 fn process(&mut self, x: [X; 2]) -> [Y; 2] {
79 [x[0] + x[1], x[0] - x[1]]
80 }
81}
82
83impl<X: Copy> Inplace<X> for Butterfly where Self: Process<X> {}
84
85#[derive(Debug, Copy, Clone, Default)]
90pub struct Identity;
91impl<T: Copy> Process<T> for Identity {
92 fn process(&mut self, x: T) -> T {
93 x
94 }
95
96 fn block(&mut self, x: &[T], y: &mut [T]) {
97 y.copy_from_slice(x);
98 }
99}
100
101impl<T: Copy> Inplace<T> for Identity {
103 fn inplace(&mut self, _xy: &mut [T]) {}
104}
105
106impl<X: Copy> Process<X, (X, X)> for Identity {
108 fn process(&mut self, x: X) -> (X, X) {
109 (x, x)
110 }
111}
112
113impl<X: Copy, const N: usize> Process<X, [X; N]> for Identity {
115 fn process(&mut self, x: X) -> [X; N] {
116 core::array::repeat(x)
117 }
118}
119
120impl<X: Copy> Process<[X; 1], X> for Identity {
122 fn process(&mut self, x: [X; 1]) -> X {
123 x[0]
124 }
125}
126
127#[derive(Debug, Copy, Clone, Default)]
129pub struct Neg;
130impl<T: Copy + core::ops::Neg<Output = T>> Process<T> for Neg {
131 fn process(&mut self, x: T) -> T {
132 x.neg()
133 }
134}
135
136impl<T: Copy> Inplace<T> for Neg where Self: Process<T> {}
137
138#[derive(Debug, Clone, Copy, Default)]
142#[repr(transparent)]
143pub struct Offset<T>(pub T);
144
145impl<X: Copy + core::ops::Add<T, Output = Y>, Y, T: Copy> SplitProcess<X, Y> for Offset<T> {
147 fn process(&self, _state: &mut (), x: X) -> Y {
148 x + self.0
149 }
150}
151
152impl<X: Copy, T> SplitInplace<X> for Offset<T> where Self: SplitProcess<X> {}
153
154#[derive(Debug, Clone, Copy, Default)]
156#[repr(transparent)]
157pub struct Gain<T>(pub T);
158
159impl<X: Copy + core::ops::Mul<T, Output = Y>, Y, T: Copy> SplitProcess<X, Y> for Gain<T> {
161 fn process(&self, _state: &mut (), x: X) -> Y {
162 x * self.0
163 }
164}
165
166impl<X: Copy, T> SplitInplace<X> for Gain<T> where Self: SplitProcess<X> {}
167
168#[derive(Debug, Copy, Clone, Default)]
173pub struct Clamp<T> {
174 pub min: T,
176 pub max: T,
178}
179
180impl<T: Copy + Ord> SplitProcess<T> for Clamp<T> {
181 fn process(&self, _state: &mut (), x: T) -> T {
182 x.clamp(self.min, self.max)
183 }
184}
185
186impl<T: Copy> SplitInplace<T> for Clamp<T> where Self: SplitProcess<T> {}
187
188#[derive(Debug, Copy, Clone, Default)]
199pub struct Rate<const I: usize>;
200impl<X: Copy, const I: usize, const N: usize> Process<[X; N], X> for Rate<I> {
201 fn process(&mut self, x: [X; N]) -> X {
202 const { assert!(I < N) }
203 x[I]
204 }
205}
206
207impl<X: Copy + Default, const I: usize, const N: usize> Process<X, [X; N]> for Rate<I> {
208 fn process(&mut self, x: X) -> [X; N] {
209 const { assert!(I < N) }
210 let mut y = [X::default(); N];
211 y[I] = x;
212 y
213 }
214}
215impl<X: Copy, const I: usize> Inplace<X> for Rate<I> where Self: Process<X> {}
216
217#[derive(Debug, Copy, Clone, Default)]
225pub struct Buffer<B> {
226 buffer: B,
227 idx: usize,
228}
229
230impl<X, const N: usize> Buffer<[X; N]> {
231 #[must_use]
236 pub fn is_empty(&self) -> bool {
237 self.idx == 0
238 }
239}
240
241impl<X: Copy, const N: usize> Process<X> for Buffer<[X; N]> {
245 fn process(&mut self, x: X) -> X {
246 const { assert!(N > 0) }
247 let y = core::mem::replace(&mut self.buffer[self.idx], x);
248 self.idx = (self.idx + 1) % N;
249 y
250 }
251
252 fn block(&mut self, x: &[X], y: &mut [X]) {
253 const { assert!(N > 0) }
254 debug_assert_eq!(x.len(), y.len());
255 let mut x = x;
256 let mut y = y;
257
258 if self.idx != 0 {
259 let n = x.len().min(N - self.idx);
260 let (xh, xr) = x.split_at(n);
261 let (yh, yr) = y.split_at_mut(n);
262 yh.copy_from_slice(&self.buffer[self.idx..self.idx + n]);
263 self.buffer[self.idx..self.idx + n].copy_from_slice(xh);
264 self.idx = (self.idx + n) % N;
265 if self.idx != 0 {
266 return;
267 }
268 x = xr;
269 y = yr;
270 }
271
272 let (xc, xt) = x.as_chunks::<N>();
273 let (yc, yt) = y.as_chunks_mut::<N>();
274 for (xc, yc) in xc.iter().zip(yc) {
275 *yc = self.buffer;
276 self.buffer = *xc;
277 }
278
279 yt.copy_from_slice(&self.buffer[..xt.len()]);
280 self.buffer[..xt.len()].copy_from_slice(xt);
281 self.idx = xt.len();
282 }
283}
284
285impl<X: Copy, const N: usize> Inplace<X> for Buffer<[X; N]> {
286 fn inplace(&mut self, xy: &mut [X]) {
287 const { assert!(N > 0) }
288 let mut xy = xy;
289
290 if self.idx != 0 {
291 let n = xy.len().min(N - self.idx);
292 let (head, rest) = xy.split_at_mut(n);
293 for (xy, buf) in head
294 .iter_mut()
295 .zip(self.buffer[self.idx..self.idx + n].iter_mut())
296 {
297 core::mem::swap(xy, buf);
298 }
299 self.idx = (self.idx + n) % N;
300 if self.idx != 0 {
301 return;
302 }
303 xy = rest;
304 }
305
306 let (chunks, tail) = xy.as_chunks_mut::<N>();
307 for chunk in chunks {
308 core::mem::swap(chunk, &mut self.buffer);
309 }
310
311 let n = tail.len();
312 for (xy, buf) in tail.iter_mut().zip(self.buffer[..n].iter_mut()) {
313 core::mem::swap(xy, buf);
314 }
315 self.idx = n;
316 }
317}
318
319impl<X: Copy, const N: usize, const M: usize> Process<[X; M]> for Buffer<[X; N]> {
320 fn process(&mut self, x: [X; M]) -> [X; M] {
321 const { assert!(N > 0) }
322 let mut y = x;
323 <Self as Process<X>>::block(self, &x, &mut y);
324 y
325 }
326}
327
328impl<X: Copy, const N: usize> Process<X, Option<[X; N]>> for Buffer<[X; N]> {
332 fn process(&mut self, x: X) -> Option<[X; N]> {
333 const { assert!(N > 0) }
334 self.buffer[self.idx] = x;
335 self.idx += 1;
336 (self.idx == N).then(|| {
337 self.idx = 0;
338 self.buffer
339 })
340 }
341
342 fn block(&mut self, x: &[X], y: &mut [Option<[X; N]>]) {
343 const { assert!(N > 0) }
344 debug_assert_eq!(x.len(), y.len());
345 let mut x = x;
346 let mut y = y;
347
348 if self.idx != 0 {
349 let n = x.len().min(N - self.idx);
350 let (xh, xr) = x.split_at(n);
351 let (yh, yr) = y.split_at_mut(n);
352 self.buffer[self.idx..self.idx + n].copy_from_slice(xh);
353 yh.fill(None);
354 self.idx += n;
355 if self.idx == N {
356 self.idx = 0;
357 yh[n - 1] = Some(self.buffer);
358 } else {
359 return;
360 }
361 x = xr;
362 y = yr;
363 }
364
365 let (xc, xt) = x.as_chunks::<N>();
366 let (yc, yt) = y.as_chunks_mut::<N>();
367 for (xc, yc) in xc.iter().zip(yc) {
368 let (yl, yr) = yc.split_last_mut().unwrap();
369 yr.fill(None);
370 *yl = Some(*xc);
371 }
372
373 self.buffer[..xt.len()].copy_from_slice(xt);
374 yt.fill(None);
375 self.idx = xt.len();
376 }
377}
378
379impl<X: Copy, const N: usize> Process<Option<[X; N]>, X> for Buffer<[X; N]> {
380 fn process(&mut self, x: Option<[X; N]>) -> X {
381 const { assert!(N > 0) }
382 if let Some(x) = x {
383 self.buffer = x;
384 self.idx = 0;
385 } else {
386 self.idx += 1;
387 }
388 self.buffer[self.idx]
389 }
390
391 fn block(&mut self, x: &[Option<[X; N]>], y: &mut [X]) {
392 const { assert!(N > 0) }
393 debug_assert_eq!(x.len(), y.len());
394 let mut i = 0;
395 while i < x.len() {
396 if let Some(buf) = x[i] {
397 self.buffer = buf;
398 self.idx = 0;
399 y[i] = self.buffer[0];
400 i += 1;
401 continue;
402 }
403
404 let run = x[i..]
405 .iter()
406 .position(Option::is_some)
407 .unwrap_or(x.len() - i);
408 y[i..i + run].copy_from_slice(&self.buffer[self.idx + 1..self.idx + 1 + run]);
409 self.idx += run;
410 i += run;
411 }
412 }
413}
414
415#[derive(Debug, Copy, Clone, Default)]
421pub struct Nyquist<X>(
422 pub X,
424);
425impl<X: Copy + core::ops::Add<X, Output = Y>, Y, const N: usize> Process<X, Y> for Nyquist<[X; N]> {
426 fn process(&mut self, x: X) -> Y {
427 const { assert!(N > 0) }
428 let y = x + self.0[N - 1];
429 self.0.copy_within(..N - 1, 1);
430 self.0[0] = x;
431 y
432 }
433
434 fn block(&mut self, x: &[X], y: &mut [Y]) {
435 const { assert!(N > 0) }
436 debug_assert_eq!(x.len(), y.len());
437 let n = x.len().min(N);
438 let (xh, xt) = x.split_at(n);
439 let (yh, yt) = y.split_at_mut(n);
440
441 for ((xi, yi), s) in xh
442 .iter()
443 .zip(yh.iter_mut())
444 .zip(self.0[N - n..].iter().rev())
445 {
446 *yi = *xi + *s;
447 }
448 for ((xi, yi), xp) in xt.iter().zip(yt.iter_mut()).zip(x.iter()) {
449 *yi = *xi + *xp;
450 }
451
452 if x.len() >= N {
453 for (dst, src) in self.0.iter_mut().zip(x[x.len() - N..].iter().rev()) {
454 *dst = *src;
455 }
456 } else {
457 self.0.copy_within(..N - x.len(), x.len());
458 for (dst, src) in self.0.iter_mut().zip(x.iter().rev()) {
459 *dst = *src;
460 }
461 }
462 }
463
464 }
466impl<X: Copy, const N: usize> Inplace<X> for Nyquist<[X; N]> where Self: Process<X> {}
467
468#[derive(Debug, Copy, Clone, Default)]
470pub struct Integrator<Y>(
471 pub Y,
473);
474impl<X: Copy, Y: core::ops::AddAssign<X> + Copy> Process<X, Y> for Integrator<Y> {
475 fn process(&mut self, x: X) -> Y {
476 self.0 += x;
477 self.0
478 }
479}
480impl<X: Copy> Inplace<X> for Integrator<X> where Self: Process<X> {}
481
482#[derive(Debug, Copy, Clone, Default)]
488pub struct Comb<X>(
489 pub X,
491);
492impl<X: Copy + core::ops::Sub<X, Output = Y>, Y, const N: usize> Process<X, Y> for Comb<[X; N]> {
493 fn process(&mut self, x: X) -> Y {
494 const { assert!(N > 0) }
495 let y = x - self.0[N - 1];
496 self.0.copy_within(..N - 1, 1);
497 self.0[0] = x;
498 y
499 }
500
501 fn block(&mut self, x: &[X], y: &mut [Y]) {
502 const { assert!(N > 0) }
503 debug_assert_eq!(x.len(), y.len());
504 let n = x.len().min(N);
505 let (xh, xt) = x.split_at(n);
506 let (yh, yt) = y.split_at_mut(n);
507
508 for ((xi, yi), s) in xh
509 .iter()
510 .zip(yh.iter_mut())
511 .zip(self.0[N - n..].iter().rev())
512 {
513 *yi = *xi - *s;
514 }
515 for ((xi, yi), xp) in xt.iter().zip(yt.iter_mut()).zip(x.iter()) {
516 *yi = *xi - *xp;
517 }
518
519 if x.len() >= N {
520 for (dst, src) in self.0.iter_mut().zip(x[x.len() - N..].iter().rev()) {
521 *dst = *src;
522 }
523 } else {
524 self.0.copy_within(..N - x.len(), x.len());
525 for (dst, src) in self.0.iter_mut().zip(x.iter().rev()) {
526 *dst = *src;
527 }
528 }
529 }
530
531 }
533impl<X: Copy, const N: usize> Inplace<X> for Comb<[X; N]> where Self: Process<X> {}