rustdct/lib.rs
1pub use rustfft;
2pub use rustfft::num_complex;
3pub use rustfft::num_traits;
4
5use rustfft::Length;
6
7#[macro_use]
8mod common;
9
10/// Algorithms for computing the Modified Discrete Cosine Transform
11pub mod mdct;
12
13pub mod algorithm;
14
15mod array_utils;
16
17mod plan;
18mod twiddles;
19pub use crate::common::DctNum;
20
21pub use self::plan::DctPlanner;
22
23#[cfg(test)]
24mod test_utils;
25
26pub trait RequiredScratch {
27 fn get_scratch_len(&self) -> usize;
28}
29
30/// A trait for algorithms which compute the Discrete Cosine Transform Type 1 (DCT1)
31pub trait Dct1<T: DctNum>: RequiredScratch + Length + Sync + Send {
32 /// Computes the DCT Type 1 on the provided buffer, in-place.
33 ///
34 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
35 /// multiple computations, consider calling `process_dct1_with_scratch` instead.
36 ///
37 /// Does not normalize outputs.
38 fn process_dct1(&self, buffer: &mut [T]) {
39 let mut scratch = vec![T::zero(); self.get_scratch_len()];
40 self.process_dct1_with_scratch(buffer, &mut scratch);
41 }
42 /// Computes the DCT Type 1 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
43 ///
44 /// Does not normalize outputs.
45 fn process_dct1_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
46}
47
48/// A trait for algorithms which compute the Discrete Cosine Transform Type 2 (DCT2)
49pub trait Dct2<T: DctNum>: RequiredScratch + Length + Sync + Send {
50 /// Computes the DCT Type 2 on the provided buffer, in-place.
51 ///
52 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
53 /// multiple computations, consider calling `process_dct2_with_scratch` instead.
54 ///
55 /// Does not normalize outputs.
56 fn process_dct2(&self, buffer: &mut [T]) {
57 let mut scratch = vec![T::zero(); self.get_scratch_len()];
58 self.process_dct2_with_scratch(buffer, &mut scratch);
59 }
60 /// Computes the DCT Type 2 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
61 ///
62 /// Does not normalize outputs.
63 fn process_dct2_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
64}
65
66/// A trait for algorithms which compute the Discrete Cosine Transform Type 3 (DCT3)
67pub trait Dct3<T: DctNum>: RequiredScratch + Length + Sync + Send {
68 /// Computes the DCT Type 3 on the provided buffer, in-place.
69 ///
70 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
71 /// multiple computations, consider calling `process_dct3_with_scratch` instead.
72 ///
73 /// Does not normalize outputs.
74 fn process_dct3(&self, buffer: &mut [T]) {
75 let mut scratch = vec![T::zero(); self.get_scratch_len()];
76 self.process_dct3_with_scratch(buffer, &mut scratch);
77 }
78 /// Computes the DCT Type 3 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
79 ///
80 /// Does not normalize outputs.
81 fn process_dct3_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
82}
83
84/// A trait for algorithms which compute the Discrete Cosine Transform Type 4 (DCT4)
85pub trait Dct4<T: DctNum>: RequiredScratch + Length + Sync + Send {
86 /// Computes the DCT Type 4 on the provided buffer, in-place.
87 ///
88 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
89 /// multiple computations, consider calling `process_dst4_with_scratch` instead.
90 ///
91 /// Does not normalize outputs.
92 fn process_dct4(&self, buffer: &mut [T]) {
93 let mut scratch = vec![T::zero(); self.get_scratch_len()];
94 self.process_dct4_with_scratch(buffer, &mut scratch);
95 }
96 /// Computes the DCT Type 4 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
97 ///
98 /// Does not normalize outputs.
99 fn process_dct4_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
100}
101
102/// A trait for algorithms which compute the Discrete Cosine Transform Type 5 (DCT5)
103pub trait Dct5<T: DctNum>: RequiredScratch + Length + Sync + Send {
104 /// Computes the DCT Type 5 on the provided buffer, in-place.
105 ///
106 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
107 /// multiple computations, consider calling `process_dct5_with_scratch` instead.
108 ///
109 /// Does not normalize outputs.
110 fn process_dct5(&self, buffer: &mut [T]) {
111 let mut scratch = vec![T::zero(); self.get_scratch_len()];
112 self.process_dct5_with_scratch(buffer, &mut scratch);
113 }
114 /// Computes the DCT Type 5 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
115 ///
116 /// Does not normalize outputs.
117 fn process_dct5_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
118}
119
120/// A trait for algorithms which compute the Discrete Cosine Transform Type 6 (DCT6)
121pub trait Dct6<T: DctNum>: RequiredScratch + Length + Sync + Send {
122 /// Computes the DCT Type 6 on the provided buffer, in-place.
123 ///
124 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
125 /// multiple computations, consider calling `process_dct6_with_scratch` instead.
126 ///
127 /// Does not normalize outputs.
128 fn process_dct6(&self, buffer: &mut [T]) {
129 let mut scratch = vec![T::zero(); self.get_scratch_len()];
130 self.process_dct6_with_scratch(buffer, &mut scratch);
131 }
132 /// Computes the DCT Type 6 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
133 ///
134 /// Does not normalize outputs.
135 fn process_dct6_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
136}
137
138/// A trait for algorithms which compute the Discrete Cosine Transform Type 7 (DCT7)
139pub trait Dct7<T: DctNum>: RequiredScratch + Length + Sync + Send {
140 /// Computes the DCT Type 7 on the provided buffer, in-place.
141 ///
142 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
143 /// multiple computations, consider calling `process_dct7_with_scratch` instead.
144 ///
145 /// Does not normalize outputs.
146 fn process_dct7(&self, buffer: &mut [T]) {
147 let mut scratch = vec![T::zero(); self.get_scratch_len()];
148 self.process_dct7_with_scratch(buffer, &mut scratch);
149 }
150 /// Computes the DCT Type 7 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
151 ///
152 /// Does not normalize outputs.
153 fn process_dct7_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
154}
155
156/// A trait for algorithms which compute the Discrete Cosine Transform Type 8 (DCT8)
157pub trait Dct8<T: DctNum>: RequiredScratch + Length + Sync + Send {
158 /// Computes the DCT Type 8 on the provided buffer, in-place.
159 ///
160 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
161 /// multiple computations, consider calling `process_dct8_with_scratch` instead.
162 ///
163 /// Does not normalize outputs.
164 fn process_dct8(&self, buffer: &mut [T]) {
165 let mut scratch = vec![T::zero(); self.get_scratch_len()];
166 self.process_dct8_with_scratch(buffer, &mut scratch);
167 }
168 /// Computes the DCT Type 8 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
169 ///
170 /// Does not normalize outputs.
171 fn process_dct8_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
172}
173
174/// A trait for algorithms which compute the Discrete Sine Transform Type 1 (DST1)
175pub trait Dst1<T: DctNum>: RequiredScratch + Length + Sync + Send {
176 /// Computes the DST Type 1 on the provided buffer, in-place.
177 ///
178 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
179 /// multiple computations, consider calling `process_dst1_with_scratch` instead.
180 ///
181 /// Does not normalize outputs.
182 fn process_dst1(&self, buffer: &mut [T]) {
183 let mut scratch = vec![T::zero(); self.get_scratch_len()];
184 self.process_dst1_with_scratch(buffer, &mut scratch);
185 }
186 /// Computes the DST Type 1 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
187 ///
188 /// Does not normalize outputs.
189 fn process_dst1_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
190}
191
192/// A trait for algorithms which compute the Discrete Sine Transform Type 2 (DST2)
193pub trait Dst2<T: DctNum>: RequiredScratch + Length + Sync + Send {
194 /// Computes the DST Type 2 on the provided buffer, in-place.
195 ///
196 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
197 /// multiple computations, consider calling `process_dst2_with_scratch` instead.
198 ///
199 /// Does not normalize outputs.
200 fn process_dst2(&self, buffer: &mut [T]) {
201 let mut scratch = vec![T::zero(); self.get_scratch_len()];
202 self.process_dst2_with_scratch(buffer, &mut scratch);
203 }
204 /// Computes the DST Type 2 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
205 ///
206 /// Does not normalize outputs.
207 fn process_dst2_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
208}
209
210/// A trait for algorithms which compute the Discrete Sine Transform Type 3 (DST3)
211pub trait Dst3<T: DctNum>: RequiredScratch + Length + Sync + Send {
212 /// Computes the DST Type 3 on the provided buffer, in-place.
213 ///
214 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
215 /// multiple computations, consider calling `process_dst3_with_scratch` instead.
216 ///
217 /// Does not normalize outputs.
218 fn process_dst3(&self, buffer: &mut [T]) {
219 let mut scratch = vec![T::zero(); self.get_scratch_len()];
220 self.process_dst3_with_scratch(buffer, &mut scratch);
221 }
222 /// Computes the DST Type 3 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
223 ///
224 /// Does not normalize outputs.
225 fn process_dst3_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
226}
227
228/// A trait for algorithms which compute the Discrete Sine Transform Type 4 (DST4)
229pub trait Dst4<T: DctNum>: RequiredScratch + Length + Sync + Send {
230 /// Computes the DST Type 4 on the provided buffer, in-place.
231 ///
232 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
233 /// multiple computations, consider calling `process_dst4_with_scratch` instead.
234 ///
235 /// Does not normalize outputs.
236 fn process_dst4(&self, buffer: &mut [T]) {
237 let mut scratch = vec![T::zero(); self.get_scratch_len()];
238 self.process_dst4_with_scratch(buffer, &mut scratch);
239 }
240 /// Computes the DST Type 4 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
241 ///
242 /// Does not normalize outputs.
243 fn process_dst4_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
244}
245
246/// A trait for algorithms which compute the Discrete Cosine Transform Type 5 (DST5)
247pub trait Dst5<T: DctNum>: RequiredScratch + Length + Sync + Send {
248 /// Computes the DST Type 5 on the provided buffer, in-place.
249 ///
250 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
251 /// multiple computations, consider calling `process_dst4_with_scratch` instead.
252 ///
253 /// Does not normalize outputs.
254 fn process_dst5(&self, buffer: &mut [T]) {
255 let mut scratch = vec![T::zero(); self.get_scratch_len()];
256 self.process_dst5_with_scratch(buffer, &mut scratch);
257 }
258 /// Computes the DST Type 5 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
259 ///
260 /// Does not normalize outputs.
261 fn process_dst5_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
262}
263
264/// A trait for algorithms which compute the Discrete Cosine Transform Type 6 (DST6)
265pub trait Dst6<T: DctNum>: RequiredScratch + Length + Sync + Send {
266 /// Computes the DST Type 6 on the provided buffer, in-place.
267 ///
268 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
269 /// multiple computations, consider calling `process_dst6_with_scratch` instead.
270 ///
271 /// Does not normalize outputs.
272 fn process_dst6(&self, buffer: &mut [T]) {
273 let mut scratch = vec![T::zero(); self.get_scratch_len()];
274 self.process_dst6_with_scratch(buffer, &mut scratch);
275 }
276 /// Computes the DST Type 6 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
277 ///
278 /// Does not normalize outputs.
279 fn process_dst6_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
280}
281
282/// A trait for algorithms which compute the Discrete Cosine Transform Type 7 (DST7)
283pub trait Dst7<T: DctNum>: RequiredScratch + Length + Sync + Send {
284 /// Computes the DST Type 7 on the provided buffer, in-place.
285 ///
286 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
287 /// multiple computations, consider calling `process_dst7_with_scratch` instead.
288 ///
289 /// Does not normalize outputs.
290 fn process_dst7(&self, buffer: &mut [T]) {
291 let mut scratch = vec![T::zero(); self.get_scratch_len()];
292 self.process_dst7_with_scratch(buffer, &mut scratch);
293 }
294 /// Computes the DST Type 7 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
295 ///
296 /// Does not normalize outputs.
297 fn process_dst7_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
298}
299
300/// A trait for algorithms which compute the Discrete Cosine Transform Type 8 (DST8)
301pub trait Dst8<T: DctNum>: RequiredScratch + Length + Sync + Send {
302 /// Computes the DST Type 8 on the provided buffer, in-place.
303 ///
304 /// This method may allocate a Vec<T> of scratch space as needed. If you'd like to reuse that allocation between
305 /// multiple computations, consider calling `process_dst8_with_scratch` instead.
306 ///
307 /// Does not normalize outputs.
308 fn process_dst8(&self, buffer: &mut [T]) {
309 let mut scratch = vec![T::zero(); self.get_scratch_len()];
310 self.process_dst8_with_scratch(buffer, &mut scratch);
311 }
312 /// Computes the DST Type 8 on the provided buffer, in-place. Uses the provided `scratch` buffer as scratch space.
313 ///
314 /// Does not normalize outputs.
315 fn process_dst8_with_scratch(&self, buffer: &mut [T], scratch: &mut [T]);
316}
317
318/// A trait for algorithms that can compute all of DCT2, DCT3, DST2, DST3, all in one struct
319pub trait TransformType2And3<T: DctNum>: Dct2<T> + Dct3<T> + Dst2<T> + Dst3<T> {}
320
321/// A trait for algorithms that can compute both DCT4 and DST4, all in one struct
322pub trait TransformType4<T: DctNum>: Dct4<T> + Dst4<T> {}
323
324/// A trait for algorithms that can compute both DCT6 and DCT7, all in one struct
325pub trait Dct6And7<T: DctNum>: Dct6<T> + Dct7<T> {}
326
327/// A trait for algorithms that can compute both DST6 and DST7, all in one struct
328pub trait Dst6And7<T: DctNum>: Dst6<T> + Dst7<T> {}
329
330#[test]
331fn test_send_sync_impls() {
332 fn assert_send_sync<T: ?Sized>()
333 where
334 T: Send + Sync,
335 {
336 }
337
338 assert_send_sync::<dyn Dct1<f32>>();
339 assert_send_sync::<dyn Dct2<f32>>();
340 assert_send_sync::<dyn Dct3<f32>>();
341 assert_send_sync::<dyn Dct4<f32>>();
342 assert_send_sync::<dyn Dct5<f32>>();
343 assert_send_sync::<dyn Dct6<f32>>();
344 assert_send_sync::<dyn Dct7<f32>>();
345 assert_send_sync::<dyn Dct8<f32>>();
346
347 assert_send_sync::<dyn Dct1<f64>>();
348 assert_send_sync::<dyn Dct2<f64>>();
349 assert_send_sync::<dyn Dct3<f64>>();
350 assert_send_sync::<dyn Dct4<f64>>();
351 assert_send_sync::<dyn Dct5<f64>>();
352 assert_send_sync::<dyn Dct6<f64>>();
353 assert_send_sync::<dyn Dct7<f64>>();
354 assert_send_sync::<dyn Dct8<f64>>();
355
356 assert_send_sync::<dyn Dst1<f32>>();
357 assert_send_sync::<dyn Dst2<f32>>();
358 assert_send_sync::<dyn Dst3<f32>>();
359 assert_send_sync::<dyn Dst4<f32>>();
360 assert_send_sync::<dyn Dst5<f32>>();
361 assert_send_sync::<dyn Dst6<f32>>();
362 assert_send_sync::<dyn Dst7<f32>>();
363 assert_send_sync::<dyn Dst8<f32>>();
364
365 assert_send_sync::<dyn Dst1<f64>>();
366 assert_send_sync::<dyn Dst2<f64>>();
367 assert_send_sync::<dyn Dst3<f64>>();
368 assert_send_sync::<dyn Dst4<f64>>();
369 assert_send_sync::<dyn Dst5<f64>>();
370 assert_send_sync::<dyn Dst6<f64>>();
371 assert_send_sync::<dyn Dst7<f64>>();
372 assert_send_sync::<dyn Dst8<f64>>();
373
374 assert_send_sync::<dyn mdct::Mdct<f32>>();
375 assert_send_sync::<dyn mdct::Mdct<f64>>();
376}