]>
Commit | Line | Data |
---|---|---|
f1f6f4aa KS |
1 | use std::f32::consts; |
2 | use super::fft::*; | |
3 | ||
4 | pub struct IMDCT { | |
5 | twiddle: Vec<FFTComplex>, | |
6 | fft: FFT, | |
7 | size: usize, | |
8 | z: Vec<FFTComplex>, | |
9 | } | |
10 | ||
11 | /* | |
12 | fn imdct(src: &[f32], dst: &mut [f32], length: usize) { | |
13 | for n in 0..length*2 { | |
14 | dst[n] = 0.0; | |
15 | for k in 0..length { | |
16 | dst[n] += src[k] * (consts::PI / (length as f32) * ((n as f32) + 0.5 + ((length/2) as f32)) * ((k as f32) + 0.5)).cos(); | |
17 | } | |
18 | } | |
19 | }*/ | |
20 | ||
21 | impl IMDCT { | |
9e78289c | 22 | pub fn new(size: usize, scaledown: bool) -> Self { |
f1f6f4aa KS |
23 | let mut twiddle: Vec<FFTComplex> = Vec::with_capacity(size / 4); |
24 | let factor = 2.0 * consts::PI / ((8 * size) as f32); | |
8cb5b63b | 25 | let scale = if scaledown { (1.0 / (size as f32)).sqrt() } else { 1.0 }; |
f1f6f4aa | 26 | for k in 0..size/4 { |
8cb5b63b | 27 | twiddle.push(FFTComplex::exp(factor * ((8 * k + 1) as f32)).scale(scale)); |
f1f6f4aa | 28 | } |
9e78289c | 29 | let fft = FFTBuilder::new_fft(size/4, false); |
f1f6f4aa KS |
30 | let mut z: Vec<FFTComplex> = Vec::with_capacity(size / 2); |
31 | z.resize(size / 2, FFTC_ZERO); | |
32 | IMDCT { twiddle, fft, size, z } | |
33 | } | |
34 | pub fn imdct(&mut self, src: &[f32], dst: &mut [f32]) { | |
35 | let size2 = self.size / 2; | |
36 | let size4 = self.size / 4; | |
37 | let size8 = self.size / 8; | |
38 | for k in 0..size4 { | |
39 | let c = FFTComplex { re: src[size2 - 2 * k - 1], im: src[ 2 * k] }; | |
40 | self.z[k] = c * self.twiddle[k]; | |
41 | } | |
9e78289c | 42 | self.fft.do_ifft_inplace(&mut self.z); |
f1f6f4aa KS |
43 | for k in 0..size4 { |
44 | self.z[k] *= self.twiddle[k]; | |
45 | } | |
46 | for n in 0..size8 { | |
47 | dst[ 2 * n] = -self.z[size8 + n] .im; | |
48 | dst[ 2 * n + 1] = self.z[size8 - n - 1].re; | |
49 | dst[ size4 + 2 * n] = -self.z[ n] .re; | |
50 | dst[ size4 + 2 * n + 1] = self.z[size4 - n - 1].im; | |
51 | dst[ size2 + 2 * n] = -self.z[size8 + n] .re; | |
52 | dst[ size2 + 2 * n + 1] = self.z[size8 - n - 1].im; | |
53 | dst[3 * size4 + 2 * n] = self.z[ n] .im; | |
54 | dst[3 * size4 + 2 * n + 1] = -self.z[size4 - n - 1].re; | |
55 | } | |
56 | } | |
9e424d2f KS |
57 | pub fn imdct_half(&mut self, src: &[f32], dst: &mut [f32]) { |
58 | let size2 = self.size / 2; | |
59 | let size4 = self.size / 4; | |
60 | let size8 = self.size / 8; | |
61 | for k in 0..size4 { | |
62 | let c = FFTComplex { re: src[size2 - 2 * k - 1], im: src[ 2 * k] }; | |
63 | self.z[k] = c * self.twiddle[k]; | |
64 | } | |
65 | self.fft.do_ifft_inplace(&mut self.z); | |
66 | for k in 0..size4 { | |
67 | self.z[k] *= self.twiddle[k]; | |
68 | } | |
69 | for n in 0..size8 { | |
70 | dst[ 2 * n] = -self.z[ n] .re; | |
71 | dst[ 2 * n + 1] = self.z[size4 - n - 1].im; | |
72 | dst[size4 + 2 * n] = -self.z[size8 + n] .re; | |
73 | dst[size4 + 2 * n + 1] = self.z[size8 - n - 1].im; | |
74 | } | |
75 | } | |
f1f6f4aa | 76 | } |