fix some clippy warnings
[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 }
577 fn compute_mask(&mut self, mask: &mut [i32; MAX_BANDS], fscod: usize, sgain: u16, fdecay: u8, sdecay: u8,
578 dbknee: u16, cplfleak: u16, cplsleak: u16, shift: u8) {
c83013a1 579 let fgain = i32::from(TS102366_FAST_GAIN[self.fgaincod]);
16dd4f44
KS
580
581 let bndstart = TS102366_BIN_TO_BAND[self.startmant] as usize;
582 let bndend = (TS102366_BIN_TO_BAND[self.endmant - 1] as usize) + 1;
583
584 let mut excite: [i32; MAX_BANDS] = [0; MAX_BANDS];
585
586 let begin;
587 let mut fast_leak;
588 let mut slow_leak;
589 if bndstart == 0 {
590 let lowcomp0 = calc_lowcomp(0, self.bndpsd[0], self.bndpsd[1], 0);
591 excite[0] = self.bndpsd[0] - fgain - lowcomp0;
592 let lowcomp1 = calc_lowcomp(lowcomp0, self.bndpsd[1], self.bndpsd[2], 1);
593 excite[1] = self.bndpsd[1] - fgain - lowcomp1;
594 let mut sband = 7;
595 let mut lowcomp = lowcomp1;
596 fast_leak = 0;
597 slow_leak = 0;
598 for band in 2..7 {
599 let not_lfe_case = (bndend != 7) || (band != 6);
600 if not_lfe_case {
601 lowcomp = calc_lowcomp(lowcomp, self.bndpsd[band], self.bndpsd[band + 1], band);
602 }
603 fast_leak = self.bndpsd[band] - fgain;
c83013a1 604 slow_leak = self.bndpsd[band] - i32::from(sgain);
16dd4f44 605 excite[band] = fast_leak - lowcomp;
c83013a1
KS
606 if not_lfe_case && (self.bndpsd[band] <= self.bndpsd[band + 1]) {
607 sband = band + 1;
608 break;
16dd4f44
KS
609 }
610 }
611 for band in sband..bndend.min(22) {
612 if (bndend != 7) || (band != 6) {
613 lowcomp = calc_lowcomp(lowcomp, self.bndpsd[band], self.bndpsd[band + 1], band);
614 }
c83013a1
KS
615 fast_leak = (fast_leak - i32::from(fdecay)).max(self.bndpsd[band] - fgain);
616 slow_leak = (slow_leak - i32::from(sdecay)).max(self.bndpsd[band] - i32::from(sgain));
16dd4f44
KS
617 excite[band] = slow_leak.max(fast_leak - lowcomp);
618 }
619 begin = 22;
620 } else {
621 begin = bndstart;
c83013a1
KS
622 fast_leak = i32::from(cplfleak);
623 slow_leak = i32::from(cplsleak);
16dd4f44
KS
624 }
625 for band in begin..bndend {
c83013a1
KS
626 fast_leak = (fast_leak - i32::from(fdecay)).max(self.bndpsd[band] - fgain);
627 slow_leak = (slow_leak - i32::from(sdecay)).max(self.bndpsd[band] - i32::from(sgain));
16dd4f44
KS
628 excite[band] = fast_leak.max(slow_leak);
629 }
630 for band in bndstart..bndend {
c83013a1
KS
631 if self.bndpsd[band] < i32::from(dbknee) {
632 excite[band] += (i32::from(dbknee) - self.bndpsd[band]) >> 2;
16dd4f44 633 }
c83013a1 634 mask[band] = excite[band].max(i32::from(TS102366_HTH[fscod][band >> shift]));
16dd4f44
KS
635 }
636 }
637 fn apply_delta_info(&mut self, mask: &mut [i32; MAX_BANDS]) {
638 if self.deltbae == 0 || self.deltbae == 1 {
639 let mut band = TS102366_BIN_TO_BAND[self.startmant] as usize;
640 for seg in 0..self.deltnseg {
641 band += self.deltoffst[seg] as usize;
642 let delta = if self.deltba[seg] >= 4 {
c83013a1 643 (i32::from(self.deltba[seg]) - 3) << 7
16dd4f44 644 } else {
c83013a1 645 (i32::from(self.deltba[seg]) - 4) << 7
16dd4f44
KS
646 };
647 if band + self.deltlen[seg] > MAX_BANDS { break; }
648 for _ in 0..self.deltlen[seg] {
649 mask[band] += delta;
650 band += 1;
651 }
652 }
653 }
654 }
655 fn calc_snr_offset(&mut self, csnroffst: u8) {
c83013a1 656 self.snroffset = (((i32::from(csnroffst) - 15) << 4) + i32::from(self.fsnroffst)) << 2;
16dd4f44
KS
657 }
658 fn compute_bap(&mut self, mask: &mut [i32; MAX_BANDS], floor: u16) {
659 let end = self.endmant;
660 let mut band = TS102366_BIN_TO_BAND[self.startmant] as usize;
661 let mut bin = self.startmant;
662 let mut lastbin;
663 loop {
664 lastbin = ((TS102366_BAND_START[band] as usize) + (TS102366_BAND_SIZE[band] as usize)).min(end);
c83013a1
KS
665 mask[band] = (mask[band] - self.snroffset - i32::from(floor)).max(0) & 0x1FE0;
666 mask[band] += i32::from(floor);
16dd4f44 667 while bin < lastbin {
c83013a1 668 let addr = ((i32::from(self.psd[bin]) - mask[band]) >> 5).min(63).max(0) as usize;
16dd4f44
KS
669 self.bap[bin] = TS102366_BAPTAB[addr];
670 bin += 1;
671 }
672 if lastbin == end { break; }
673 band += 1;
674 }
675 }
676 fn read_mant(&mut self, br: &mut BitReader, bap_buf: &mut [[i32; 2]; 3], bap_buf_fill: &mut [usize; 3]) -> DecoderResult<()> {
677 self.mant = [0; BLOCK_LEN];
678 for bin in self.startmant..self.endmant {
679 self.mant[bin] = match self.bap[bin] {
680 0 => {
681 if self.dithflag {
682 42 // todo dither
683 } else {
684 0
685 }
686 },
687 1 => { read_bap!(br, TS102366_QUANT3_MAP, 5, 0, bap_buf, bap_buf_fill) },
688 2 => { read_bap!(br, TS102366_QUANT5_MAP, 7, 1, bap_buf, bap_buf_fill) },
689 3 => { read_bap!(br, TS102366_QUANT7_MAP, 3) },
690 4 => { read_bap!(br, TS102366_QUANT11_MAP, 7, 2, bap_buf, bap_buf_fill) },
691 5 => { read_bap!(br, TS102366_QUANT15_MAP, 4) },
692 _ => {
693 validate!(self.bap[bin] < 15);
694 let nbits = TS102366_BAP_BITS[(self.bap[bin] as usize) - 6];
695 let val = br.read(nbits)? as i16;
c83013a1 696 i32::from(val << (16 - nbits)) << 9
16dd4f44
KS
697 },
698 };
699 self.mant[bin] >>= self.exps[bin];
700 }
701 Ok(())
702 }
703
704 fn synth(&mut self, imdct512: &mut IMDCTContext, imdct256: &mut IMDCTContext, tmp: &mut IMDCTWorkspace, delay: &mut [f32; BLOCK_LEN], dst: &mut [f32]) {
705 if !self.blksw {
706 imdct512.do_imdct(&self.mant, tmp);
707 } else {
708 imdct256.do_imdct_ileave(&self.mant, tmp);
709 }
710 overlap(delay, &tmp.out, dst);
711 }
712}
713
714fn logadd(acc: i32, add: i32) -> i32 {
715 let c = acc - add;
716 let addr = (c.abs() >> 1).min(255);
717 if c >= 0 {
c83013a1 718 acc + i32::from(TS102366_LATAB[addr as usize])
16dd4f44 719 } else {
c83013a1 720 add + i32::from(TS102366_LATAB[addr as usize])
16dd4f44
KS
721 }
722}
723
724fn calc_lowcomp(a: i32, b0: i32, b1: i32, band: usize) -> i32 {
725 if band < 7 {
726 if (b0 + 256) == b1 {
727 384
728 } else if b0 > b1 {
729 0.max(a - 64)
730 } else {
731 a
732 }
733 } else if band < 20 {
734 if (b0 + 256) == b1 {
735 320
736 } else if b0 > b1 {
737 0.max(a - 64)
738 } else {
739 a
740 }
741 } else {
742 0.max(a - 128)
743 }
744}
745
746fn overlap(delay: &mut [f32; BLOCK_LEN], src: &[f32; BLOCK_LEN * 2], out: &mut [f32]) {
747 {
748 let dly = &delay;
c83013a1 749 for ((d, s), o) in dly.iter().zip(src.iter()).zip(out.iter_mut()) {
16dd4f44
KS
750 *o = (*d + *s) * 2.0;
751 }
752 }
753 delay.copy_from_slice(&src[BLOCK_LEN..]);
754}
755
756#[derive(Clone)]
757struct AudioBlock {
758 dynrng: Option<u8>,
759 dynrng2: Option<u8>,
760
761 cplstre: bool,
762 cplinu: bool,
763 phsflginu: bool,
764 cplbegf: usize,
765 cplendf: usize,
766 ncplsubnd: usize,
767 ncplbnd: usize,
768 cplbndstrc: [bool; MAX_CPLBANDS],
769
770 phsflg: [bool; MAX_CPLBANDS],
771 rematstr: bool,
772 rematflg: [bool; 4],
773
774 chdata: [ChannelData; MAX_CHANNELS + 2],
775
776 baie: bool,
777 fdcycod: usize,
778 sdcycod: usize,
779 sgaincod: usize,
780 dbpbcod: usize,
781 floorcod: usize,
782 snroffste: bool,
783 csnroffst: u8,
784 cplleake: bool,
785 cplfleak: u8,
786 cplsleak: u8,
787
788 deltbaie: bool,
789
790 bap_buf: [[i32; 2]; 3],
791 bap_buf_fill: [usize; 3],
792}
793
794impl AudioBlock {
795 fn new() -> Self {
796 AudioBlock {
797 chdata: [ChannelData::new(); MAX_CHANNELS + 2],
798
799 dynrng: None,
800 dynrng2: None,
801
802 cplstre: false,
803 cplinu: false,
804 phsflginu: false,
805 cplbegf: 0,
806 cplendf: 0,
807 ncplsubnd: 0,
808 ncplbnd: 0,
809 cplbndstrc: [false; MAX_CPLBANDS],
810
811 phsflg: [false; MAX_CPLBANDS],
812 rematstr: false,
813 rematflg: [false; 4],
814
815 baie: false,
816 sdcycod: 0,
817 fdcycod: 0,
818 sgaincod: 0,
819 dbpbcod: 0,
820 floorcod: 0,
821 snroffste: false,
822 csnroffst: 0,
823 cplleake: false,
824 cplfleak: 0,
825 cplsleak: 0,
826
827 deltbaie: false,
828
829 bap_buf: [[0; 2]; 3],
830 bap_buf_fill: [0; 3],
831 }
832 }
b7c882c1 833 #[allow(clippy::cognitive_complexity)]
16dd4f44
KS
834 fn read(&mut self, br: &mut BitReader, bsi: &BSI, fscod: usize, blk_no: usize) -> DecoderResult<bool> {
835 let channels = bsi.acmod.get_num_channels();
836 let is_stereo = bsi.acmod == ACMode::Stereo;
1a151e53 837
16dd4f44
KS
838 for ch in 0..channels {
839 self.chdata[ch].blksw = br.read_bool()?;
840 }
841 // dynamic range information
842 for ch in 0..channels {
843 self.chdata[ch].dithflag = br.read_bool()?;
844 }
845 self.dynrng = br.read_optional8()?;
846 if bsi.acmod == ACMode::DualMono {
847 self.dynrng2 = br.read_optional8()?;
848 }
849 // coupling strategy information
850 self.cplstre = br.read_bool()?;
851 validate!((blk_no != 0) || self.cplstre);
852 if self.cplstre {
853 self.cplinu = br.read_bool()?;
854 if self.cplinu {
855 for ch in 0..channels {
856 self.chdata[ch].chincpl = br.read_bool()?;
857 }
858 if is_stereo {
859 self.phsflginu = br.read_bool()?;
860 }
861 self.cplbegf = br.read(4)? as usize;
862 self.cplendf = (br.read(4)? as usize) + 3;
863 validate!(self.cplendf >= self.cplbegf);
864 self.ncplsubnd = self.cplendf - self.cplbegf;
865 self.ncplbnd = self.ncplsubnd;
866 self.chdata[CPL_CHANNEL].startmant = self.cplbegf * 12 + 37;
867 self.chdata[CPL_CHANNEL].endmant = self.cplendf * 12 + 37;
868 for bnd in 1..self.ncplsubnd {
869 self.cplbndstrc[bnd] = br.read_bool()?;
870 if self.cplbndstrc[bnd] {
871 self.ncplbnd -= 1;
872 }
873 }
874 }
875 }
876 // coupling coordinates
877 if self.cplinu {
878 for c in 0..channels {
879 let ch = &mut self.chdata[c];
880 if ch.chincpl {
881 ch.cplcoe = br.read_bool()?;
882 if ch.cplcoe {
883 ch.mstrcplco = br.read(2)? as u8;
884 for bnd in 0..self.ncplbnd {
885 ch.cplcoexp [bnd] = br.read(4)? as u8;
886 ch.cplcomant[bnd] = br.read(4)? as u8;
887 }
888 }
889 }
890 }
891 if is_stereo && self.phsflginu && (self.chdata[0].cplcoe || self.chdata[1].cplcoe) {
892 for bnd in 0..self.ncplbnd {
893 self.phsflg[bnd] = br.read_bool()?;
894 }
895 }
205d69bc
KS
896 } else {
897 for ch in 0..channels {
898 self.chdata[ch].chincpl = false;
899 }
16dd4f44
KS
900 }
901 // stereo rematrixing
902 if is_stereo {
903 self.rematstr = br.read_bool()?;
904 if self.rematstr {
905 if self.cplbegf > 2 || !self.cplinu {
906 for rbnd in 0..4 {
907 self.rematflg[rbnd] = br.read_bool()?;
908 }
909 }
910 if self.cplbegf > 0 && self.cplbegf <= 2 && self.cplinu {
911 for rbnd in 0..3 {
912 self.rematflg[rbnd] = br.read_bool()?;
913 }
914 }
915 if self.cplbegf == 0 && self.cplinu {
916 for rbnd in 0..2 {
917 self.rematflg[rbnd] = br.read_bool()?;
918 }
919 }
920 }
921 }
922 // exponent strategy
923 if self.cplinu {
924 self.chdata[CPL_CHANNEL].read_strategy(br, blk_no)?;
925 }
926 for ch in 0..channels {
927 self.chdata[ch].read_strategy(br, blk_no)?;
928 }
929 if bsi.lfeon {
930 self.chdata[LFE_CHANNEL].expstr = br.read(1)? as u8;
931 validate!(blk_no != 0 || self.chdata[LFE_CHANNEL].expstr != STRATEGY_REUSE);
932 self.chdata[LFE_CHANNEL].groups = 2;
933 self.chdata[LFE_CHANNEL].startmant = 0;
934 self.chdata[LFE_CHANNEL].endmant = 7;
935 }
936 let cpl_startmant = self.chdata[CPL_CHANNEL].startmant;
937 for c in 0..channels {
938 let ch = &mut self.chdata[c];
939 if ch.expstr != STRATEGY_REUSE && !ch.chincpl {
940 ch.chbwcod = br.read(6)? as u8;
941 }
942 if !ch.chincpl {
943 ch.startmant = 0;
944 ch.endmant = ((ch.chbwcod as usize) + 12) * 3 + 37;
945 } else {
946 ch.startmant = 0;
947 ch.endmant = cpl_startmant;
948 }
949 }
950 // set number of mantissas
951 if self.cplinu {
952 self.chdata[CPL_CHANNEL].read_exps(br, true, false)?;
953 }
954 for ch in 0..channels {
955 self.chdata[ch].read_exps(br, false, false)?;
956 }
957 if bsi.lfeon {
958 self.chdata[LFE_CHANNEL].read_exps(br, false, true)?;
959 }
960 // bit allocation parameters
961 self.baie = br.read_bool()?;
962 if self.baie {
963 self.sdcycod = br.read(2)? as usize;
964 self.fdcycod = br.read(2)? as usize;
965 self.sgaincod = br.read(2)? as usize;
966 self.dbpbcod = br.read(2)? as usize;
967 self.floorcod = br.read(3)? as usize;
968 }
969 self.snroffste = br.read_bool()?;
970 if self.snroffste {
971 self.csnroffst = br.read(6)? as u8;
972 if self.cplinu {
973 self.chdata[CPL_CHANNEL].read_snr(br)?;
974 }
975 for ch in 0..channels {
976 self.chdata[ch].read_snr(br)?;
977 }
978 if bsi.lfeon {
979 self.chdata[LFE_CHANNEL].read_snr(br)?;
980 }
981 }
982 if self.cplinu {
983 self.cplleake = br.read_bool()?;
984 if self.cplleake {
985 self.cplfleak = br.read(3)? as u8;
986 self.cplsleak = br.read(3)? as u8;
987 }
988 }
989 // delta bit allocation information
990 self.deltbaie = br.read_bool()?;
991 if self.deltbaie {
992 if self.cplinu {
993 self.chdata[CPL_CHANNEL].deltbae = br.read(2)? as u8;
994 validate!(blk_no != 0 || self.chdata[CPL_CHANNEL].deltbae != 0);
995 validate!(self.chdata[CPL_CHANNEL].deltbae != 3);
996 }
997 for ch in 0..channels {
998 self.chdata[ch].deltbae = br.read(2)? as u8;
999 validate!(blk_no != 0 || self.chdata[ch].deltbae != 0);
1000 validate!(self.chdata[ch].deltbae != 3);
1001 }
1002 if self.cplinu {
1003 self.chdata[CPL_CHANNEL].read_deltbai(br)?;
1004 }
1005 for ch in 0..channels {
1006 self.chdata[ch].read_deltbai(br)?;
1007 }
1008 }
1009 // dummy data
1010 if br.read_bool()? {
1011 let skipl = br.read(9)?;
1012 br.skip(skipl * 8)?;
1013 }
1014
1015 let all_zero = self.calc_bitalloc(bsi, channels, fscod);
1016 if all_zero { return Ok(true); }
1017
1018 // quantised mantissa values
1019 let mut got_cplchan = false;
1020 for i in 0..self.bap_buf_fill.len() { self.bap_buf_fill[i] = 0; }
1021 for c in 0..channels {
1022 {
1023 let ch = &mut self.chdata[c];
1024 ch.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
1025 }
1026 if self.cplinu && self.chdata[c].chincpl && !got_cplchan {
1027 let cplch = &mut self.chdata[CPL_CHANNEL];
1028 cplch.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
1029 got_cplchan = true;
1030 }
1031 }
1032 if bsi.lfeon {
1033 let lfech = &mut self.chdata[LFE_CHANNEL];
1034 lfech.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
1035 }
1036 Ok(false)
1037 }
1038 fn calc_bitalloc(&mut self, bsi: &BSI, channels: usize, fscod: usize) -> bool {
1039 let sdecay1 = TS102366_SLOW_DECAY[self.sdcycod];
1040 let fdecay1 = TS102366_FAST_DECAY[self.fdcycod];
1041
1042 let sdecay = sdecay1 >> bsi.shift;
1043 let fdecay = fdecay1 >> bsi.shift;
1044 let sgain = TS102366_SLOW_GAIN[self.sgaincod];
1045 let dbknee = TS102366_DBP_TAB[self.dbpbcod];
1046 let floor = TS102366_FLOOR_TAB[self.floorcod];
1047
1048 let mut all_zero = self.csnroffst == 0;
1049 if !all_zero && self.chdata[LFE_CHANNEL].fsnroffst == 0 {
1050 for ch in 0..channels {
1051 if self.chdata[ch].fsnroffst != 0 {
1052 all_zero = false;
1053 break;
1054 }
1055 }
1056 }
1057 if all_zero { return true; }
1058
1059 let mut mask: [i32; MAX_BANDS] = [0; MAX_BANDS];
1060
1061 if self.cplinu {
1062 self.chdata[CPL_CHANNEL].compute_bndpsd();
1063 self.chdata[CPL_CHANNEL].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee,
c83013a1 1064 (u16::from(self.cplfleak) << 8) + 768, (u16::from(self.cplsleak) << 8) + 768, bsi.shift);
16dd4f44
KS
1065 self.chdata[CPL_CHANNEL].apply_delta_info(&mut mask);
1066 self.chdata[CPL_CHANNEL].calc_snr_offset(self.csnroffst);
1067 self.chdata[CPL_CHANNEL].compute_bap(&mut mask, floor);
1068 }
1069 for ch in 0..channels {
1070 self.chdata[ch].compute_bndpsd();
1071 self.chdata[ch].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee, 0, 0, bsi.shift);
1072 self.chdata[ch].apply_delta_info(&mut mask);
1073 self.chdata[ch].calc_snr_offset(self.csnroffst);
1074 self.chdata[ch].compute_bap(&mut mask, floor);
1075 }
1076 if bsi.lfeon {
1077 self.chdata[LFE_CHANNEL].compute_bndpsd();
1078 self.chdata[LFE_CHANNEL].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee,
1079 0, 0, bsi.shift);
1080 self.chdata[LFE_CHANNEL].calc_snr_offset(self.csnroffst);
1081 self.chdata[LFE_CHANNEL].compute_bap(&mut mask, floor);
1082 }
1083
1084 false
1085 }
1086 fn couple_channels(&mut self, acmod: ACMode) {
1087 if !self.cplinu { return; }
1088 for ch in 0..acmod.get_num_channels() {
1089 if !self.chdata[ch].chincpl { continue; }
1090 let mut pband = 0;
1091 for band in self.cplbegf..self.cplendf {
1092 let cband = band - self.cplbegf;
1093 let comant = self.chdata[ch].cplcomant[cband];
c83013a1 1094 let mut cotemp = i32::from(if self.chdata[ch].cplcoexp[cband] == 15 { comant << 1 } else { comant + 16 });
16dd4f44
KS
1095 if (acmod == ACMode::Stereo) && (ch == 1) && self.phsflginu && self.phsflg[pband] {
1096 cotemp = -cotemp;
1097 }
1098 if !self.cplbndstrc[cband] {
1099 pband += 1;
1100 }
1101 let exp = self.chdata[ch].cplcoexp[cband] + 3 * self.chdata[ch].mstrcplco + 5 - 3;
1102 let start = band * 12 + 37;
1103 for bin in 0..12 {
c83013a1 1104 self.chdata[ch].mant[start + bin] = (self.chdata[CPL_CHANNEL].mant[start + bin] * cotemp) >> exp;
16dd4f44
KS
1105 }
1106//todo dither
1107 }
1108 }
1109 }
205d69bc
KS
1110 fn rematrix(&mut self) {
1111 let maxbin = self.chdata[0].endmant.min(self.chdata[1].endmant);
1112 if self.rematflg[0] {
1113 let end = maxbin.min(25);
1114 for bin in 13..end {
1115 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1116 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1117 self.chdata[0].mant[bin] = d;
1118 self.chdata[1].mant[bin] = s;
1119 }
1120 if maxbin <= 25 { return; }
1121 }
1122 if self.rematflg[1] {
1123 let end = maxbin.min(37);
1124 for bin in 25..end {
1125 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1126 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1127 self.chdata[0].mant[bin] = d;
1128 self.chdata[1].mant[bin] = s;
1129 }
1130 if maxbin <= 37 { return; }
1131 }
1132 if self.rematflg[2] {
1133 let end = maxbin.min(61);
1134 for bin in 37..end {
1135 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1136 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1137 self.chdata[0].mant[bin] = d;
1138 self.chdata[1].mant[bin] = s;
1139 }
1140 if maxbin <= 61 { return; }
1141 }
1142 if self.rematflg[3] {
1143 let end = maxbin;
1144 for bin in 61..end {
1145 let s = self.chdata[0].mant[bin] + self.chdata[1].mant[bin];
1146 let d = self.chdata[0].mant[bin] - self.chdata[1].mant[bin];
1147 self.chdata[0].mant[bin] = d;
1148 self.chdata[1].mant[bin] = s;
1149 }
1150 }
1151 }
16dd4f44
KS
1152 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]) {
1153 self.chdata[channel].synth(imdct512, imdct256, tmp, delay, dst);
1154 }
1155}
1156
1157impl NADecoder for AudioDecoder {
01613464 1158 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
16dd4f44
KS
1159 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
1160 self.info = info.clone();
1161 Ok(())
1162 } else {
1163 Err(DecoderError::InvalidData)
1164 }
1165 }
01613464 1166 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
16dd4f44
KS
1167 let info = pkt.get_stream().get_info();
1168 validate!(info.get_properties().is_audio());
1169 let pktbuf = pkt.get_buffer();
1170 validate!(pktbuf.len() > 5);
1171
1172 let mut br;
1173 if (pktbuf[0] == MAGIC_BYTE0) && (pktbuf[1] == MAGIC_BYTE1) {
fa90ccfb 1174 br = BitReader::new(pktbuf.as_slice(), BitReaderMode::BE);
16dd4f44 1175 } else if (pktbuf[0] == MAGIC_BYTE1) && (pktbuf[1] == MAGIC_BYTE0) {
fa90ccfb 1176 br = BitReader::new(pktbuf.as_slice(), BitReaderMode::LE16MSB);
16dd4f44
KS
1177 } else {
1178 return Err(DecoderError::InvalidData);
1179 }
1180
1181 let sinfo = Syncinfo::read(&mut br)?;
1182 validate!(sinfo.is_valid());
1183
1184 let bsi = BSI::read(&mut br)?;
1185 if bsi.has_addb {
c83013a1 1186 let len = br.read(6)?;
16dd4f44
KS
1187 br.skip((len + 1) * 8)?;
1188 }
1189
1190 let duration = BLOCK_LEN * NBLOCKS;
1191
1192 let core_channels = bsi.acmod.get_num_channels();
1193 let channels = core_channels + if bsi.lfeon { 1 } else { 0 };
1194
1195 let ainfo = NAAudioInfo::new(sinfo.samplerate >> bsi.shift, channels as u8,
1196 SND_F32P_FORMAT, BLOCK_LEN);
1197
b70cc006 1198 let abuf = alloc_audio_buffer(ainfo, duration, bsi.acmod.get_channel_map(bsi.lfeon))?;
16dd4f44 1199 let mut adata = abuf.get_abuf_f32().unwrap();
1a967e6b 1200 let output = adata.get_data_mut().unwrap();
16dd4f44
KS
1201
1202 self.ablk = AudioBlock::new();
1203 for blk in 0..NBLOCKS {
1204 let all_zero = self.ablk.read(&mut br, &bsi, sinfo.fscod as usize, blk)?;
1205 let off = blk * BLOCK_LEN;
1206 self.ablk.couple_channels(bsi.acmod);
205d69bc
KS
1207 if bsi.acmod == ACMode::Stereo {
1208 self.ablk.rematrix();
1209 }
16dd4f44
KS
1210 for ch in 0..core_channels {
1211 let dpos = abuf.get_offset(ch) + off;
1212 let dst = &mut output[dpos..][..BLOCK_LEN];
1213 if !all_zero {
1214 self.ablk.synth_audio_block(&mut self.imdct512, &mut self.imdct256, &mut self.tmp, ch, &mut self.delay[ch], dst);
1215 } else {
1216 self.delay[ch] = [0.0; BLOCK_LEN];
c83013a1 1217 for el in dst.iter_mut().take(BLOCK_LEN) { *el = 0.0; }
16dd4f44
KS
1218 }
1219 }
1220 if bsi.lfeon {
1221 let dpos = abuf.get_offset(core_channels) + off;
1222 let dst = &mut output[dpos..][..BLOCK_LEN];
1223 if !all_zero {
1224 self.ablk.synth_audio_block(&mut self.imdct512, &mut self.imdct256, &mut self.tmp, LFE_CHANNEL, &mut self.delay[LFE_CHANNEL], dst);
1225 } else {
1226 self.delay[LFE_CHANNEL] = [0.0; BLOCK_LEN];
c83013a1 1227 for el in dst.iter_mut().take(BLOCK_LEN) { *el = 0.0; }
16dd4f44
KS
1228 }
1229 }
1230 }
1231//todo skip auxdata
1232//todo do errorcheck
1233
1234 let mut frm = NAFrame::new_from_pkt(pkt, self.info.replace_info(NACodecTypeInfo::Audio(ainfo)), abuf);
1235 frm.set_keyframe(true);
171860fc 1236 Ok(frm.into_ref())
16dd4f44 1237 }
f9be4e75
KS
1238 fn flush(&mut self) {
1239 self.delay = [[0.0; BLOCK_LEN]; MAX_CHANNELS + 1];
1240 }
16dd4f44
KS
1241}
1242
7d57ae2f
KS
1243impl NAOptionHandler for AudioDecoder {
1244 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
1245 fn set_options(&mut self, _options: &[NAOption]) { }
1246 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
1247}
1248
08a1fab7 1249pub fn get_decoder() -> Box<dyn NADecoder + Send> {
16dd4f44
KS
1250 Box::new(AudioDecoder::new())
1251}
1252
1253#[cfg(test)]
1254mod test {
4f6124ac
KS
1255 use nihav_core::codecs::RegisteredDecoders;
1256 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 1257 use nihav_codec_support::test::dec_video::test_decode_audio;
78fb6560 1258 use crate::generic_register_all_decoders;
e64739f8 1259 use nihav_realmedia::realmedia_register_all_demuxers;
16dd4f44
KS
1260 #[test]
1261 fn test_ts102366() {
4f6124ac
KS
1262 let mut dmx_reg = RegisteredDemuxers::new();
1263 realmedia_register_all_demuxers(&mut dmx_reg);
1264 let mut dec_reg = RegisteredDecoders::new();
78fb6560 1265 generic_register_all_decoders(&mut dec_reg);
4f6124ac 1266
886cde48 1267 // sample: https://samples.mplayerhq.hu/real/VC-RV10/sp_sample1.rm
16dd4f44 1268 let file = "assets/RV/sp_sample1.rm";
5580b11b 1269 test_decode_audio("realmedia", file, Some(12000), None/*Some("ac3")*/, &dmx_reg, &dec_reg);
16dd4f44
KS
1270 }
1271}
1272
1273const TS102366_SLOW_DECAY: [u8; 4] = [ 0x0F, 0x11, 0x13, 0x15 ];
1274const TS102366_FAST_DECAY: [u8; 4] = [ 0x3F, 0x53, 0x67, 0x7B ];
1275const TS102366_SLOW_GAIN: [u16; 4] = [ 0x540, 0x4D8, 0x478, 0x410 ];
1276const TS102366_FAST_GAIN: [u16; 8] = [ 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 ];
1277const TS102366_DBP_TAB: [u16; 4] = [ 0x000, 0x700, 0x900, 0xB00 ];
1278const TS102366_FLOOR_TAB: [u16; 8] = [ 0x02F0, 0x02B0, 0x0270, 0x0230, 0x01F0, 0x0170, 0x00F0, 0xF800 ];
1279
1280const TS102366_BIN_TO_BAND: [u8; 256] = [
1281 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1282 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1283 20, 21, 22, 23, 24, 25, 26, 27, 28, 28,
1284 28, 29, 29, 29, 30, 30, 30, 31, 31, 31,
1285 32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
1286 35, 35, 35, 35, 35, 36, 36, 36, 36, 36,
1287 36, 37, 37, 37, 37, 37, 37, 38, 38, 38,
1288 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
1289 40, 40, 40, 40, 40, 41, 41, 41, 41, 41,
1290 41, 41, 41, 41, 41, 41, 41, 42, 42, 42,
1291 42, 42, 42, 42, 42, 42, 42, 42, 42, 43,
1292 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
1293 43, 44, 44, 44, 44, 44, 44, 44, 44, 44,
1294 44, 44, 44, 45, 45, 45, 45, 45, 45, 45,
1295 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
1296 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
1297 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
1298 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
1299 46, 47, 47, 47, 47, 47, 47, 47, 47, 47,
1300 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
1301 47, 47, 47, 47, 47, 48, 48, 48, 48, 48,
1302 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
1303 48, 48, 48, 48, 48, 48, 48, 48, 48, 49,
1304 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
1305 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
1306 49, 49, 49, 0, 0, 0
1307];
1308const TS102366_BAND_SIZE: [u8; MAX_BANDS] = [
1309 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1310 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1311 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
1312 3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
1313 6, 12, 12, 12, 12, 24, 24, 24, 24, 24
1314];
1315const TS102366_BAND_START: [u8; MAX_BANDS] = [
1316 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1317 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1318 20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
1319 34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
1320 79, 85, 97, 109, 121, 133, 157, 181, 205, 229
1321];
1322
1323const TS102366_LATAB: [u16; 256] = [
1324 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
1325 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
1326 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
1327 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
1328 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
1329 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
1330 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
1331 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
1332 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
1333 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
1334 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
1335 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
1336 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
1337 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
1338 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
1339 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
1340 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
1341 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
1342 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
1343 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
1344 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
1345 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
1346 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
1347 0x0001, 0x0001, 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, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1351 0x0000, 0x0000, 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];
1357const TS102366_HTH: [[u16; MAX_BANDS]; 3] = [
1358 [
1359 0x04D0, 0x04D0, 0x0440, 0x0400, 0x03E0, 0x03C0, 0x03B0, 0x03B0, 0x03A0, 0x03A0,
1360 0x03A0, 0x03A0, 0x03A0, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0370, 0x0370,
1361 0x0360, 0x0360, 0x0350, 0x0350, 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300,
1362 0x02F0, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03E0, 0x0420,
1363 0x0460, 0x0490, 0x04A0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, 0x0840, 0x0840,
1364 ], [
1365 0x04F0, 0x04F0, 0x0460, 0x0410, 0x03E0, 0x03D0, 0x03C0, 0x03B0, 0x03B0, 0x03A0,
1366 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0380,
1367 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310,
1368 0x0300, 0x02F0, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03E0,
1369 0x0420, 0x0450, 0x04A0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, 0x0840, 0x0840,
1370 ], [
1371 0x0580, 0x0580, 0x04B0, 0x0450, 0x0420, 0x03F0, 0x03E0, 0x03D0, 0x03C0, 0x03B0,
1372 0x03B0, 0x03B0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0,
1373 0x0390, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350,
1374 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0310,
1375 0x0330, 0x0350, 0x03C0, 0x0410, 0x0470, 0x04A0, 0x0460, 0x0440, 0x0450, 0x04E0,
1376 ]
1377];
1378const TS102366_BAPTAB: [u8; 64] = [
1379 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
1380 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,
1381 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
1382 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15
1383];
1384
1385const TS102366_QUANT3_MAP: [[i32; 3]; 27] = [
1386 [ -0x0AAAAAA, -0x0AAAAAA, -0x0AAAAAA ],
1387 [ -0x0AAAAAA, -0x0AAAAAA, 0x00000000 ],
1388 [ -0x0AAAAAA, -0x0AAAAAA, 0x00AAAAAA ],
1389 [ -0x0AAAAAA, 0x00000000, -0x0AAAAAA ],
1390 [ -0x0AAAAAA, 0x00000000, 0x00000000 ],
1391 [ -0x0AAAAAA, 0x00000000, 0x00AAAAAA ],
1392 [ -0x0AAAAAA, 0x00AAAAAA, -0x0AAAAAA ],
1393 [ -0x0AAAAAA, 0x00AAAAAA, 0x00000000 ],
1394 [ -0x0AAAAAA, 0x00AAAAAA, 0x00AAAAAA ],
1395 [ 0x00000000, -0x0AAAAAA, -0x0AAAAAA ],
1396 [ 0x00000000, -0x0AAAAAA, 0x00000000 ],
1397 [ 0x00000000, -0x0AAAAAA, 0x00AAAAAA ],
1398 [ 0x00000000, 0x00000000, -0x0AAAAAA ],
1399 [ 0x00000000, 0x00000000, 0x00000000 ],
1400 [ 0x00000000, 0x00000000, 0x00AAAAAA ],
1401 [ 0x00000000, 0x00AAAAAA, -0x0AAAAAA ],
1402 [ 0x00000000, 0x00AAAAAA, 0x00000000 ],
1403 [ 0x00000000, 0x00AAAAAA, 0x00AAAAAA ],
1404 [ 0x00AAAAAA, -0x0AAAAAA, -0x0AAAAAA ],
1405 [ 0x00AAAAAA, -0x0AAAAAA, 0x00000000 ],
1406 [ 0x00AAAAAA, -0x0AAAAAA, 0x00AAAAAA ],
1407 [ 0x00AAAAAA, 0x00000000, -0x0AAAAAA ],
1408 [ 0x00AAAAAA, 0x00000000, 0x00000000 ],
1409 [ 0x00AAAAAA, 0x00000000, 0x00AAAAAA ],
1410 [ 0x00AAAAAA, 0x00AAAAAA, -0x0AAAAAA ],
1411 [ 0x00AAAAAA, 0x00AAAAAA, 0x00000000 ],
1412 [ 0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA ]
1413];
1414const TS102366_QUANT5_MAP: [[i32; 3]; 125] = [
1415 [ -0x0CCCCCC, -0x0CCCCCC, -0x0CCCCCC ], [ -0x0CCCCCC, -0x0CCCCCC, -0x0666666 ], [ -0x0CCCCCC, -0x0CCCCCC, 0x00000000 ],
1416 [ -0x0CCCCCC, -0x0CCCCCC, 0x00666666 ], [ -0x0CCCCCC, -0x0CCCCCC, 0x00CCCCCC ],
1417 [ -0x0CCCCCC, -0x0666666, -0x0CCCCCC ], [ -0x0CCCCCC, -0x0666666, -0x0666666 ], [ -0x0CCCCCC, -0x0666666, 0x00000000 ],
1418 [ -0x0CCCCCC, -0x0666666, 0x00666666 ], [ -0x0CCCCCC, -0x0666666, 0x00CCCCCC ],
1419 [ -0x0CCCCCC, 0x00000000, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00000000, -0x0666666 ], [ -0x0CCCCCC, 0x00000000, 0x00000000 ],
1420 [ -0x0CCCCCC, 0x00000000, 0x00666666 ], [ -0x0CCCCCC, 0x00000000, 0x00CCCCCC ],
1421 [ -0x0CCCCCC, 0x00666666, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00666666, -0x0666666 ], [ -0x0CCCCCC, 0x00666666, 0x00000000 ],
1422 [ -0x0CCCCCC, 0x00666666, 0x00666666 ], [ -0x0CCCCCC, 0x00666666, 0x00CCCCCC ],
1423 [ -0x0CCCCCC, 0x00CCCCCC, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00CCCCCC, -0x0666666 ], [ -0x0CCCCCC, 0x00CCCCCC, 0x00000000 ],
1424 [ -0x0CCCCCC, 0x00CCCCCC, 0x00666666 ], [ -0x0CCCCCC, 0x00CCCCCC, 0x00CCCCCC ],
1425 [ -0x0666666, -0x0CCCCCC, -0x0CCCCCC ], [ -0x0666666, -0x0CCCCCC, -0x0666666 ], [ -0x0666666, -0x0CCCCCC, 0x00000000 ],
1426 [ -0x0666666, -0x0CCCCCC, 0x00666666 ], [ -0x0666666, -0x0CCCCCC, 0x00CCCCCC ],
1427 [ -0x0666666, -0x0666666, -0x0CCCCCC ], [ -0x0666666, -0x0666666, -0x0666666 ], [ -0x0666666, -0x0666666, 0x00000000 ],
1428 [ -0x0666666, -0x0666666, 0x00666666 ], [ -0x0666666, -0x0666666, 0x00CCCCCC ],
1429 [ -0x0666666, 0x00000000, -0x0CCCCCC ], [ -0x0666666, 0x00000000, -0x0666666 ], [ -0x0666666, 0x00000000, 0x00000000 ],
1430 [ -0x0666666, 0x00000000, 0x00666666 ], [ -0x0666666, 0x00000000, 0x00CCCCCC ],
1431 [ -0x0666666, 0x00666666, -0x0CCCCCC ], [ -0x0666666, 0x00666666, -0x0666666 ], [ -0x0666666, 0x00666666, 0x00000000 ],
1432 [ -0x0666666, 0x00666666, 0x00666666 ], [ -0x0666666, 0x00666666, 0x00CCCCCC ],
1433 [ -0x0666666, 0x00CCCCCC, -0x0CCCCCC ], [ -0x0666666, 0x00CCCCCC, -0x0666666 ], [ -0x0666666, 0x00CCCCCC, 0x00000000 ],
1434 [ -0x0666666, 0x00CCCCCC, 0x00666666 ], [ -0x0666666, 0x00CCCCCC, 0x00CCCCCC ],
1435 [ 0x00000000, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00000000, -0x0CCCCCC, -0x0666666 ], [ 0x00000000, -0x0CCCCCC, 0x00000000 ],
1436 [ 0x00000000, -0x0CCCCCC, 0x00666666 ], [ 0x00000000, -0x0CCCCCC, 0x00CCCCCC ],
1437 [ 0x00000000, -0x0666666, -0x0CCCCCC ], [ 0x00000000, -0x0666666, -0x0666666 ], [ 0x00000000, -0x0666666, 0x00000000 ],
1438 [ 0x00000000, -0x0666666, 0x00666666 ], [ 0x00000000, -0x0666666, 0x00CCCCCC ],
1439 [ 0x00000000, 0x00000000, -0x0CCCCCC ], [ 0x00000000, 0x00000000, -0x0666666 ], [ 0x00000000, 0x00000000, 0x00000000 ],
1440 [ 0x00000000, 0x00000000, 0x00666666 ], [ 0x00000000, 0x00000000, 0x00CCCCCC ],
1441 [ 0x00000000, 0x00666666, -0x0CCCCCC ], [ 0x00000000, 0x00666666, -0x0666666 ], [ 0x00000000, 0x00666666, 0x00000000 ],
1442 [ 0x00000000, 0x00666666, 0x00666666 ], [ 0x00000000, 0x00666666, 0x00CCCCCC ],
1443 [ 0x00000000, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00000000, 0x00CCCCCC, -0x0666666 ], [ 0x00000000, 0x00CCCCCC, 0x00000000 ],
1444 [ 0x00000000, 0x00CCCCCC, 0x00666666 ], [ 0x00000000, 0x00CCCCCC, 0x00CCCCCC ],
1445 [ 0x00666666, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00666666, -0x0CCCCCC, -0x0666666 ], [ 0x00666666, -0x0CCCCCC, 0x00000000 ],
1446 [ 0x00666666, -0x0CCCCCC, 0x00666666 ], [ 0x00666666, -0x0CCCCCC, 0x00CCCCCC ],
1447 [ 0x00666666, -0x0666666, -0x0CCCCCC ], [ 0x00666666, -0x0666666, -0x0666666 ], [ 0x00666666, -0x0666666, 0x00000000 ],
1448 [ 0x00666666, -0x0666666, 0x00666666 ], [ 0x00666666, -0x0666666, 0x00CCCCCC ],
1449 [ 0x00666666, 0x00000000, -0x0CCCCCC ], [ 0x00666666, 0x00000000, -0x0666666 ], [ 0x00666666, 0x00000000, 0x00000000 ],
1450 [ 0x00666666, 0x00000000, 0x00666666 ], [ 0x00666666, 0x00000000, 0x00CCCCCC ],
1451 [ 0x00666666, 0x00666666, -0x0CCCCCC ], [ 0x00666666, 0x00666666, -0x0666666 ], [ 0x00666666, 0x00666666, 0x00000000 ],
1452 [ 0x00666666, 0x00666666, 0x00666666 ], [ 0x00666666, 0x00666666, 0x00CCCCCC ],
1453 [ 0x00666666, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00666666, 0x00CCCCCC, -0x0666666 ], [ 0x00666666, 0x00CCCCCC, 0x00000000 ],
1454 [ 0x00666666, 0x00CCCCCC, 0x00666666 ], [ 0x00666666, 0x00CCCCCC, 0x00CCCCCC ],
1455 [ 0x00CCCCCC, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00CCCCCC, -0x0CCCCCC, -0x0666666 ], [ 0x00CCCCCC, -0x0CCCCCC, 0x00000000 ],
1456 [ 0x00CCCCCC, -0x0CCCCCC, 0x00666666 ], [ 0x00CCCCCC, -0x0CCCCCC, 0x00CCCCCC ],
1457 [ 0x00CCCCCC, -0x0666666, -0x0CCCCCC ], [ 0x00CCCCCC, -0x0666666, -0x0666666 ], [ 0x00CCCCCC, -0x0666666, 0x00000000 ],
1458 [ 0x00CCCCCC, -0x0666666, 0x00666666 ], [ 0x00CCCCCC, -0x0666666, 0x00CCCCCC ],
1459 [ 0x00CCCCCC, 0x00000000, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00000000, -0x0666666 ], [ 0x00CCCCCC, 0x00000000, 0x00000000 ],
1460 [ 0x00CCCCCC, 0x00000000, 0x00666666 ], [ 0x00CCCCCC, 0x00000000, 0x00CCCCCC ],
1461 [ 0x00CCCCCC, 0x00666666, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00666666, -0x0666666 ], [ 0x00CCCCCC, 0x00666666, 0x00000000 ],
1462 [ 0x00CCCCCC, 0x00666666, 0x00666666 ], [ 0x00CCCCCC, 0x00666666, 0x00CCCCCC ],
1463 [ 0x00CCCCCC, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00CCCCCC, -0x0666666 ], [ 0x00CCCCCC, 0x00CCCCCC, 0x00000000 ],
1464 [ 0x00CCCCCC, 0x00CCCCCC, 0x00666666 ], [ 0x00CCCCCC, 0x00CCCCCC, 0x00CCCCCC ],
1465];
1466const TS102366_QUANT7_MAP: [i32; 7] = [
1467 -0xDB6DB6, -0x924924, -0x492492, 0x000000, 0x492492, 0x924924, 0xDB6DB6
1468];
1469const TS102366_QUANT11_MAP: [[i32; 2]; 121] = [
1470 [ -0x0E8BA2E, -0x0E8BA2E ], [ -0x0E8BA2E, -0x0BA2E8B ], [ -0x0E8BA2E, -0x08BA2E8 ],
1471 [ -0x0E8BA2E, -0x05D1745 ], [ -0x0E8BA2E, -0x02E8BA2 ], [ -0x0E8BA2E, 0x00000000 ],
1472 [ -0x0E8BA2E, 0x002E8BA2 ], [ -0x0E8BA2E, 0x005D1745 ], [ -0x0E8BA2E, 0x008BA2E8 ],
1473 [ -0x0E8BA2E, 0x00BA2E8B ], [ -0x0E8BA2E, 0x00E8BA2E ], [ -0x0BA2E8B, -0x0E8BA2E ],
1474 [ -0x0BA2E8B, -0x0BA2E8B ], [ -0x0BA2E8B, -0x08BA2E8 ], [ -0x0BA2E8B, -0x05D1745 ],
1475 [ -0x0BA2E8B, -0x02E8BA2 ], [ -0x0BA2E8B, 0x00000000 ], [ -0x0BA2E8B, 0x002E8BA2 ],
1476 [ -0x0BA2E8B, 0x005D1745 ], [ -0x0BA2E8B, 0x008BA2E8 ], [ -0x0BA2E8B, 0x00BA2E8B ],
1477 [ -0x0BA2E8B, 0x00E8BA2E ], [ -0x08BA2E8, -0x0E8BA2E ], [ -0x08BA2E8, -0x0BA2E8B ],
1478 [ -0x08BA2E8, -0x08BA2E8 ], [ -0x08BA2E8, -0x05D1745 ], [ -0x08BA2E8, -0x02E8BA2 ],
1479 [ -0x08BA2E8, 0x00000000 ], [ -0x08BA2E8, 0x002E8BA2 ], [ -0x08BA2E8, 0x005D1745 ],
1480 [ -0x08BA2E8, 0x008BA2E8 ], [ -0x08BA2E8, 0x00BA2E8B ], [ -0x08BA2E8, 0x00E8BA2E ],
1481 [ -0x05D1745, -0x0E8BA2E ], [ -0x05D1745, -0x0BA2E8B ], [ -0x05D1745, -0x08BA2E8 ],
1482 [ -0x05D1745, -0x05D1745 ], [ -0x05D1745, -0x02E8BA2 ], [ -0x05D1745, 0x00000000 ],
1483 [ -0x05D1745, 0x002E8BA2 ], [ -0x05D1745, 0x005D1745 ], [ -0x05D1745, 0x008BA2E8 ],
1484 [ -0x05D1745, 0x00BA2E8B ], [ -0x05D1745, 0x00E8BA2E ], [ -0x02E8BA2, -0x0E8BA2E ],
1485 [ -0x02E8BA2, -0x0BA2E8B ], [ -0x02E8BA2, -0x08BA2E8 ], [ -0x02E8BA2, -0x05D1745 ],
1486 [ -0x02E8BA2, -0x02E8BA2 ], [ -0x02E8BA2, 0x00000000 ], [ -0x02E8BA2, 0x002E8BA2 ],
1487 [ -0x02E8BA2, 0x005D1745 ], [ -0x02E8BA2, 0x008BA2E8 ], [ -0x02E8BA2, 0x00BA2E8B ],
1488 [ -0x02E8BA2, 0x00E8BA2E ], [ 0x00000000, -0x0E8BA2E ], [ 0x00000000, -0x0BA2E8B ],
1489 [ 0x00000000, -0x08BA2E8 ], [ 0x00000000, -0x05D1745 ], [ 0x00000000, -0x02E8BA2 ],
1490 [ 0x00000000, 0x00000000 ], [ 0x00000000, 0x002E8BA2 ], [ 0x00000000, 0x005D1745 ],
1491 [ 0x00000000, 0x008BA2E8 ], [ 0x00000000, 0x00BA2E8B ], [ 0x00000000, 0x00E8BA2E ],
1492 [ 0x002E8BA2, -0x0E8BA2E ], [ 0x002E8BA2, -0x0BA2E8B ], [ 0x002E8BA2, -0x08BA2E8 ],
1493 [ 0x002E8BA2, -0x05D1745 ], [ 0x002E8BA2, -0x02E8BA2 ], [ 0x002E8BA2, 0x00000000 ],
1494 [ 0x002E8BA2, 0x002E8BA2 ], [ 0x002E8BA2, 0x005D1745 ], [ 0x002E8BA2, 0x008BA2E8 ],
1495 [ 0x002E8BA2, 0x00BA2E8B ], [ 0x002E8BA2, 0x00E8BA2E ], [ 0x005D1745, -0x0E8BA2E ],
1496 [ 0x005D1745, -0x0BA2E8B ], [ 0x005D1745, -0x08BA2E8 ], [ 0x005D1745, -0x05D1745 ],
1497 [ 0x005D1745, -0x02E8BA2 ], [ 0x005D1745, 0x00000000 ], [ 0x005D1745, 0x002E8BA2 ],
1498 [ 0x005D1745, 0x005D1745 ], [ 0x005D1745, 0x008BA2E8 ], [ 0x005D1745, 0x00BA2E8B ],
1499 [ 0x005D1745, 0x00E8BA2E ], [ 0x008BA2E8, -0x0E8BA2E ], [ 0x008BA2E8, -0x0BA2E8B ],
1500 [ 0x008BA2E8, -0x08BA2E8 ], [ 0x008BA2E8, -0x05D1745 ], [ 0x008BA2E8, -0x02E8BA2 ],
1501 [ 0x008BA2E8, 0x00000000 ], [ 0x008BA2E8, 0x002E8BA2 ], [ 0x008BA2E8, 0x005D1745 ],
1502 [ 0x008BA2E8, 0x008BA2E8 ], [ 0x008BA2E8, 0x00BA2E8B ], [ 0x008BA2E8, 0x00E8BA2E ],
1503 [ 0x00BA2E8B, -0x0E8BA2E ], [ 0x00BA2E8B, -0x0BA2E8B ], [ 0x00BA2E8B, -0x08BA2E8 ],
1504 [ 0x00BA2E8B, -0x05D1745 ], [ 0x00BA2E8B, -0x02E8BA2 ], [ 0x00BA2E8B, 0x00000000 ],
1505 [ 0x00BA2E8B, 0x002E8BA2 ], [ 0x00BA2E8B, 0x005D1745 ], [ 0x00BA2E8B, 0x008BA2E8 ],
1506 [ 0x00BA2E8B, 0x00BA2E8B ], [ 0x00BA2E8B, 0x00E8BA2E ], [ 0x00E8BA2E, -0x0E8BA2E ],
1507 [ 0x00E8BA2E, -0x0BA2E8B ], [ 0x00E8BA2E, -0x08BA2E8 ], [ 0x00E8BA2E, -0x05D1745 ],
1508 [ 0x00E8BA2E, -0x02E8BA2 ], [ 0x00E8BA2E, 0x00000000 ], [ 0x00E8BA2E, 0x002E8BA2 ],
1509 [ 0x00E8BA2E, 0x005D1745 ], [ 0x00E8BA2E, 0x008BA2E8 ], [ 0x00E8BA2E, 0x00BA2E8B ],
1510 [ 0x00E8BA2E, 0x00E8BA2E ],
1511];
1512const TS102366_QUANT15_MAP: [i32; 15] = [
1513 -0x0EEEEEE, -0x0CCCCCC, -0x0AAAAAA, -0x0888888, -0x0666666, -0x0444444, -0x0222222, 0x00000000,
1514 0x00222222, 0x00444444, 0x00666666, 0x00888888, 0x00AAAAAA, 0x00CCCCCC, 0x00EEEEEE,
1515];
1516const TS102366_BAP_BITS: [u8; 10] = [ 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 ];
1517
1518const TS102366_WINDOW: [f32; 256] = [
1519 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
1520 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
1521 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
1522 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
1523 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
1524 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
1525 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
1526 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
1527 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
1528 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
1529 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
1530 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
1531 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
1532 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
1533 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
1534 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
1535 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
1536 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
1537 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
1538 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
1539 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
1540 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
1541 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
1542 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
1543 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
1544 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
1545 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
1546 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
1547 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
1548 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
1549 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1550 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
1551];