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}