silence warnings in a newer rustc
[nihav.git] / nihav-commonfmt / src / codecs / ts102366.rs
1 use nihav_core::formats::*;
2 use nihav_core::frame::*;
3 use nihav_core::codecs::*;
4 use nihav_core::io::bitreader::*;
5 use nihav_codec_support::dsp::fft::*;
6 use std::str::FromStr;
7 use std::f32::consts;
8
9 const BLOCK_LEN: usize = 256;
10 const NBLOCKS: usize = 6;
11 const MAX_CHANNELS: usize = 5;
12 const MAX_CPLBANDS: usize = 18;
13 const MAX_BANDS: usize = 50;
14
15 const MAGIC_BYTE0: u8 = 0x0B;
16 const MAGIC_BYTE1: u8 = 0x77;
17
18 const STRATEGY_REUSE: u8 = 0;
19
20 const LFE_CHANNEL: usize = MAX_CHANNELS;
21 const CPL_CHANNEL: usize = MAX_CHANNELS + 1;
22
23 struct IMDCTContext {
24 xsincos: [FFTComplex; BLOCK_LEN/2],
25 fft: FFT,
26 size: usize,
27 }
28
29 struct IMDCTWorkspace {
30 z: [FFTComplex; BLOCK_LEN / 2],
31 y: [FFTComplex; BLOCK_LEN / 2],
32 out: [f32; BLOCK_LEN * 2],
33 }
34
35 impl IMDCTContext {
36 fn new(bits: usize) -> Self {
37 let size = 1 << bits;
38 let size4 = 1 << (bits - 2);
39 let mut xsincos: [FFTComplex; 512/4] = [FFTC_ZERO; 512/4];
40 for k in 0..size4 {
41 let factor = 2.0 * consts::PI * ((8 * k + 1) as f32) / ((8 * size) as f32);
42 xsincos[k].re = -factor.cos();
43 xsincos[k].im = -factor.sin();
44 }
45 let fft = FFTBuilder::new_fft(size/4, false);
46 IMDCTContext { xsincos, size, fft }
47 }
48 #[allow(non_snake_case)]
49 fn do_imdct(&mut self, coeffs: &[i32; BLOCK_LEN], tmp: &mut IMDCTWorkspace) {
50 do_imdct_core(&mut self.fft, &self.xsincos, self.size, false, coeffs, &mut tmp.z, &mut tmp.y);
51 let w = &TS102366_WINDOW;
52 let N2 = self.size / 2;
53 let N4 = self.size / 4;
54 let N8 = self.size / 8;
55 for n in 0..N8 {
56 tmp.out[ 2 * n] = -tmp.y[N8 + n] .im * w[ 2 * n];
57 tmp.out[ 2 * n + 1] = tmp.y[N8 - n - 1].re * w[ 2 * n + 1];
58 tmp.out[ N4 + 2 * n] = -tmp.y[ n] .re * w[N4 + 2 * n];
59 tmp.out[ N4 + 2 * n + 1] = tmp.y[N4 - n - 1].im * w[N4 + 2 * n + 1];
60 tmp.out[ N2 + 2 * n] = -tmp.y[N8 + n] .re * w[N2 - 2 * n - 1];
61 tmp.out[ N2 + 2 * n + 1] = tmp.y[N8 - n - 1].im * w[N2 - 2 * n - 2];
62 tmp.out[3 * N4 + 2 * n] = tmp.y[ n] .im * w[N4 - 2 * n - 1];
63 tmp.out[3 * N4 + 2 * n + 1] = -tmp.y[N4 - n - 1].re * w[N4 - 2 * n - 2];
64 }
65 }
66 #[allow(non_snake_case)]
67 fn do_imdct_ileave(&mut self, coeffs: &[i32; BLOCK_LEN], tmp: &mut IMDCTWorkspace) {
68 let mut ziter = tmp.z.chunks_mut(self.size / 4);
69 let z1 = ziter.next().unwrap();
70 let z2 = ziter.next().unwrap();
71 let mut yiter = tmp.y.chunks_mut(self.size / 4);
72 let y1 = yiter.next().unwrap();
73 let y2 = yiter.next().unwrap();
74 do_imdct_core(&mut self.fft, &self.xsincos, self.size, true, coeffs, z1, y1);
75 do_imdct_core(&mut self.fft, &self.xsincos, self.size, true, &coeffs[1..], z2, y2);
76 let w = &TS102366_WINDOW;
77 let N2 = self.size / 2;
78 let N4 = self.size / 4;
79 let N8 = self.size / 8;
80 for n in 0..N8 {
81 tmp.out[ 2 * n] = -y1[ n] .im * w[ 2 * n];
82 tmp.out[ 2 * n + 1] = y1[N8 - n - 1].re * w[ 2 * n + 1];
83 tmp.out[ N4 + 2 * n] = -y1[ n] .re * w[N4 + 2 * n];
84 tmp.out[ N4 + 2 * n + 1] = y1[N8 - n - 1].im * w[N4 + 2 * n + 1];
85 tmp.out[ N2 + 2 * n] = -y2[ n] .re * w[N2 - 2 * n - 1];
86 tmp.out[ N2 + 2 * n + 1] = y2[N8 - n - 1].im * w[N2 - 2 * n - 2];
87 tmp.out[3 * N4 + 2 * n] = y2[ n] .im * w[N4 - 2 * n - 1];
88 tmp.out[3 * N4 + 2 * n + 1] = -y2[N8 - n - 1].re * w[N4 - 2 * n - 2];
89 }
90 }
91 }
92
93 #[allow(non_snake_case)]
94 fn do_imdct_core(fft: &mut FFT, xsc: &[FFTComplex; BLOCK_LEN/2], size: usize, ilace: bool, coeffs: &[i32], z: &mut [FFTComplex], y: &mut [FFTComplex]) {
95 let N = size;
96 let N2 = size / 2;
97 let N4 = size / 4;
98 let scale = 1.0 / ((1 << 24) as f32);
99 for k in 0..N4 {
100 let (c0, c1) = if !ilace {
101 ((coeffs[N2 - 2 * k - 1] as f32) * scale,
102 (coeffs[ 2 * k] as f32) * scale)
103 } else {
104 ((coeffs[N - 4 * k - 2] as f32) * scale,
105 (coeffs[ 4 * k] as f32) * scale)
106 };
107 let c = FFTComplex { re: c0, im: c1 };
108 z[k] = c * xsc[k];
109 }
110 fft.do_ifft_inplace(z);
111 for k in 0..N4 {
112 y[k] = z[k] * xsc[k];
113 }
114 }
115
116 struct AudioDecoder {
117 info: NACodecInfoRef,
118 ablk: AudioBlock,
119 imdct512: IMDCTContext,
120 imdct256: IMDCTContext,
121 tmp: IMDCTWorkspace,
122 delay: [[f32; BLOCK_LEN]; MAX_CHANNELS + 1],
123 }
124
125 impl AudioDecoder {
126 fn new() -> Self {
127 AudioDecoder {
128 info: NACodecInfo::new_dummy(),
129 ablk: AudioBlock::new(),
130 imdct512: IMDCTContext::new(9),
131 imdct256: IMDCTContext::new(8),
132 tmp: IMDCTWorkspace {
133 z: [FFTC_ZERO; BLOCK_LEN / 2],
134 y: [FFTC_ZERO; BLOCK_LEN / 2],
135 out: [0.0; BLOCK_LEN * 2],
136 },
137 delay: [[0.0; BLOCK_LEN]; MAX_CHANNELS + 1],
138 }
139 }
140 }
141
142 const SAMPLE_RATES: [u32; 4] = [ 48000, 44100, 32000, 0 ];
143
144 const FRAME_SIZES: [[usize; 64]; 4] = [
145 [
146 64, 64, 80, 80, 96, 96, 112, 112,
147 128, 128, 160, 160, 192, 192, 224, 224,
148 256, 256, 320, 320, 384, 384, 448, 448,
149 512, 512, 640, 640, 768, 768, 896, 896,
150 1024, 1024, 1152, 1152, 1280, 1280,
151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153 ], [
154 69, 70, 87, 88, 104, 105, 121, 122,
155 139, 140, 174, 175, 208, 209, 243, 244,
156 278, 279, 348, 349, 417, 418, 487, 488,
157 557, 558, 696, 697, 835, 836, 975, 976,
158 1114, 1115, 1253, 1254, 1393, 1394,
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
161 ], [
162 96, 96, 120, 120, 144, 144, 168, 168,
163 192, 192, 240, 240, 288, 288, 336, 336,
164 384, 384, 480, 480, 576, 576, 672, 672,
165 768, 768, 960, 960, 1152, 1152, 1344, 1344,
166 1536, 1536, 1728, 1728, 1920, 1920,
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
169 ], [ 0; 64 ],
170 ];
171
172 #[derive(Debug,Clone,Copy)]
173 #[allow(dead_code)]
174 struct Syncinfo {
175 crc1: u16,
176 fscod: u8,
177 frmsizecod: u8,
178 samplerate: u32,
179 frame_size: usize,
180 }
181
182 impl Syncinfo {
183 fn read(br: &mut BitReader) -> DecoderResult<Self> {
184 let syncword = br.read(16)?;
185 validate!(syncword == (u32::from(MAGIC_BYTE0) * 256) + u32::from(MAGIC_BYTE1));
186 let crc1 = br.read(16)? as u16;
187 let fscod = br.read(2)? as usize;
188 let frmsizecod = br.read(6)? as usize;
189 Ok(Syncinfo { crc1, fscod: fscod as u8, frmsizecod: frmsizecod as u8,
190 samplerate: SAMPLE_RATES[fscod], frame_size: FRAME_SIZES[fscod][frmsizecod] * 2 })
191 }
192 fn is_valid(&self) -> bool {
193 (self.samplerate != 0) && (self.frame_size != 0)
194 }
195 }
196
197 trait ReadOptional {
198 fn read_optional8(&mut self) -> BitReaderResult<Option<u8>>;
199 fn read_optional16(&mut self, bits: u8) -> BitReaderResult<Option<u16>>;
200 }
201
202 impl<'a> ReadOptional for BitReader<'a> {
203 fn read_optional8(&mut self) -> BitReaderResult<Option<u8>> {
204 if self.read_bool()? {
205 Ok(Some(self.read(8)? as u8))
206 } else {
207 Ok(None)
208 }
209 }
210 fn read_optional16(&mut self, bits: u8) -> BitReaderResult<Option<u16>> {
211 if self.read_bool()? {
212 Ok(Some(self.read(bits)? as u16))
213 } else {
214 Ok(None)
215 }
216 }
217 }
218
219 #[derive(Debug,Clone,Copy,PartialEq)]
220 enum ACMode {
221 DualMono,
222 Mono,
223 Stereo,
224 Mode3_0,
225 Mode2_1,
226 Mode3_1,
227 Mode2_2,
228 Mode3_2,
229 }
230
231 impl ACMode {
232 fn get_num_channels(self) -> usize {
233 match self {
234 ACMode::DualMono => 2,
235 ACMode::Mono => 1,
236 ACMode::Stereo => 2,
237 ACMode::Mode3_0 => 3,
238 ACMode::Mode2_1 => 3,
239 ACMode::Mode3_1 => 4,
240 ACMode::Mode2_2 => 4,
241 ACMode::Mode3_2 => 5,
242 }
243 }
244 fn get_channel_map_str(self) -> &'static str {
245 match self {
246 ACMode::DualMono => "C,C",
247 ACMode::Mono => "C",
248 ACMode::Stereo => "L,R",
249 ACMode::Mode3_0 => "L,C,R",
250 ACMode::Mode2_1 => "L,R,Cs",
251 ACMode::Mode3_1 => "L,C,R,Cs",
252 ACMode::Mode2_2 => "L,R,Ls,Rs",
253 ACMode::Mode3_2 => "L,C,R,Ls,Rs",
254 }
255 }
256 fn get_channel_map(self, has_lfe: bool) -> NAChannelMap {
257 let mut chmap = NAChannelMap::from_str(self.get_channel_map_str()).unwrap();
258 if has_lfe {
259 chmap.add_channel(NAChannelType::LFE);
260 }
261 chmap
262 }
263 fn is_3_x(self) -> bool {
264 match self {
265 ACMode::Mode3_0 |
266 ACMode::Mode3_1 |
267 ACMode::Mode3_2 => true,
268 _ => false,
269 }
270 }
271 fn is_surround(self) -> bool {
272 match self {
273 ACMode::Mode2_1 |
274 ACMode::Mode3_1 |
275 ACMode::Mode2_2 |
276 ACMode::Mode3_2 => true,
277 _ => false,
278 }
279 }
280 }
281
282 const AC_MODES: [ACMode; 8] = [
283 ACMode::DualMono, ACMode::Mono, ACMode::Stereo,
284 ACMode::Mode3_0, ACMode::Mode2_1,
285 ACMode::Mode3_1, ACMode::Mode2_2,
286 ACMode::Mode3_2
287 ];
288
289 #[derive(Debug,Clone,Copy)]
290 #[allow(dead_code)]
291 struct Mixinfo {
292 dialnorm: u8,
293 compr: Option<u8>,
294 langcod: Option<u8>,
295 mixlevel: Option<u8>,
296 roomtyp: Option<u8>,
297 }
298
299 impl Mixinfo {
300 fn read(br: &mut BitReader) -> DecoderResult<Self> {
301 let dialnorm = br.read(5)? as u8;
302 let compr = br.read_optional8()?;
303 let langcod = br.read_optional8()?;
304 let (mixlevel, roomtyp) = if br.read_bool()? {
305 let mlev = br.read(5)? as u8;
306 let rt = br.read(2)? as u8;
307 validate!(rt < 3);
308 (Some(mlev), Some(rt))
309 } else {
310 (None, None)
311 };
312 Ok(Mixinfo { dialnorm, compr, langcod, mixlevel, roomtyp })
313 }
314 }
315
316 #[derive(Debug,Clone,Copy)]
317 #[allow(dead_code)]
318 struct BSI {
319 bsid: u8,
320 shift: u8,
321 bsmod: u8,
322 acmod: ACMode,
323 cmixlev: Option<u8>,
324 surmixlev: Option<u8>,
325 dsurmod: Option<u8>,
326 lfeon: bool,
327 mixinfo: Mixinfo,
328 mixinfo2: Option<Mixinfo>,
329 copysmth: bool,
330 origbs: bool,
331 timecod1: Option<u16>,
332 timecod2: Option<u16>,
333 has_addb: bool,
334 }
335
336 impl BSI {
337 fn read(br: &mut BitReader) -> DecoderResult<BSI> {
338 let bsid = br.read(5)? as u8;
339 validate!(bsid <= 10);
340 let shift = if bsid < 9 { 0 } else { bsid - 9 + 1 };
341 let bsmod = br.read(3)? as u8;
342 let acmod_id = br.read(3)? as usize;
343 validate!(acmod_id < AC_MODES.len());
344 let acmod = AC_MODES[acmod_id];
345 let cmixlev = if acmod.is_3_x() {
346 let cl = br.read(2)? as u8;
347 validate!(cl < 3);
348 Some(cl)
349 } else { None };
350 let surmixlev = if acmod.is_surround() {
351 let sml = br.read(2)? as u8;
352 validate!(sml < 3);
353 Some(sml)
354 } else { None };
355 let dsurmod = if acmod == ACMode::Stereo {
356 let dsm = br.read(2)? as u8;
357 validate!(dsm < 3);
358 Some(dsm)
359 } else { None };
360 let lfeon = br.read_bool()?;
361 let mixinfo = Mixinfo::read(br)?;
362 let mixinfo2 = if acmod == ACMode::DualMono {
363 Some(Mixinfo::read(br)?)
364 } else {
365 None
366 };
367 let copysmth = br.read_bool()?;
368 let origbs = br.read_bool()?;
369 let timecod1 = br.read_optional16(14)?;
370 let timecod2 = br.read_optional16(14)?;
371 let has_addb = br.read_bool()?;
372 Ok(BSI{
373 bsid, shift, bsmod, acmod, lfeon,
374 cmixlev, surmixlev, dsurmod,
375 mixinfo, mixinfo2,
376 copysmth, origbs, timecod1, timecod2, has_addb,
377 })
378 }
379 }
380
381 #[derive(Clone, Copy)]
382 struct ChannelData {
383 blksw: bool,
384 dithflag: bool,
385
386 chincpl: bool,
387 cplcoe: bool,
388 cplcoexp: [u8; MAX_CPLBANDS],
389 cplcomant: [u8; MAX_CPLBANDS],
390 mstrcplco: u8,
391
392 chbwcod: u8,
393
394 expstr: u8,
395 gainrng: u8,
396 startmant: usize,
397 endmant: usize,
398 groups: usize,
399
400 fsnroffst: u8,
401 fgaincod: usize,
402 snroffset: i32,
403
404 deltbae: u8,
405 deltnseg: usize,
406 deltoffst: [u8; 8],
407 deltlen: [usize; 8],
408 deltba: [u8; 8],
409
410 bap: [u8; 256],
411 exps: [u8; 256],
412 mant: [i32; 256],
413
414 psd: [i16; 256],
415 bndpsd: [i32; 64],
416 }
417
418 const GROUPS: [usize; 4] = [ 0, 3, 6, 12 ];
419 const GROUP_BIAS: [usize; 4] = [ 0, 0, 3, 9 ];
420
421 fn decode_exps(br: &mut BitReader, dst: &mut [u8], mut prev: u8, grplen: usize) -> DecoderResult<()> {
422 let repeat = grplen / 3;
423
424 for out in dst.chunks_mut(grplen) {
425 let val = br.read(7)? as u8;
426 validate!(val < 125);
427 let diff: [u8; 3] = [ val / 25, (val / 5) % 5, val % 5 ];
428 for (i, exps) in out.chunks_mut(repeat).enumerate() {
429 exps[0] = (prev + diff[i]).wrapping_sub(2);
430 validate!(exps[0] <= 24);
431 for j in 1..repeat {
432 exps[j] = exps[0];
433 }
434 prev = exps[0];
435 }
436 }
437
438 Ok(())
439 }
440
441 macro_rules! read_bap {
442 ($br: expr, $tab:ident, $nbits:expr) => ({
443 let val = $br.read($nbits)? as usize;
444 validate!(val < $tab.len());
445 $tab[val]
446 });
447 ($br:expr, $tab:ident, $nbits:expr, $bufidx:expr, $bap_buf:expr, $bap_buf_fill:expr) => (
448 if $bap_buf_fill[$bufidx] > 0 {
449 $bap_buf_fill[$bufidx] -= 1;
450 $bap_buf[$bufidx][$bap_buf_fill[$bufidx]]
451 } else {
452 let val = $br.read($nbits)? as usize;
453 validate!(val < $tab.len());
454 for i in 1..$tab[0].len() {
455 $bap_buf[$bufidx][i - 1] = $tab[val][i];
456 }
457 $bap_buf_fill[$bufidx] = $tab[0].len() - 1;
458 $tab[val][0]
459 }
460 );
461 }
462
463 impl ChannelData {
464 fn new() -> Self {
465 ChannelData {
466 blksw: false,
467 dithflag: false,
468
469 chincpl: false,
470 cplcoe: false,
471 cplcoexp: [0; MAX_CPLBANDS],
472 cplcomant: [0; MAX_CPLBANDS],
473 mstrcplco: 0,
474
475 chbwcod: 0,
476
477 expstr: 0,
478 gainrng: 0,
479 startmant: 0,
480 endmant: 0,
481 groups: 0,
482
483 fsnroffst: 0,
484 fgaincod: 0,
485 snroffset: 0,
486
487 deltbae: 0,
488 deltnseg: 0,
489 deltoffst: [0; 8],
490 deltlen: [0; 8],
491 deltba: [0; 8],
492
493 bap: [0; 256],
494 exps: [0; 256],
495 mant: [0; 256],
496
497 psd: [0; 256],
498 bndpsd: [0; 64],
499 }
500 }
501 fn read_strategy(&mut self, br: &mut BitReader, blk_no: usize) -> DecoderResult<()> {
502 self.expstr = br.read(2)? as u8;
503 validate!(blk_no != 0 || self.expstr != STRATEGY_REUSE);
504 if self.expstr != STRATEGY_REUSE {
505 if self.startmant > 0 {
506 self.groups = (self.endmant - self.startmant) / GROUPS[self.expstr as usize];
507 } else if self.endmant != 0{
508 let idx = self.expstr as usize;
509 self.groups = (self.endmant + GROUP_BIAS[idx] - 1) / GROUPS[idx];
510 } else {
511 self.groups = 0;
512 }
513 }
514 Ok(())
515 }
516 fn read_exps(&mut self, br: &mut BitReader, is_cpl: bool, is_lfe: bool) -> DecoderResult<()> {
517 if self.expstr == STRATEGY_REUSE { return Ok(()); }
518 let grpsize = GROUPS[self.expstr as usize];
519 self.exps = [0; 256];
520 if is_cpl {
521 let first = (br.read(4)? as u8) << 1;
522 let out = &mut self.exps[self.startmant..self.endmant];
523 decode_exps(br, out, first, grpsize)?;
524 } else if !is_lfe {
525 self.exps[0] = br.read(4)? as u8;
526 let first = self.exps[0];
527 let out = &mut self.exps[1..self.endmant];
528 decode_exps(br, out, first, grpsize)?;
529 self.gainrng = br.read(2)? as u8;
530 } else {
531 self.exps[0] = br.read(4)? as u8;
532 let first = self.exps[0];
533 let out = &mut self.exps[1..7];
534 decode_exps(br, out, first, grpsize)?;
535 }
536 Ok(())
537 }
538 fn read_snr(&mut self, br: &mut BitReader) -> DecoderResult<()> {
539 self.fsnroffst = br.read(4)? as u8;
540 self.fgaincod = br.read(3)? as usize;
541 Ok(())
542 }
543 fn read_deltbai(&mut self, br: &mut BitReader) -> DecoderResult<()> {
544 if self.deltbae == 1 {
545 self.deltnseg = (br.read(3)? as usize) + 1;
546 for seg in 0..self.deltnseg {
547 self.deltoffst[seg] = br.read(5)? as u8;
548 self.deltlen[seg] = br.read(4)? as usize;
549 self.deltba[seg] = br.read(3)? as u8;
550 }
551 }
552 Ok(())
553 }
554
555 fn compute_bndpsd(&mut self) {
556 let start = self.startmant;
557 let end = self.endmant;
558 let exps = &mut self.exps;
559 let psd = &mut self.psd;
560 let bndpsd = &mut self.bndpsd;
561
562 for bin in start..end {
563 psd[bin] = 3072 - (i16::from(exps[bin]) << 7);
564 }
565
566 let mut bin = start;
567 let mut band = TS102366_BIN_TO_BAND[bin] as usize;
568 let mut lastbin;
569 loop {
570 lastbin = ((TS102366_BAND_START[band] as usize) + (TS102366_BAND_SIZE[band] as usize)).min(end);
571 bndpsd[band] = i32::from(psd[bin]);
572 bin += 1;
573 while bin < lastbin {
574 bndpsd[band] = logadd(bndpsd[band], i32::from(psd[bin]));
575 bin += 1;
576 }
577 band += 1;
578 if lastbin >= end { break; }
579 }
580 }
581 fn compute_mask(&mut self, mask: &mut [i32; MAX_BANDS], fscod: usize, sgain: u16, fdecay: u8, sdecay: u8,
582 dbknee: u16, cplfleak: u16, cplsleak: u16, shift: u8) {
583 let fgain = i32::from(TS102366_FAST_GAIN[self.fgaincod]);
584
585 let bndstart = TS102366_BIN_TO_BAND[self.startmant] as usize;
586 let bndend = (TS102366_BIN_TO_BAND[self.endmant - 1] as usize) + 1;
587
588 let mut excite: [i32; MAX_BANDS] = [0; MAX_BANDS];
589
590 let begin;
591 let mut fast_leak;
592 let mut slow_leak;
593 if bndstart == 0 {
594 let lowcomp0 = calc_lowcomp(0, self.bndpsd[0], self.bndpsd[1], 0);
595 excite[0] = self.bndpsd[0] - fgain - lowcomp0;
596 let lowcomp1 = calc_lowcomp(lowcomp0, self.bndpsd[1], self.bndpsd[2], 1);
597 excite[1] = self.bndpsd[1] - fgain - lowcomp1;
598 let mut sband = 7;
599 let mut lowcomp = lowcomp1;
600 fast_leak = 0;
601 slow_leak = 0;
602 for band in 2..7 {
603 let not_lfe_case = (bndend != 7) || (band != 6);
604 if not_lfe_case {
605 lowcomp = calc_lowcomp(lowcomp, self.bndpsd[band], self.bndpsd[band + 1], band);
606 }
607 fast_leak = self.bndpsd[band] - fgain;
608 slow_leak = self.bndpsd[band] - i32::from(sgain);
609 excite[band] = fast_leak - lowcomp;
610 if not_lfe_case && (self.bndpsd[band] <= self.bndpsd[band + 1]) {
611 sband = band + 1;
612 break;
613 }
614 }
615 for band in sband..bndend.min(22) {
616 if (bndend != 7) || (band != 6) {
617 lowcomp = calc_lowcomp(lowcomp, self.bndpsd[band], self.bndpsd[band + 1], band);
618 }
619 fast_leak = (fast_leak - i32::from(fdecay)).max(self.bndpsd[band] - fgain);
620 slow_leak = (slow_leak - i32::from(sdecay)).max(self.bndpsd[band] - i32::from(sgain));
621 excite[band] = slow_leak.max(fast_leak - lowcomp);
622 }
623 begin = 22;
624 } else {
625 begin = bndstart;
626 fast_leak = i32::from(cplfleak);
627 slow_leak = i32::from(cplsleak);
628 }
629 for band in begin..bndend {
630 fast_leak = (fast_leak - i32::from(fdecay)).max(self.bndpsd[band] - fgain);
631 slow_leak = (slow_leak - i32::from(sdecay)).max(self.bndpsd[band] - i32::from(sgain));
632 excite[band] = fast_leak.max(slow_leak);
633 }
634 for band in bndstart..bndend {
635 if self.bndpsd[band] < i32::from(dbknee) {
636 excite[band] += (i32::from(dbknee) - self.bndpsd[band]) >> 2;
637 }
638 mask[band] = excite[band].max(i32::from(TS102366_HTH[fscod][band >> shift]));
639 }
640 }
641 fn apply_delta_info(&mut self, mask: &mut [i32; MAX_BANDS]) {
642 if self.deltbae == 0 || self.deltbae == 1 {
643 let mut band = TS102366_BIN_TO_BAND[self.startmant] as usize;
644 for seg in 0..self.deltnseg {
645 band += self.deltoffst[seg] as usize;
646 let delta = if self.deltba[seg] >= 4 {
647 (i32::from(self.deltba[seg]) - 3) << 7
648 } else {
649 (i32::from(self.deltba[seg]) - 4) << 7
650 };
651 if band + self.deltlen[seg] > MAX_BANDS { break; }
652 for _ in 0..self.deltlen[seg] {
653 mask[band] += delta;
654 band += 1;
655 }
656 }
657 }
658 }
659 fn calc_snr_offset(&mut self, csnroffst: u8) {
660 self.snroffset = (((i32::from(csnroffst) - 15) << 4) + i32::from(self.fsnroffst)) << 2;
661 }
662 fn compute_bap(&mut self, mask: &mut [i32; MAX_BANDS], floor: u16) {
663 let end = self.endmant;
664 let mut band = TS102366_BIN_TO_BAND[self.startmant] as usize;
665 let mut bin = self.startmant;
666 let mut lastbin;
667 loop {
668 lastbin = ((TS102366_BAND_START[band] as usize) + (TS102366_BAND_SIZE[band] as usize)).min(end);
669 mask[band] = (mask[band] - self.snroffset - i32::from(floor)).max(0) & 0x1FE0;
670 mask[band] += i32::from(floor);
671 while bin < lastbin {
672 let addr = ((i32::from(self.psd[bin]) - mask[band]) >> 5).min(63).max(0) as usize;
673 self.bap[bin] = TS102366_BAPTAB[addr];
674 bin += 1;
675 }
676 if lastbin == end { break; }
677 band += 1;
678 }
679 }
680 fn read_mant(&mut self, br: &mut BitReader, bap_buf: &mut [[i32; 2]; 3], bap_buf_fill: &mut [usize; 3]) -> DecoderResult<()> {
681 self.mant = [0; BLOCK_LEN];
682 for bin in self.startmant..self.endmant {
683 self.mant[bin] = match self.bap[bin] {
684 0 => {
685 if self.dithflag {
686 42 // todo dither
687 } else {
688 0
689 }
690 },
691 1 => { read_bap!(br, TS102366_QUANT3_MAP, 5, 0, bap_buf, bap_buf_fill) },
692 2 => { read_bap!(br, TS102366_QUANT5_MAP, 7, 1, bap_buf, bap_buf_fill) },
693 3 => { read_bap!(br, TS102366_QUANT7_MAP, 3) },
694 4 => { read_bap!(br, TS102366_QUANT11_MAP, 7, 2, bap_buf, bap_buf_fill) },
695 5 => { read_bap!(br, TS102366_QUANT15_MAP, 4) },
696 _ => {
697 validate!(self.bap[bin] < 15);
698 let nbits = TS102366_BAP_BITS[(self.bap[bin] as usize) - 6];
699 let val = br.read(nbits)? as i16;
700 i32::from(val << (16 - nbits)) << 9
701 },
702 };
703 self.mant[bin] >>= self.exps[bin];
704 }
705 Ok(())
706 }
707
708 fn synth(&mut self, imdct512: &mut IMDCTContext, imdct256: &mut IMDCTContext, tmp: &mut IMDCTWorkspace, delay: &mut [f32; BLOCK_LEN], dst: &mut [f32]) {
709 if !self.blksw {
710 imdct512.do_imdct(&self.mant, tmp);
711 } else {
712 imdct256.do_imdct_ileave(&self.mant, tmp);
713 }
714 overlap(delay, &tmp.out, dst);
715 }
716 }
717
718 fn logadd(acc: i32, add: i32) -> i32 {
719 let c = acc - add;
720 let addr = (c.abs() >> 1).min(255);
721 if c >= 0 {
722 acc + i32::from(TS102366_LATAB[addr as usize])
723 } else {
724 add + i32::from(TS102366_LATAB[addr as usize])
725 }
726 }
727
728 fn calc_lowcomp(a: i32, b0: i32, b1: i32, band: usize) -> i32 {
729 if band < 7 {
730 if (b0 + 256) == b1 {
731 384
732 } else if b0 > b1 {
733 0.max(a - 64)
734 } else {
735 a
736 }
737 } else if band < 20 {
738 if (b0 + 256) == b1 {
739 320
740 } else if b0 > b1 {
741 0.max(a - 64)
742 } else {
743 a
744 }
745 } else {
746 0.max(a - 128)
747 }
748 }
749
750 fn overlap(delay: &mut [f32; BLOCK_LEN], src: &[f32; BLOCK_LEN * 2], out: &mut [f32]) {
751 {
752 let dly = &delay;
753 for ((d, s), o) in dly.iter().zip(src.iter()).zip(out.iter_mut()) {
754 *o = (*d + *s) * 2.0;
755 }
756 }
757 delay.copy_from_slice(&src[BLOCK_LEN..]);
758 }
759
760 #[derive(Clone)]
761 struct AudioBlock {
762 dynrng: Option<u8>,
763 dynrng2: Option<u8>,
764
765 cplstre: bool,
766 cplinu: bool,
767 phsflginu: bool,
768 cplbegf: usize,
769 cplendf: usize,
770 ncplsubnd: usize,
771 ncplbnd: usize,
772 cplbndstrc: [bool; MAX_CPLBANDS],
773
774 phsflg: [bool; MAX_CPLBANDS],
775 rematstr: bool,
776 rematflg: [bool; 4],
777
778 chdata: [ChannelData; MAX_CHANNELS + 2],
779
780 baie: bool,
781 fdcycod: usize,
782 sdcycod: usize,
783 sgaincod: usize,
784 dbpbcod: usize,
785 floorcod: usize,
786 snroffste: bool,
787 csnroffst: u8,
788 cplleake: bool,
789 cplfleak: u8,
790 cplsleak: u8,
791
792 deltbaie: bool,
793
794 bap_buf: [[i32; 2]; 3],
795 bap_buf_fill: [usize; 3],
796 }
797
798 impl AudioBlock {
799 fn new() -> Self {
800 AudioBlock {
801 chdata: [ChannelData::new(); MAX_CHANNELS + 2],
802
803 dynrng: None,
804 dynrng2: None,
805
806 cplstre: false,
807 cplinu: false,
808 phsflginu: false,
809 cplbegf: 0,
810 cplendf: 0,
811 ncplsubnd: 0,
812 ncplbnd: 0,
813 cplbndstrc: [false; MAX_CPLBANDS],
814
815 phsflg: [false; MAX_CPLBANDS],
816 rematstr: false,
817 rematflg: [false; 4],
818
819 baie: false,
820 sdcycod: 0,
821 fdcycod: 0,
822 sgaincod: 0,
823 dbpbcod: 0,
824 floorcod: 0,
825 snroffste: false,
826 csnroffst: 0,
827 cplleake: false,
828 cplfleak: 0,
829 cplsleak: 0,
830
831 deltbaie: false,
832
833 bap_buf: [[0; 2]; 3],
834 bap_buf_fill: [0; 3],
835 }
836 }
837 #[allow(clippy::cognitive_complexity)]
838 fn read(&mut self, br: &mut BitReader, bsi: &BSI, fscod: usize, blk_no: usize) -> DecoderResult<bool> {
839 let channels = bsi.acmod.get_num_channels();
840 let is_stereo = bsi.acmod == ACMode::Stereo;
841
842 for ch in 0..channels {
843 self.chdata[ch].blksw = br.read_bool()?;
844 }
845 // dynamic range information
846 for ch in 0..channels {
847 self.chdata[ch].dithflag = br.read_bool()?;
848 }
849 self.dynrng = br.read_optional8()?;
850 if bsi.acmod == ACMode::DualMono {
851 self.dynrng2 = br.read_optional8()?;
852 }
853 // coupling strategy information
854 self.cplstre = br.read_bool()?;
855 validate!((blk_no != 0) || self.cplstre);
856 if self.cplstre {
857 self.cplinu = br.read_bool()?;
858 if self.cplinu {
859 for ch in 0..channels {
860 self.chdata[ch].chincpl = br.read_bool()?;
861 }
862 if is_stereo {
863 self.phsflginu = br.read_bool()?;
864 }
865 self.cplbegf = br.read(4)? as usize;
866 self.cplendf = (br.read(4)? as usize) + 3;
867 validate!(self.cplendf >= self.cplbegf);
868 self.ncplsubnd = self.cplendf - self.cplbegf;
869 self.ncplbnd = self.ncplsubnd;
870 self.chdata[CPL_CHANNEL].startmant = self.cplbegf * 12 + 37;
871 self.chdata[CPL_CHANNEL].endmant = self.cplendf * 12 + 37;
872 for bnd in 1..self.ncplsubnd {
873 self.cplbndstrc[bnd] = br.read_bool()?;
874 if self.cplbndstrc[bnd] {
875 self.ncplbnd -= 1;
876 }
877 }
878 }
879 }
880 // coupling coordinates
881 if self.cplinu {
882 for c in 0..channels {
883 let ch = &mut self.chdata[c];
884 if ch.chincpl {
885 ch.cplcoe = br.read_bool()?;
886 if ch.cplcoe {
887 ch.mstrcplco = br.read(2)? as u8;
888 for bnd in 0..self.ncplbnd {
889 ch.cplcoexp [bnd] = br.read(4)? as u8;
890 ch.cplcomant[bnd] = br.read(4)? as u8;
891 }
892 }
893 }
894 }
895 if is_stereo && self.phsflginu && (self.chdata[0].cplcoe || self.chdata[1].cplcoe) {
896 for bnd in 0..self.ncplbnd {
897 self.phsflg[bnd] = br.read_bool()?;
898 }
899 }
900 } else {
901 for ch in 0..channels {
902 self.chdata[ch].chincpl = false;
903 }
904 }
905 // stereo rematrixing
906 if is_stereo {
907 self.rematstr = br.read_bool()?;
908 if self.rematstr {
909 if self.cplbegf > 2 || !self.cplinu {
910 for rbnd in 0..4 {
911 self.rematflg[rbnd] = br.read_bool()?;
912 }
913 }
914 if self.cplbegf > 0 && self.cplbegf <= 2 && self.cplinu {
915 for rbnd in 0..3 {
916 self.rematflg[rbnd] = br.read_bool()?;
917 }
918 }
919 if self.cplbegf == 0 && self.cplinu {
920 for rbnd in 0..2 {
921 self.rematflg[rbnd] = br.read_bool()?;
922 }
923 }
924 }
925 }
926 // exponent strategy
927 if self.cplinu {
928 self.chdata[CPL_CHANNEL].read_strategy(br, blk_no)?;
929 }
930 for ch in 0..channels {
931 self.chdata[ch].read_strategy(br, blk_no)?;
932 }
933 if bsi.lfeon {
934 self.chdata[LFE_CHANNEL].expstr = br.read(1)? as u8;
935 validate!(blk_no != 0 || self.chdata[LFE_CHANNEL].expstr != STRATEGY_REUSE);
936 self.chdata[LFE_CHANNEL].groups = 2;
937 self.chdata[LFE_CHANNEL].startmant = 0;
938 self.chdata[LFE_CHANNEL].endmant = 7;
939 }
940 let cpl_startmant = self.chdata[CPL_CHANNEL].startmant;
941 for c in 0..channels {
942 let ch = &mut self.chdata[c];
943 if ch.expstr != STRATEGY_REUSE && !ch.chincpl {
944 ch.chbwcod = br.read(6)? as u8;
945 }
946 if !ch.chincpl {
947 ch.startmant = 0;
948 ch.endmant = ((ch.chbwcod as usize) + 12) * 3 + 37;
949 } else {
950 ch.startmant = 0;
951 ch.endmant = cpl_startmant;
952 }
953 }
954 // set number of mantissas
955 if self.cplinu {
956 self.chdata[CPL_CHANNEL].read_exps(br, true, false)?;
957 }
958 for ch in 0..channels {
959 self.chdata[ch].read_exps(br, false, false)?;
960 }
961 if bsi.lfeon {
962 self.chdata[LFE_CHANNEL].read_exps(br, false, true)?;
963 }
964 // bit allocation parameters
965 self.baie = br.read_bool()?;
966 if self.baie {
967 self.sdcycod = br.read(2)? as usize;
968 self.fdcycod = br.read(2)? as usize;
969 self.sgaincod = br.read(2)? as usize;
970 self.dbpbcod = br.read(2)? as usize;
971 self.floorcod = br.read(3)? as usize;
972 }
973 self.snroffste = br.read_bool()?;
974 if self.snroffste {
975 self.csnroffst = br.read(6)? as u8;
976 if self.cplinu {
977 self.chdata[CPL_CHANNEL].read_snr(br)?;
978 }
979 for ch in 0..channels {
980 self.chdata[ch].read_snr(br)?;
981 }
982 if bsi.lfeon {
983 self.chdata[LFE_CHANNEL].read_snr(br)?;
984 }
985 }
986 if self.cplinu {
987 self.cplleake = br.read_bool()?;
988 if self.cplleake {
989 self.cplfleak = br.read(3)? as u8;
990 self.cplsleak = br.read(3)? as u8;
991 }
992 }
993 // delta bit allocation information
994 self.deltbaie = br.read_bool()?;
995 if self.deltbaie {
996 if self.cplinu {
997 self.chdata[CPL_CHANNEL].deltbae = br.read(2)? as u8;
998 validate!(blk_no != 0 || self.chdata[CPL_CHANNEL].deltbae != 0);
999 validate!(self.chdata[CPL_CHANNEL].deltbae != 3);
1000 }
1001 for ch in 0..channels {
1002 self.chdata[ch].deltbae = br.read(2)? as u8;
1003 validate!(blk_no != 0 || self.chdata[ch].deltbae != 0);
1004 validate!(self.chdata[ch].deltbae != 3);
1005 }
1006 if self.cplinu {
1007 self.chdata[CPL_CHANNEL].read_deltbai(br)?;
1008 }
1009 for ch in 0..channels {
1010 self.chdata[ch].read_deltbai(br)?;
1011 }
1012 }
1013 // dummy data
1014 if br.read_bool()? {
1015 let skipl = br.read(9)?;
1016 br.skip(skipl * 8)?;
1017 }
1018
1019 let all_zero = self.calc_bitalloc(bsi, channels, fscod);
1020 if all_zero { return Ok(true); }
1021
1022 // quantised mantissa values
1023 let mut got_cplchan = false;
1024 for i in 0..self.bap_buf_fill.len() { self.bap_buf_fill[i] = 0; }
1025 for c in 0..channels {
1026 {
1027 let ch = &mut self.chdata[c];
1028 ch.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
1029 }
1030 if self.cplinu && self.chdata[c].chincpl && !got_cplchan {
1031 let cplch = &mut self.chdata[CPL_CHANNEL];
1032 cplch.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
1033 got_cplchan = true;
1034 }
1035 }
1036 if bsi.lfeon {
1037 let lfech = &mut self.chdata[LFE_CHANNEL];
1038 lfech.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
1039 }
1040 Ok(false)
1041 }
1042 fn calc_bitalloc(&mut self, bsi: &BSI, channels: usize, fscod: usize) -> bool {
1043 let sdecay1 = TS102366_SLOW_DECAY[self.sdcycod];
1044 let fdecay1 = TS102366_FAST_DECAY[self.fdcycod];
1045
1046 let sdecay = sdecay1 >> bsi.shift;
1047 let fdecay = fdecay1 >> bsi.shift;
1048 let sgain = TS102366_SLOW_GAIN[self.sgaincod];
1049 let dbknee = TS102366_DBP_TAB[self.dbpbcod];
1050 let floor = TS102366_FLOOR_TAB[self.floorcod];
1051
1052 let mut all_zero = self.csnroffst == 0;
1053 if !all_zero && self.chdata[LFE_CHANNEL].fsnroffst == 0 {
1054 for ch in 0..channels {
1055 if self.chdata[ch].fsnroffst != 0 {
1056 all_zero = false;
1057 break;
1058 }
1059 }
1060 }
1061 if all_zero { return true; }
1062
1063 let mut mask: [i32; MAX_BANDS] = [0; MAX_BANDS];
1064
1065 if self.cplinu {
1066 self.chdata[CPL_CHANNEL].compute_bndpsd();
1067 self.chdata[CPL_CHANNEL].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee,
1068 (u16::from(self.cplfleak) << 8) + 768, (u16::from(self.cplsleak) << 8) + 768, bsi.shift);
1069 self.chdata[CPL_CHANNEL].apply_delta_info(&mut mask);
1070 self.chdata[CPL_CHANNEL].calc_snr_offset(self.csnroffst);
1071 self.chdata[CPL_CHANNEL].compute_bap(&mut mask, floor);
1072 }
1073 for ch in 0..channels {
1074 self.chdata[ch].compute_bndpsd();
1075 self.chdata[ch].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee, 0, 0, bsi.shift);
1076 self.chdata[ch].apply_delta_info(&mut mask);
1077 self.chdata[ch].calc_snr_offset(self.csnroffst);
1078 self.chdata[ch].compute_bap(&mut mask, floor);
1079 }
1080 if bsi.lfeon {
1081 self.chdata[LFE_CHANNEL].compute_bndpsd();
1082 self.chdata[LFE_CHANNEL].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee,
1083 0, 0, bsi.shift);
1084 self.chdata[LFE_CHANNEL].calc_snr_offset(self.csnroffst);
1085 self.chdata[LFE_CHANNEL].compute_bap(&mut mask, floor);
1086 }
1087
1088 false
1089 }
1090 fn couple_channels(&mut self, acmod: ACMode) {
1091 if !self.cplinu { return; }
1092 for ch in 0..acmod.get_num_channels() {
1093 if !self.chdata[ch].chincpl { continue; }
1094 let mut pband = 0;
1095 for band in self.cplbegf..self.cplendf {
1096 let cband = band - self.cplbegf;
1097 let comant = self.chdata[ch].cplcomant[cband];
1098 let mut cotemp = i32::from(if self.chdata[ch].cplcoexp[cband] == 15 { comant << 1 } else { comant + 16 });
1099 if (acmod == ACMode::Stereo) && (ch == 1) && self.phsflginu && self.phsflg[pband] {
1100 cotemp = -cotemp;
1101 }
1102 if !self.cplbndstrc[cband] {
1103 pband += 1;
1104 }
1105 let exp = self.chdata[ch].cplcoexp[cband] + 3 * self.chdata[ch].mstrcplco + 5 - 3;
1106 let start = band * 12 + 37;
1107 for bin in 0..12 {
1108 self.chdata[ch].mant[start + bin] = (self.chdata[CPL_CHANNEL].mant[start + bin] * cotemp) >> exp;
1109 }
1110 //todo dither
1111 }
1112 }
1113 }
1114 fn rematrix(&mut self) {
1115 let maxbin = self.chdata[0].endmant.min(self.chdata[1].endmant);
1116 if self.rematflg[0] {
1117 let end = maxbin.min(25);
1118 for bin in 13..end {
1119 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1120 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1121 self.chdata[0].mant[bin] = d;
1122 self.chdata[1].mant[bin] = s;
1123 }
1124 if maxbin <= 25 { return; }
1125 }
1126 if self.rematflg[1] {
1127 let end = maxbin.min(37);
1128 for bin in 25..end {
1129 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1130 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1131 self.chdata[0].mant[bin] = d;
1132 self.chdata[1].mant[bin] = s;
1133 }
1134 if maxbin <= 37 { return; }
1135 }
1136 if self.rematflg[2] {
1137 let end = maxbin.min(61);
1138 for bin in 37..end {
1139 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1140 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1141 self.chdata[0].mant[bin] = d;
1142 self.chdata[1].mant[bin] = s;
1143 }
1144 if maxbin <= 61 { return; }
1145 }
1146 if self.rematflg[3] {
1147 let end = maxbin;
1148 for bin in 61..end {
1149 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1150 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1151 self.chdata[0].mant[bin] = d;
1152 self.chdata[1].mant[bin] = s;
1153 }
1154 }
1155 }
1156 fn synth_audio_block(&mut self, imdct512: &mut IMDCTContext, imdct256: &mut IMDCTContext, tmp: &mut IMDCTWorkspace, channel: usize, delay: &mut [f32; BLOCK_LEN], dst: &mut [f32]) {
1157 self.chdata[channel].synth(imdct512, imdct256, tmp, delay, dst);
1158 }
1159 }
1160
1161 impl NADecoder for AudioDecoder {
1162 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
1163 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
1164 self.info = info.clone();
1165 Ok(())
1166 } else {
1167 Err(DecoderError::InvalidData)
1168 }
1169 }
1170 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
1171 let info = pkt.get_stream().get_info();
1172 validate!(info.get_properties().is_audio());
1173 let pktbuf = pkt.get_buffer();
1174 validate!(pktbuf.len() > 5);
1175
1176 let mut br;
1177 if (pktbuf[0] == MAGIC_BYTE0) && (pktbuf[1] == MAGIC_BYTE1) {
1178 br = BitReader::new(pktbuf.as_slice(), BitReaderMode::BE);
1179 } else if (pktbuf[0] == MAGIC_BYTE1) && (pktbuf[1] == MAGIC_BYTE0) {
1180 br = BitReader::new(pktbuf.as_slice(), BitReaderMode::LE16MSB);
1181 } else {
1182 return Err(DecoderError::InvalidData);
1183 }
1184
1185 let sinfo = Syncinfo::read(&mut br)?;
1186 validate!(sinfo.is_valid());
1187
1188 let bsi = BSI::read(&mut br)?;
1189 if bsi.has_addb {
1190 let len = br.read(6)?;
1191 br.skip((len + 1) * 8)?;
1192 }
1193
1194 let duration = BLOCK_LEN * NBLOCKS;
1195
1196 let core_channels = bsi.acmod.get_num_channels();
1197 let channels = core_channels + if bsi.lfeon { 1 } else { 0 };
1198
1199 let ainfo = NAAudioInfo::new(sinfo.samplerate >> bsi.shift, channels as u8,
1200 SND_F32P_FORMAT, BLOCK_LEN);
1201
1202 let abuf = alloc_audio_buffer(ainfo, duration, bsi.acmod.get_channel_map(bsi.lfeon))?;
1203 let mut adata = abuf.get_abuf_f32().unwrap();
1204 let output = adata.get_data_mut().unwrap();
1205
1206 self.ablk = AudioBlock::new();
1207 for blk in 0..NBLOCKS {
1208 let all_zero = self.ablk.read(&mut br, &bsi, sinfo.fscod as usize, blk)?;
1209 let off = blk * BLOCK_LEN;
1210 self.ablk.couple_channels(bsi.acmod);
1211 if bsi.acmod == ACMode::Stereo {
1212 self.ablk.rematrix();
1213 }
1214 for ch in 0..core_channels {
1215 let dpos = abuf.get_offset(ch) + off;
1216 let dst = &mut output[dpos..][..BLOCK_LEN];
1217 if !all_zero {
1218 self.ablk.synth_audio_block(&mut self.imdct512, &mut self.imdct256, &mut self.tmp, ch, &mut self.delay[ch], dst);
1219 } else {
1220 self.delay[ch] = [0.0; BLOCK_LEN];
1221 for el in dst.iter_mut().take(BLOCK_LEN) { *el = 0.0; }
1222 }
1223 }
1224 if bsi.lfeon {
1225 let dpos = abuf.get_offset(core_channels) + off;
1226 let dst = &mut output[dpos..][..BLOCK_LEN];
1227 if !all_zero {
1228 self.ablk.synth_audio_block(&mut self.imdct512, &mut self.imdct256, &mut self.tmp, LFE_CHANNEL, &mut self.delay[LFE_CHANNEL], dst);
1229 } else {
1230 self.delay[LFE_CHANNEL] = [0.0; BLOCK_LEN];
1231 for el in dst.iter_mut().take(BLOCK_LEN) { *el = 0.0; }
1232 }
1233 }
1234 }
1235 //todo skip auxdata
1236 //todo do errorcheck
1237
1238 let mut frm = NAFrame::new_from_pkt(pkt, self.info.replace_info(NACodecTypeInfo::Audio(ainfo)), abuf);
1239 frm.set_keyframe(true);
1240 Ok(frm.into_ref())
1241 }
1242 fn flush(&mut self) {
1243 self.delay = [[0.0; BLOCK_LEN]; MAX_CHANNELS + 1];
1244 }
1245 }
1246
1247 impl NAOptionHandler for AudioDecoder {
1248 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1249 fn set_options(&mut self, _options: &[NAOption]) { }
1250 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1251 }
1252
1253 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
1254 Box::new(AudioDecoder::new())
1255 }
1256
1257 #[cfg(test)]
1258 mod test {
1259 use nihav_core::codecs::RegisteredDecoders;
1260 use nihav_core::demuxers::RegisteredDemuxers;
1261 use nihav_codec_support::test::dec_video::test_decode_audio;
1262 use crate::generic_register_all_decoders;
1263 use nihav_realmedia::realmedia_register_all_demuxers;
1264 #[test]
1265 fn test_ts102366() {
1266 let mut dmx_reg = RegisteredDemuxers::new();
1267 realmedia_register_all_demuxers(&mut dmx_reg);
1268 let mut dec_reg = RegisteredDecoders::new();
1269 generic_register_all_decoders(&mut dec_reg);
1270
1271 // sample: https://samples.mplayerhq.hu/real/VC-RV10/sp_sample1.rm
1272 let file = "assets/RV/sp_sample1.rm";
1273 test_decode_audio("realmedia", file, Some(12000), None/*Some("ac3")*/, &dmx_reg, &dec_reg);
1274 }
1275 }
1276
1277 const TS102366_SLOW_DECAY: [u8; 4] = [ 0x0F, 0x11, 0x13, 0x15 ];
1278 const TS102366_FAST_DECAY: [u8; 4] = [ 0x3F, 0x53, 0x67, 0x7B ];
1279 const TS102366_SLOW_GAIN: [u16; 4] = [ 0x540, 0x4D8, 0x478, 0x410 ];
1280 const TS102366_FAST_GAIN: [u16; 8] = [ 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 ];
1281 const TS102366_DBP_TAB: [u16; 4] = [ 0x000, 0x700, 0x900, 0xB00 ];
1282 const TS102366_FLOOR_TAB: [u16; 8] = [ 0x02F0, 0x02B0, 0x0270, 0x0230, 0x01F0, 0x0170, 0x00F0, 0xF800 ];
1283
1284 const TS102366_BIN_TO_BAND: [u8; 256] = [
1285 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1286 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1287 20, 21, 22, 23, 24, 25, 26, 27, 28, 28,
1288 28, 29, 29, 29, 30, 30, 30, 31, 31, 31,
1289 32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
1290 35, 35, 35, 35, 35, 36, 36, 36, 36, 36,
1291 36, 37, 37, 37, 37, 37, 37, 38, 38, 38,
1292 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
1293 40, 40, 40, 40, 40, 41, 41, 41, 41, 41,
1294 41, 41, 41, 41, 41, 41, 41, 42, 42, 42,
1295 42, 42, 42, 42, 42, 42, 42, 42, 42, 43,
1296 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
1297 43, 44, 44, 44, 44, 44, 44, 44, 44, 44,
1298 44, 44, 44, 45, 45, 45, 45, 45, 45, 45,
1299 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
1300 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
1301 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
1302 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
1303 46, 47, 47, 47, 47, 47, 47, 47, 47, 47,
1304 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
1305 47, 47, 47, 47, 47, 48, 48, 48, 48, 48,
1306 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
1307 48, 48, 48, 48, 48, 48, 48, 48, 48, 49,
1308 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
1309 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
1310 49, 49, 49, 0, 0, 0
1311 ];
1312 const TS102366_BAND_SIZE: [u8; MAX_BANDS] = [
1313 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1314 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1315 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
1316 3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
1317 6, 12, 12, 12, 12, 24, 24, 24, 24, 24
1318 ];
1319 const TS102366_BAND_START: [u8; MAX_BANDS] = [
1320 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1321 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1322 20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
1323 34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
1324 79, 85, 97, 109, 121, 133, 157, 181, 205, 229
1325 ];
1326
1327 const TS102366_LATAB: [u16; 256] = [
1328 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
1329 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
1330 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
1331 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
1332 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
1333 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
1334 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
1335 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
1336 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
1337 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
1338 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
1339 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
1340 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
1341 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
1342 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
1343 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
1344 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
1345 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
1346 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
1347 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
1348 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
1349 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
1350 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
1351 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
1352 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
1353 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
1354 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1355 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1356 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1357 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1358 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1359 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1360 ];
1361 const TS102366_HTH: [[u16; MAX_BANDS]; 3] = [
1362 [
1363 0x04D0, 0x04D0, 0x0440, 0x0400, 0x03E0, 0x03C0, 0x03B0, 0x03B0, 0x03A0, 0x03A0,
1364 0x03A0, 0x03A0, 0x03A0, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0370, 0x0370,
1365 0x0360, 0x0360, 0x0350, 0x0350, 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300,
1366 0x02F0, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03E0, 0x0420,
1367 0x0460, 0x0490, 0x04A0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, 0x0840, 0x0840,
1368 ], [
1369 0x04F0, 0x04F0, 0x0460, 0x0410, 0x03E0, 0x03D0, 0x03C0, 0x03B0, 0x03B0, 0x03A0,
1370 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0380,
1371 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310,
1372 0x0300, 0x02F0, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03E0,
1373 0x0420, 0x0450, 0x04A0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, 0x0840, 0x0840,
1374 ], [
1375 0x0580, 0x0580, 0x04B0, 0x0450, 0x0420, 0x03F0, 0x03E0, 0x03D0, 0x03C0, 0x03B0,
1376 0x03B0, 0x03B0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0,
1377 0x0390, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350,
1378 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0310,
1379 0x0330, 0x0350, 0x03C0, 0x0410, 0x0470, 0x04A0, 0x0460, 0x0440, 0x0450, 0x04E0,
1380 ]
1381 ];
1382 const TS102366_BAPTAB: [u8; 64] = [
1383 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
1384 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,
1385 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
1386 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15
1387 ];
1388
1389 const TS102366_QUANT3_MAP: [[i32; 3]; 27] = [
1390 [ -0x0AAAAAA, -0x0AAAAAA, -0x0AAAAAA ],
1391 [ -0x0AAAAAA, -0x0AAAAAA, 0x00000000 ],
1392 [ -0x0AAAAAA, -0x0AAAAAA, 0x00AAAAAA ],
1393 [ -0x0AAAAAA, 0x00000000, -0x0AAAAAA ],
1394 [ -0x0AAAAAA, 0x00000000, 0x00000000 ],
1395 [ -0x0AAAAAA, 0x00000000, 0x00AAAAAA ],
1396 [ -0x0AAAAAA, 0x00AAAAAA, -0x0AAAAAA ],
1397 [ -0x0AAAAAA, 0x00AAAAAA, 0x00000000 ],
1398 [ -0x0AAAAAA, 0x00AAAAAA, 0x00AAAAAA ],
1399 [ 0x00000000, -0x0AAAAAA, -0x0AAAAAA ],
1400 [ 0x00000000, -0x0AAAAAA, 0x00000000 ],
1401 [ 0x00000000, -0x0AAAAAA, 0x00AAAAAA ],
1402 [ 0x00000000, 0x00000000, -0x0AAAAAA ],
1403 [ 0x00000000, 0x00000000, 0x00000000 ],
1404 [ 0x00000000, 0x00000000, 0x00AAAAAA ],
1405 [ 0x00000000, 0x00AAAAAA, -0x0AAAAAA ],
1406 [ 0x00000000, 0x00AAAAAA, 0x00000000 ],
1407 [ 0x00000000, 0x00AAAAAA, 0x00AAAAAA ],
1408 [ 0x00AAAAAA, -0x0AAAAAA, -0x0AAAAAA ],
1409 [ 0x00AAAAAA, -0x0AAAAAA, 0x00000000 ],
1410 [ 0x00AAAAAA, -0x0AAAAAA, 0x00AAAAAA ],
1411 [ 0x00AAAAAA, 0x00000000, -0x0AAAAAA ],
1412 [ 0x00AAAAAA, 0x00000000, 0x00000000 ],
1413 [ 0x00AAAAAA, 0x00000000, 0x00AAAAAA ],
1414 [ 0x00AAAAAA, 0x00AAAAAA, -0x0AAAAAA ],
1415 [ 0x00AAAAAA, 0x00AAAAAA, 0x00000000 ],
1416 [ 0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA ]
1417 ];
1418 const TS102366_QUANT5_MAP: [[i32; 3]; 125] = [
1419 [ -0x0CCCCCC, -0x0CCCCCC, -0x0CCCCCC ], [ -0x0CCCCCC, -0x0CCCCCC, -0x0666666 ], [ -0x0CCCCCC, -0x0CCCCCC, 0x00000000 ],
1420 [ -0x0CCCCCC, -0x0CCCCCC, 0x00666666 ], [ -0x0CCCCCC, -0x0CCCCCC, 0x00CCCCCC ],
1421 [ -0x0CCCCCC, -0x0666666, -0x0CCCCCC ], [ -0x0CCCCCC, -0x0666666, -0x0666666 ], [ -0x0CCCCCC, -0x0666666, 0x00000000 ],
1422 [ -0x0CCCCCC, -0x0666666, 0x00666666 ], [ -0x0CCCCCC, -0x0666666, 0x00CCCCCC ],
1423 [ -0x0CCCCCC, 0x00000000, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00000000, -0x0666666 ], [ -0x0CCCCCC, 0x00000000, 0x00000000 ],
1424 [ -0x0CCCCCC, 0x00000000, 0x00666666 ], [ -0x0CCCCCC, 0x00000000, 0x00CCCCCC ],
1425 [ -0x0CCCCCC, 0x00666666, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00666666, -0x0666666 ], [ -0x0CCCCCC, 0x00666666, 0x00000000 ],
1426 [ -0x0CCCCCC, 0x00666666, 0x00666666 ], [ -0x0CCCCCC, 0x00666666, 0x00CCCCCC ],
1427 [ -0x0CCCCCC, 0x00CCCCCC, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00CCCCCC, -0x0666666 ], [ -0x0CCCCCC, 0x00CCCCCC, 0x00000000 ],
1428 [ -0x0CCCCCC, 0x00CCCCCC, 0x00666666 ], [ -0x0CCCCCC, 0x00CCCCCC, 0x00CCCCCC ],
1429 [ -0x0666666, -0x0CCCCCC, -0x0CCCCCC ], [ -0x0666666, -0x0CCCCCC, -0x0666666 ], [ -0x0666666, -0x0CCCCCC, 0x00000000 ],
1430 [ -0x0666666, -0x0CCCCCC, 0x00666666 ], [ -0x0666666, -0x0CCCCCC, 0x00CCCCCC ],
1431 [ -0x0666666, -0x0666666, -0x0CCCCCC ], [ -0x0666666, -0x0666666, -0x0666666 ], [ -0x0666666, -0x0666666, 0x00000000 ],
1432 [ -0x0666666, -0x0666666, 0x00666666 ], [ -0x0666666, -0x0666666, 0x00CCCCCC ],
1433 [ -0x0666666, 0x00000000, -0x0CCCCCC ], [ -0x0666666, 0x00000000, -0x0666666 ], [ -0x0666666, 0x00000000, 0x00000000 ],
1434 [ -0x0666666, 0x00000000, 0x00666666 ], [ -0x0666666, 0x00000000, 0x00CCCCCC ],
1435 [ -0x0666666, 0x00666666, -0x0CCCCCC ], [ -0x0666666, 0x00666666, -0x0666666 ], [ -0x0666666, 0x00666666, 0x00000000 ],
1436 [ -0x0666666, 0x00666666, 0x00666666 ], [ -0x0666666, 0x00666666, 0x00CCCCCC ],
1437 [ -0x0666666, 0x00CCCCCC, -0x0CCCCCC ], [ -0x0666666, 0x00CCCCCC, -0x0666666 ], [ -0x0666666, 0x00CCCCCC, 0x00000000 ],
1438 [ -0x0666666, 0x00CCCCCC, 0x00666666 ], [ -0x0666666, 0x00CCCCCC, 0x00CCCCCC ],
1439 [ 0x00000000, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00000000, -0x0CCCCCC, -0x0666666 ], [ 0x00000000, -0x0CCCCCC, 0x00000000 ],
1440 [ 0x00000000, -0x0CCCCCC, 0x00666666 ], [ 0x00000000, -0x0CCCCCC, 0x00CCCCCC ],
1441 [ 0x00000000, -0x0666666, -0x0CCCCCC ], [ 0x00000000, -0x0666666, -0x0666666 ], [ 0x00000000, -0x0666666, 0x00000000 ],
1442 [ 0x00000000, -0x0666666, 0x00666666 ], [ 0x00000000, -0x0666666, 0x00CCCCCC ],
1443 [ 0x00000000, 0x00000000, -0x0CCCCCC ], [ 0x00000000, 0x00000000, -0x0666666 ], [ 0x00000000, 0x00000000, 0x00000000 ],
1444 [ 0x00000000, 0x00000000, 0x00666666 ], [ 0x00000000, 0x00000000, 0x00CCCCCC ],
1445 [ 0x00000000, 0x00666666, -0x0CCCCCC ], [ 0x00000000, 0x00666666, -0x0666666 ], [ 0x00000000, 0x00666666, 0x00000000 ],
1446 [ 0x00000000, 0x00666666, 0x00666666 ], [ 0x00000000, 0x00666666, 0x00CCCCCC ],
1447 [ 0x00000000, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00000000, 0x00CCCCCC, -0x0666666 ], [ 0x00000000, 0x00CCCCCC, 0x00000000 ],
1448 [ 0x00000000, 0x00CCCCCC, 0x00666666 ], [ 0x00000000, 0x00CCCCCC, 0x00CCCCCC ],
1449 [ 0x00666666, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00666666, -0x0CCCCCC, -0x0666666 ], [ 0x00666666, -0x0CCCCCC, 0x00000000 ],
1450 [ 0x00666666, -0x0CCCCCC, 0x00666666 ], [ 0x00666666, -0x0CCCCCC, 0x00CCCCCC ],
1451 [ 0x00666666, -0x0666666, -0x0CCCCCC ], [ 0x00666666, -0x0666666, -0x0666666 ], [ 0x00666666, -0x0666666, 0x00000000 ],
1452 [ 0x00666666, -0x0666666, 0x00666666 ], [ 0x00666666, -0x0666666, 0x00CCCCCC ],
1453 [ 0x00666666, 0x00000000, -0x0CCCCCC ], [ 0x00666666, 0x00000000, -0x0666666 ], [ 0x00666666, 0x00000000, 0x00000000 ],
1454 [ 0x00666666, 0x00000000, 0x00666666 ], [ 0x00666666, 0x00000000, 0x00CCCCCC ],
1455 [ 0x00666666, 0x00666666, -0x0CCCCCC ], [ 0x00666666, 0x00666666, -0x0666666 ], [ 0x00666666, 0x00666666, 0x00000000 ],
1456 [ 0x00666666, 0x00666666, 0x00666666 ], [ 0x00666666, 0x00666666, 0x00CCCCCC ],
1457 [ 0x00666666, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00666666, 0x00CCCCCC, -0x0666666 ], [ 0x00666666, 0x00CCCCCC, 0x00000000 ],
1458 [ 0x00666666, 0x00CCCCCC, 0x00666666 ], [ 0x00666666, 0x00CCCCCC, 0x00CCCCCC ],
1459 [ 0x00CCCCCC, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00CCCCCC, -0x0CCCCCC, -0x0666666 ], [ 0x00CCCCCC, -0x0CCCCCC, 0x00000000 ],
1460 [ 0x00CCCCCC, -0x0CCCCCC, 0x00666666 ], [ 0x00CCCCCC, -0x0CCCCCC, 0x00CCCCCC ],
1461 [ 0x00CCCCCC, -0x0666666, -0x0CCCCCC ], [ 0x00CCCCCC, -0x0666666, -0x0666666 ], [ 0x00CCCCCC, -0x0666666, 0x00000000 ],
1462 [ 0x00CCCCCC, -0x0666666, 0x00666666 ], [ 0x00CCCCCC, -0x0666666, 0x00CCCCCC ],
1463 [ 0x00CCCCCC, 0x00000000, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00000000, -0x0666666 ], [ 0x00CCCCCC, 0x00000000, 0x00000000 ],
1464 [ 0x00CCCCCC, 0x00000000, 0x00666666 ], [ 0x00CCCCCC, 0x00000000, 0x00CCCCCC ],
1465 [ 0x00CCCCCC, 0x00666666, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00666666, -0x0666666 ], [ 0x00CCCCCC, 0x00666666, 0x00000000 ],
1466 [ 0x00CCCCCC, 0x00666666, 0x00666666 ], [ 0x00CCCCCC, 0x00666666, 0x00CCCCCC ],
1467 [ 0x00CCCCCC, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00CCCCCC, -0x0666666 ], [ 0x00CCCCCC, 0x00CCCCCC, 0x00000000 ],
1468 [ 0x00CCCCCC, 0x00CCCCCC, 0x00666666 ], [ 0x00CCCCCC, 0x00CCCCCC, 0x00CCCCCC ],
1469 ];
1470 const TS102366_QUANT7_MAP: [i32; 7] = [
1471 -0xDB6DB6, -0x924924, -0x492492, 0x000000, 0x492492, 0x924924, 0xDB6DB6
1472 ];
1473 const TS102366_QUANT11_MAP: [[i32; 2]; 121] = [
1474 [ -0x0E8BA2E, -0x0E8BA2E ], [ -0x0E8BA2E, -0x0BA2E8B ], [ -0x0E8BA2E, -0x08BA2E8 ],
1475 [ -0x0E8BA2E, -0x05D1745 ], [ -0x0E8BA2E, -0x02E8BA2 ], [ -0x0E8BA2E, 0x00000000 ],
1476 [ -0x0E8BA2E, 0x002E8BA2 ], [ -0x0E8BA2E, 0x005D1745 ], [ -0x0E8BA2E, 0x008BA2E8 ],
1477 [ -0x0E8BA2E, 0x00BA2E8B ], [ -0x0E8BA2E, 0x00E8BA2E ], [ -0x0BA2E8B, -0x0E8BA2E ],
1478 [ -0x0BA2E8B, -0x0BA2E8B ], [ -0x0BA2E8B, -0x08BA2E8 ], [ -0x0BA2E8B, -0x05D1745 ],
1479 [ -0x0BA2E8B, -0x02E8BA2 ], [ -0x0BA2E8B, 0x00000000 ], [ -0x0BA2E8B, 0x002E8BA2 ],
1480 [ -0x0BA2E8B, 0x005D1745 ], [ -0x0BA2E8B, 0x008BA2E8 ], [ -0x0BA2E8B, 0x00BA2E8B ],
1481 [ -0x0BA2E8B, 0x00E8BA2E ], [ -0x08BA2E8, -0x0E8BA2E ], [ -0x08BA2E8, -0x0BA2E8B ],
1482 [ -0x08BA2E8, -0x08BA2E8 ], [ -0x08BA2E8, -0x05D1745 ], [ -0x08BA2E8, -0x02E8BA2 ],
1483 [ -0x08BA2E8, 0x00000000 ], [ -0x08BA2E8, 0x002E8BA2 ], [ -0x08BA2E8, 0x005D1745 ],
1484 [ -0x08BA2E8, 0x008BA2E8 ], [ -0x08BA2E8, 0x00BA2E8B ], [ -0x08BA2E8, 0x00E8BA2E ],
1485 [ -0x05D1745, -0x0E8BA2E ], [ -0x05D1745, -0x0BA2E8B ], [ -0x05D1745, -0x08BA2E8 ],
1486 [ -0x05D1745, -0x05D1745 ], [ -0x05D1745, -0x02E8BA2 ], [ -0x05D1745, 0x00000000 ],
1487 [ -0x05D1745, 0x002E8BA2 ], [ -0x05D1745, 0x005D1745 ], [ -0x05D1745, 0x008BA2E8 ],
1488 [ -0x05D1745, 0x00BA2E8B ], [ -0x05D1745, 0x00E8BA2E ], [ -0x02E8BA2, -0x0E8BA2E ],
1489 [ -0x02E8BA2, -0x0BA2E8B ], [ -0x02E8BA2, -0x08BA2E8 ], [ -0x02E8BA2, -0x05D1745 ],
1490 [ -0x02E8BA2, -0x02E8BA2 ], [ -0x02E8BA2, 0x00000000 ], [ -0x02E8BA2, 0x002E8BA2 ],
1491 [ -0x02E8BA2, 0x005D1745 ], [ -0x02E8BA2, 0x008BA2E8 ], [ -0x02E8BA2, 0x00BA2E8B ],
1492 [ -0x02E8BA2, 0x00E8BA2E ], [ 0x00000000, -0x0E8BA2E ], [ 0x00000000, -0x0BA2E8B ],
1493 [ 0x00000000, -0x08BA2E8 ], [ 0x00000000, -0x05D1745 ], [ 0x00000000, -0x02E8BA2 ],
1494 [ 0x00000000, 0x00000000 ], [ 0x00000000, 0x002E8BA2 ], [ 0x00000000, 0x005D1745 ],
1495 [ 0x00000000, 0x008BA2E8 ], [ 0x00000000, 0x00BA2E8B ], [ 0x00000000, 0x00E8BA2E ],
1496 [ 0x002E8BA2, -0x0E8BA2E ], [ 0x002E8BA2, -0x0BA2E8B ], [ 0x002E8BA2, -0x08BA2E8 ],
1497 [ 0x002E8BA2, -0x05D1745 ], [ 0x002E8BA2, -0x02E8BA2 ], [ 0x002E8BA2, 0x00000000 ],
1498 [ 0x002E8BA2, 0x002E8BA2 ], [ 0x002E8BA2, 0x005D1745 ], [ 0x002E8BA2, 0x008BA2E8 ],
1499 [ 0x002E8BA2, 0x00BA2E8B ], [ 0x002E8BA2, 0x00E8BA2E ], [ 0x005D1745, -0x0E8BA2E ],
1500 [ 0x005D1745, -0x0BA2E8B ], [ 0x005D1745, -0x08BA2E8 ], [ 0x005D1745, -0x05D1745 ],
1501 [ 0x005D1745, -0x02E8BA2 ], [ 0x005D1745, 0x00000000 ], [ 0x005D1745, 0x002E8BA2 ],
1502 [ 0x005D1745, 0x005D1745 ], [ 0x005D1745, 0x008BA2E8 ], [ 0x005D1745, 0x00BA2E8B ],
1503 [ 0x005D1745, 0x00E8BA2E ], [ 0x008BA2E8, -0x0E8BA2E ], [ 0x008BA2E8, -0x0BA2E8B ],
1504 [ 0x008BA2E8, -0x08BA2E8 ], [ 0x008BA2E8, -0x05D1745 ], [ 0x008BA2E8, -0x02E8BA2 ],
1505 [ 0x008BA2E8, 0x00000000 ], [ 0x008BA2E8, 0x002E8BA2 ], [ 0x008BA2E8, 0x005D1745 ],
1506 [ 0x008BA2E8, 0x008BA2E8 ], [ 0x008BA2E8, 0x00BA2E8B ], [ 0x008BA2E8, 0x00E8BA2E ],
1507 [ 0x00BA2E8B, -0x0E8BA2E ], [ 0x00BA2E8B, -0x0BA2E8B ], [ 0x00BA2E8B, -0x08BA2E8 ],
1508 [ 0x00BA2E8B, -0x05D1745 ], [ 0x00BA2E8B, -0x02E8BA2 ], [ 0x00BA2E8B, 0x00000000 ],
1509 [ 0x00BA2E8B, 0x002E8BA2 ], [ 0x00BA2E8B, 0x005D1745 ], [ 0x00BA2E8B, 0x008BA2E8 ],
1510 [ 0x00BA2E8B, 0x00BA2E8B ], [ 0x00BA2E8B, 0x00E8BA2E ], [ 0x00E8BA2E, -0x0E8BA2E ],
1511 [ 0x00E8BA2E, -0x0BA2E8B ], [ 0x00E8BA2E, -0x08BA2E8 ], [ 0x00E8BA2E, -0x05D1745 ],
1512 [ 0x00E8BA2E, -0x02E8BA2 ], [ 0x00E8BA2E, 0x00000000 ], [ 0x00E8BA2E, 0x002E8BA2 ],
1513 [ 0x00E8BA2E, 0x005D1745 ], [ 0x00E8BA2E, 0x008BA2E8 ], [ 0x00E8BA2E, 0x00BA2E8B ],
1514 [ 0x00E8BA2E, 0x00E8BA2E ],
1515 ];
1516 const TS102366_QUANT15_MAP: [i32; 15] = [
1517 -0x0EEEEEE, -0x0CCCCCC, -0x0AAAAAA, -0x0888888, -0x0666666, -0x0444444, -0x0222222, 0x00000000,
1518 0x00222222, 0x00444444, 0x00666666, 0x00888888, 0x00AAAAAA, 0x00CCCCCC, 0x00EEEEEE,
1519 ];
1520 const TS102366_BAP_BITS: [u8; 10] = [ 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 ];
1521
1522 const TS102366_WINDOW: [f32; 256] = [
1523 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
1524 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
1525 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
1526 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
1527 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
1528 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
1529 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
1530 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
1531 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
1532 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
1533 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
1534 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
1535 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
1536 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
1537 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
1538 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
1539 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
1540 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
1541 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
1542 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
1543 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
1544 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
1545 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
1546 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
1547 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
1548 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
1549 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
1550 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
1551 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
1552 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
1553 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1554 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1555 ];