allow RDFT use inverse FFT and remove reversing results in Bink audio decoder
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 31 Jan 2019 10:09:59 +0000 (11:09 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 31 Jan 2019 10:09:59 +0000 (11:09 +0100)
nihav-core/src/dsp/fft.rs
nihav-rad/src/codecs/binkaud.rs

index b7bf77a0dd34795527a828269e160feef31c5443..3727e387c7151460bfa1ebf96b8513f980ec510a 100644 (file)
@@ -430,6 +430,7 @@ pub struct RDFT {
     fft:    FFT,
     fwd:    bool,
     size:   usize,
+    fwd_fft:    bool,
 }
 
 fn crossadd(a: &FFTComplex, b: &FFTComplex) -> FFTComplex {
@@ -460,7 +461,7 @@ impl RDFT {
             buf[0].re = a - b;
             buf[0].im = a + b;
         }
-        self.fft.do_fft_inplace(buf, true);
+        self.fft.do_fft_inplace(buf, self.fwd_fft);
         if self.fwd {
             for n in 0..self.size/2 {
                 let in0 = buf[n + 1];
@@ -489,14 +490,14 @@ pub struct RDFTBuilder {
 }
 
 impl RDFTBuilder {
-    pub fn new_rdft(mode: FFTMode, size: usize, forward: bool) -> RDFT {
+    pub fn new_rdft(mode: FFTMode, size: usize, forward: bool, forward_fft: bool) -> RDFT {
         let mut table: Vec<FFTComplex> = Vec::with_capacity(size / 4);
         let (base, scale) = if forward { (consts::PI / (size as f32), 0.5) } else { (-consts::PI / (size as f32), 1.0) };
         for i in 0..size/2 {
             table.push(FFTComplex::exp(base * ((i + 1) as f32)).scale(scale));
         }
         let fft = FFTBuilder::new_fft(mode, size);
-        RDFT { table, fft, size, fwd: forward }
+        RDFT { table, fft, size, fwd: forward, fwd_fft: forward_fft }
     }
 }
 
@@ -552,7 +553,7 @@ mod test {
     fn test_rdft() {
         let mut fin:   [FFTComplex; 128] = [FFTC_ZERO; 128];
         let mut fout1: [FFTComplex; 128] = [FFTC_ZERO; 128];
-        let mut rdft = RDFTBuilder::new_rdft(FFTMode::SplitRadix,  fin.len(), true);
+        let mut rdft = RDFTBuilder::new_rdft(FFTMode::SplitRadix,  fin.len(), true, true);
         let mut seed: u32 = 42;
         for i in 0..fin.len() {
             seed = seed.wrapping_mul(1664525).wrapping_add(1013904223);
@@ -563,7 +564,7 @@ mod test {
             fin[i].im = (val as f32) / 256.0;
         }
         rdft.do_rdft(&fin, &mut fout1);
-        let mut irdft = RDFTBuilder::new_rdft(FFTMode::SplitRadix,  fin.len(), false);
+        let mut irdft = RDFTBuilder::new_rdft(FFTMode::SplitRadix,  fin.len(), false, true);
         irdft.do_rdft_inplace(&mut fout1);
 
         for i in 0..fin.len() {
index a85a07ed00fd5ee2a3986dcb421d3b1863d9f5bc..05440190008cd533efb394ad4841cd2287045801 100644 (file)
@@ -152,15 +152,7 @@ impl BinkAudioDecoder {
             for i in 0..(self.len >> 4) {
                 self.delay[chno][i] = self.coeffs[self.duration + i];
             }
-        } else { // somehow it ends here in reverse order
-            for i in 0..self.len >> 2 {
-                let t0 = self.coeffs[self.len - 2 - i * 2];
-                let t1 = self.coeffs[self.len - 1 - i * 2];
-                self.coeffs[self.len - 2 - i * 2] = self.coeffs[i * 2];
-                self.coeffs[self.len - 1 - i * 2] = self.coeffs[i * 2 + 1];
-                self.coeffs[i * 2] = t0;
-                self.coeffs[i * 2 + 1] = t1;
-            }
+        } else {
             let overlap_len = if self.first_frm { 0 } else { self.len >> 8 };
             overlap(&self.delay[0], &self.coeffs[0..], &mut dst[off0..], overlap_len, 2);
             overlap(&self.delay[1], &self.coeffs[1..], &mut dst[off1..], overlap_len, 2);
@@ -211,7 +203,7 @@ impl NADecoder for BinkAudioDecoder {
                 self.duration >>= 1;
             }
             self.transform = if !self.use_dct {
-                    Transform::RDFT(RDFTBuilder::new_rdft(FFTMode::SplitRadix, self.len >> 1, false))
+                    Transform::RDFT(RDFTBuilder::new_rdft(FFTMode::SplitRadix, self.len >> 1, false, false))
                 } else {
                     Transform::DCT(DCT::new(DCTMode::DCT_III, self.len))
                 };