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