aac: clear M/S flags
[nihav.git] / nihav-duck / src / codecs / on2avc.rs
index 59fa8f8156d45fbe76ede4beccd5bc6c6a106958..9a0e0cd64e74d55c48c5370ebeff5f6f30bdcf23 100644 (file)
@@ -237,7 +237,7 @@ impl AVCDecoder {
                         first = false;
                     } else {
                         scale                   += i16::from(br.read_cb(&self.codebooks.scale_cb)?);
-                        validate!((scale >= 0) && (scale < 128));
+                        validate!((0..128).contains(&scale));
                     }
                     self.scales[cur_band] = scale as u8;
                     cur_band += 1;
@@ -346,7 +346,7 @@ impl AVCDecoder {
         }
         Ok(())
     }
-    #[allow(clippy::cyclomatic_complexity)]
+    #[allow(clippy::cognitive_complexity)]
     fn synth_channel(&mut self, chno: usize, dst: &mut [f32]) {
         let coeffs = &mut self.coeffs[chno];
         let delay  = &mut self.delay[chno];
@@ -355,23 +355,13 @@ impl AVCDecoder {
             0 | 1 => {
                 self.imdct_long.imdct_half(coeffs, &mut self.tmp);
                 overlap_half(dst, &self.tmp, delay, self.win_long);
-                (&mut delay[0..COEFFS/2]).copy_from_slice(&self.tmp[COEFFS/2..COEFFS]);
+                delay[0..COEFFS/2].copy_from_slice(&self.tmp[COEFFS/2..COEFFS]);
                 for i in COEFFS/2..COEFFS {
                     delay[i] = delay[COEFFS - 1 - i];
                 }
             },
             2 | 7 => {
-                self.imdct_long.imdct(coeffs, &mut self.tmp);
-                for i in 0..SHORT_WIN_POINT0 {
-                    dst[i] = delay[i];
-                }
-                overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                        &self.tmp[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                        &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
-                for i in SHORT_WIN_POINT1..COEFFS {
-                    dst[i] = self.tmp[i - SHORT_WIN_POINT1 + 128];
-                }
-                delay.copy_from_slice(&self.tmp[COEFFS..]);
+                self.imdct_long.imdct_half(coeffs, &mut self.ew_buf);
             },
             3 => {
                 for (ain, aout) in coeffs.chunks(128).zip(self.tmp.chunks_mut(256)) {
@@ -402,76 +392,52 @@ impl AVCDecoder {
                 for i in 0..SHORT_WIN_POINT1 {
                     delay[i] = self.ew_buf[SHORT_WIN_POINT1 + i];
                 }
-                for i in SHORT_WIN_POINT1..COEFFS {
-                    delay[i] = 0.0;
+                for i in COEFFS/2..COEFFS {
+                    delay[i] = delay[COEFFS - 1 - i];
                 }
             },
             4 => {
-                for i in 0..SHORT_WIN_POINT0 {
-                    dst[i] = delay[i];
-                }
                 if !self.use_generic {
                     synth1024(&mut self.dsp, coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz);
                 } else {
                     synth_generic(coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz, 1024);
                 }
-                overlap_half(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                             &self.ew_buf[0..64],
-                             &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
-                for i in SHORT_WIN_POINT1..COEFFS {
-                    dst[i] = self.ew_buf[i - SHORT_WIN_POINT1 + 64];
-                }
-                for i in 0..COEFFS/2 {
-                    delay[i] = self.ew_buf[COEFFS/2 + i];
-                }
-                for i in COEFFS/2..COEFFS {
-                    delay[i] = delay[COEFFS - 1 - i];
-                }
-            },
+             },
             5 => {
-                for i in 0..SHORT_WIN_POINT0 {
-                    dst[i] = delay[i];
-                }
                 if !self.use_generic {
                     synth512(&mut self.dsp, coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz);
                 } else {
                     synth_generic(coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz, 512);
                 }
-                self.imdct_mid.imdct(&coeffs[512..], &mut self.ew_buf[512..]);
-                overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                        &self.ew_buf[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                        &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
-                for i in SHORT_WIN_POINT1..COEFFS {
-                    dst[i] = self.ew_buf[i];
-                }
-                *delay = [0.0; COEFFS];
-                for i in 0..SHORT_WIN_POINT1 {
-                    delay[i] = self.ew_buf[i];
-                }
+                self.imdct_mid.imdct_half(&coeffs[512..], &mut self.ew_buf[512..]);
             },
             6 => {
-                for i in 0..SHORT_WIN_POINT0 {
-                    dst[i] = delay[i];
-                }
-                self.imdct_mid.imdct(coeffs, &mut self.ew_buf);
+                self.imdct_mid.imdct_half(coeffs, &mut self.ew_buf);
                 if !self.use_generic {
                     synth512(&mut self.dsp, &coeffs[512..], &mut self.ew_buf[512..], &mut self.tmp, self.is_40khz);
                 } else {
                     synth_generic(&coeffs[512..], &mut self.ew_buf[512..], &mut self.tmp, self.is_40khz, 512);
                 }
-                overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                        &self.ew_buf[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
-                        &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
-                for i in SHORT_WIN_POINT1..COEFFS {
-                    dst[i] = self.ew_buf[i];
-                }
-                *delay = [0.0; COEFFS];
-                for i in 0..SHORT_WIN_POINT1 {
-                    delay[i] = self.ew_buf[i];
-                }
             },
             _ => unreachable!(),
         };
+        if (self.cur_win == 2) || (self.cur_win >= 4) {
+            for i in 0..SHORT_WIN_POINT0 {
+                dst[i] = delay[i];
+            }
+            overlap_half(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
+                         &self.ew_buf[0..64],
+                         &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
+            for i in SHORT_WIN_POINT1..COEFFS {
+                dst[i] = self.ew_buf[i - SHORT_WIN_POINT1 + 64];
+            }
+            for i in 0..COEFFS/2 {
+                delay[i] = self.ew_buf[COEFFS/2 + i];
+            }
+            for i in COEFFS/2..COEFFS {
+                delay[i] = delay[COEFFS - 1 - i];
+            }
+        }
     }
 }
 
@@ -691,12 +657,12 @@ fn synth_recursive(dst: &mut [f32], tmp: &mut [f32], size: usize, order: &[u8],
         let idx = if !dir { i } else { bands - 1 - i };
         synth_filter(src, tmp, size, step, bands, idx);
     }
-    (&mut dst[..size]).copy_from_slice(&tmp[..size]);
+    dst[..size].copy_from_slice(&tmp[..size]);
 }
 
 fn synth_generic(src: &[f32], dst: &mut [f32], tmpbuf: &mut [f32; COEFFS * 2], is_40khz: bool, size: usize) {
     let order = if is_40khz { MERGE_ORDER_40K } else { MERGE_ORDER_44K };
-    (&mut dst[..size]).copy_from_slice(&src[..size]);
+    dst[..size].copy_from_slice(&src[..size]);
     let mut order_idx = 0;
     synth_recursive(dst, tmpbuf, size, order, &mut order_idx, false);
     for el in dst.iter_mut().take(COEFFS) { *el *= 0.125; }
@@ -942,7 +908,7 @@ fn dequant(val: i16, qtab: &[f32; QTAB_SIZE], scale: f32) -> f32 {
     if val >= 0 {
         qtab[val as usize] * scale
     } else {
-        -qtab[val.abs() as usize] * scale
+        -qtab[val.unsigned_abs() as usize] * scale
     }
 }
 
@@ -1094,6 +1060,7 @@ mod test {
 
         //let file = "assets/Duck/Cell-140.vp5";
         //let file = "assets/Duck/Chocolat-500.vp5";
+        // sample: https://samples.mplayerhq.hu/V-codecs/VP7/potter-500.vp7
         let file = "assets/Duck/potter-500.vp7";
         test_decode_audio("avi", file, Some(1500), None/*Some("avc")*/, &dmx_reg, &dec_reg);
     }