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