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