]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/indeo/imc.rs
trailing whitespace fixes
[nihav.git] / src / codecs / indeo / imc.rs
index b60819975d53c3f2dff5d6b2976a6a5d57e227b7..9a2ba219b40fde2f2b5f744044f687a83bd19576 100644 (file)
@@ -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) 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,6 @@ 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;
-                        }
-                    }
-                }
-            }
-}
-
     }
 }
 
@@ -338,7 +299,7 @@ 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); // almost exp(-lev)
+            exp_lev[lev] = 10.0f32.powf(-(lev as f32) * 0.4375);
         }
 
         let mut exp_10: [f32; 32] = [0.0; 32];
@@ -375,8 +336,12 @@ struct IMCDecoder {
     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())
 }
 
@@ -422,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];
@@ -434,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;
@@ -469,7 +434,7 @@ 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;
 
@@ -477,53 +442,53 @@ impl IMCDecoder {
         for i in 0..BANDS {
             if i != maxc_pos {
                 let level = br.read(4)?;
-                ch_data.coeffs1[i] = c1 * self.luts.exp_lev[level as usize];
-                ch_data.coeffs2[i] = c2 - 1.4533435415 * (level as f32);
+                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];
@@ -531,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];
         }
@@ -540,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;
         }
     }
 
@@ -561,14 +526,14 @@ 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 {
@@ -580,35 +545,35 @@ impl IMCDecoder {
                     }
                     c1 *= self.luts.exp_10[(lval + 16) as usize];
                     c2 += 0.83048 * (lval as f32);
-                    ch_data.coeffs1[i] = c1;
-                    ch_data.coeffs2[i] = c2;
+                    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;
-                    ch_data.coeffs1[i]  = self.luts.exp_10[(lval + 16) as usize] * ch_data.old_floor[i];
-                    ch_data.coeffs2[i] += (lval as f32) * 0.83048;
+                    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);
@@ -617,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;
@@ -675,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;
                 }
             }
@@ -688,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] *= self.luts.sqrt_tab[band_w] / self.luts.sqrt_tab[nonskip];//
+            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;
@@ -708,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(())
@@ -716,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;
@@ -731,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;
@@ -744,18 +710,18 @@ 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];
+                    }
                 }
             }
         }
@@ -784,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 {
@@ -812,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;
             }
         }
 
@@ -931,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;
         }
 
@@ -1128,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<Option<Box<NADecoder>>> = 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);
     }
 }