1#![no_std]
2#![doc = include_str!("../README.md")]
3
4mod process;
5pub use process::*;
6mod view;
7pub use view::*;
8mod basic;
9pub use basic::*;
10mod adapters;
11pub use adapters::*;
12mod split;
13pub use split::*;
14mod compose;
15pub use compose::*;
16
17pub type Pair<C0, C1, X, I = (), J = ()> = Minor<((I, Parallel<(C0, C1)>), J), [X; 2]>;
44
45#[cfg(test)]
46mod test {
47 use super::*;
48 use dsp_fixedpoint::Q32;
49
50 #[test]
51 fn basic() {
52 assert_eq!(3, Identity.process(3));
53 assert_eq!([7, 1], Butterfly.process([4, 3]));
54 assert_eq!(
55 Split::stateless(Gain(Q32::<3>::from_bits(32))).process(9),
56 9 * 4
57 );
58 assert_eq!(Split::stateless(Offset(7)).process(9), 7 + 9);
59 }
60
61 #[test]
62 fn stateless() {
63 assert_eq!(Neg.process(9), -9);
64 assert_eq!(Split::stateful(Neg).process(9), -9);
65
66 let mut p = (Split::stateless(Offset(7)) * Split::stateless(Offset(1))).minor();
67 p.assert_process::<i8, _>();
68 assert_eq!(p.process(9), 7 + 1 + 9);
69 }
70
71 #[test]
72 fn stateful() {
73 let mut xy = [3, 0, 0];
74 let mut dly = Buffer::<[_; 2]>::default();
75 dly.inplace(&mut xy);
76 assert_eq!(xy, [0, 0, 3]);
77 let y: i32 = Split::stateful(dly).process(4);
78 assert_eq!(y, 0);
79 }
80
81 #[test]
82 fn pair() {
83 let g = Gain(Q32::<1>::from_bits(4));
84 let mut f = Split::new(
85 Pair::<_, _, _>::new((((), Parallel::new((Offset(3), g))), ())),
86 ((Unsplit(Identity), Default::default()), Unsplit(Add)),
87 );
88 let y: i32 = f.process(5);
89 assert_eq!(y, (5 + 3) + ((5 * 4) >> 1));
90
91 let y: [i32; 5] = f.lanes().process([5; _]);
92 assert_eq!(y, [(5 + 3) + ((5 * 4) >> 1); 5]);
93 }
94
95 #[test]
96 fn chunk_in_out() {
97 let mut p = Split::stateless(ChunkInOut(FnSplitProcess(
98 |_: &mut (), [x0, x1]: [i32; 2]| [x0 + x1],
99 )));
100 let y = p.process([1, 2, 3, 4]);
101 assert_eq!(y, [3, 7]);
102 }
103
104 #[cfg(feature = "bytemuck")]
105 #[test]
106 fn chunk_out_pod() {
107 let mut p = Split::stateless(ChunkOutPod(FnSplitProcess(|_: &mut (), x: i32| [x, -x])));
108 let y = p.process([2, 3]);
109 assert_eq!(y, [2, -2, 3, -3]);
110 }
111
112 #[test]
113 fn frame_major_view_fallback() {
114 let mut p = Split::stateless(Offset(3));
115 let x = View::from_frames(&[[1, 2], [3, 4]]);
116 let mut y = [[0; 2]; 2];
117 let yb = ViewMut::from_frames(&mut y);
118 p.process_view(x, yb);
119 assert_eq!(y, [[4, 5], [6, 7]]);
120 }
121
122 #[test]
123 fn lane_major_lanes() {
124 let mut p = Split::stateless(Offset(3)).lanes::<2>();
125 let x = View::from_flat(&[1, 2, 3, 10, 20, 30], 3);
126 let mut y = [0; 6];
127 let yb = ViewMut::from_flat(&mut y, 3);
128 p.process_view(x, yb);
129 assert_eq!(y, [4, 5, 6, 13, 23, 33]);
130 }
131
132 #[test]
133 fn lane_major_by_lane() {
134 let mut p = Split::new(ByLane::new([Offset(1), Offset(10)]), [(), ()]);
135 let x = View::from_flat(&[1, 2, 3, 10, 20, 30], 3);
136 let mut y = [0; 6];
137 let yb = ViewMut::from_flat(&mut y, 3);
138 p.process_view(x, yb);
139 assert_eq!(y, [2, 3, 4, 20, 30, 40]);
140 }
141
142 #[test]
143 fn framewise_chunk_bridge() {
144 let mut p = Split::stateless(ChunkInOut::<_, 2, 1>(FnSplitProcess(
145 |_: &mut (), [x0, x1]: [i32; 2]| [x0 + x1],
146 )))
147 .per_frame();
148 let x = View::from_frames(&[[1, 2], [3, 4]]);
149 let mut y = [[0; 1]; 2];
150 let yb = ViewMut::from_frames(&mut y);
151 p.process_frames(x, yb);
152 assert_eq!(y, [[3], [7]]);
153 }
154
155 #[test]
156 fn buffer_blocks() {
157 let mut dly = Buffer::<[_; 2]>::default();
158 let mut y = [0; 5];
159 dly.block(&[1, 2, 3, 4, 5], &mut y);
160 assert_eq!(y, [0, 0, 1, 2, 3]);
161 assert_eq!(dly.process([6, 7, 8]), [4, 5, 6]);
162
163 let mut chunk = Buffer::<[i32; 2]>::default();
164 let mut y = [None; 5];
165 chunk.block(&[1, 2, 3, 4, 5], &mut y);
166 assert_eq!(y, [None, Some([1, 2]), None, Some([3, 4]), None]);
167
168 let mut stream = Buffer::<[i32; 2]>::default();
169 let mut y = [0; 5];
170 stream.block(
171 &[Some([1, 2]), None, Some([3, 4]), None, Some([5, 6])],
172 &mut y,
173 );
174 assert_eq!(y, [1, 2, 3, 4, 5]);
175 }
176
177 #[test]
178 fn diffsum_block() {
179 let mut nyq = Nyquist([10, 20]);
180 let mut y = [0; 4];
181 nyq.block(&[1, 2, 3, 4], &mut y);
182 assert_eq!(y, [21, 12, 4, 6]);
183 let mut xy = [5, 6, 7];
184 nyq.inplace(&mut xy);
185 assert_eq!(xy, [8, 10, 12]);
186
187 let mut comb = Comb([10, 20]);
188 let mut y = [0; 4];
189 comb.block(&[1, 2, 3, 4], &mut y);
190 assert_eq!(y, [-19, -8, 2, 2]);
191 let mut xy = [5, 6, 7];
192 comb.inplace(&mut xy);
193 assert_eq!(xy, [2, 2, 2]);
194 }
195}