]> git.nihav.org Git - nihav.git/blobdiff - nihav-core/src/dsp/mdct.rs
core/dsp: document module
[nihav.git] / nihav-core / src / dsp / mdct.rs
index 540ae4527986b375f14420646fc6614753fc0c39..e6ed3dc9bdfd5994aad24ff48dca12e536e27362 100644 (file)
@@ -1,6 +1,8 @@
+//! Modified Discrete Cosine transform functionality.
 use std::f32::consts;
 use super::fft::*;
 
+/// IMDCT working context.
 pub struct IMDCT {
     twiddle:    Vec<FFTComplex>,
     fft:        FFT,
@@ -19,18 +21,20 @@ fn imdct(src: &[f32], dst: &mut [f32], length: usize) {
 }*/
 
 impl IMDCT {
-    pub fn new(mode: FFTMode, size: usize, scaledown: bool) -> Self {
+    /// Constructs a new instance of `IMDCT` context.
+    pub fn new(size: usize, scaledown: bool) -> Self {
         let mut twiddle: Vec<FFTComplex> = Vec::with_capacity(size / 4);
         let factor = 2.0 * consts::PI / ((8 * size) as f32);
         let scale = if scaledown { (1.0 / (size as f32)).sqrt() } else { 1.0 };
         for k in 0..size/4 {
             twiddle.push(FFTComplex::exp(factor * ((8 * k + 1) as f32)).scale(scale));
         }
-        let fft = FFTBuilder::new_fft(mode, size/4);
+        let fft = FFTBuilder::new_fft(size/4, false);
         let mut z: Vec<FFTComplex> = Vec::with_capacity(size / 2);
         z.resize(size / 2, FFTC_ZERO);
         IMDCT { twiddle, fft, size, z }
     }
+    /// Calculates IMDCT.
     pub fn imdct(&mut self, src: &[f32], dst: &mut [f32]) {
         let size2 = self.size / 2;
         let size4 = self.size / 4;
@@ -39,7 +43,7 @@ impl IMDCT {
             let c = FFTComplex { re: src[size2 - 2 * k - 1], im: src[        2 * k] };
             self.z[k] = c * self.twiddle[k];
         }
-        self.fft.do_fft_inplace(&mut self.z, false);
+        self.fft.do_ifft_inplace(&mut self.z);
         for k in 0..size4 {
             self.z[k] *= self.twiddle[k];
         }
@@ -54,4 +58,24 @@ impl IMDCT {
             dst[3 * size4 + 2 * n + 1] = -self.z[size4 - n - 1].re;
         }
     }
+    /// Calculates only non-mirrored part of IMDCT.
+    pub fn imdct_half(&mut self, src: &[f32], dst: &mut [f32]) {
+        let size2 = self.size / 2;
+        let size4 = self.size / 4;
+        let size8 = self.size / 8;
+        for k in 0..size4 {
+            let c = FFTComplex { re: src[size2 - 2 * k - 1], im: src[        2 * k] };
+            self.z[k] = c * self.twiddle[k];
+        }
+        self.fft.do_ifft_inplace(&mut self.z);
+        for k in 0..size4 {
+            self.z[k] *= self.twiddle[k];
+        }
+        for n in 0..size8 {
+            dst[        2 * n]     = -self.z[        n]    .re;
+            dst[        2 * n + 1] =  self.z[size4 - n - 1].im;
+            dst[size4 + 2 * n]     = -self.z[size8 + n]    .re;
+            dst[size4 + 2 * n + 1] =  self.z[size8 - n - 1].im;
+        }
+    }
 }