spec_cb: [Codebook<u16>; 15],
}
-fn scale_map(idx: usize) -> i8 { (idx as i8) - 60 }
-fn cb_map1(idx: usize) -> u16 { AVC_SPEC_CB1_SYMS[idx] }
-fn cb_map2(idx: usize) -> u16 { AVC_SPEC_CB2_SYMS[idx] }
-fn cb_map3(idx: usize) -> u16 { AVC_SPEC_CB3_SYMS[idx] }
-fn cb_map4(idx: usize) -> u16 { AVC_SPEC_CB4_SYMS[idx] }
-fn cb_map5(idx: usize) -> u16 { AVC_SPEC_CB5_SYMS[idx] }
-fn cb_map6(idx: usize) -> u16 { AVC_SPEC_CB6_SYMS[idx] }
-fn cb_map7(idx: usize) -> u16 { AVC_SPEC_CB7_SYMS[idx] }
-fn cb_map8(idx: usize) -> u16 { AVC_SPEC_CB8_SYMS[idx] }
-fn cb_map9(idx: usize) -> u16 { AVC_SPEC_CB9_SYMS[idx] }
-fn cb_map10(idx: usize) -> u16 { AVC_SPEC_CB10_SYMS[idx] }
-fn cb_map11(idx: usize) -> u16 { AVC_SPEC_CB11_SYMS[idx] }
-fn cb_map12(idx: usize) -> u16 { AVC_SPEC_CB12_SYMS[idx] }
-fn cb_map13(idx: usize) -> u16 { AVC_SPEC_CB13_SYMS[idx] }
-fn cb_map14(idx: usize) -> u16 { AVC_SPEC_CB14_SYMS[idx] }
-fn cb_map15(idx: usize) -> u16 { AVC_SPEC_CB15_SYMS[idx] }
-
impl Codebooks {
fn new() -> Self {
- let mut coderead = TableCodebookDescReader::new(AVC_SCF_CODEBOOK_CODES, AVC_SCF_CODEBOOK_BITS, scale_map);
+ let mut coderead = TableCodebookDescReader::new(AVC_SCF_CODEBOOK_CODES, AVC_SCF_CODEBOOK_BITS, |idx| (idx as i8) - 60);
let scale_cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB1_CODES, AVC_SPEC_CB1_BITS, cb_map1);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB1_CODES, AVC_SPEC_CB1_BITS, |idx| AVC_SPEC_CB1_SYMS[idx]);
let cb1 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB2_CODES, AVC_SPEC_CB2_BITS, cb_map2);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB2_CODES, AVC_SPEC_CB2_BITS, |idx| AVC_SPEC_CB2_SYMS[idx]);
let cb2 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB3_CODES, AVC_SPEC_CB3_BITS, cb_map3);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB3_CODES, AVC_SPEC_CB3_BITS, |idx| AVC_SPEC_CB3_SYMS[idx]);
let cb3 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB4_CODES, AVC_SPEC_CB4_BITS, cb_map4);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB4_CODES, AVC_SPEC_CB4_BITS, |idx| AVC_SPEC_CB4_SYMS[idx]);
let cb4 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB5_CODES, AVC_SPEC_CB5_BITS, cb_map5);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB5_CODES, AVC_SPEC_CB5_BITS, |idx| AVC_SPEC_CB5_SYMS[idx]);
let cb5 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB6_CODES, AVC_SPEC_CB6_BITS, cb_map6);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB6_CODES, AVC_SPEC_CB6_BITS, |idx| AVC_SPEC_CB6_SYMS[idx]);
let cb6 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB7_CODES, AVC_SPEC_CB7_BITS, cb_map7);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB7_CODES, AVC_SPEC_CB7_BITS, |idx| AVC_SPEC_CB7_SYMS[idx]);
let cb7 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB8_CODES, AVC_SPEC_CB8_BITS, cb_map8);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB8_CODES, AVC_SPEC_CB8_BITS, |idx| AVC_SPEC_CB8_SYMS[idx]);
let cb8 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB9_CODES, AVC_SPEC_CB9_BITS, cb_map9);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB9_CODES, AVC_SPEC_CB9_BITS, |idx| AVC_SPEC_CB9_SYMS[idx]);
let cb9 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB10_CODES, AVC_SPEC_CB10_BITS, cb_map10);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB10_CODES, AVC_SPEC_CB10_BITS, |idx| AVC_SPEC_CB10_SYMS[idx]);
let cb10 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB11_CODES, AVC_SPEC_CB11_BITS, cb_map11);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB11_CODES, AVC_SPEC_CB11_BITS, |idx| AVC_SPEC_CB11_SYMS[idx]);
let cb11 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB12_CODES, AVC_SPEC_CB12_BITS, cb_map12);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB12_CODES, AVC_SPEC_CB12_BITS, |idx| AVC_SPEC_CB12_SYMS[idx]);
let cb12 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB13_CODES, AVC_SPEC_CB13_BITS, cb_map13);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB13_CODES, AVC_SPEC_CB13_BITS, |idx| AVC_SPEC_CB13_SYMS[idx]);
let cb13 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB14_CODES, AVC_SPEC_CB14_BITS, cb_map14);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB14_CODES, AVC_SPEC_CB14_BITS, |idx| AVC_SPEC_CB14_SYMS[idx]);
let cb14 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
- let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB15_CODES, AVC_SPEC_CB15_BITS, cb_map15);
+ let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB15_CODES, AVC_SPEC_CB15_BITS, |idx| AVC_SPEC_CB15_SYMS[idx]);
let cb15 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
let spec_cb = [cb1, cb2, cb3, cb4, cb5, cb6, cb7, cb8, cb9, cb10, cb11, cb12, cb13, cb14, cb15];
Self { scale_cb, spec_cb }
let mut cur_band = 0;
let mut scale = 0;
let mut first = true;
- for wg in self.win_grp.iter().take(self.windows) {
- if *wg {
+ for wg in 0..self.windows {
+ if self.win_grp[wg] {
for _ in 0..bands {
if self.cbs[cur_band] == 0 {
- self.scales[cur_band] = 0;
- } else {
- if first {
- scale = br.read(7)? as i16;
- first = false
- } else {
- scale += i16::from(br.read_cb(&self.codebooks.scale_cb)?);
- validate!((scale >= 0) && (scale < 128));
+ let mut all_zero = true;
+ let mut band2 = cur_band;
+ for wg2 in wg + 1..self.windows {
+ if self.win_grp[wg2] {
+ break;
+ }
+ band2 += bands;
+ if self.cbs[band2] != 0 {
+ all_zero = false;
+ break;
+ }
+ }
+ if all_zero {
+ self.scales[cur_band] = 0;
+ cur_band += 1;
+ continue;
}
- self.scales[cur_band] = scale as u8;
}
+ if first {
+ scale = br.read(7)? as i16;
+ first = false;
+ } else {
+ scale += i16::from(br.read_cb(&self.codebooks.scale_cb)?);
+ validate!((0..128).contains(&scale));
+ }
+ self.scales[cur_band] = scale as u8;
cur_band += 1;
}
} else {
}
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];
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)) {
self.imdct_short.imdct(ain, aout);
}
self.ew_buf = [0.0; 1152];
- for i in 0..128 {
- self.ew_buf[i] = self.tmp[i];
- }
+ self.ew_buf[..128].copy_from_slice(&self.tmp[..128]);
for w in 0..7 {
overlap(&mut self.ew_buf[(w + 1) * 128..][..128],
&self.tmp[(w + 1) * 256..][..128],
&self.tmp[w * 256 + 128..][..128],
AVC_WIN_SHORT);
}
- for i in 0..128 {
- self.ew_buf[1024 + i] = self.tmp[7 * 256 + 128 + i];
- }
- for i in 0..SHORT_WIN_POINT0 {
- dst[i] = delay[i];
- }
+ self.ew_buf[1024..][..128].copy_from_slice(&self.tmp[7 * 256 + 128..][..128]);
+ dst[..SHORT_WIN_POINT0].copy_from_slice(&delay[..SHORT_WIN_POINT0]);
overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
&self.ew_buf[0..128],
&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 + 128];
- }
- 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;
+ dst[SHORT_WIN_POINT1..COEFFS].copy_from_slice(&self.ew_buf[128..][..COEFFS-SHORT_WIN_POINT1]);
+ delay[..SHORT_WIN_POINT1].copy_from_slice(&self.ew_buf[SHORT_WIN_POINT1..][..SHORT_WIN_POINT1]);
+ 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) {
+ dst[..SHORT_WIN_POINT0].copy_from_slice(&delay[..SHORT_WIN_POINT0]);
+ 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);
+ dst[SHORT_WIN_POINT1..COEFFS].copy_from_slice(&self.ew_buf[64..][..COEFFS-SHORT_WIN_POINT1]);
+ delay[..COEFFS/2].copy_from_slice(&self.ew_buf[COEFFS/2..COEFFS]);
+ for i in COEFFS/2..COEFFS {
+ delay[i] = delay[COEFFS - 1 - i];
+ }
+ }
}
}
}
}
+#[allow(clippy::identity_op)]
fn merge_bands(src: &[FFTComplex], dst: &mut [FFTComplex], size: usize) {
let step = if size == 512 { 2 } else { 4 };
let (s01, s23) = src.split_at(size / 2);
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; }
if val >= 0 {
qtab[val as usize] * scale
} else {
- -qtab[val.abs() as usize] * scale
+ -qtab[val.unsigned_abs() as usize] * scale
}
}
//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);
}