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 x = xr;
266 y = yr;
267 }
268
269 let (xc, xt) = x.as_chunks::<N>();
270 let (yc, yt) = y.as_chunks_mut::<N>();
271 for (xc, yc) in xc.iter().zip(yc) {
272 *yc = self.buffer;
273 self.buffer = *xc;
274 }
275
276 yt.copy_from_slice(&self.buffer[..xt.len()]);
277 self.buffer[..xt.len()].copy_from_slice(xt);
278 self.idx = xt.len();
279 }
280}
281
282impl<X: Copy, const N: usize> Inplace<X> for Buffer<[X; N]> {
283 fn inplace(&mut self, xy: &mut [X]) {
284 const { assert!(N > 0) }
285 let mut xy = xy;
286
287 if self.idx != 0 {
288 let n = xy.len().min(N - self.idx);
289 let (head, rest) = xy.split_at_mut(n);
290 for (xy, buf) in head
291 .iter_mut()
292 .zip(self.buffer[self.idx..self.idx + n].iter_mut())
293 {
294 core::mem::swap(xy, buf);
295 }
296 self.idx = (self.idx + n) % N;
297 xy = rest;
298 }
299
300 let (chunks, tail) = xy.as_chunks_mut::<N>();
301 for chunk in chunks {
302 core::mem::swap(chunk, &mut self.buffer);
303 }
304
305 let n = tail.len();
306 for (xy, buf) in tail.iter_mut().zip(self.buffer[..n].iter_mut()) {
307 core::mem::swap(xy, buf);
308 }
309 self.idx = n;
310 }
311}
312
313impl<X: Copy, const N: usize, const M: usize> Process<[X; M]> for Buffer<[X; N]> {
314 fn process(&mut self, x: [X; M]) -> [X; M] {
315 const { assert!(N > 0) }
316 let mut y = x;
317 <Self as Process<X>>::block(self, &x, &mut y);
318 y
319 }
320}
321
322impl<X: Copy, const N: usize> Process<X, Option<[X; N]>> for Buffer<[X; N]> {
326 fn process(&mut self, x: X) -> Option<[X; N]> {
327 const { assert!(N > 0) }
328 self.buffer[self.idx] = x;
329 self.idx += 1;
330 (self.idx == N).then(|| {
331 self.idx = 0;
332 self.buffer
333 })
334 }
335
336 fn block(&mut self, x: &[X], y: &mut [Option<[X; N]>]) {
337 const { assert!(N > 0) }
338 debug_assert_eq!(x.len(), y.len());
339 let mut x = x;
340 let mut y = y;
341
342 if self.idx != 0 {
343 let n = x.len().min(N - self.idx);
344 let (xh, xr) = x.split_at(n);
345 let (yh, yr) = y.split_at_mut(n);
346 self.buffer[self.idx..self.idx + n].copy_from_slice(xh);
347 yh.fill(None);
348 self.idx += n;
349 if self.idx == N {
350 self.idx = 0;
351 yh[n - 1] = Some(self.buffer);
352 }
353 x = xr;
354 y = yr;
355 }
356
357 let (xc, xt) = x.as_chunks::<N>();
358 let (yc, yt) = y.as_chunks_mut::<N>();
359 for (xc, yc) in xc.iter().zip(yc) {
360 let (yl, yr) = yc.split_last_mut().unwrap();
361 yr.fill(None);
362 *yl = Some(*xc);
363 }
364
365 self.buffer[..xt.len()].copy_from_slice(xt);
366 yt.fill(None);
367 self.idx = xt.len();
368 }
369}
370
371impl<X: Copy, const N: usize> Process<Option<[X; N]>, X> for Buffer<[X; N]> {
372 fn process(&mut self, x: Option<[X; N]>) -> X {
373 const { assert!(N > 0) }
374 if let Some(x) = x {
375 self.buffer = x;
376 self.idx = 0;
377 } else {
378 self.idx += 1;
379 }
380 self.buffer[self.idx]
381 }
382
383 fn block(&mut self, x: &[Option<[X; N]>], y: &mut [X]) {
384 const { assert!(N > 0) }
385 debug_assert_eq!(x.len(), y.len());
386 let mut i = 0;
387 while i < x.len() {
388 if let Some(buf) = x[i] {
389 self.buffer = buf;
390 self.idx = 0;
391 y[i] = self.buffer[0];
392 i += 1;
393 continue;
394 }
395
396 let run = x[i..]
397 .iter()
398 .position(Option::is_some)
399 .unwrap_or(x.len() - i);
400 y[i..i + run].copy_from_slice(&self.buffer[self.idx + 1..self.idx + 1 + run]);
401 self.idx += run;
402 i += run;
403 }
404 }
405}
406
407#[derive(Debug, Copy, Clone, Default)]
413pub struct Nyquist<X>(
414 pub X,
416);
417impl<X: Copy + core::ops::Add<X, Output = Y>, Y, const N: usize> Process<X, Y> for Nyquist<[X; N]> {
418 fn process(&mut self, x: X) -> Y {
419 const { assert!(N > 0) }
420 let y = x + self.0[N - 1];
421 self.0.copy_within(..N - 1, 1);
422 self.0[0] = x;
423 y
424 }
425
426 fn block(&mut self, x: &[X], y: &mut [Y]) {
427 debug_assert_eq!(x.len(), y.len());
428 let n = x.len().min(N);
429 let (xh, xt) = x.split_at(n);
430 let (yh, yt) = y.split_at_mut(n);
431
432 for ((xi, yi), s) in xh.iter().zip(yh.iter_mut()).zip(self.0[..n].iter().rev()) {
433 *yi = *xi + *s;
434 }
435 for ((xi, yi), xp) in xt.iter().zip(yt.iter_mut()).zip(x.iter()) {
436 *yi = *xi + *xp;
437 }
438
439 if x.len() >= N {
440 for (dst, src) in self.0.iter_mut().zip(x[x.len() - N..].iter().rev()) {
441 *dst = *src;
442 }
443 } else {
444 self.0.copy_within(..N - x.len(), x.len());
445 for (dst, src) in self.0.iter_mut().zip(x.iter().rev()) {
446 *dst = *src;
447 }
448 }
449 }
450
451 }
453impl<X: Copy, const N: usize> Inplace<X> for Nyquist<[X; N]> where Self: Process<X> {}
454
455#[derive(Debug, Copy, Clone, Default)]
457pub struct Integrator<Y>(
458 pub Y,
460);
461impl<X: Copy, Y: core::ops::AddAssign<X> + Copy> Process<X, Y> for Integrator<Y> {
462 fn process(&mut self, x: X) -> Y {
463 self.0 += x;
464 self.0
465 }
466}
467impl<X: Copy> Inplace<X> for Integrator<X> where Self: Process<X> {}
468
469#[derive(Debug, Copy, Clone, Default)]
475pub struct Comb<X>(
476 pub X,
478);
479impl<X: Copy + core::ops::Sub<X, Output = Y>, Y, const N: usize> Process<X, Y> for Comb<[X; N]> {
480 fn process(&mut self, x: X) -> Y {
481 const { assert!(N > 0) }
482 let y = x - self.0[N - 1];
483 self.0.copy_within(..N - 1, 1);
484 self.0[0] = x;
485 y
486 }
487
488 fn block(&mut self, x: &[X], y: &mut [Y]) {
489 debug_assert_eq!(x.len(), y.len());
490 let n = x.len().min(N);
491 let (xh, xt) = x.split_at(n);
492 let (yh, yt) = y.split_at_mut(n);
493
494 for ((xi, yi), s) in xh.iter().zip(yh.iter_mut()).zip(self.0[..n].iter().rev()) {
495 *yi = *xi - *s;
496 }
497 for ((xi, yi), xp) in xt.iter().zip(yt.iter_mut()).zip(x.iter()) {
498 *yi = *xi - *xp;
499 }
500
501 if x.len() >= N {
502 for (dst, src) in self.0.iter_mut().zip(x[x.len() - N..].iter().rev()) {
503 *dst = *src;
504 }
505 } else {
506 self.0.copy_within(..N - x.len(), x.len());
507 for (dst, src) in self.0.iter_mut().zip(x.iter().rev()) {
508 *dst = *src;
509 }
510 }
511 }
512
513 }
515impl<X: Copy, const N: usize> Inplace<X> for Comb<[X; N]> where Self: Process<X> {}