1 use nihav_core::frame::*;
2 use nihav_core::codecs::*;
3 use nihav_core::io::byteio::read_u16le;
4 use nihav_core::io::bitreader::*;
5 use nihav_core::io::codebook::*;
6 use nihav_core::io::intcode::*;
7 use nihav_codec_support::dsp::fft::*;
8 use nihav_codec_support::dsp::mdct::IMDCT;
10 use std::str::FromStr;
12 use super::on2avcdata::*;
14 const COEFFS: usize = 1024;
15 const MAX_BANDS: usize = 14 * 8;
16 const QTAB_SIZE: usize = 10000;
17 const SHORT_WIN_POINT0: usize = 512 - 64;
18 const SHORT_WIN_POINT1: usize = 512 + 64;
22 bands: &'static [usize],
26 fn get_tot_bands(&self) -> usize {
36 scale_cb: Codebook<i8>,
37 spec_cb: [Codebook<u16>; 15],
40 fn scale_map(idx: usize) -> i8 { (idx as i8) - 60 }
41 fn cb_map1(idx: usize) -> u16 { AVC_SPEC_CB1_SYMS[idx] }
42 fn cb_map2(idx: usize) -> u16 { AVC_SPEC_CB2_SYMS[idx] }
43 fn cb_map3(idx: usize) -> u16 { AVC_SPEC_CB3_SYMS[idx] }
44 fn cb_map4(idx: usize) -> u16 { AVC_SPEC_CB4_SYMS[idx] }
45 fn cb_map5(idx: usize) -> u16 { AVC_SPEC_CB5_SYMS[idx] }
46 fn cb_map6(idx: usize) -> u16 { AVC_SPEC_CB6_SYMS[idx] }
47 fn cb_map7(idx: usize) -> u16 { AVC_SPEC_CB7_SYMS[idx] }
48 fn cb_map8(idx: usize) -> u16 { AVC_SPEC_CB8_SYMS[idx] }
49 fn cb_map9(idx: usize) -> u16 { AVC_SPEC_CB9_SYMS[idx] }
50 fn cb_map10(idx: usize) -> u16 { AVC_SPEC_CB10_SYMS[idx] }
51 fn cb_map11(idx: usize) -> u16 { AVC_SPEC_CB11_SYMS[idx] }
52 fn cb_map12(idx: usize) -> u16 { AVC_SPEC_CB12_SYMS[idx] }
53 fn cb_map13(idx: usize) -> u16 { AVC_SPEC_CB13_SYMS[idx] }
54 fn cb_map14(idx: usize) -> u16 { AVC_SPEC_CB14_SYMS[idx] }
55 fn cb_map15(idx: usize) -> u16 { AVC_SPEC_CB15_SYMS[idx] }
59 let mut coderead = TableCodebookDescReader::new(AVC_SCF_CODEBOOK_CODES, AVC_SCF_CODEBOOK_BITS, scale_map);
60 let scale_cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
61 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB1_CODES, AVC_SPEC_CB1_BITS, cb_map1);
62 let cb1 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
63 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB2_CODES, AVC_SPEC_CB2_BITS, cb_map2);
64 let cb2 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
65 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB3_CODES, AVC_SPEC_CB3_BITS, cb_map3);
66 let cb3 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
67 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB4_CODES, AVC_SPEC_CB4_BITS, cb_map4);
68 let cb4 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
69 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB5_CODES, AVC_SPEC_CB5_BITS, cb_map5);
70 let cb5 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
71 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB6_CODES, AVC_SPEC_CB6_BITS, cb_map6);
72 let cb6 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
73 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB7_CODES, AVC_SPEC_CB7_BITS, cb_map7);
74 let cb7 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
75 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB8_CODES, AVC_SPEC_CB8_BITS, cb_map8);
76 let cb8 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
77 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB9_CODES, AVC_SPEC_CB9_BITS, cb_map9);
78 let cb9 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
79 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB10_CODES, AVC_SPEC_CB10_BITS, cb_map10);
80 let cb10 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
81 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB11_CODES, AVC_SPEC_CB11_BITS, cb_map11);
82 let cb11 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
83 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB12_CODES, AVC_SPEC_CB12_BITS, cb_map12);
84 let cb12 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
85 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB13_CODES, AVC_SPEC_CB13_BITS, cb_map13);
86 let cb13 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
87 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB14_CODES, AVC_SPEC_CB14_BITS, cb_map14);
88 let cb14 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
89 let mut coderead = TableCodebookDescReader::new(AVC_SPEC_CB15_CODES, AVC_SPEC_CB15_BITS, cb_map15);
90 let cb15 = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
91 let spec_cb = [cb1, cb2, cb3, cb4, cb5, cb6, cb7, cb8, cb9, cb10, cb11, cb12, cb13, cb14, cb15];
92 Self { scale_cb, spec_cb }
101 synth_tmp: [FFTComplex; 512],
102 synth_out: [FFTComplex; 512],
107 let rdft512 = RDFTBuilder::new_rdft(512, true, true);
108 let rdft256 = RDFTBuilder::new_rdft(256, true, true);
109 let irdft128 = RDFTBuilder::new_rdft(128, false, false);
110 let irdft64 = RDFTBuilder::new_rdft(64, false, false);
112 rdft512, rdft256, irdft128, irdft64,
113 synth_tmp: [FFTC_ZERO; 512],
114 synth_out: [FFTC_ZERO; 512],
122 info: NACodecInfoRef,
125 codebooks: Codebooks,
128 win_long: &'static [f32; 1024],
132 winfo: &'static WinInfo,
136 ms_info: [bool; MAX_BANDS],
137 cbs: [u8; MAX_BANDS],
138 scales: [u8; MAX_BANDS],
143 coeffs: [[f32; COEFFS]; 2],
144 delay: [[f32; COEFFS]; 2],
145 tmp: [f32; COEFFS * 2],
149 qtab: [f32; QTAB_SIZE],
150 scale_tab: [f32; 128],
154 fn new(version: i32) -> Self {
155 let mut qtab = [0.0f32; QTAB_SIZE];
156 for (i, el) in qtab.iter_mut().enumerate() {
157 *el = (i as f32) * (i as f32).sqrt();
159 let mut scale_tab = [0.0f32; 128];
160 for (i, el) in scale_tab.iter_mut().enumerate() {
161 let pow = 10.0f32.powf((i as f32) * 0.1);
163 *el = (pow * 16.0).ceil() / 32.0;
165 *el = (pow * 0.5).ceil();
171 chmap: NAChannelMap::new(),
172 ainfo: NAAudioInfo::new(0, 0, SND_F32P_FORMAT, 0),
173 info: NACodecInfo::new_dummy(),
174 dsp: SynthDSP::new(),
176 codebooks: Codebooks::new(),
179 win_long: AVC_WIN_LONG_32K,
183 winfo: &AVC_WINFO_LONG,
187 ms_info: [false; MAX_BANDS],
189 scales: [0; MAX_BANDS],
191 imdct_long: IMDCT::new(1024 * 2, true),
192 imdct_mid: IMDCT::new(512 * 2, true),
193 imdct_short: IMDCT::new(128 * 2, true),
194 coeffs: [[0.0; COEFFS]; 2],
195 delay: [[0.0; COEFFS]; 2],
196 tmp: [0.0; COEFFS * 2],
204 fn decode_channel(&mut self, br: &mut BitReader, chno: usize) -> DecoderResult<()> {
205 let coeffs = &mut self.coeffs[chno];
207 decode_band_types(br, &mut self.cbs, self.winfo)?;
209 let bands = self.winfo.bands.len();
210 let mut cur_band = 0;
212 let mut first = true;
213 for wg in 0..self.windows {
214 if self.win_grp[wg] {
216 if self.cbs[cur_band] == 0 {
217 let mut all_zero = true;
218 let mut band2 = cur_band;
219 for wg2 in wg + 1..self.windows {
220 if self.win_grp[wg2] {
224 if self.cbs[band2] != 0 {
230 self.scales[cur_band] = 0;
236 scale = br.read(7)? as i16;
239 scale += i16::from(br.read_cb(&self.codebooks.scale_cb)?);
240 validate!((0..128).contains(&scale));
242 self.scales[cur_band] = scale as u8;
247 self.scales[cur_band] = self.scales[cur_band - bands];
253 let mut cur_band = 0;
255 *coeffs = [0.0; COEFFS];
256 for _ in 0..self.windows {
257 let mut band_start = 0;
258 for band_end in self.winfo.bands.iter() {
259 let band_size = *band_end - band_start;
260 let cb_idx = self.cbs[cur_band];
262 let cb = &self.codebooks.spec_cb[(cb_idx - 1) as usize];
263 let scale = self.scale_tab[self.scales[cur_band] as usize];
264 let dst = &mut coeffs[idx..][..band_size];
266 decode_quads(br, cb, &self.qtab, scale, dst)?;
268 decode_pairs(br, cb, &self.qtab, scale, dst, cb_idx == 15)?;
272 band_start = *band_end;
279 fn decode_frame(&mut self, br: &mut BitReader, adata: &mut NAAudioBuffer<f32>, offset: usize) -> DecoderResult<()> {
280 let enh_flag = br.read_bool()?;
281 validate!(!enh_flag);
282 self.prev_win = self.cur_win;
283 self.cur_win = br.read(3)? as u8;
284 self.winfo = match self.cur_win {
285 3 => &AVC_WINFO_SHORT,
286 4 => if self.is_40khz { &AVC_WINFO_40K_MODE4 } else { &AVC_WINFO_44K_MODE4 },
287 5 => if self.is_40khz { &AVC_WINFO_40K_MODE5 } else { &AVC_WINFO_44K_MODE5 },
288 6 => if self.is_40khz { &AVC_WINFO_40K_MODE6 } else { &AVC_WINFO_44K_MODE6 },
289 _ => &AVC_WINFO_LONG,
291 self.windows = if self.winfo.is_long { 1 } else { 8 };
292 let bands = self.winfo.bands.len();
293 self.win_grp[0] = true;
294 for el in self.win_grp.iter_mut().skip(1).take(self.windows - 1) {
295 *el = !br.read_bool()?;
298 self.ms_present = br.read_bool()?;
300 validate!(self.channels == 2);
301 let mut cur_band = 0;
302 for wg in self.win_grp.iter().take(self.windows) {
305 self.ms_info[cur_band] = br.read_bool()?;
310 self.ms_info[cur_band] = self.ms_info[cur_band - bands];
316 for ch in 0..self.channels {
317 self.decode_channel(br, ch)?;
320 if (self.channels == 2) && self.ms_present {
322 let mut cur_band = 0;
323 for _ in 0..self.windows {
324 let mut band_start = 0;
325 for band_end in self.winfo.bands.iter() {
326 let band_size = *band_end - band_start;
327 if self.ms_info[cur_band] {
328 for i in 0..band_size {
329 let l = self.coeffs[0][idx + i];
330 let r = self.coeffs[1][idx + i];
331 self.coeffs[0][idx + i] = l + r;
332 self.coeffs[1][idx + i] = l - r;
337 band_start = *band_end;
342 for ch in 0..self.channels {
343 let off = adata.get_offset(ch) + offset;
344 let output = adata.get_data_mut().unwrap();
345 self.synth_channel(ch, &mut output[off..][..COEFFS]);
349 #[allow(clippy::cognitive_complexity)]
350 fn synth_channel(&mut self, chno: usize, dst: &mut [f32]) {
351 let coeffs = &mut self.coeffs[chno];
352 let delay = &mut self.delay[chno];
356 self.imdct_long.imdct_half(coeffs, &mut self.tmp);
357 overlap_half(dst, &self.tmp, delay, self.win_long);
358 (&mut delay[0..COEFFS/2]).copy_from_slice(&self.tmp[COEFFS/2..COEFFS]);
359 for i in COEFFS/2..COEFFS {
360 delay[i] = delay[COEFFS - 1 - i];
364 self.imdct_long.imdct_half(coeffs, &mut self.ew_buf);
367 for (ain, aout) in coeffs.chunks(128).zip(self.tmp.chunks_mut(256)) {
368 self.imdct_short.imdct(ain, aout);
370 self.ew_buf = [0.0; 1152];
372 self.ew_buf[i] = self.tmp[i];
375 overlap(&mut self.ew_buf[(w + 1) * 128..][..128],
376 &self.tmp[(w + 1) * 256..][..128],
377 &self.tmp[w * 256 + 128..][..128],
381 self.ew_buf[1024 + i] = self.tmp[7 * 256 + 128 + i];
383 for i in 0..SHORT_WIN_POINT0 {
386 overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
387 &self.ew_buf[0..128],
388 &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
389 for i in SHORT_WIN_POINT1..COEFFS {
390 dst[i] = self.ew_buf[i - SHORT_WIN_POINT1 + 128];
392 for i in 0..SHORT_WIN_POINT1 {
393 delay[i] = self.ew_buf[SHORT_WIN_POINT1 + i];
395 for i in COEFFS/2..COEFFS {
396 delay[i] = delay[COEFFS - 1 - i];
400 if !self.use_generic {
401 synth1024(&mut self.dsp, coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz);
403 synth_generic(coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz, 1024);
407 if !self.use_generic {
408 synth512(&mut self.dsp, coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz);
410 synth_generic(coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz, 512);
412 self.imdct_mid.imdct_half(&coeffs[512..], &mut self.ew_buf[512..]);
415 self.imdct_mid.imdct_half(coeffs, &mut self.ew_buf);
416 if !self.use_generic {
417 synth512(&mut self.dsp, &coeffs[512..], &mut self.ew_buf[512..], &mut self.tmp, self.is_40khz);
419 synth_generic(&coeffs[512..], &mut self.ew_buf[512..], &mut self.tmp, self.is_40khz, 512);
424 if (self.cur_win == 2) || (self.cur_win >= 4) {
425 for i in 0..SHORT_WIN_POINT0 {
428 overlap_half(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1],
430 &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT);
431 for i in SHORT_WIN_POINT1..COEFFS {
432 dst[i] = self.ew_buf[i - SHORT_WIN_POINT1 + 64];
434 for i in 0..COEFFS/2 {
435 delay[i] = self.ew_buf[COEFFS/2 + i];
437 for i in COEFFS/2..COEFFS {
438 delay[i] = delay[COEFFS - 1 - i];
444 fn overlap(dst: &mut [f32], src: &[f32], delay: &[f32], win: &[f32]) {
445 for (i, ((out, s), d)) in dst.iter_mut().zip(src.iter()).zip(delay.iter()).enumerate() {
446 *out = *s * win[i] + *d * win[win.len() - 1 - i];
450 fn overlap_half(dst: &mut [f32], src: &[f32], delay: &[f32], win: &[f32]) {
454 let c = src [n/2 - 1 - i];
458 dst[i] = d * w1 - c * w0;
459 dst[ii] = d * w0 + c * w1;
463 #[derive(Clone,Copy)]
470 macro_rules! synth_step0_template {
471 ($name:ident, $tab: ident, $size: expr) => {
472 fn $name(src: &[f32], dst: &mut [f32], step: usize, off: usize, sp: &SynthParams) {
475 dst[i] += (f64::from(src[j]) * $tab[sp.idx][j][i]) as f32;
480 dst[$size - step + i] += (f64::from(src[sp.p0 + off + j]) * $tab[sp.idx][sp.p0 + j][i]) as f32;
487 synth_step0_template!(synth_step0_10, AVC_SYNTH_TABS10, 10);
488 synth_step0_template!(synth_step0_20, AVC_SYNTH_TABS20, 20);
489 synth_step0_template!(synth_step0_40, AVC_SYNTH_TABS40, 40);
490 synth_step0_template!(synth_step0_84, AVC_SYNTH_TABS84, 84);
492 fn synth_step1(src: &[f32], dst: &mut [f32], size: usize, stride: usize, step: usize, off: usize, mut p0: usize, win: &[f64])
494 let mut pos = step - 1;
496 let scale = f64::from(src[p0]);
499 for i in 0..pos.min(step) {
500 dst[pos - i] += (scale * win[i]) as f32;
506 fn zero_some(buf: &mut [FFTComplex], p0: usize, p1: usize)
508 for el in buf.iter_mut().take(p0/2) {
512 buf[p0 / 2].re = 0.0;
515 let dst = &mut buf[len - p1/2..];
516 for el in dst.iter_mut() {
520 buf[len - p1/2 - 1].im = 0.0;
524 fn merge_bands(src: &[FFTComplex], dst: &mut [FFTComplex], size: usize) {
525 let step = if size == 512 { 2 } else { 4 };
526 let (s01, s23) = src.split_at(size / 2);
527 let (src0, src1) = s01.split_at(size / 4);
528 let (src2, src3) = s23.split_at(size / 4);
529 let (t00, t01) = AVC_SYNTH_TAB0.split_at(512);
530 let (t10, t11) = AVC_SYNTH_TAB1.split_at(512);
531 let (t20, t21) = AVC_SYNTH_TAB2.split_at(512);
532 let (t30, t31) = AVC_SYNTH_TAB3.split_at(512);
533 let hsize = size / 2;
534 let qsize = size / 4;
535 let osize = size / 8;
536 dst[0].re = src0[0].re * t00[0] + src1[0].re * t10[0] + src2[0].re * t20[0] + src3[0].re * t30[0];
537 dst[0].im = src0[0].re * t00[1] + src1[0].re * t10[1] + src2[0].re * t20[1] + src3[0].re * t30[1];
538 dst[qsize].re = src0[0].im * t00[256] + src1[0].im * t10[256] +
539 src2[0].im * t20[256] + src3[0].im * t30[256];
540 dst[qsize].im = src0[0].im * t00[257] + src1[0].im * t10[257] +
541 src2[0].im * t20[257] + src3[0].im * t30[257];
547 let t0 = s0 * FFTComplex { re: t00[i * step + 0], im: t00[i * step + 1] } +
548 s1 * FFTComplex { re: t10[i * step + 0], im: t10[i * step + 1] } +
549 s2 * FFTComplex { re: t20[i * step + 0], im: t20[i * step + 1] } +
550 s3 * FFTComplex { re: t30[i * step + 0], im: t30[i * step + 1] };
551 let t1 = s0 * FFTComplex { re: t01[i * step + 0], im: t01[i * step + 1] } +
552 s1 * FFTComplex { re: t11[i * step + 0], im: t11[i * step + 1] } +
553 s2 * FFTComplex { re: t21[i * step + 0], im: t21[i * step + 1] } +
554 s3 * FFTComplex { re: t31[i * step + 0], im: t31[i * step + 1] };
559 dst[hsize].re = src0[0].im * t01[256] + src1[0].im * t11[256] +
560 src2[0].im * t21[256] + src3[0].im * t31[256];
561 dst[hsize].im = src0[0].im * t01[257] + src1[0].im * t11[257] +
562 src2[0].im * t21[257] + src3[0].im * t31[257];
563 dst[hsize + qsize].re = src0[0].re * t01[256] + src1[0].re * t11[256] +
564 src2[0].re * t21[256] + src3[0].re * t31[256];
565 dst[hsize + qsize].im = src0[0].re * t01[257] + src1[0].re * t11[257] +
566 src2[0].re * t21[257] + src3[0].re * t31[257];
568 let s0 = !src0[qsize - i];
569 let s1 = !src1[qsize - i];
570 let s2 = !src2[qsize - i];
571 let s3 = !src3[qsize - i];
572 let t0 = s0 * FFTComplex { re: t00[256 + i * step + 0], im: t00[256 + i * step + 1] } +
573 s1 * FFTComplex { re: t10[256 + i * step + 0], im: t10[256 + i * step + 1] } +
574 s2 * FFTComplex { re: t20[256 + i * step + 0], im: t20[256 + i * step + 1] } +
575 s3 * FFTComplex { re: t30[256 + i * step + 0], im: t30[256 + i * step + 1] };
576 let t1 = s0 * FFTComplex { re: t01[256 + i * step + 0], im: t01[256 + i * step + 1] } +
577 s1 * FFTComplex { re: t11[256 + i * step + 0], im: t11[256 + i * step + 1] } +
578 s2 * FFTComplex { re: t21[256 + i * step + 0], im: t21[256 + i * step + 1] } +
579 s3 * FFTComplex { re: t31[256 + i * step + 0], im: t31[256 + i * step + 1] };
580 dst[hsize + i] = !t0;
581 dst[hsize + qsize + i] = !t1;
585 const SPARAMS10: [SynthParams; 2] = [
586 SynthParams { p0: 1, p1: 3, idx: 0 },
587 SynthParams { p0: 3, p1: 1, idx: 1 } ];
588 const SPARAMS20: [SynthParams; 2] = [
589 SynthParams { p0: 5, p1: 4, idx: 0 },
590 SynthParams { p0: 4, p1: 5, idx: 1 } ];
591 const SPARAMS40: [SynthParams; 2] = [
592 SynthParams { p0: 11, p1: 8, idx: 0 },
593 SynthParams { p0: 8, p1: 11, idx: 1 } ];
594 const SPARAMS84: [SynthParams; 4] = [
595 SynthParams { p0: 16, p1: 4, idx: 0 },
596 SynthParams { p0: 16, p1: 4, idx: 1 },
597 SynthParams { p0: 13, p1: 7, idx: 2 },
598 SynthParams { p0: 15, p1: 5, idx: 3 } ];
600 const MERGE_ORDER_44K: &[u8] = &[
601 4, 4, 2, 2, 0, 0, 2, 0, 0, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0,
602 2, 0, 0, 4, 0, 0, 0, 0, 2, 0, 0, 0
604 const MERGE_ORDER_40K: &[u8] = &[
605 4, 4, 2, 2, 0, 0, 2, 0, 0, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0,
606 2, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0
609 fn synth_filter(src: &[f32], dst: &mut [f32], len: usize, step: usize, bands: usize, idx: usize)
611 let off = (len - step) / bands + 1;
612 let params = match step {
613 10 => &SPARAMS10[idx],
614 20 => &SPARAMS20[idx],
615 40 => &SPARAMS40[idx],
616 _ => &SPARAMS84[idx],
620 synth_step0_10(src, dst, step, off, params);
621 synth_step1(src, dst, len, bands, step, off, params.p0, &AVC_TAB10[idx]);
622 } else if step == 20 {
623 synth_step0_20(src, dst, step, off, params);
624 synth_step1(src, dst, len, bands, step, off, params.p0, &AVC_TAB20[idx]);
625 } else if step == 40 {
626 synth_step0_40(src, dst, step, off, params);
627 synth_step1(src, dst, len, bands, step, off, params.p0, &AVC_TAB40[idx]);
629 synth_step0_84(src, dst, step, off, params);
630 synth_step1(src, dst, len, bands, step, off, params.p0, &AVC_TAB84[idx]);
634 fn synth_recursive(dst: &mut [f32], tmp: &mut [f32], size: usize, order: &[u8], order_idx: &mut usize, dir: bool) {
635 let bands = order[*order_idx] as usize;
637 if bands == 0 { return; }
638 let sub_size = size / bands;
639 let mut sub_dir = false;
640 for (dst, tmp) in dst.chunks_mut(sub_size).take(bands).zip(tmp.chunks_mut(sub_size)) {
641 synth_recursive(dst, tmp, sub_size, order, order_idx, sub_dir);
644 for el in tmp.iter_mut().take(size) { *el = 0.0; }
645 let step = if bands == 2 {
648 } else if sub_size <= 40 {
656 for (i, src) in dst.chunks_mut(sub_size).take(bands).enumerate() {
657 let idx = if !dir { i } else { bands - 1 - i };
658 synth_filter(src, tmp, size, step, bands, idx);
660 (&mut dst[..size]).copy_from_slice(&tmp[..size]);
663 fn synth_generic(src: &[f32], dst: &mut [f32], tmpbuf: &mut [f32; COEFFS * 2], is_40khz: bool, size: usize) {
664 let order = if is_40khz { MERGE_ORDER_40K } else { MERGE_ORDER_44K };
665 (&mut dst[..size]).copy_from_slice(&src[..size]);
666 let mut order_idx = 0;
667 synth_recursive(dst, tmpbuf, size, order, &mut order_idx, false);
668 for el in dst.iter_mut().take(COEFFS) { *el *= 0.125; }
671 fn synth1024(dsp: &mut SynthDSP, src: &[f32], dst: &mut [f32], tmpbuf: &mut [f32; COEFFS * 2], is_40khz: bool) {
672 for el in tmpbuf.iter_mut() {
675 let (tmp, tmp2) = tmpbuf.split_at_mut(COEFFS);
676 for el in dsp.synth_tmp.iter_mut() { *el = FFTC_ZERO; }
677 for el in dsp.synth_out.iter_mut() { *el = FFTC_ZERO; }
679 let (size, step, stride) = (32, 20, 2);
680 let off = (size - step) / stride + 1;
681 let mut sparam0 = SynthParams { p0: 5, p1: 4, idx: 0 };
682 let mut sparam1 = SynthParams { p0: 4, p1: 5, idx: 1 };
683 for (i, dst) in tmp.chunks_mut(size).take(8).enumerate() {
684 let coeffs = &src[i * 32..];
685 synth_step0_20(coeffs, dst, step, off, &sparam0);
686 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, &AVC_TAB20[sparam0.idx]);
687 let coeffs = &src[i * 32 + 16..];
688 synth_step0_20(coeffs, dst, step, off, &sparam1);
689 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, &AVC_TAB20[sparam1.idx]);
690 std::mem::swap(&mut sparam0, &mut sparam1);
693 let (size, step, stride) = (64, 40, 2);
694 let off = (size - step) / stride + 1;
695 let mut sparam0 = SynthParams { p0: 11, p1: 8, idx: 0 };
696 let mut sparam1 = SynthParams { p0: 8, p1: 11, idx: 1 };
697 let nchunks = if !is_40khz { 8 } else { 12 };
698 for (i, dst) in tmp2.chunks_mut(size).take(nchunks).enumerate() {
699 let coeffs = if i < 4 { &tmp[i * 64..] } else { &src[i * 64 + 32..] };
700 synth_step0_40(coeffs, dst, step, off, &sparam0);
701 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, &AVC_TAB40[sparam0.idx]);
702 let coeffs = if i < 4 { &tmp[i * 64 + 32..] } else { &src[i * 64 + 32..] };
703 synth_step0_40(coeffs, dst, step, off, &sparam1);
704 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, &AVC_TAB40[sparam1.idx]);
705 std::mem::swap(&mut sparam0, &mut sparam1);
708 for el in tmp.iter_mut().take(128) {
711 let (size, step, stride) = (256, 84, 4);
712 let off = (size - step) / stride + 1;
714 let coeffs = &tmp2[i * 64..];
715 synth_step0_84(coeffs, tmp, step, off, &SPARAMS84[i]);
716 synth_step1(coeffs, tmp, size, stride, step, off, SPARAMS84[i].p0, &AVC_TAB84[i]);
719 let coeffs = if i < 2 && is_40khz { &tmp2[256 + i * 64..] } else { &src[256 + i * 64..] };
720 let dst = &mut tmp[256..];
721 synth_step0_84(coeffs, dst, step, off, &SPARAMS84[3 - i]);
722 synth_step1(coeffs, dst, size, stride, step, off, SPARAMS84[3 - i].p0, &AVC_TAB84[3 - i]);
726 let (size, step, stride) = (256, 40, 2);
727 let off = (size - step) / stride + 1;
728 let sparams = [ SynthParams { p0: 11, p1: 8, idx: 0 },
729 SynthParams { p0: 8, p1: 11, idx: 1 } ];
731 let coeffs = &src[512 + i * 128..];
732 let dst = &mut tmp[512..];
733 synth_step0_40(coeffs, dst, step, off, &sparams[i]);
734 synth_step1(coeffs, dst, size, stride, step, off, sparams[i].p0, &AVC_TAB40[i]);
737 let (size, step, stride) = (256, 84, 4);
738 let off = (size - step) / stride + 1;
740 let coeffs = &src[512 + i * 64..];
741 let dst = &mut tmp[512..];
742 synth_step0_84(coeffs, dst, step, off, &SPARAMS84[i]);
743 synth_step1(coeffs, dst, size, stride, step, off, SPARAMS84[i].p0, &AVC_TAB84[i]);
747 for (i, s) in tmp.chunks(2).take(768/2).enumerate() {
748 dsp.synth_tmp[i] = FFTComplex { re: s[0], im: s[1] };
750 for i in (768..1024).step_by(2) {
751 dsp.synth_tmp[i >> 1] = FFTComplex { re: src[i], im: src[i + 1] };
754 let dst = &mut tmp[768..1024];
755 dst.copy_from_slice(&src[768..1024]);
757 for (i, chunk) in dsp.synth_tmp.chunks_exact_mut(128).enumerate() {
758 zero_some(chunk, SPARAMS84[i].p0, SPARAMS84[i].p1);
760 for chunk in dsp.synth_tmp.chunks_exact_mut(128) {
761 dsp.irdft128.do_rdft_inplace(chunk);
762 for el in chunk.iter_mut() { *el = el.scale(1.0/128.0f32); }
764 merge_bands(&dsp.synth_tmp, &mut dsp.synth_out, 512);
765 dsp.rdft512.do_rdft_inplace(&mut dsp.synth_out);
766 for (out, src) in dst.chunks_exact_mut(2).zip(dsp.synth_out.iter()) {
767 out[0] = src.re * (1.0 / 1024.0f32.sqrt());
768 out[1] = src.im * (1.0 / 1024.0f32.sqrt());
770 let (size, step, stride) = (1024, 84, 4);
771 let off = (size - step) / stride + 1;
773 let src = &tmp[256 * i..];
774 synth_step0_84(src, dst, step, off, &SPARAMS84[i]);
777 fn synth512(dsp: &mut SynthDSP, src: &[f32], dst: &mut [f32], tmpbuf: &mut [f32; COEFFS * 2], is_40khz: bool) {
778 for el in tmpbuf.iter_mut() {
781 let (tmp, tmp2) = tmpbuf.split_at_mut(COEFFS);
783 let (size, step, stride) = (16, 10, 2);
784 let off = (size - step) / stride + 1;
785 let mut sparam0 = SynthParams { p0: 1, p1: 3, idx: 0 };
786 let mut sparam1 = SynthParams { p0: 3, p1: 1, idx: 1 };
787 let mut tab_ptr0: &[f64] = AVC_TAB10_0;
788 let mut tab_ptr1: &[f64] = AVC_TAB10_1;
789 for (i, dst) in tmp.chunks_mut(size).take(8).enumerate() {
790 let coeffs = &src[i * 16..];
791 synth_step0_10(coeffs, dst, step, off, &sparam0);
792 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, tab_ptr0);
793 let coeffs = &src[i * 16 + 8..];
794 synth_step0_10(coeffs, dst, step, off, &sparam1);
795 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, tab_ptr1);
796 std::mem::swap(&mut sparam0, &mut sparam1);
797 std::mem::swap(&mut tab_ptr0, &mut tab_ptr1);
800 let (size, step, stride) = (32, 20, 2);
801 let off = (size - step) / stride + 1;
802 let mut sparam0 = SynthParams { p0: 5, p1: 4, idx: 0 };
803 let mut sparam1 = SynthParams { p0: 4, p1: 5, idx: 1 };
804 let nchunks = if !is_40khz { 8 } else { 12 };
805 for (i, dst) in tmp2.chunks_mut(size).take(nchunks).enumerate() {
806 let coeffs = if i < 4 { &tmp[i * 32..] } else { &src[i * 32..] };
807 synth_step0_20(coeffs, dst, step, off, &sparam0);
808 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, &AVC_TAB20[sparam0.idx]);
809 let coeffs = if i < 4 { &tmp[i * 32 + 16..] } else { &src[i * 32 + 16..] };
810 synth_step0_20(coeffs, dst, step, off, &sparam1);
811 synth_step1(coeffs, dst, size, stride, step, off, sparam0.p0, &AVC_TAB20[sparam1.idx]);
812 std::mem::swap(&mut sparam0, &mut sparam1);
815 for el in tmp.iter_mut().take(64) {
818 let (size, step, stride) = (128, 84, 4);
819 let off = (size - step) / stride + 1;
821 let coeffs = &tmp2[i * 32..];
822 synth_step0_84(coeffs, tmp, step, off, &SPARAMS84[i]);
823 synth_step1(coeffs, tmp, size, stride, step, off, SPARAMS84[i].p0, &AVC_TAB84[i]);
826 let coeffs = if i < 2 && is_40khz { &tmp2[128 + i * 32..] } else { &src[128 + i * 32..] };
827 let dst = &mut tmp[128..];
828 synth_step0_84(coeffs, dst, step, off, &SPARAMS84[3 - i]);
829 synth_step1(coeffs, dst, size, stride, step, off, SPARAMS84[3 - i].p0, &AVC_TAB84[3 - i]);
833 let (size, step, stride) = (128, 40, 2);
834 let off = (size - step) / stride + 1;
835 let sparams = [ SynthParams { p0: 11, p1: 8, idx: 0 },
836 SynthParams { p0: 8, p1: 11, idx: 1 } ];
838 let coeffs = &src[256 + i * 64..];
839 let dst = &mut tmp[256..];
840 synth_step0_40(coeffs, dst, step, off, &sparams[i]);
841 synth_step1(coeffs, dst, size, stride, step, off, sparams[i].p0, &AVC_TAB40[i]);
844 let (size, step, stride) = (128, 84, 4);
845 let off = (size - step) / stride + 1;
847 let coeffs = &src[256 + i * 32..];
848 let dst = &mut tmp[256..];
849 synth_step0_84(coeffs, dst, step, off, &SPARAMS84[i]);
850 synth_step1(coeffs, dst, size, stride, step, off, SPARAMS84[i].p0, &AVC_TAB84[i]);
854 for (i, s) in tmp.chunks(2).take(384/2).enumerate() {
855 dsp.synth_tmp[i] = FFTComplex { re: s[0], im: s[1] };
857 for i in (384..512).step_by(2) {
858 dsp.synth_tmp[i >> 1] = FFTComplex { re: src[i], im: src[i + 1] };
861 let dst = &mut tmp[384..512];
862 dst.copy_from_slice(&src[384..512]);
864 for (i, chunk) in dsp.synth_tmp.chunks_exact_mut(128).enumerate() {
865 zero_some(chunk, SPARAMS84[i].p0, SPARAMS84[i].p1);
867 for chunk in dsp.synth_tmp.chunks_exact_mut(64) {
868 dsp.irdft64.do_rdft_inplace(chunk);
870 merge_bands(&dsp.synth_tmp, &mut dsp.synth_out, 256);
871 dsp.rdft256.do_rdft_inplace(&mut dsp.synth_out);
872 for (out, src) in dst.chunks_exact_mut(2).zip(dsp.synth_out.iter()).take(256) {
873 out[0] = src.re * (1.0 / 512.0f32 / 1024.0f32);
874 out[1] = src.im * (1.0 / 512.0f32 / 1024.0f32);
876 let (size, step, stride) = (512, 84, 4);
877 let off = (size - step) / stride + 1;
879 let src = &tmp[128 * i..];
880 synth_step0_84(src, dst, step, off, &SPARAMS84[i]);
884 fn decode_band_types(br: &mut BitReader, cbs: &mut [u8; MAX_BANDS], winfo: &WinInfo) -> DecoderResult<()> {
885 let bits_per_sect = if winfo.is_long { 5 } else { 3 };
886 let esc_val = (1 << bits_per_sect) - 1;
887 let tot_bands = winfo.get_tot_bands();
889 let mut cur_band = 0;
890 while cur_band < tot_bands {
891 let codebook = br.read(4)? as u8;
894 let run_add = br.read(bits_per_sect)? as usize;
896 if run_add != esc_val { break; }
898 validate!(cur_band + run <= tot_bands);
900 cbs[cur_band] = codebook;
907 fn dequant(val: i16, qtab: &[f32; QTAB_SIZE], scale: f32) -> f32 {
909 qtab[val as usize] * scale
911 -qtab[val.abs() as usize] * scale
915 fn decode_quads(br: &mut BitReader, cb: &Codebook<u16>, qtab: &[f32; QTAB_SIZE], scale: f32, dst: &mut [f32]) -> DecoderResult<()> {
916 for quad in dst.chunks_exact_mut(4) {
917 let mut idx = br.read_cb(cb)? as i16;
918 for el in quad.iter_mut() {
919 *el = dequant(idx >> 12, qtab, scale);
926 fn decode_esc_val(br: &mut BitReader, qtab: &[f32; QTAB_SIZE], scale: f32, sign: bool) -> DecoderResult<f32> {
927 let pfx = br.read_code(UintCodeType::LimitedOnes(24))? + 4;
928 let add = br.read(pfx as u8)? as usize;
929 let val = (1 << pfx) + add;
930 let fval = scale * if val < qtab.len() {
933 (val as f32) * (val as f32).sqrt()
942 fn decode_pairs(br: &mut BitReader, cb: &Codebook<u16>, qtab: &[f32; QTAB_SIZE], scale: f32, dst: &mut [f32], is_esc: bool) -> DecoderResult<()> {
943 for pair in dst.chunks_exact_mut(2) {
944 let idx = br.read_cb(cb)? as i16;
946 let idx1 = (idx << 8) >> 8;
947 if !is_esc || (idx0.abs() < 16) {
948 pair[0] = dequant(idx0, qtab, scale);
950 pair[0] = decode_esc_val(br, qtab, scale, idx0 < 0)?;
952 if !is_esc || (idx1.abs() < 16) {
953 pair[1] = dequant(idx1, qtab, scale);
955 pair[1] = decode_esc_val(br, qtab, scale, idx1 < 0)?;
961 impl NADecoder for AVCDecoder {
962 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
963 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
964 self.chmap = match ainfo.get_channels() {
965 1 => { NAChannelMap::from_str("C").unwrap() },
966 2 => { NAChannelMap::from_str("L,R").unwrap() },
967 _ => { return Err(DecoderError::InvalidData); },
969 let srate = ainfo.get_sample_rate();
970 self.ainfo = NAAudioInfo::new(srate, ainfo.get_channels(),
971 SND_F32P_FORMAT, COEFFS);
972 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
973 self.channels = ainfo.get_channels() as usize;
974 self.is_40khz = srate <= 40000;
976 self.win_long = if (srate > 24000) && ((srate > 32000) || (self.channels == 2)) {
984 Err(DecoderError::InvalidData)
987 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
988 let info = pkt.get_stream().get_info();
989 validate!(info.get_properties().is_audio());
990 let src = pkt.get_buffer();
994 if self.version == 500 {
995 abuf = alloc_audio_buffer(self.ainfo, COEFFS, self.chmap.clone())?;
996 let mut adata = abuf.get_abuf_f32().unwrap();
997 let mut br = BitReader::new(src.as_slice(), BitReaderMode::BE);
998 self.decode_frame(&mut br, &mut adata, 0)?;
1000 let mut offsets: Vec<usize> = Vec::new();
1001 let mut sizes: Vec<usize> = Vec::new();
1003 let mut cur_off = 0;
1004 while cur_off + 2 < src.len() {
1005 let sz = read_u16le(&src[cur_off..])? as usize;
1007 validate!(cur_off + sz + 2 <= src.len());
1008 offsets.push(cur_off + 2);
1013 validate!(!sizes.is_empty());
1015 abuf = alloc_audio_buffer(self.ainfo, COEFFS * sizes.len(), self.chmap.clone())?;
1016 let mut adata = abuf.get_abuf_f32().unwrap();
1017 let mut aoffset = 0;
1018 for (o, s) in offsets.iter().zip(sizes.iter()) {
1019 let mut br = BitReader::new(&src[*o..][..*s], BitReaderMode::BE);
1020 self.decode_frame(&mut br, &mut adata, aoffset)?;
1025 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
1026 frm.set_keyframe(true);
1029 fn flush(&mut self) {
1033 impl NAOptionHandler for AVCDecoder {
1034 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1035 fn set_options(&mut self, _options: &[NAOption]) { }
1036 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1039 pub fn get_decoder_500() -> Box<dyn NADecoder + Send> {
1040 Box::new(AVCDecoder::new(500))
1043 pub fn get_decoder_501() -> Box<dyn NADecoder + Send> {
1044 Box::new(AVCDecoder::new(501))
1049 use nihav_core::codecs::RegisteredDecoders;
1050 use nihav_core::demuxers::RegisteredDemuxers;
1051 use nihav_codec_support::test::dec_video::*;
1052 use crate::duck_register_all_decoders;
1053 use nihav_commonfmt::generic_register_all_demuxers;
1056 let mut dmx_reg = RegisteredDemuxers::new();
1057 generic_register_all_demuxers(&mut dmx_reg);
1058 let mut dec_reg = RegisteredDecoders::new();
1059 duck_register_all_decoders(&mut dec_reg);
1061 //let file = "assets/Duck/Cell-140.vp5";
1062 //let file = "assets/Duck/Chocolat-500.vp5";
1063 // sample: https://samples.mplayerhq.hu/V-codecs/VP7/potter-500.vp7
1064 let file = "assets/Duck/potter-500.vp7";
1065 test_decode_audio("avi", file, Some(1500), None/*Some("avc")*/, &dmx_reg, &dec_reg);
1069 const AVC_WINFO_LONG: WinInfo = WinInfo {
1072 4, 8, 12, 16, 20, 24, 28, 32,
1073 36, 40, 48, 56, 64, 72, 80, 88,
1074 96, 108, 120, 132, 144, 156, 172, 188,
1075 204, 224, 244, 264, 288, 312, 340, 368,
1076 400, 432, 464, 496, 528, 560, 592, 624,
1077 656, 688, 720, 752, 784, 816, 848, 880, 1024
1081 const AVC_WINFO_SHORT: WinInfo = WinInfo {
1083 bands: &[ 4, 8, 12, 16, 20, 24, 32, 40, 48, 56, 68, 80, 108, 128 ],
1086 const AVC_WINFO_40K_MODE4: WinInfo = WinInfo {
1089 8, 16, 24, 32, 40, 48, 56, 64,
1090 72, 80, 88, 96, 104, 112, 120, 128,
1091 144, 160, 176, 192, 208, 224, 240, 256,
1092 264, 272, 280, 288, 296, 304, 312, 320,
1093 328, 336, 344, 352, 360, 368, 376, 384,
1094 400, 416, 432, 448, 464, 480, 496, 512,
1095 520, 528, 536, 544, 552, 560, 568, 576,
1096 584, 592, 600, 608, 616, 624, 632, 640,
1097 648, 656, 664, 672, 680, 688, 696, 704,
1098 712, 720, 728, 736, 744, 752, 760, 768,
1099 800, 832, 864, 896, 928, 960, 992, 1024
1102 const AVC_WINFO_40K_MODE5: WinInfo = WinInfo {
1105 8, 16, 24, 32, 40, 48, 56, 64,
1106 80, 96, 112, 128, 136, 144, 152, 160,
1107 168, 176, 184, 192, 208, 224, 240, 256,
1108 264, 272, 280, 288, 296, 304, 312, 320,
1109 328, 336, 344, 352, 360, 368, 376, 384,
1110 416, 448, 480, 512, 516, 520, 524, 528,
1111 532, 536, 540, 548, 556, 568, 580, 592,
1112 608, 624, 640, 656, 672, 688, 704, 720,
1113 736, 752, 768, 784, 800, 816, 832, 848,
1114 864, 880, 896, 912, 928, 944, 1024
1117 const AVC_WINFO_40K_MODE6: WinInfo = WinInfo {
1120 4, 8, 12, 16, 20, 24, 28, 36,
1121 44, 56, 68, 80, 96, 112, 128, 144,
1122 160, 176, 192, 208, 224, 240, 256, 272,
1123 288, 304, 320, 336, 352, 368, 384, 400,
1124 416, 432, 512, 520, 528, 536, 544, 552,
1125 560, 568, 576, 592, 608, 624, 640, 648,
1126 656, 664, 672, 680, 688, 696, 704, 720,
1127 736, 752, 768, 776, 784, 792, 800, 808,
1128 816, 824, 832, 840, 848, 856, 864, 872,
1129 880, 888, 896, 928, 960, 992, 1024
1133 const AVC_WINFO_44K_MODE4: WinInfo = WinInfo {
1136 8, 16, 24, 32, 40, 48, 56, 64,
1137 72, 80, 88, 96, 104, 112, 120, 128,
1138 136, 144, 152, 160, 168, 176, 184, 192,
1139 200, 208, 216, 224, 232, 240, 248, 256,
1140 264, 272, 280, 288, 296, 304, 312, 320,
1141 328, 336, 344, 352, 360, 368, 376, 384,
1142 392, 400, 408, 416, 424, 432, 440, 448,
1143 456, 464, 472, 480, 488, 496, 504, 512,
1144 528, 544, 560, 576, 592, 608, 624, 640,
1145 672, 704, 736, 768, 832, 896, 960, 1024
1148 const AVC_WINFO_44K_MODE5: WinInfo = WinInfo {
1151 8, 16, 24, 32, 40, 48, 56, 64,
1152 72, 80, 88, 96, 104, 112, 120, 128,
1153 136, 144, 152, 160, 168, 176, 184, 192,
1154 200, 208, 216, 224, 232, 240, 248, 256,
1155 272, 288, 304, 320, 352, 384, 448, 512,
1156 516, 520, 524, 528, 532, 536, 540, 548,
1157 556, 568, 580, 592, 608, 624, 640, 656,
1158 672, 688, 704, 720, 736, 752, 768, 784,
1159 800, 816, 832, 848, 864, 880, 896, 912,
1163 const AVC_WINFO_44K_MODE6: WinInfo = WinInfo {
1166 4, 8, 12, 16, 20, 24, 28, 36,
1167 44, 56, 68, 80, 96, 112, 128, 144,
1168 160, 176, 192, 208, 224, 240, 256, 272,
1169 288, 304, 320, 336, 352, 368, 384, 400,
1170 416, 432, 512, 520, 528, 536, 544, 552,
1171 560, 568, 576, 584, 592, 600, 608, 616,
1172 624, 632, 640, 648, 656, 664, 672, 680,
1173 688, 696, 704, 712, 720, 728, 736, 744,
1174 752, 760, 768, 784, 800, 816, 832, 864,