]> git.nihav.org Git - nihav.git/blame_incremental - nihav-indeo/src/codecs/imc.rs
add Truemotion RT encoder
[nihav.git] / nihav-indeo / src / codecs / imc.rs
... / ...
CommitLineData
1use std::mem;
2use std::ptr;
3use std::f32::consts;
4
5use nihav_core::formats::*;
6use nihav_core::frame::*;
7use nihav_core::codecs::*;
8use nihav_core::io::bitreader::*;
9use nihav_core::io::codebook::*;
10use nihav_codec_support::dsp::fft::*;
11use nihav_codec_support::dsp::window::*;
12
13const BANDS: usize = 32;
14const COEFFS: usize = 256;
15const BLOCK_SIZE: usize = 64;
16
17struct IMDCTContext {
18 pretwiddle1: [f32; COEFFS/2],
19 pretwiddle2: [f32; COEFFS/2],
20 posttwiddle: [FFTComplex; COEFFS/2],
21 tmp: [FFTComplex; COEFFS/2],
22 fft: FFT,
23 window: [f32; COEFFS],
24}
25
26struct IMCChannel {
27 old_floor: [f32; BANDS],
28 new_floor: [f32; BANDS],
29 log_floor: [f32; BANDS],
30 log_floor2: [f32; BANDS],
31 bit_est: [f32; BANDS],
32 mask_wght: [f32; BANDS],
33 adj_floor: [f32; BANDS],
34 cw: [f32; COEFFS],
35 last_im: [f32; COEFFS/2],
36}
37
38struct BitAlloc {
39 band_width: [usize; BANDS],
40 band_present: [bool; BANDS],
41 band_skip: [bool; BANDS],
42 band_bits: [u8; BANDS],
43 cw_len: [u8; COEFFS],
44 band_bitsum: [usize; BANDS],
45 skip_flag: [bool; COEFFS],
46 skip_flag_bits: [u8; BANDS],
47 skips_per_band: [usize; BANDS],
48 keep_flag: [bool; BANDS],
49 coeff: [u8; COEFFS],
50}
51
52impl IMCChannel {
53 fn new() -> Self {
54 IMCChannel {
55 old_floor: [0.0; BANDS],
56 new_floor: [0.0; BANDS],
57 log_floor: [0.0; BANDS],
58 log_floor2: [0.0; BANDS],
59 bit_est: [0.0; BANDS],
60 mask_wght: [0.0; BANDS],
61 adj_floor: [0.0; BANDS],
62 cw: [0.0; COEFFS],
63 last_im: [0.0; COEFFS/2],
64 }
65 }
66 fn reset(&mut self) {
67 for i in 0..self.old_floor.len() { self.old_floor[i] = 1.0; }
68 for i in 0..self.cw.len() { self.cw[i] = 0.0; }
69 }
70}
71
72const BITALLOC_LIMIT: f32 = -1.0e20;
73const BITALLOC_TOP_LIMIT: f32 = 1.0e20;
74impl BitAlloc {
75 fn new() -> Self {
76 BitAlloc {
77 band_width: [0; BANDS],
78 band_present: [false; BANDS],
79 band_skip: [false; BANDS],
80 band_bits: [0; BANDS],
81 cw_len: [0; COEFFS],
82 band_bitsum: [0; BANDS],
83 skip_flag: [false; COEFFS],
84 skip_flag_bits: [0; BANDS],
85 skips_per_band: [0; BANDS],
86 keep_flag: [false; BANDS],
87 coeff: [0; COEFFS],
88 }
89 }
90 fn reset(&mut self) {
91 for i in 0..BANDS {
92 self.band_width[i] = 0;
93 self.band_present[i] = false;
94 self.band_skip[i] = false;
95 self.band_bits[i] = 0;
96 self.keep_flag[i] = false;
97 self.band_bitsum[i] = 0;
98 self.skips_per_band[i] = 0;
99 self.skip_flag_bits[i] = 0;
100 }
101 for i in 0..COEFFS {
102 self.cw_len[i] = 0;
103 self.skip_flag[i] = false;
104 }
105 }
106 #[allow(clippy::cognitive_complexity)]
107 fn calculate_bit_allocation(&mut self, ch_data: &mut IMCChannel, bits: usize, fixed_head: bool, adj_idx: usize) -> DecoderResult<()> {
108
109 let mut peak = 0.0;
110 for coef in ch_data.new_floor.iter() { if *coef > peak { peak = *coef; } }
111 peak *= 0.25;
112
113 for band in 0..BANDS-1 {
114 ch_data.bit_est[band] = ch_data.log_floor2[band] - ch_data.mask_wght[band].log2();
115 }
116 ch_data.bit_est[BANDS - 1] = BITALLOC_LIMIT;
117
118 for band in 0..BANDS {
119 let mut idx = 42;
120 let band_w = IMC_BANDS[band + 1] - IMC_BANDS[band];
121 if band_w == self.band_width[band] { idx = 0; }
122 if band_w > self.band_width[band] { idx = 1; }
123 if band_w/2 >= self.band_width[band] { idx = 2; }
124 validate!(idx <= 2);
125 idx *= 2;
126 if ch_data.new_floor[band] < peak { idx += 1; }
127 ch_data.bit_est[band] += IMC_BITALLOC_ADJ[adj_idx][idx];
128 }
129
130 if fixed_head {
131 for i in 0..4 {
132 ch_data.bit_est[i] = BITALLOC_LIMIT;
133 }
134 }
135
136 let start = if fixed_head { 4 } else { 0 };
137
138 let mut a_width = 0;
139 let mut pool = 0.0;
140 for band in start..BANDS-1 {
141 a_width += self.band_width[band];
142 pool += (self.band_width[band] as f32) * ch_data.bit_est[band];
143 }
144 validate!(a_width > 0);
145
146 self.band_width[BANDS - 1] = 0;
147 pool = (pool * 0.5 - (bits as f32)) / (a_width as f32);
148
149 let free_bits = bits as i32;
150 let mut cur_bits: i32 = 0;
151 let mut flag = 1;
152 let mut mmcount = 0;
153 for i in 0..BANDS/2 {
154 let diff = cur_bits - free_bits;
155 if diff.abs() <= 8 { break; }
156
157 cur_bits = 0;
158 let mut acc = 0;
159 for band in start..BANDS {
160 let mut len = (ch_data.bit_est[band] * 0.5 - pool + 0.5) as i32;
161 if len < 0 { len = 0; }
162 if len > 6 { len = 6; }
163 self.band_bits[band] = len as u8;
164 cur_bits += (self.band_width[band] as i32) * (len as i32);
165 if len > 0 {
166 acc += self.band_width[band] as i32;
167 }
168 }
169
170 let mut lflag = flag;
171 flag = 1;
172 if free_bits < cur_bits { flag = -1; }
173 if i == 0 { lflag = flag; }
174 if flag != lflag {
175 mmcount += 1;
176 }
177 pool += ((cur_bits - free_bits) as f32) / (((mmcount + 1) * acc) as f32);
178 }
179
180 for band in start..BANDS {
181 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
182 self.cw_len[i] = self.band_bits[band];
183 }
184 }
185
186 if free_bits > cur_bits {
187 let mut tmp: [f32; BANDS] = [BITALLOC_LIMIT; BANDS];
188 for band in 0..BANDS {
189 if self.band_bits[band] != 6 {
190 tmp[band] = f32::from(self.band_bits[band]) * -2.0 + ch_data.bit_est[band] - 0.415;
191 }
192 }
193 let mut peak = 0.0;
194 while (peak > BITALLOC_LIMIT) && (cur_bits < free_bits) {
195 peak = BITALLOC_LIMIT;
196 let mut idx: Option<usize> = None;
197 for band in 0..BANDS {
198 if tmp[band] > peak {
199 peak = tmp[band];
200 idx = Some(band);
201 }
202 }
203 if let Some(band) = idx {
204 tmp[band] -= 2.0;
205 self.band_bits[band] += 1;
206 if self.band_bits[band] == 6 {
207 tmp[band] = BITALLOC_LIMIT;
208 }
209 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
210 self.cw_len[i] += 1;
211 cur_bits += 1;
212 if cur_bits >= free_bits {
213 break;
214 }
215 }
216 }
217 }
218 }
219
220 if cur_bits > free_bits {
221 let mut tmp: [f32; BANDS] = [BITALLOC_TOP_LIMIT; BANDS];
222 for band in start..BANDS {
223 if self.band_bits[band] != 0 {
224 tmp[band] = f32::from(self.band_bits[band]) * -2.0 + ch_data.bit_est[band] - 0.415 + 2.0;
225 }
226 }
227 while free_bits < cur_bits {
228 let mut low = BITALLOC_TOP_LIMIT;
229 let mut idx = 0;
230 for band in 0..BANDS {
231 if tmp[band] < low {
232 low = tmp[band];
233 idx = band;
234 }
235 }
236 tmp[idx] += 2.0;
237 self.band_bits[idx] -= 1;
238 if self.band_bits[idx] == 0 {
239 tmp[idx] = BITALLOC_TOP_LIMIT;
240 }
241 for i in IMC_BANDS[idx]..IMC_BANDS[idx + 1] {
242 if self.cw_len[i] > 0 {
243 self.cw_len[i] -= 1;
244 cur_bits -= 1;
245 if cur_bits <= free_bits {
246 break;
247 }
248 }
249 }
250 }
251 }
252
253 Ok(())
254 }
255
256 fn adjust_bit_allocation(&mut self, ch_data: &mut IMCChannel, free_bits: i32) {
257 let mut tmp: [f32; BANDS] = [BITALLOC_LIMIT; BANDS];
258 for band in 0..BANDS {
259 if self.band_bits[band] != 6 {
260 tmp[band] = f32::from(self.band_bits[band]) * -2.0 + ch_data.bit_est[band] - 0.415;
261 }
262 }
263 let mut used_bits: i32 = 0;
264 let mut peak = 0.0;
265 while (peak > BITALLOC_LIMIT) && (used_bits < free_bits) {
266 peak = BITALLOC_LIMIT;
267 let mut idx: Option<usize> = None;
268 for band in 0..BANDS {
269 if tmp[band] > peak {
270 peak = tmp[band];
271 idx = Some(band);
272 }
273 }
274 if let Some(band) = idx {
275 tmp[band] -= 2.0;
276 self.band_bits[band] += 1;
277 if self.band_bits[band] == 6 {
278 tmp[band] = BITALLOC_LIMIT;
279 }
280 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
281 if self.cw_len[i] >= 6 { continue; }
282 self.cw_len[i] += 1;
283 used_bits += 1;
284 if used_bits >= free_bits {
285 break;
286 }
287 }
288 }
289 }
290 }
291}
292
293struct LUTs {
294 exp_lev: [f32; 16],
295 exp_10: [f32; 32],
296 sqrt_tab: [f32; 32],
297}
298
299impl LUTs {
300 fn new() -> Self {
301 let mut exp_lev: [f32; 16] = [0.0; 16];
302 for lev in 0..16 {
303 exp_lev[lev] = 10.0f32.powf(-(lev as f32) * 0.4375);
304 }
305
306 let mut exp_10: [f32; 32] = [0.0; 32];
307 for i in 0..32 {
308 exp_10[i] = 10.0f32.powf(((i as f32) - 16.0) * 0.25);
309 }
310
311 let mut sqrt_tab: [f32; 32] = [0.0; 32];
312 for i in 0..32 {
313 sqrt_tab[i] = (i as f32).sqrt();
314 }
315
316 LUTs { exp_lev, exp_10, sqrt_tab }
317 }
318}
319
320struct IMCDecoder {
321 is_imc: bool,
322
323 chmap: NAChannelMap,
324 ainfo: NAAudioInfo,
325 info: NACodecInfoRef,
326
327 codes: [[Codebook<u8>; 4]; 4],
328 ch_data: [IMCChannel; 2],
329 ba: BitAlloc,
330 imdct: IMDCTContext,
331
332 cycle1: [usize; BANDS],
333 cycle2: [usize; BANDS],
334 weights1: [f32; BANDS-1],
335 weights2: [f32; BANDS-1],
336
337 luts: LUTs,
338}
339
340fn freq2bark(freq: f32) -> f32 {
341 3.5 * ((freq / 7500.0) * (freq / 7500.0)).atan() + 13.0 * (freq * 0.00076).atan()
342}
343
344fn calc_maxcoef(coef: f32) -> (f32, f32) {
345 let c1 = 20000.0 / 10.0f32.powf(coef * 0.057031251);
346 (c1, c1.log2())
347}
348
349impl IMCDecoder {
350 fn new(is_imc: bool) -> Self {
351 let mut cycle1: [usize; BANDS] = [0; BANDS];
352 let mut cycle2: [usize; BANDS] = [0; BANDS];
353 let mut weights1: [f32; BANDS-1] = [0.0; BANDS-1];
354 let mut weights2: [f32; BANDS-1] = [0.0; BANDS-1];
355 if is_imc {
356 cycle1.copy_from_slice(&IMC_CYCLE1);
357 cycle2.copy_from_slice(&IMC_CYCLE2);
358 weights1.copy_from_slice(&IMC_WEIGHTS1);
359 weights2.copy_from_slice(&IMC_WEIGHTS2);
360 }
361 let codes = unsafe {
362 let mut ucodes: mem::MaybeUninit::<[[Codebook<u8>; 4]; 4]> = mem::MaybeUninit::uninit();
363 for i in 0..4 {
364 for j in 0..4 {
365 let mut cr = IMCCodeReader::new(i, j);
366 ptr::write(&mut (*ucodes.as_mut_ptr())[i][j], Codebook::new(&mut cr, CodebookMode::MSB).unwrap());
367 }
368 }
369 ucodes.assume_init()
370 };
371 IMCDecoder {
372 is_imc,
373 chmap: NAChannelMap::new(),
374 ainfo: NAAudioInfo::new(0, 0, SND_F32P_FORMAT, 0),
375 info: NACodecInfo::new_dummy(),
376
377 codes,
378 ch_data: [IMCChannel::new(), IMCChannel::new()],
379 ba: BitAlloc::new(),
380 imdct: IMDCTContext::new(),
381 luts: LUTs::new(),
382
383 cycle1,
384 cycle2,
385 weights1,
386 weights2,
387 }
388 }
389
390 fn generate_iac_tables(&mut self, sample_rate: f32) {
391 let scale = sample_rate / 256.0 / 2.0 * 0.5;
392 let nyq_freq = sample_rate / 2.0;
393 let mut last_bark = 0.0;
394 let mut freq_max: [f32; BANDS] = [0.0; BANDS];
395 let mut freq_mid: [f32; BANDS] = [0.0; BANDS];
396 let mut freq_min: [f32; BANDS] = [0.0; BANDS];
397 for band in 0..BANDS {
398 let freq = ((IMC_BANDS[band] + IMC_BANDS[band + 1] - 1) as f32) * scale;
399 let bark = freq2bark(freq);
400 if band > 0 {
401 let bark_diff = bark - last_bark;
402 self.weights1[band - 1] = 10.0f32.powf(-1.0 * bark_diff);
403 self.weights2[band - 1] = 10.0f32.powf(-2.7 * bark_diff);
404 }
405 last_bark = bark;
406 freq_mid[band] = freq;
407
408 let mut tmp_freq = freq;
409 while tmp_freq < nyq_freq {
410 tmp_freq += 0.5;
411 if freq2bark(tmp_freq) > bark + 0.5 { break; }
412 }
413 freq_max[band] = tmp_freq;
414
415 let mut tmp_freq = freq;
416 while tmp_freq > 0.0 {
417 tmp_freq -= 0.5;
418 if freq2bark(tmp_freq) < bark - 0.5 { break; }
419 }
420 freq_min[band] = tmp_freq;
421 }
422
423 for band in 0..BANDS {
424 let mut s_band = BANDS - 1;
425 while s_band > 0 && freq_max[band] <= freq_mid[s_band] { s_band -= 1; }
426 self.cycle1[band] = s_band + 1;
427 }
428
429 self.cycle2[0] = 0;
430 for band in 1..BANDS {
431 let mut s_band = 0;
432 while s_band < BANDS-1 && freq_min[band] >= freq_mid[s_band] { s_band += 1; }
433 self.cycle2[band] = s_band - 1;
434 }
435 }
436
437 fn read_level_coeffs_raw(&mut self, br: &mut BitReader, ch: usize) -> DecoderResult<()> {
438 let ch_data = &mut self.ch_data[ch];
439 let maxc_pos = br.read(5)? as usize;
440 let max_coef = br.read(7)? as u8;
441
442 let (c1, c2) = calc_maxcoef(f32::from(max_coef));
443 for i in 0..BANDS {
444 if i != maxc_pos {
445 let level = br.read(4)?;
446 ch_data.new_floor[i] = c1 * self.luts.exp_lev[level as usize];
447 ch_data.log_floor[i] = c2 - 1.4533435415 * (level as f32);
448 } else {
449 ch_data.new_floor[i] = c1;
450 ch_data.log_floor[i] = c2;
451 }
452 self.ba.band_width[i] = IMC_BANDS[i + 1] - IMC_BANDS[i];
453
454 ch_data.log_floor2[i] = ch_data.log_floor[i] * 2.0;
455 ch_data.mask_wght[i] = 1.0;
456 }
457
458 Ok(())
459 }
460
461 fn calculate_channel_values(&mut self, ch: usize) {
462 let ch_data = &mut self.ch_data[ch];
463 let mut tmp2: [f32; BANDS+1] = [0.0; BANDS+1];
464 let mut tmp3: [f32; BANDS] = [0.0; BANDS];
465
466 for band in 0..BANDS {
467 ch_data.mask_wght[band] = 0.0;
468 let val;
469 if self.ba.band_width[band] > 0 {
470 val = f64::from(ch_data.new_floor[band]).powi(2);
471 ch_data.log_floor2[band] = 2.0 * ch_data.log_floor[band];
472 } else {
473 val = 0.0;
474 ch_data.log_floor2[band] = -30000.0;
475 }
476 let tmp = val * (self.ba.band_width[band] as f64) * 0.01;
477 if val <= 1.0e-30 { tmp3[band] = 0.0; }
478 else { tmp3[band] = tmp as f32; }
479 }
480
481 for band in 0..BANDS {
482 let next_band = self.cycle1[band];
483 for band2 in band..next_band {
484 ch_data.mask_wght[band2] += tmp3[band];
485 }
486 tmp2[next_band] += tmp3[band];
487 }
488
489 let mut accum = 0.0;
490 for band in 1..BANDS {
491 accum = (tmp2[band] + accum) * self.weights1[band - 1];
492 ch_data.mask_wght[band] += accum;
493 }
494
495 let mut tmp2: [f32; BANDS] = [0.0; BANDS];
496 tmp2[0] = tmp3[0];
497 for band in 1..BANDS {
498 let prev_band = self.cycle2[band];
499 for band2 in prev_band+1..band {
500 ch_data.mask_wght[band2] += tmp3[band];
501 }
502 tmp2[prev_band + 1] += tmp3[band];
503 }
504
505 let mut accum = 0.0;
506 for i in 0..BANDS-1 {
507 let band = BANDS - 2 - i;
508 accum = (tmp2[band + 1] + accum) * self.weights2[band];
509 ch_data.mask_wght[band] += accum;
510 }
511 }
512
513 fn read_level_coeffs(&mut self, br: &mut BitReader, reset: bool, sel_idx: usize, ch: usize) -> DecoderResult<()> {
514 let mut level: [i8; BANDS] = [0; BANDS];
515 let start;
516 if reset {
517 start = 1;
518 level[0] = br.read(7)? as i8;
519 } else {
520 start = 0;
521 }
522 for i in start..BANDS {
523 level[i] = br.read_cb(&self.codes[sel_idx][IMC_CB_SELECTOR[sel_idx][i]])? as i8;
524 if level[i] == 17 {
525 level[i] += br.read(4)? as i8;
526 }
527 self.ba.keep_flag[i] = level[i] == 16;
528 }
529 if reset {
530 let ch_data = &mut self.ch_data[ch];
531 let (mut c1, mut c2) = calc_maxcoef(f32::from(level[0]));
532 ch_data.new_floor[0] = c1;
533 ch_data.log_floor[0] = c2;
534 for i in 1..BANDS {
535 if level[i] == 16 {
536 ch_data.new_floor[i] = 1.0;
537 ch_data.log_floor[i] = 0.0;
538 } else {
539 let lval;
540 if level[i] < 17 {
541 lval = level[i] - 7;
542 } else if level[i] < 25 {
543 lval = level[i] - 32;
544 } else {
545 lval = level[i] - 16;
546 }
547 c1 *= self.luts.exp_10[(lval + 16) as usize];
548 c2 += 0.83048 * f32::from(lval);
549 ch_data.new_floor[i] = c1;
550 ch_data.log_floor[i] = c2;
551 }
552 }
553 } else {
554 let ch_data = &mut self.ch_data[ch];
555 for i in 0..BANDS {
556 if level[i] < 16 {
557 let lval = level[i] - 7;
558 ch_data.new_floor[i] = self.luts.exp_10[(lval + 16) as usize] * ch_data.old_floor[i];
559 ch_data.log_floor[i] += f32::from(lval) * 0.83048;
560 } else {
561 ch_data.new_floor[i] = ch_data.old_floor[i];
562 }
563 }
564 }
565
566 self.ba.band_width[0] = IMC_BANDS[1] - IMC_BANDS[0];
567 for i in 1..BANDS {
568 if level[i] != 16 {
569 self.ba.band_width[i] = IMC_BANDS[i + 1] - IMC_BANDS[i];
570 } else {
571 self.ba.band_width[i] = 0;
572 }
573 }
574
575 for i in 0..BANDS-1 {
576 if self.ba.band_width[i] > 0 {
577 self.ba.band_present[i] = br.read_bool()?;
578 }
579 }
580 self.calculate_channel_values(ch);
581
582 Ok(())
583 }
584
585 fn read_skip_flags(&mut self, br: &mut BitReader) -> DecoderResult<()> {
586 let ba = &mut self.ba;
587 for band in 0..BANDS {
588 if !ba.band_present[band] || ba.band_width[band] == 0 { continue; }
589
590 if !ba.band_skip[band] {
591 ba.skip_flag_bits[band] = (IMC_BANDS[band + 1] - IMC_BANDS[band]) as u8;
592 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
593 ba.skip_flag[i] = br.read_bool()?;
594 if ba.skip_flag[i] {
595 ba.skips_per_band[band] += 1;
596 }
597 }
598 } else {
599 let mut i = IMC_BANDS[band];
600 while i < IMC_BANDS[band + 1] - 1 {
601 if !br.read_bool()? {
602 ba.skip_flag_bits[band] += 1;
603 ba.skip_flag[i] = true;
604 ba.skip_flag[i + 1] = true;
605 ba.skips_per_band[band] += 2;
606 } else {
607 if br.read_bool()? {
608 ba.skip_flag_bits[band] += 2;
609 ba.skip_flag[i] = false;
610 ba.skip_flag[i + 1] = true;
611 ba.skips_per_band[band] += 1;
612 } else {
613 ba.skip_flag_bits[band] += 3;
614 if !br.read_bool()? {
615 ba.skip_flag[i] = true;
616 ba.skips_per_band[band] += 1;
617 } else {
618 ba.skip_flag[i] = false;
619 }
620 ba.skip_flag[i + 1] = false;
621 }
622 }
623 i += 2;
624 }
625 if i != IMC_BANDS[band + 1] {
626 ba.skip_flag_bits[band] += 1;
627 ba.skip_flag[i] = br.read_bool()?;
628 if ba.skip_flag[i] {
629 ba.skips_per_band[band] += 1;
630 }
631 }
632 }
633 }
634 Ok(())
635 }
636
637 fn read_bitalloc_delta(&mut self, br: &mut BitReader, ch: usize) -> DecoderResult<()> {
638 for band in 0..BANDS {
639 self.ba.band_bitsum[band] = 0;
640 self.ba.band_skip[band] = false;
641 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
642 self.ba.band_bitsum[band] += self.ba.cw_len[i] as usize;
643 }
644 if self.ba.band_present[band] {
645 let band_w = IMC_BANDS[band + 1] - IMC_BANDS[band];
646 let bitsum = self.ba.band_bitsum[band] as usize;
647 if (bitsum > 0) && (((band_w * 3) >> 1) > bitsum) {
648 self.ba.band_skip[band] = true;
649 }
650 }
651 }
652
653 self.read_skip_flags(br)?;
654
655 let ch_data = &mut self.ch_data[ch];
656 for band in 0..BANDS {
657 ch_data.adj_floor[band] = ch_data.new_floor[band];
658 let band_w = IMC_BANDS[band + 1] - IMC_BANDS[band];
659 let nonskip = band_w - self.ba.skips_per_band[band];
660 if self.ba.band_present[band] && nonskip > 0 {
661 ch_data.adj_floor[band] *= self.luts.sqrt_tab[band_w] / self.luts.sqrt_tab[nonskip];
662 }
663 }
664
665 let mut bits_freed: i32 = 0;
666 for band in 0..BANDS {
667 if !self.ba.band_present[band] { continue; }
668 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
669 if self.ba.skip_flag[i] {
670 bits_freed += i32::from(self.ba.cw_len[i]);
671 self.ba.cw_len[i] = 0;
672 }
673 }
674 bits_freed -= i32::from(self.ba.skip_flag_bits[band]);
675 }
676
677 if bits_freed < 0 { return Err(DecoderError::Bug); }
678 self.ba.adjust_bit_allocation(ch_data, bits_freed);
679
680 Ok(())
681 }
682
683 fn read_coeffs(&mut self, br: &mut BitReader) -> DecoderResult<()> {
684 for band in 0..BANDS {
685 if self.ba.band_bitsum[band] == 0 { continue; }
686 if !self.ba.band_present[band] && (self.ba.band_width[band] == 0) { continue; }
687 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
688 let len = self.ba.cw_len[i];
689 if len > 0 && (!self.ba.band_present[band] || !self.ba.skip_flag[i]) {
690 self.ba.coeff[i] = br.read(len)? as u8;
691 } else {
692 self.ba.coeff[i] = 0;
693 }
694 }
695 }
696 Ok(())
697 }
698
699 fn inv_quant(&mut self, ch: usize, raw_coeffs: bool) {
700 let qidx: usize = if raw_coeffs { 1 } else { 0 };
701 let ch_data = &mut self.ch_data[ch];
702 for band in 0..BANDS {
703 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
704 ch_data.cw[i] = 0.0;
705 let cw_len = self.ba.cw_len[i];
706 if cw_len == 0 || self.ba.skip_flag[i] { continue; }
707
708 let val = self.ba.coeff[i] as usize;
709 let mid = 1 << (cw_len - 1);
710 let max = (1 << cw_len) - 1;
711 if cw_len >= 4 {
712 let quant = &IMC_QUANT_LARGE[qidx];
713 if val >= mid {
714 ch_data.cw[i] = quant[val - 8] * ch_data.adj_floor[band];
715 } else {
716 ch_data.cw[i] = -quant[max - val - 8] * ch_data.adj_floor[band];
717 }
718 } else {
719 let idx = qidx + (if self.ba.band_present[band] { 2 } else { 0 });
720 let quant = &IMC_QUANT_SMALL[idx];
721 if val >= mid {
722 ch_data.cw[i] = quant[val - 1] * ch_data.adj_floor[band];
723 } else {
724 ch_data.cw[i] = -quant[max - val - 1] * ch_data.adj_floor[band];
725 }
726 }
727 }
728 }
729 }
730
731 fn decode_block(&mut self, data: &[u8], ch: usize, dst: &mut [f32]) -> DecoderResult<()> {
732 let mut br = BitReader::new(&data[BLOCK_SIZE*ch..][..BLOCK_SIZE], BitReaderMode::LE16MSB);
733 let hdr = br.read(9)?;
734 validate!((hdr & 0x18) == 0);
735
736 let reset = br.read_bool()?;
737 let fixed_head = br.read_bool()?;
738 let raw_coeffs = br.read_bool()?;
739 let weight_idx = br.read(1)? as usize;
740
741 if reset {
742 self.ch_data[ch].reset();
743 }
744
745 self.ba.reset();
746
747 if raw_coeffs {
748 self.read_level_coeffs_raw(&mut br, ch)?;
749 } else {
750 let cb_idx = (if reset { 2 } else { 0 }) + (if fixed_head { 1 } else { 0 });
751 self.read_level_coeffs(&mut br, reset, cb_idx, ch)?;
752 }
753
754 self.ch_data[ch].old_floor.copy_from_slice(&self.ch_data[ch].new_floor);
755
756 let mut bitcount: usize = 0;
757 if fixed_head {
758 bitcount += 15;
759 self.ba.band_bits[0] = 5;
760 for i in 0..3 {
761 self.ba.cw_len[i] = 5;
762 }
763 for band in 1..4 {
764 let bits: u8;
765 if raw_coeffs || !self.ba.keep_flag[band]{
766 bits = 5;
767 } else {
768 bits = 0;
769 }
770 self.ba.band_bits[band] = bits;
771 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
772 self.ba.cw_len[i] = bits;
773 bitcount += bits as usize;
774 }
775 }
776 }
777
778 if !self.is_imc {
779 if self.ba.band_width[BANDS - 1] != 0 {
780 bitcount += 1;
781 }
782 bitcount += 16;
783 } else {
784 if self.ba.band_width[BANDS - 1] != 0 {
785 bitcount += 1;
786 }
787 }
788
789 validate!(br.tell() + bitcount < BLOCK_SIZE * 8);
790 self.ba.calculate_bit_allocation(&mut self.ch_data[ch], 512 - bitcount - br.tell(), fixed_head, weight_idx)?;
791
792 if !raw_coeffs {
793 self.read_bitalloc_delta(&mut br, ch)?;
794 }
795
796 for band in 0..BANDS {
797 self.ba.band_bitsum[band] = 0;
798 for i in IMC_BANDS[band]..IMC_BANDS[band + 1] {
799 if !self.ba.skip_flag[i] {
800 self.ba.band_bitsum[band] += self.ba.cw_len[i] as usize;
801 }
802 }
803 }
804
805 self.read_coeffs(&mut br)?;
806 self.inv_quant(ch, raw_coeffs);
807 self.imdct.imdct(&self.ch_data[ch].cw, dst, &mut self.ch_data[ch].last_im);
808
809 Ok(())
810 }
811}
812
813impl IMDCTContext {
814 fn new() -> Self {
815 let mut window: [f32; COEFFS] = [0.0; COEFFS];
816 generate_window(WindowType::Sine, 1.0, COEFFS, true, &mut window);
817 let mut pretwiddle1: [f32; COEFFS/2] = [0.0; COEFFS/2];
818 let mut pretwiddle2: [f32; COEFFS/2] = [0.0; COEFFS/2];
819 let mut posttwiddle: [FFTComplex; COEFFS/2] = [FFTC_ZERO; COEFFS/2];
820 for i in 0..COEFFS/2 {
821 let n = i as f32;
822 let base = (n * 4.0 + 1.0) / 1024.0 * consts::PI;
823 let r1 = base.sin();
824 let r2 = base.cos();
825 if (i & 1) == 0 {
826 pretwiddle1[i] = -(r1 + r2) * consts::SQRT_2;
827 pretwiddle2[i] = (r1 - r2) * consts::SQRT_2;
828 } else {
829 pretwiddle1[i] = (r1 + r2) * consts::SQRT_2;
830 pretwiddle2[i] = -(r1 - r2) * consts::SQRT_2;
831 }
832 posttwiddle[i] = FFTComplex::exp(consts::PI / 256.0 * n).scale(1.0/32768.0);
833 }
834 IMDCTContext {
835 pretwiddle1,
836 pretwiddle2,
837 posttwiddle,
838 tmp: [FFTC_ZERO; COEFFS/2],
839 fft: FFTBuilder::new_fft(COEFFS/2, false),
840 window,
841 }
842 }
843 fn imdct(&mut self, coeffs: &[f32; COEFFS], dst: &mut [f32], last_im: &mut [f32; COEFFS/2]) {
844 for i in 0..COEFFS/2 {
845 let in2 = coeffs[i * 2];
846 let in1 = coeffs[COEFFS - 1 - i * 2];
847 let c2 = self.pretwiddle1[i];
848 let c1 = self.pretwiddle2[i];
849 self.tmp[i].re = -(c2 * in1 + c1 * in2);
850 self.tmp[i].im = c1 * in1 - c2 * in2;
851 }
852 self.fft.do_ifft_inplace(&mut self.tmp);
853 for i in 0..COEFFS/2 {
854 let tmp = !(self.tmp[i] * self.posttwiddle[i]);
855 let c1 = self.window[i * 2];
856 let c2 = self.window[COEFFS - 1 - i * 2];
857 let im = last_im[i];
858 dst[i * 2] = c2 * im + c1 * tmp.re;
859 dst[COEFFS - 1 - i * 2] = c1 * im - c2 * tmp.re;
860 last_im[i] = tmp.im;
861 }
862 }
863}
864
865const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C];
866const CHMAP_STEREO: [NAChannelType; 2] = [NAChannelType::L, NAChannelType::R];
867
868impl NADecoder for IMCDecoder {
869 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
870 if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
871 self.chmap = NAChannelMap::new();
872 match ainfo.get_channels() {
873 1 => { self.chmap.add_channels(&CHMAP_MONO); },
874 2 => { self.chmap.add_channels(&CHMAP_STEREO); },
875 _ => { return Err(DecoderError::InvalidData); },
876 };
877 self.ainfo = NAAudioInfo::new(ainfo.get_sample_rate(),
878 ainfo.get_channels(),
879 SND_F32P_FORMAT, 0);
880 self.info = info.replace_info(NACodecTypeInfo::Audio(self.ainfo));
881
882 if !self.is_imc {
883 self.generate_iac_tables(ainfo.get_sample_rate() as f32);
884 }
885 Ok(())
886 } else {
887 Err(DecoderError::InvalidData)
888 }
889 }
890 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
891 let info = pkt.get_stream().get_info();
892 validate!(info.get_properties().is_audio());
893 let pktbuf = pkt.get_buffer();
894
895 let nblocks = pktbuf.len() / BLOCK_SIZE / (self.ainfo.get_channels() as usize);
896 let duration = COEFFS * nblocks;
897
898 let abuf = alloc_audio_buffer(self.ainfo, duration, self.chmap.clone())?;
899 let mut adata = abuf.get_abuf_f32().unwrap();
900 let dst = adata.get_data_mut().unwrap();
901
902 let mut start: usize = 0;
903 let channels = self.ainfo.get_channels() as usize;
904 for chunk in pktbuf.chunks(BLOCK_SIZE * channels) {
905 for ch in 0..channels {
906 let off = abuf.get_offset(ch as usize) + start;
907 self.decode_block(chunk, ch as usize, &mut dst[off..off+COEFFS])?;
908 }
909 if (channels == 2) && ((chunk[1] & 0x20) != 0) {
910 let off1 = abuf.get_offset(0) + start;
911 let off2 = abuf.get_offset(1) + start;
912 for i in 0..COEFFS {
913 let l = dst[off1 + i];
914 let r = dst[off2 + i];
915 dst[off1 + i] = l + r;
916 dst[off2 + i] = l - r;
917 }
918 }
919 start += COEFFS;
920 }
921
922 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), abuf);
923 frm.set_keyframe(true);
924 Ok(frm.into_ref())
925 }
926 fn flush(&mut self) {
927 }
928}
929
930impl NAOptionHandler for IMCDecoder {
931 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
932 fn set_options(&mut self, _options: &[NAOption]) { }
933 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
934}
935
936pub fn get_decoder_imc() -> Box<dyn NADecoder + Send> {
937 Box::new(IMCDecoder::new(true))
938}
939
940pub fn get_decoder_iac() -> Box<dyn NADecoder + Send> {
941 Box::new(IMCDecoder::new(false))
942}
943
944struct IMCCodeReader { sel1: usize, sel2: usize }
945
946impl IMCCodeReader {
947 fn new(sel1: usize, sel2: usize) -> Self { IMCCodeReader { sel1, sel2 } }
948}
949
950impl CodebookDescReader<u8> for IMCCodeReader {
951 fn bits(&mut self, idx: usize) -> u8 { IMC_CODE_LENGTHS[self.sel1][self.sel2][idx] }
952 fn code(&mut self, idx: usize) -> u32 { u32::from(IMC_CODE_CODES[self.sel1][self.sel2][idx]) }
953 fn sym (&mut self, idx: usize) -> u8 { idx as u8 }
954 fn len(&mut self) -> usize { IMC_CODE_LENGTHS[0][0].len() }
955}
956
957static IMC_BANDS: [usize; 33] = [
958 0, 3, 6, 9, 12, 16, 20, 24, 29, 34, 40, 46, 53, 60, 68, 76,
959 84, 93, 102, 111, 121, 131, 141, 151, 162, 173, 184, 195, 207, 219, 231, 243,
960 256,
961];
962
963const IMC_QUANT_SMALL: &[[f32; 8]; 4] = &[
964 [ 8.4431201e-1, 4.7358301e-1, 1.448354, 2.7073899e-1,
965 7.4449003e-1, 1.241991, 1.845484, 0.0 ],
966 [ 8.6876702e-1, 4.7659001e-1, 1.478224, 2.5672799e-1,
967 7.55777e-1, 1.3229851, 2.03438, 0.0 ],
968 [ 7.5891501e-1, 6.2272799e-1, 1.271322, 3.47904e-1,
969 7.5317699e-1, 1.150767, 1.628476, 0.0 ],
970 [ 7.65257e-1, 6.44647e-1, 1.263824, 3.4548101e-1,
971 7.6384902e-1, 1.214466, 1.7638789, 0.0 ]
972];
973
974const IMC_QUANT_LARGE: &[[f32; 56]; 2] = &[
975 [ 1.39236e-1, 3.50548e-1, 5.9547901e-1, 8.5772401e-1,
976 1.121545, 1.3882281, 1.695882, 2.1270809,
977 7.2221003e-2, 1.85177e-1, 2.9521701e-1, 4.12568e-1,
978 5.4068601e-1, 6.7679501e-1, 8.1196898e-1, 9.4765198e-1,
979 1.0779999, 1.203415, 1.337265, 1.481871,
980 1.639982, 1.814766, 2.0701399, 2.449862,
981 3.7533998e-2, 1.02722e-1, 1.6021401e-1, 2.16043e-1,
982 2.7231601e-1, 3.3025399e-1, 3.9022601e-1, 4.52849e-1,
983 5.1794899e-1, 5.8529502e-1, 6.53956e-1, 7.2312802e-1,
984 7.9150802e-1, 8.5891002e-1, 9.28141e-1, 9.9706203e-1,
985 1.062153, 1.12564, 1.189834, 1.256122,
986 1.324469, 1.3955311, 1.468906, 1.545084,
987 1.6264729, 1.711524, 1.802705, 1.91023,
988 2.0533991, 2.22333, 2.4830019, 3.253329 ],
989 [ 1.11654e-1, 3.54469e-1, 6.4232099e-1, 9.6128798e-1,
990 1.295053, 1.61777, 1.989839, 2.51107,
991 5.7721999e-2, 1.69879e-1, 2.97589e-1, 4.3858799e-1,
992 5.9039903e-1, 7.4934798e-1, 9.1628098e-1, 1.087297,
993 1.262751, 1.4288321, 1.6040879, 1.79067,
994 2.000668, 2.2394669, 2.649332, 5.2760072,
995 2.9722e-2, 8.7316997e-2, 1.4445201e-1, 2.04247e-1,
996 2.6879501e-1, 3.3716801e-1, 4.08811e-1, 4.8306999e-1,
997 5.6049401e-1, 6.3955498e-1, 7.2044599e-1, 8.0427998e-1,
998 8.8933599e-1, 9.7537601e-1, 1.062461, 1.1510431,
999 1.240236, 1.326715, 1.412513, 1.500502,
1000 1.591749, 1.686413, 1.785239, 1.891233,
1001 2.0051291, 2.127681, 2.2709141, 2.475826,
1002 2.7219379, 3.101985, 4.686213, 6.2287788 ]
1003];
1004
1005static IMC_CYCLE1: [usize; BANDS] = [
1006 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1007 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32,
1008];
1009
1010static IMC_CYCLE2: [usize; BANDS] = [
1011 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
1012 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
1013];
1014
1015static IMC_WEIGHTS1: [f32; BANDS-1] = [
1016 0.119595, 0.123124, 0.129192, 9.97377e-2,
1017 8.1923e-2, 9.61153e-2, 8.77885e-2, 8.61174e-2,
1018 9.00882e-2, 9.91658e-2, 0.112991, 0.131126,
1019 0.152886, 0.177292, 0.221782, 0.244917,
1020 0.267386, 0.306816, 0.323046, 0.33729,
1021 0.366773, 0.392557, 0.398076, 0.403302,
1022 0.42451, 0.444777, 0.449188, 0.455445,
1023 0.477853, 0.500669, 0.510395
1024];
1025
1026static IMC_WEIGHTS2: [f32; BANDS-1] = [
1027 3.23466e-3, 3.49886e-3, 3.98413e-3, 1.98116e-3,
1028 1.16465e-3, 1.79283e-3, 1.40372e-3, 1.33274e-3,
1029 1.50523e-3, 1.95064e-3, 2.77472e-3, 4.14725e-3,
1030 6.2776e-3, 9.36401e-3, 1.71397e-2, 2.24052e-2,
1031 2.83971e-2, 4.11689e-2, 4.73165e-2, 5.31631e-2,
1032 6.66614e-2, 8.00824e-2, 8.31588e-2, 8.61397e-2,
1033 9.89229e-2, 0.112197, 0.115227, 0.119613,
1034 0.136174, 0.15445, 0.162685
1035];
1036
1037static IMC_BITALLOC_ADJ: [[f32; 7]; 2] = [
1038 [ 7.6, 4.4, 6.1, 2.3, 6.2, 1.8, 0.0 ],
1039 [ 3.6, 3.7, 5.1, 1.6, 1.5, 1.2, 0.0 ]
1040];
1041
1042static IMC_CODE_LENGTHS: &[[[u8; 18]; 4]; 4] = &[
1043 [
1044 [ 16, 15, 13, 11, 8, 5, 3, 1, 2, 4, 6, 9, 10, 12, 14, 16, 7, 0 ],
1045 [ 10, 8, 7, 6, 4, 4, 3, 2, 2, 3, 4, 6, 7, 9, 11, 11, 7, 0 ],
1046 [ 15, 15, 14, 11, 8, 6, 4, 2, 1, 4, 5, 7, 9, 10, 12, 13, 4, 0 ],
1047 [ 13, 11, 10, 8, 6, 4, 2, 2, 2, 3, 5, 7, 9, 12, 15, 15, 14, 0 ],
1048 ], [
1049 [ 14, 12, 10, 8, 7, 4, 2, 2, 2, 3, 5, 7, 9, 11, 13, 14, 7, 0 ],
1050 [ 14, 13, 11, 8, 6, 4, 3, 2, 2, 3, 5, 7, 9, 10, 12, 14, 3, 0 ],
1051 [ 13, 12, 10, 7, 5, 4, 3, 2, 2, 3, 4, 6, 8, 9, 11, 13, 4, 0 ],
1052 [ 13, 12, 10, 7, 5, 4, 3, 2, 2, 3, 4, 6, 8, 9, 11, 13, 4, 0 ],
1053 ], [
1054 [ 16, 14, 12, 10, 8, 5, 3, 1, 2, 4, 7, 9, 11, 13, 15, 17, 6, 17 ],
1055 [ 15, 13, 11, 8, 6, 4, 2, 2, 2, 3, 5, 7, 10, 12, 14, 16, 9, 16 ],
1056 [ 14, 12, 11, 9, 8, 6, 3, 1, 2, 5, 7, 10, 13, 15, 16, 17, 4, 17 ],
1057 [ 16, 14, 12, 9, 7, 5, 2, 2, 2, 3, 4, 6, 8, 11, 13, 15, 10, 16 ],
1058 ], [
1059 [ 13, 11, 10, 8, 7, 5, 2, 2, 2, 4, 6, 9, 12, 14, 15, 16, 3, 16 ],
1060 [ 11, 11, 10, 9, 8, 7, 5, 4, 3, 3, 3, 3, 3, 3, 4, 5, 6, 5 ],
1061 [ 9, 9, 7, 6, 5, 4, 3, 3, 2, 3, 4, 5, 4, 5, 5, 6, 8, 6 ],
1062 [ 13, 12, 10, 8, 5, 3, 3, 2, 2, 3, 4, 7, 9, 11, 14, 15, 6, 15 ]
1063 ]
1064];
1065
1066static IMC_CODE_CODES: &[[[u16; 18]; 4]; 4] = &[
1067 [
1068 [ 0xCC32, 0x6618, 0x1987, 0x0660, 0x00CD, 0x0018, 0x0007, 0x0000, 0x0002,
1069 0x000D, 0x0032, 0x0199, 0x0331, 0x0CC2, 0x330D, 0xCC33, 0x0067, 0x0000 ],
1070 [ 0x02FE, 0x00BE, 0x005E, 0x002D, 0x000A, 0x0009, 0x0003, 0x0003, 0x0000,
1071 0x0002, 0x0008, 0x002C, 0x005D, 0x017E, 0x05FE, 0x05FF, 0x005C, 0x0000 ],
1072 [ 0x5169, 0x5168, 0x28B5, 0x0517, 0x00A3, 0x0029, 0x0008, 0x0003, 0x0000,
1073 0x0009, 0x0015, 0x0050, 0x0144, 0x028A, 0x0A2C, 0x145B, 0x000B, 0x0000 ],
1074 [ 0x1231, 0x048D, 0x0247, 0x0090, 0x0025, 0x0008, 0x0001, 0x0003, 0x0000,
1075 0x0005, 0x0013, 0x0049, 0x0122, 0x0919, 0x48C3, 0x48C2, 0x2460, 0x0000 ]
1076 ], [
1077 [ 0x2D1D, 0x0B46, 0x02D0, 0x00B5, 0x0059, 0x000A, 0x0003, 0x0001, 0x0000,
1078 0x0004, 0x0017, 0x005B, 0x0169, 0x05A2, 0x168F, 0x2D1C, 0x0058, 0x0000 ],
1079 [ 0x1800, 0x0C01, 0x0301, 0x0061, 0x0019, 0x0007, 0x0004, 0x0003, 0x0000,
1080 0x0005, 0x000D, 0x0031, 0x00C1, 0x0181, 0x0601, 0x1801, 0x0002, 0x0000 ],
1081 [ 0x1556, 0x0AAA, 0x02AB, 0x0054, 0x0014, 0x000B, 0x0002, 0x0003, 0x0000,
1082 0x0003, 0x0008, 0x002B, 0x00AB, 0x0154, 0x0554, 0x1557, 0x0009, 0x0000 ],
1083 [ 0x1556, 0x0AAA, 0x02AB, 0x0054, 0x0014, 0x000B, 0x0002, 0x0003, 0x0000,
1084 0x0003, 0x0008, 0x002B, 0x00AB, 0x0154, 0x0554, 0x1557, 0x0009, 0x0000 ]
1085 ], [
1086 [ 0x2993, 0x0A65, 0x0298, 0x00A7, 0x0028, 0x0004, 0x0000, 0x0001, 0x0001,
1087 0x0003, 0x0015, 0x0052, 0x014D, 0x0533, 0x14C8, 0x5324, 0x000B, 0x5325 ],
1088 [ 0x09B8, 0x026F, 0x009A, 0x0012, 0x0005, 0x0000, 0x0001, 0x0002, 0x0003,
1089 0x0001, 0x0003, 0x0008, 0x004C, 0x0136, 0x04DD, 0x1373, 0x0027, 0x1372 ],
1090 [ 0x0787, 0x01E0, 0x00F1, 0x003D, 0x001F, 0x0006, 0x0001, 0x0001, 0x0001,
1091 0x0002, 0x000E, 0x0079, 0x03C2, 0x0F0D, 0x1E19, 0x3C30, 0x0000, 0x3C31 ],
1092 [ 0x4B06, 0x12C0, 0x04B1, 0x0097, 0x0024, 0x0008, 0x0002, 0x0003, 0x0000,
1093 0x0003, 0x0005, 0x0013, 0x004A, 0x0259, 0x0961, 0x2582, 0x012D, 0x4B07 ]
1094 ], [
1095 [ 0x0A5A, 0x0297, 0x014A, 0x0053, 0x0028, 0x000B, 0x0003, 0x0000, 0x0002,
1096 0x0004, 0x0015, 0x00A4, 0x052C, 0x14B7, 0x296C, 0x52DB, 0x0003, 0x52DA ],
1097 [ 0x0193, 0x0192, 0x00C8, 0x0065, 0x0033, 0x0018, 0x0007, 0x0004, 0x0000,
1098 0x0004, 0x0005, 0x0007, 0x0006, 0x0003, 0x0005, 0x0005, 0x000D, 0x0004 ],
1099 [ 0x0012, 0x0013, 0x0005, 0x0003, 0x0000, 0x0003, 0x0005, 0x0004, 0x0003,
1100 0x0003, 0x0005, 0x0005, 0x0004, 0x0004, 0x0003, 0x0005, 0x0008, 0x0004 ],
1101 [ 0x0D66, 0x06B2, 0x01AD, 0x006A, 0x000C, 0x0005, 0x0004, 0x0000, 0x0003,
1102 0x0002, 0x0007, 0x0034, 0x00D7, 0x0358, 0x1ACF, 0x359C, 0x001B, 0x359D ]
1103 ]
1104];
1105
1106const IMC_CB_SELECTOR: [[usize; BANDS]; 4] = [
1107 [ 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,
1108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 ],
1109 [ 0, 2, 0, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1110 0, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
1111 [ 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1112 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2 ],
1113 [ 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1114 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
1115];
1116
1117#[cfg(test)]
1118mod test {
1119 use nihav_core::codecs::RegisteredDecoders;
1120 use nihav_core::demuxers::RegisteredDemuxers;
1121 use nihav_codec_support::test::dec_video::*;
1122 use crate::indeo_register_all_decoders;
1123 use nihav_commonfmt::generic_register_all_demuxers;
1124 #[test]
1125 fn test_imc() {
1126 let mut dmx_reg = RegisteredDemuxers::new();
1127 generic_register_all_demuxers(&mut dmx_reg);
1128 let mut dec_reg = RegisteredDecoders::new();
1129 indeo_register_all_decoders(&mut dec_reg);
1130
1131// let file = "assets/Indeo/neal73_saber.avi";
1132// let file = "assets/Indeo/IMC/hvalen.avi";
1133 // sample from a private collection
1134 let file = "assets/Indeo/IMC/8khz.avi";
1135// let file = "assets/Indeo/STsKlassFist-1a.avi";
1136// let file = "assets/Indeo/IMC/Angel Bday.avi";
1137 test_decode_audio("avi", file, None, None/*Some("imc")*/, &dmx_reg, &dec_reg);
1138 //test_file_decoding("avi", file, None, false, true, None);
1139 }
1140}