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