X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcodecs%2Findeo%2Fimc.rs;h=5ba1575bdc03703666ba3fe653c5b4ed241445db;hb=9037cf6b83ce135243522ec154cd7ffb35f8c816;hp=18d24d56f493d0116afacbfcfab5e7df80c9ca67;hpb=e35062e7289092738f625242eca7693b2946af14;p=nihav.git diff --git a/src/codecs/indeo/imc.rs b/src/codecs/indeo/imc.rs index 18d24d5..5ba1575 100644 --- a/src/codecs/indeo/imc.rs +++ b/src/codecs/indeo/imc.rs @@ -14,10 +14,6 @@ const BANDS: usize = 32; const COEFFS: usize = 256; const BLOCK_SIZE: usize = 64; -fn freq2bark(freq: f32) -> f32 { - 3.5 * ((freq / 7500.0) * (freq / 7500.0)).atan() + 13.0 * (freq * 0.00076).atan() -} - struct IMDCTContext { pretwiddle1: [f32; COEFFS/2], pretwiddle2: [f32; COEFFS/2], @@ -29,40 +25,40 @@ struct IMDCTContext { struct IMCChannel { old_floor: [f32; BANDS], - coeffs1: [f32; BANDS], // new floor? - coeffs2: [f32; BANDS], // log2 of coeffs1 - coeffs3: [f32; BANDS], - coeffs4: [f32; BANDS], - coeffs5: [f32; BANDS], - coeffs6: [f32; BANDS], + new_floor: [f32; BANDS], + log_floor: [f32; BANDS], + log_floor2: [f32; BANDS], + bit_est: [f32; BANDS], + mask_wght: [f32; BANDS], + adj_floor: [f32; BANDS], cw: [f32; COEFFS], last_im: [f32; COEFFS/2], } struct BitAlloc { - band_width: [usize; BANDS], - band_flag: [bool; BANDS], - band_skip: [bool; BANDS], - band_bits: [u8; BANDS], - cw_len: [u8; COEFFS], - band_bitsum: [usize; BANDS], - skip_flag: [bool; COEFFS], + band_width: [usize; BANDS], + band_present: [bool; BANDS], + band_skip: [bool; BANDS], + band_bits: [u8; BANDS], + cw_len: [u8; COEFFS], + band_bitsum: [usize; BANDS], + skip_flag: [bool; COEFFS], skip_flag_bits: [u8; BANDS], skips_per_band: [usize; BANDS], - keep_flag: [bool; BANDS], - coeff: [u8; COEFFS], + keep_flag: [bool; BANDS], + coeff: [u8; COEFFS], } impl IMCChannel { fn new() -> Self { IMCChannel { old_floor: [0.0; BANDS], - coeffs1: [0.0; BANDS], - coeffs2: [0.0; BANDS], - coeffs3: [0.0; BANDS], - coeffs4: [0.0; BANDS], - coeffs5: [0.0; BANDS], - coeffs6: [0.0; BANDS], + new_floor: [0.0; BANDS], + log_floor: [0.0; BANDS], + log_floor2: [0.0; BANDS], + bit_est: [0.0; BANDS], + mask_wght: [0.0; BANDS], + adj_floor: [0.0; BANDS], cw: [0.0; COEFFS], last_im: [0.0; COEFFS/2], } @@ -78,45 +74,45 @@ const BITALLOC_TOP_LIMIT: f32 = 1.0e20; impl BitAlloc { fn new() -> Self { BitAlloc { - band_width: [0; BANDS], - band_flag: [false; BANDS], - band_skip: [false; BANDS], - band_bits: [0; BANDS], - cw_len: [0; COEFFS], - band_bitsum: [0; BANDS], - skip_flag: [false; COEFFS], + band_width: [0; BANDS], + band_present: [false; BANDS], + band_skip: [false; BANDS], + band_bits: [0; BANDS], + cw_len: [0; COEFFS], + band_bitsum: [0; BANDS], + skip_flag: [false; COEFFS], skip_flag_bits: [0; BANDS], skips_per_band: [0; BANDS], - keep_flag: [false; BANDS], - coeff: [0; COEFFS], + keep_flag: [false; BANDS], + coeff: [0; COEFFS], } } fn reset(&mut self) { for i in 0..BANDS { - self.band_width[i] = 0; - self.band_flag[i] = false; - self.band_skip[i] = false; - self.band_bits[i] = 0; - self.keep_flag[i] = false; - //self.band_bitsum[i] = 0; - self.skips_per_band[i] = 0; - self.skip_flag_bits[i] = 0; + self.band_width[i] = 0; + self.band_present[i] = false; + self.band_skip[i] = false; + self.band_bits[i] = 0; + self.keep_flag[i] = false; + self.band_bitsum[i] = 0; + self.skips_per_band[i] = 0; + self.skip_flag_bits[i] = 0; } for i in 0..COEFFS { - //self.cw_len[i] = 0; - self.skip_flag[i] = false; + self.cw_len[i] = 0; + self.skip_flag[i] = false; } } fn calculate_bit_allocation(&mut self, ch_data: &mut IMCChannel, bits: usize, fixed_head: bool, adj_idx: usize) -> DecoderResult<()> { let mut peak = 0.0; - for coef in ch_data.coeffs1.iter() { if *coef > peak { peak = *coef; } } + for coef in ch_data.new_floor.iter() { if *coef > peak { peak = *coef; } } peak *= 0.25; for band in 0..BANDS-1 { - ch_data.coeffs4[band] = ch_data.coeffs3[band] - ch_data.coeffs5[band].log2(); + ch_data.bit_est[band] = ch_data.log_floor2[band] - ch_data.mask_wght[band].log2(); } - ch_data.coeffs4[BANDS - 1] = BITALLOC_LIMIT; + ch_data.bit_est[BANDS - 1] = BITALLOC_LIMIT; for band in 0..BANDS { let mut idx = 42; @@ -126,13 +122,13 @@ impl BitAlloc { if band_w/2 >= self.band_width[band] { idx = 2; } validate!(idx <= 2); idx *= 2; - if ch_data.coeffs1[band] < peak { idx += 1; } - ch_data.coeffs4[band] += IMC_BITALLOC_ADJ[adj_idx][idx]; + if ch_data.new_floor[band] < peak { idx += 1; } + ch_data.bit_est[band] += IMC_BITALLOC_ADJ[adj_idx][idx]; } if fixed_head { for i in 0..4 { - ch_data.coeffs4[i] = BITALLOC_LIMIT; + ch_data.bit_est[i] = BITALLOC_LIMIT; } } @@ -142,7 +138,7 @@ impl BitAlloc { let mut pool = 0.0; for band in start..BANDS-1 { a_width += self.band_width[band]; - pool += (self.band_width[band] as f32) * ch_data.coeffs4[band]; + pool += (self.band_width[band] as f32) * ch_data.bit_est[band]; } validate!(a_width > 0); @@ -160,7 +156,7 @@ impl BitAlloc { cur_bits = 0; let mut acc = 0; for band in start..BANDS { - let mut len = (ch_data.coeffs4[band] * 0.5 - pool + 0.5).trunc() as i32; + let mut len = (ch_data.bit_est[band] * 0.5 - pool + 0.5) as i32; if len < 0 { len = 0; } if len > 6 { len = 6; } self.band_bits[band] = len as u8; @@ -190,7 +186,7 @@ impl BitAlloc { let mut tmp: [f32; BANDS] = [BITALLOC_LIMIT; BANDS]; for band in 0..BANDS { if self.band_bits[band] != 6 { - tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.coeffs4[band] - 0.415; + tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.bit_est[band] - 0.415; } } let mut peak = 0.0; @@ -224,7 +220,7 @@ impl BitAlloc { let mut tmp: [f32; BANDS] = [BITALLOC_TOP_LIMIT; BANDS]; for band in start..BANDS { if self.band_bits[band] != 0 { - tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.coeffs4[band] - 0.415 + 2.0; + tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.bit_est[band] - 0.415 + 2.0; } } while free_bits < cur_bits { @@ -258,10 +254,9 @@ impl BitAlloc { fn adjust_bit_allocation(&mut self, ch_data: &mut IMCChannel, free_bits: i32) { let mut tmp: [f32; BANDS] = [BITALLOC_LIMIT; BANDS]; -if free_bits >= 0 { for band in 0..BANDS { if self.band_bits[band] != 6 { - tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.coeffs4[band] - 0.415; + tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.bit_est[band] - 0.415; } } let mut used_bits: i32 = 0; @@ -282,6 +277,7 @@ if free_bits >= 0 { tmp[band] = BITALLOC_LIMIT; } for i in IMC_BANDS[band]..IMC_BANDS[band + 1] { + if self.cw_len[i] >= 6 { continue; } self.cw_len[i] += 1; used_bits += 1; if used_bits >= free_bits { @@ -290,41 +286,33 @@ if free_bits >= 0 { } } } -} else { - let mut used_bits: i32 = 0; + } +} - let mut tmp: [f32; BANDS] = [BITALLOC_TOP_LIMIT; BANDS]; - for band in 0..BANDS { - if self.band_bits[band] != 0 { - tmp[band] = (self.band_bits[band] as f32) * -2.0 + ch_data.coeffs4[band] - 0.415 + 2.0; - } - } - while free_bits < used_bits { - let mut low = BITALLOC_TOP_LIMIT; - let mut idx = 0; - for band in 0..BANDS { - if tmp[band] < low { - low = tmp[band]; - idx = band; - } - } - tmp[idx] += 2.0; - self.band_bits[idx] -= 1; - if self.band_bits[idx] == 0 { - tmp[idx] = BITALLOC_TOP_LIMIT; - } - for i in IMC_BANDS[idx]..IMC_BANDS[idx + 1] { - if self.cw_len[i] > 0 { - self.cw_len[i] -= 1; - used_bits -= 1; - if used_bits <= free_bits { - break; - } - } - } - } +struct LUTs { + exp_lev: [f32; 16], + exp_10: [f32; 32], + sqrt_tab: [f32; 32], } +impl LUTs { + fn new() -> Self { + let mut exp_lev: [f32; 16] = [0.0; 16]; + for lev in 0..16 { + exp_lev[lev] = 10.0f32.powf(-(lev as f32) * 0.4375); + } + + let mut exp_10: [f32; 32] = [0.0; 32]; + for i in 0..32 { + exp_10[i] = 10.0f32.powf(((i as f32) - 16.0) * 0.25); + } + + let mut sqrt_tab: [f32; 32] = [0.0; 32]; + for i in 0..32 { + sqrt_tab[i] = (i as f32).sqrt(); + } + + LUTs { exp_lev: exp_lev, exp_10: exp_10, sqrt_tab: sqrt_tab } } } @@ -344,10 +332,16 @@ struct IMCDecoder { cycle2: [usize; BANDS], weights1: [f32; BANDS-1], weights2: [f32; BANDS-1], + + luts: LUTs, +} + +fn freq2bark(freq: f32) -> f32 { + 3.5 * ((freq / 7500.0) * (freq / 7500.0)).atan() + 13.0 * (freq * 0.00076).atan() } fn calc_maxcoef(coef: f32) -> (f32, f32) { - let c1 = 20000.0 / 2.0f32.powf(coef * 0.18945); + let c1 = 20000.0 / 10.0f32.powf(coef * 0.057031251); (c1, c1.log2()) } @@ -383,6 +377,7 @@ impl IMCDecoder { ch_data: [IMCChannel::new(), IMCChannel::new()], ba: BitAlloc::new(), imdct: IMDCTContext::new(), + luts: LUTs::new(), cycle1: cycle1, cycle2: cycle2, @@ -392,7 +387,7 @@ impl IMCDecoder { } fn generate_iac_tables(&mut self, sample_rate: f32) { - let scale = sample_rate / 1024.0; + let scale = sample_rate / 256.0 / 2.0 * 0.5; let nyq_freq = sample_rate / 2.0; let mut last_bark = 0.0; let mut freq_max: [f32; BANDS] = [0.0; BANDS]; @@ -404,7 +399,7 @@ impl IMCDecoder { if band > 0 { let bark_diff = bark - last_bark; self.weights1[band - 1] = 10.0f32.powf(-1.0 * bark_diff); - self.weights1[band - 1] = 10.0f32.powf(-2.7 * bark_diff); + self.weights2[band - 1] = 10.0f32.powf(-2.7 * bark_diff); } last_bark = bark; freq_mid[band] = freq; @@ -439,61 +434,61 @@ impl IMCDecoder { } fn read_level_coeffs_raw(&mut self, br: &mut BitReader, ch: usize) -> DecoderResult<()> { - let mut ch_data = &mut self.ch_data[ch]; + let ch_data = &mut self.ch_data[ch]; let maxc_pos = br.read(5)? as usize; let max_coef = br.read(7)? as u8; let (c1, c2) = calc_maxcoef(max_coef as f32); for i in 0..BANDS { if i != maxc_pos { - let level = br.read(4)? as f32; - ch_data.coeffs1[i] = c1 * 10.0f32.powf(-level * 0.4375); // almost exp(-lev) - ch_data.coeffs2[i] = c2 - 1.4533435415 * level; + let level = br.read(4)?; + ch_data.new_floor[i] = c1 * self.luts.exp_lev[level as usize]; + ch_data.log_floor[i] = c2 - 1.4533435415 * (level as f32); } else { - ch_data.coeffs1[i] = c1; - ch_data.coeffs2[i] = c2; + ch_data.new_floor[i] = c1; + ch_data.log_floor[i] = c2; } self.ba.band_width[i] = IMC_BANDS[i + 1] - IMC_BANDS[i]; - //self.ba.band_flag[i] = false; - ch_data.coeffs3[i] = ch_data.coeffs2[i] * 2.0; - ch_data.coeffs5[i] = 1.0; + ch_data.log_floor2[i] = ch_data.log_floor[i] * 2.0; + ch_data.mask_wght[i] = 1.0; } Ok(()) } fn calculate_channel_values(&mut self, ch: usize) { - let mut ch_data = &mut self.ch_data[ch]; - let mut tmp2: [f32; BANDS] = [0.0; BANDS]; + let ch_data = &mut self.ch_data[ch]; + let mut tmp2: [f32; BANDS+1] = [0.0; BANDS+1]; let mut tmp3: [f32; BANDS] = [0.0; BANDS]; for band in 0..BANDS { - ch_data.coeffs5[band] = 0.0; + ch_data.mask_wght[band] = 0.0; let val; if self.ba.band_width[band] > 0 { - val = ch_data.coeffs1[band] * ch_data.coeffs1[band]; - ch_data.coeffs3[band] = 2.0 * ch_data.coeffs2[band]; + val = (ch_data.new_floor[band] as f64).powi(2); + ch_data.log_floor2[band] = 2.0 * ch_data.log_floor[band]; } else { val = 0.0; - ch_data.coeffs3[band] = -30000.0; + ch_data.log_floor2[band] = -30000.0; } - tmp3[band] = val * (self.ba.band_width[band] as f32) * 0.01; - if tmp3[band] <= 1.0e-6 { tmp3[band] = 0.0; } + let tmp = val * (self.ba.band_width[band] as f64) * 0.01; + if val <= 1.0e-30 { tmp3[band] = 0.0; } + else { tmp3[band] = tmp as f32; } } for band in 0..BANDS { let next_band = self.cycle1[band]; for band2 in band..next_band { - ch_data.coeffs5[band2] += tmp3[band]; + ch_data.mask_wght[band2] += tmp3[band]; } - tmp2[next_band - 1] += tmp3[band]; + tmp2[next_band] += tmp3[band]; } let mut accum = 0.0; - for band in 0..BANDS-1 { - accum = (tmp2[band] + accum) * self.weights1[band]; - ch_data.coeffs5[band + 1] += accum; + for band in 1..BANDS { + accum = (tmp2[band] + accum) * self.weights1[band - 1]; + ch_data.mask_wght[band] += accum; } let mut tmp2: [f32; BANDS] = [0.0; BANDS]; @@ -501,7 +496,7 @@ impl IMCDecoder { for band in 1..BANDS { let prev_band = self.cycle2[band]; for band2 in prev_band+1..band { - ch_data.coeffs5[band2] += tmp3[band]; + ch_data.mask_wght[band2] += tmp3[band]; } tmp2[prev_band + 1] += tmp3[band]; } @@ -510,7 +505,7 @@ impl IMCDecoder { for i in 0..BANDS-1 { let band = BANDS - 2 - i; accum = (tmp2[band + 1] + accum) * self.weights2[band]; - ch_data.coeffs5[band] += accum; + ch_data.mask_wght[band] += accum; } } @@ -531,54 +526,54 @@ impl IMCDecoder { self.ba.keep_flag[i] = level[i] == 16; } if reset { - let mut ch_data = &mut self.ch_data[ch]; + let ch_data = &mut self.ch_data[ch]; let (mut c1, mut c2) = calc_maxcoef(level[0] as f32); - ch_data.coeffs1[0] = c1; - ch_data.coeffs2[0] = c2; + ch_data.new_floor[0] = c1; + ch_data.log_floor[0] = c2; for i in 1..BANDS { if level[i] == 16 { - ch_data.coeffs1[i] = 1.0; - ch_data.coeffs2[i] = 0.0; + ch_data.new_floor[i] = 1.0; + ch_data.log_floor[i] = 0.0; } else { let lval; if level[i] < 17 { - lval = (level[i] - 7) as f32; + lval = level[i] - 7; } else if level[i] < 25 { - lval = (level[i] - 32) as f32; + lval = level[i] - 32; } else { - lval = (level[i] - 16) as f32; + lval = level[i] - 16; } - c1 *= 10.0f32.powf(lval * 0.25); - c2 += 0.83048 * lval; - ch_data.coeffs1[i] = c1; - ch_data.coeffs2[i] = c2; + c1 *= self.luts.exp_10[(lval + 16) as usize]; + c2 += 0.83048 * (lval as f32); + ch_data.new_floor[i] = c1; + ch_data.log_floor[i] = c2; } } } else { - let mut ch_data = &mut self.ch_data[ch]; + let ch_data = &mut self.ch_data[ch]; for i in 0..BANDS { if level[i] < 16 { - let lval = (level[i] - 7) as f32; - ch_data.coeffs1[i] = 10.0f32.powf(lval * 0.25) * ch_data.old_floor[i]; - ch_data.coeffs2[i] += lval * 0.83048; + let lval = level[i] - 7; + ch_data.new_floor[i] = self.luts.exp_10[(lval + 16) as usize] * ch_data.old_floor[i]; + ch_data.log_floor[i] += (lval as f32) * 0.83048; } else { - ch_data.coeffs1[i] = ch_data.old_floor[i]; + ch_data.new_floor[i] = ch_data.old_floor[i]; } } } - for i in 0..BANDS { + self.ba.band_width[0] = IMC_BANDS[1] - IMC_BANDS[0]; + for i in 1..BANDS { if level[i] != 16 { self.ba.band_width[i] = IMC_BANDS[i + 1] - IMC_BANDS[i]; } else { self.ba.band_width[i] = 0; } - //self.ba.band_flag[i] = false; } for i in 0..BANDS-1 { if self.ba.band_width[i] > 0 { - self.ba.band_flag[i] = br.read_bool()?; + self.ba.band_present[i] = br.read_bool()?; } } self.calculate_channel_values(ch); @@ -587,9 +582,9 @@ impl IMCDecoder { } fn read_skip_flags(&mut self, br: &mut BitReader) -> DecoderResult<()> { - let mut ba = &mut self.ba; + let ba = &mut self.ba; for band in 0..BANDS { - if !ba.band_flag[band] || ba.band_width[band] == 0 { continue; } + if !ba.band_present[band] || ba.band_width[band] == 0 { continue; } if !ba.band_skip[band] { ba.skip_flag_bits[band] = (IMC_BANDS[band + 1] - IMC_BANDS[band]) as u8; @@ -645,10 +640,10 @@ impl IMCDecoder { for i in IMC_BANDS[band]..IMC_BANDS[band + 1] { self.ba.band_bitsum[band] += self.ba.cw_len[i] as usize; } - if self.ba.band_flag[band] { + if self.ba.band_present[band] { let band_w = IMC_BANDS[band + 1] - IMC_BANDS[band]; let bitsum = self.ba.band_bitsum[band] as usize; - if (bitsum > 0) && (band_w * 3 > bitsum * 2) { + if (bitsum > 0) && (((band_w * 3) >> 1) > bitsum) { self.ba.band_skip[band] = true; } } @@ -658,17 +653,17 @@ impl IMCDecoder { let mut ch_data = &mut self.ch_data[ch]; for band in 0..BANDS { - ch_data.coeffs6[band] = ch_data.coeffs1[band]; + ch_data.adj_floor[band] = ch_data.new_floor[band]; let band_w = IMC_BANDS[band + 1] - IMC_BANDS[band]; let nonskip = band_w - self.ba.skips_per_band[band]; - if self.ba.band_flag[band] && nonskip > 0 { - ch_data.coeffs6[band] *= (band_w as f32).sqrt() / (nonskip as f32).sqrt(); + if self.ba.band_present[band] && nonskip > 0 { + ch_data.adj_floor[band] *= self.luts.sqrt_tab[band_w] / self.luts.sqrt_tab[nonskip]; } } let mut bits_freed: i32 = 0; for band in 0..BANDS { - if !self.ba.band_flag[band] { continue; } + if !self.ba.band_present[band] { continue; } for i in IMC_BANDS[band]..IMC_BANDS[band + 1] { if self.ba.skip_flag[i] { bits_freed += self.ba.cw_len[i] as i32; @@ -678,6 +673,7 @@ impl IMCDecoder { bits_freed -= self.ba.skip_flag_bits[band] as i32; } + if bits_freed < 0 { return Err(DecoderError::Bug); } self.ba.adjust_bit_allocation(&mut ch_data, bits_freed); Ok(()) @@ -686,10 +682,10 @@ impl IMCDecoder { fn read_coeffs(&mut self, br: &mut BitReader) -> DecoderResult<()> { for band in 0..BANDS { if self.ba.band_bitsum[band] == 0 { continue; } - if !self.ba.band_flag[band] && (self.ba.band_width[band] == 0) { continue; } + if !self.ba.band_present[band] && (self.ba.band_width[band] == 0) { continue; } for i in IMC_BANDS[band]..IMC_BANDS[band + 1] { let len = self.ba.cw_len[i]; - if len > 0 && (!self.ba.band_flag[band] || !self.ba.skip_flag[i]) { + if len > 0 && (!self.ba.band_present[band] || !self.ba.skip_flag[i]) { self.ba.coeff[i] = br.read(len)? as u8; } else { self.ba.coeff[i] = 0; @@ -701,7 +697,7 @@ impl IMCDecoder { fn inv_quant(&mut self, ch: usize, raw_coeffs: bool) { let qidx: usize = if raw_coeffs { 1 } else { 0 }; - let mut ch_data = &mut self.ch_data[ch]; + let ch_data = &mut self.ch_data[ch]; for band in 0..BANDS { for i in IMC_BANDS[band]..IMC_BANDS[band + 1] { ch_data.cw[i] = 0.0; @@ -714,17 +710,17 @@ impl IMCDecoder { if cw_len >= 4 { let quant = &IMC_QUANT_LARGE[qidx]; if val >= mid { - ch_data.cw[i] = quant[val - 8] * ch_data.coeffs6[band]; + ch_data.cw[i] = quant[val - 8] * ch_data.adj_floor[band]; } else { - ch_data.cw[i] = -quant[max - val - 8] * ch_data.coeffs6[band]; + ch_data.cw[i] = -quant[max - val - 8] * ch_data.adj_floor[band]; } } else { - let idx = qidx + (if self.ba.band_flag[band] { 2 } else { 0 }); + let idx = qidx + (if self.ba.band_present[band] { 2 } else { 0 }); let quant = &IMC_QUANT_SMALL[idx]; if val >= mid { - ch_data.cw[i] = quant[val - 1] * ch_data.coeffs6[band]; + ch_data.cw[i] = quant[val - 1] * ch_data.adj_floor[band]; } else { - ch_data.cw[i] = -quant[max - val - 1] * ch_data.coeffs6[band]; + ch_data.cw[i] = -quant[max - val - 1] * ch_data.adj_floor[band]; } } } @@ -754,7 +750,7 @@ impl IMCDecoder { self.read_level_coeffs(&mut br, reset, cb_idx, ch)?; } - self.ch_data[ch].old_floor.copy_from_slice(&self.ch_data[ch].coeffs1); + self.ch_data[ch].old_floor.copy_from_slice(&self.ch_data[ch].new_floor); let mut bitcount: usize = 0; if fixed_head { @@ -782,8 +778,10 @@ impl IMCDecoder { if self.ba.band_width[BANDS - 1] != 0 { bitcount += 1; } - if !fixed_head { - bitcount += 16; + bitcount += 16; + } else { + if self.ba.band_width[BANDS - 1] != 0 { + bitcount += 1; } } @@ -901,11 +899,22 @@ impl NADecoder for IMCDecoder { let mut dst = adata.get_data_mut(); let mut start: usize = 0; - for chunk in pktbuf.chunks(BLOCK_SIZE * (self.ainfo.get_channels() as usize)) { - for ch in 0..self.ainfo.get_channels() { + let channels = self.ainfo.get_channels() as usize; + for chunk in pktbuf.chunks(BLOCK_SIZE * channels) { + for ch in 0..channels { let off = abuf.get_offset(ch as usize) + start; self.decode_block(chunk, ch as usize, &mut dst[off..off+COEFFS])?; } + if (channels == 2) && ((chunk[1] & 0x20) != 0) { + let off1 = abuf.get_offset(0) + start; + let off2 = abuf.get_offset(1) + start; + for i in 0..COEFFS { + let l = dst[off1 + i]; + let r = dst[off2 + i]; + dst[off1 + i] = l + r; + dst[off2 + i] = l - r; + } + } start += COEFFS; } @@ -1098,65 +1107,15 @@ const IMC_CB_SELECTOR: [[usize; BANDS]; 4] = [ #[cfg(test)] mod test { - use codecs::*; - use demuxers::*; - use io::byteio::*; - use test::wavwriter::WavWriter; - + use test::dec_video::*; #[test] fn test_imc() { - let avi_dmx = find_demuxer("avi").unwrap(); - let mut file = File::open("assets/neal73_saber.avi").unwrap(); - let mut fr = FileReader::new_read(&mut file); - let mut br = ByteReader::new(&mut fr); - let mut dmx = avi_dmx.new_demuxer(&mut br); - dmx.open().unwrap(); - - let mut file = File::create("assets/imc-out.wav").unwrap(); - let mut fw = FileWriter::new_write(&mut file); - let mut wr = ByteWriter::new(&mut fw); - let mut wwr = WavWriter::new(&mut wr); - let mut wrote_header = false; - - let mut decs: Vec>> = Vec::new(); - for i in 0..dmx.get_num_streams() { - let s = dmx.get_stream(i).unwrap(); - let info = s.get_info(); - let decfunc = find_decoder(info.get_name()); - if let Some(df) = decfunc { - if info.is_audio() { - let mut dec = (df)(); - dec.init(info).unwrap(); - decs.push(Some(dec)); - } else { - decs.push(None); - } - } else { - decs.push(None); - } - } - - loop { - let pktres = dmx.get_frame(); - if let Err(e) = pktres { - if e == DemuxerError::EOF { break; } - panic!("error"); - } - let pkt = pktres.unwrap(); - //if pkt.get_pts().unwrap() > 10 { break; } - let streamno = pkt.get_stream().get_id() as usize; - if let Some(ref mut dec) = decs[streamno] { - let frm_ = dec.decode(&pkt).unwrap(); - let frm = frm_.borrow(); - if frm.get_info().is_audio() { - if !wrote_header { - wwr.write_header(frm.get_info().as_ref().get_properties().get_audio_info().unwrap()).unwrap(); - wrote_header = true; - } - wwr.write_frame(frm.get_buffer()).unwrap(); - } - } - } -panic!("the end"); +// let file = "assets/neal73_saber.avi"; +// let file = "assets/IMC/hvalen.avi"; + let file = "assets/IMC/8khz.avi"; +// let file = "assets/STsKlassFist-1a.avi"; +// let file = "assets/IMC/Angel Bday.avi"; + test_decode_audio("avi", file, None, "imc"); + //test_file_decoding("avi", file, None, false, true, None); } }