]> git.nihav.org Git - nihav.git/blob - nihav-core/src/dsp/mdct.rs
vp6: switch to MD5-based tests
[nihav.git] / nihav-core / src / dsp / mdct.rs
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 {
22 pub fn new(size: usize, scaledown: bool) -> Self {
23 let mut twiddle: Vec<FFTComplex> = Vec::with_capacity(size / 4);
24 let factor = 2.0 * consts::PI / ((8 * size) as f32);
25 let scale = if scaledown { (1.0 / (size as f32)).sqrt() } else { 1.0 };
26 for k in 0..size/4 {
27 twiddle.push(FFTComplex::exp(factor * ((8 * k + 1) as f32)).scale(scale));
28 }
29 let fft = FFTBuilder::new_fft(size/4, false);
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 }
42 self.fft.do_ifft_inplace(&mut self.z);
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 }
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 }
76 }