]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/atrac3.rs
split NihAV into subcrates
[nihav.git] / src / codecs / atrac3.rs
diff --git a/src/codecs/atrac3.rs b/src/codecs/atrac3.rs
deleted file mode 100644 (file)
index 5281892..0000000
+++ /dev/null
@@ -1,765 +0,0 @@
-use crate::formats::*;
-use crate::frame::*;
-use super::*;
-use crate::io::bitreader::*;
-use crate::io::byteio::*;
-use crate::io::codebook::*;
-use crate::dsp::fft::FFTMode;
-use crate::dsp::mdct::IMDCT;
-use std::f32::consts;
-
-#[derive(Clone,Copy,PartialEq)]
-enum Mode {
-    Mono,
-    Stereo,
-    JointStereo,
-}
-
-const ATRAC3_FRAME_SIZE: usize = 1024;
-
-#[derive(Clone,Copy)]
-struct Tone {
-    pos:        usize,
-    ncoeffs:    usize,
-    coeffs:     [f32; 8],
-}
-
-struct GainData {
-    ngains:     [usize; 4],
-    gain_lev:   [[usize; 8]; 4],
-    gain_loc:   [[usize; 8]; 4],
-}
-
-impl GainData {
-    fn new() -> Self {
-        Self {
-            ngains:     [0; 4],
-            gain_lev:   [[0; 8]; 4],
-            gain_loc:   [[0; 8]; 4],
-        }
-    }
-    fn read(&mut self, br: &mut BitReader, bands: usize) -> DecoderResult<()> {
-        self.ngains = [0; 4];
-        for band in 0..bands {
-            self.ngains[band]                           = br.read(3)? as usize;
-            for i in 0..self.ngains[band] {
-                self.gain_lev[band][i]                  = br.read(4)? as usize;
-                self.gain_loc[band][i]                  = br.read(5)? as usize;
-            }
-        }
-        Ok(())
-    }
-}
-
-struct Channel {
-    data:       [f32; ATRAC3_FRAME_SIZE],
-    delay:      [f32; ATRAC3_FRAME_SIZE],
-    qmf_delay:  [f32; 64 * 3],
-
-    bands:      usize,
-    block_no:   usize,
-
-    gain_data:  [GainData; 2],
-
-    subbands:   usize,
-    components: usize,
-    ntones:     usize,
-    tones:      [Tone; 64],
-}
-
-impl Channel {
-    fn new() -> Self {
-        Self {
-            data:       [0.0; ATRAC3_FRAME_SIZE],
-            delay:      [0.0; ATRAC3_FRAME_SIZE],
-            qmf_delay:  [0.0; 64 * 3],
-
-            bands:      0,
-            block_no:   0,
-
-            gain_data:  [GainData::new(), GainData::new()],
-
-            subbands:   0,
-            components: 0,
-            ntones:     0,
-            tones:      [Tone {pos: 0, ncoeffs: 0, coeffs: [0.0; 8]}; 64],
-        }
-    }
-    fn decode_unit(&mut self, br: &mut BitReader, codebooks: &[Codebook<u8>; 7], scalefactors: &[f32; 64]) -> DecoderResult<()> {
-        self.bands                                      = (br.read(2)? as usize) + 1;
-        self.gain_data[self.block_no].read(br, self.bands)?;
-        self.data = [0.0; ATRAC3_FRAME_SIZE];
-
-        self.ntones = 0;
-        self.components                                 = br.read(5)? as usize;
-        if self.components > 0 {
-            let selector                                = br.read(2)?;
-            validate!(selector != 2);
-            let mut mode0 = (selector & 1) != 0;
-
-            for _ in 0..self.components {
-                let mut flags: [bool; 4] = [false; 4];
-                for band in 0..self.bands {
-                    flags[band]                         = br.read_bool()?;
-                }
-                let nvals                               = br.read(3)? as usize;
-                let quant                               = br.read(3)? as usize;
-                validate!(quant > 1);
-                if selector == 3 {
-                    mode0                               = br.read_bool()?;
-                }
-                for j in 0..self.bands*4 {
-                    if !flags[j >> 2] { continue; }
-                    let count                           = br.read(3)? as usize;
-                    validate!(self.ntones + count < 64);
-                    for _ in 0..count {
-                        let scale_idx                   = br.read(6)? as usize;
-                        let tone = &mut self.tones[self.ntones];
-                        tone.pos                        = (br.read(6)? as usize) + j * 64;
-                        tone.ncoeffs                    = (ATRAC3_FRAME_SIZE - tone.pos).min(nvals + 1);
-                        let scale = scalefactors[scale_idx] * ATRAC3_MAX_QUANT[quant];
-                        read_coeffs(br, codebooks, &mut tone.coeffs[..tone.ncoeffs], quant, scale, mode0)?;
-                        self.ntones += 1;
-                    }
-                }
-            }
-        }
-
-        // spectrum
-        let mut quants: [usize; 32] = [0; 32];
-        let mut scf:    [usize; 32] = [0; 32];
-        self.subbands                                   = (br.read(5)? as usize) + 1;
-        let mode0                                       = br.read_bool()?;
-        for i in 0..self.subbands {
-            quants[i]                                   = br.read(3)? as usize;
-        }
-        for i in 0..self.subbands {
-            if quants[i] == 0 { continue; }
-            scf[i]                                      = br.read(6)? as usize;
-        }
-
-        self.data = [0.0; ATRAC3_FRAME_SIZE];
-        for i in 0..self.subbands {
-            if quants[i] == 0 { continue; }
-            let start = ATRAC3_SUBBANDS[i];
-            let end   = ATRAC3_SUBBANDS[i + 1];
-            let scale = scalefactors[scf[i]] * ATRAC3_MAX_QUANT[quants[i]];
-            read_coeffs(br, codebooks, &mut self.data[start..end], quants[i], scale, mode0)?;
-        }
-
-        for i in 0..self.ntones {
-            let tone = &self.tones[i];
-            for j in 0..tone.ncoeffs {
-                self.data[tone.pos + j] += tone.coeffs[j];
-            }
-        }
-        Ok(())
-    }
-    fn synth(&mut self, dsp: &mut DSP) {
-        let mut flag = 0;
-        let mut band = 0;
-        for (data, delay) in self.data.chunks_mut(256).zip(self.delay.chunks_mut(256)) {
-            if (flag & 1) != 0 {
-                for i in 0..128 {
-                    let t0 = data[i];
-                    let t1 = data[255 - i];
-                    data[i]         = t1;
-                    data[255 - i]   = t0;
-                }
-            }
-            dsp.synth_band(data);
-            dsp.apply_gains(data, delay, &mut self.gain_data, self.block_no, band);
-            delay.copy_from_slice(&dsp.tmp[256..512]);
-            flag ^= 1;
-            band += 1;
-        }
-        self.block_no ^= 1;
-    }
-    fn do_qmf(&mut self, dsp: &mut DSP, dst: &mut [f32]) {
-        let mut qchunks = self.qmf_delay.chunks_mut(64);
-        let qmf0 = qchunks.next().unwrap();
-        let qmf1 = qchunks.next().unwrap();
-        let qmf2 = qchunks.next().unwrap();
-        {
-            let mut tchunks = self.data.chunks_mut(512);
-            let tmp0 = tchunks.next().unwrap();
-            let tmp1 = tchunks.next().unwrap();
-            dsp.do_qmf(tmp0, qmf0, false);
-            dsp.do_qmf(tmp1, qmf1, true);
-        }
-        dsp.do_qmf_out(dst, &self.data, qmf2);
-    }
-}
-
-const ATRAC3_DEFAULT_DELAY: usize = 2190;
-const ATRAC3_WEIGHTING_DELAYS: [u8; 6] = [ 0, 7, 0, 7, 0, 7 ];
-
-fn read_coeffs(br: &mut BitReader, cb: &[Codebook<u8>; 7], dst: &mut [f32], quant: usize, scale: f32, mode0: bool) -> DecoderResult<()> {
-    if mode0 {
-        read_coeffs_mode0(br, dst, quant, scale)
-    } else if quant == 1 {
-        read_coeffs_mode1(br, &cb[0], dst, scale)
-    } else {
-        read_coeffs_other(br, &cb[quant - 1], dst, scale)
-    }
-}
-
-const ATRAC3_MODE0_CB: [f32; 4] = [ 0.0, 1.0, -2.0, -1.0 ];
-const ATRAC3_MODE0_BITS: [u8; 8] = [ 0, 4, 3, 3, 4, 4, 5, 6 ];
-
-fn read_coeffs_mode0(br: &mut BitReader, dst: &mut [f32], quant: usize, scale: f32) -> DecoderResult<()> {
-    let bits = ATRAC3_MODE0_BITS[quant];
-    if bits > 0 {
-        for i in 0..dst.len() {
-            let val                                     = br.read_s(bits)? as f32;
-            dst[i] = val * scale;
-        }
-    } else {
-        for i in (0..dst.len()).step_by(2) {
-            let val                                     = br.read(4)? as usize;
-            dst[i + 0] = ATRAC3_MODE0_CB[val >> 2] * scale;
-            dst[i + 1] = ATRAC3_MODE0_CB[val &  3] * scale;
-        }
-    }
-    Ok(())
-}
-
-const ATRAC3_MODE1_CB: [f32; 9 * 2] = [
-     0.0,  0.0,
-     0.0,  1.0,
-     0.0, -1.0,
-     1.0,  0.0,
-    -1.0,  0.0,
-     1.0,  1.0,
-     1.0, -1.0,
-    -1.0,  1.0,
-    -1.0, -1.0
-];
-
-fn read_coeffs_mode1(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], scale: f32) -> DecoderResult<()> {
-    for i in (0..dst.len()).step_by(2) {
-        let val                                         = br.read_cb(cb)? as usize;
-        dst[i + 0] = ATRAC3_MODE1_CB[val * 2 + 0] * scale;
-        dst[i + 1] = ATRAC3_MODE1_CB[val * 2 + 1] * scale;
-    }
-    Ok(())
-}
-
-fn read_coeffs_other(br: &mut BitReader, cb: &Codebook<u8>, dst: &mut [f32], scale: f32) -> DecoderResult<()> {
-    for i in 0..dst.len() {
-        let val                                         = (br.read_cb(cb)? as i8) + 1;
-        let sign = (val & 1) != 0;
-        let coef = (if sign { -(val >> 1) } else { val >> 1 }) as f32;
-        dst[i] = coef * scale;
-    }
-    Ok(())
-}
-
-struct DSP {
-    imdct:          IMDCT,
-    window:         [f32; 512],
-    gain_tab:       [f32; 16],
-    gain_tab2:      [f32; 32],
-    tmp:            [f32; ATRAC3_FRAME_SIZE + 64],
-}
-
-impl DSP {
-    fn new() -> Self {
-        let mut gain_tab: [f32; 16] = [0.0; 16];
-        let mut gain_tab2: [f32; 32] = [0.0; 32];
-
-        for i in 0..16 {
-            gain_tab[i] = 2.0f32.powf(4.0 - (i as f32));
-        }
-        for i in 0..32 {
-            gain_tab2[i] = 2.0f32.powf(((i as f32) - 15.0) * -0.125);
-        }
-
-        let mut tmpw: [f32; 256] = [0.0; 256];
-        for i in 0..tmpw.len() {
-            tmpw[i] = (((((i as f32) + 0.5) / 256.0 - 0.5) * consts::PI).sin() + 1.0) * 0.5;
-        }
-
-        let mut window: [f32; 512] = [0.0; 512];
-        for i in 0..tmpw.len() {
-            let w = tmpw[i] / (tmpw[i] * tmpw[i] + tmpw[255 - i] * tmpw[255 - i]);
-            window[i] = w;
-            window[512 - 1 - i] = w;
-        }
-
-        Self {
-                imdct:  IMDCT::new(FFTMode::SplitRadix, 512, false),
-                tmp:    [0.0; ATRAC3_FRAME_SIZE + 64],
-                gain_tab, gain_tab2, window,
-            }
-    }
-    fn synth_band(&mut self, src: &[f32]) {
-        let dst = &mut self.tmp;
-        self.imdct.imdct(src, dst);
-        for i in 0..512 {
-            dst[i] *= self.window[i];
-        }
-    }
-    fn apply_gains(&mut self, dst: &mut [f32], delay: &[f32], gain_data: &mut [GainData; 2], block_no: usize, band: usize) {
-        let prev_ngains = gain_data[block_no ^ 1].ngains[band];
-        let gain1 = if gain_data[block_no].ngains[band] > 0 {
-                            self.gain_tab[gain_data[block_no].gain_lev[band][0]]
-                    } else { 1.0 };
-
-        if prev_ngains == 0 {
-            for i in 0..256 {
-                dst[i] = self.tmp[i] * gain1 + delay[i];
-            }
-            return;
-        }
-
-        gain_data[block_no ^ 1].gain_lev[band][prev_ngains] = 4;
-        gain_data[block_no ^ 1].gain_loc[band][prev_ngains] = 32;
-
-        let mut off = 0;
-        for i in 0..prev_ngains {
-            let start = gain_data[block_no ^ 1].gain_loc[band][i] * 8;
-            let end = start + 8;
-
-            let mut gain2   = self.gain_tab [gain_data[block_no ^ 1].gain_lev[band][i]];
-            let gain_inc    = self.gain_tab2[gain_data[block_no ^ 1].gain_lev[band][i + 1] + 15 -
-                                             gain_data[block_no ^ 1].gain_lev[band][i]];
-
-            while off < start {
-                dst[off] = (self.tmp[off] * gain1 + delay[off]) * gain2;
-                off += 1;
-            }
-            while off < end {
-                dst[off] = (self.tmp[off] * gain1 + delay[off]) * gain2;
-                gain2 *= gain_inc;
-                off += 1;
-            }
-        }
-        for i in off..256 {
-            dst[i] = self.tmp[i] * gain1 + delay[i];
-        }
-    }
-    fn qmf_prepare(&mut self, src: &[f32], delay: &[f32], size: usize, swap: bool) {
-        for i in 0..46 {
-            self.tmp[i] = delay[i];
-        }
-        let (s0, s1) = if !swap {
-                (&src[0..], &src[size/2..])
-            } else {
-                (&src[size/2..], &src[0..])
-            };
-        for i in (0..size).step_by(4) {
-            self.tmp[46 + i + 0] = s0[i / 2 + 0] + s1[i / 2 + 0];
-            self.tmp[46 + i + 1] = s0[i / 2 + 0] - s1[i / 2 + 0];
-            self.tmp[46 + i + 2] = s0[i / 2 + 1] + s1[i / 2 + 1];
-            self.tmp[46 + i + 3] = s0[i / 2 + 1] - s1[i / 2 + 1];
-        }
-    }
-    fn qmf_synth(&mut self, dst: &mut [f32], size: usize) {
-        for i in (0..size).step_by(2) {
-            let mut acc0 = 0.0;
-            let mut acc1 = 0.0;
-
-            for j in (0..ATRAC3_QMF_FILTER.len()).step_by(2) {
-                acc0 += self.tmp[i + j + 0] * ATRAC3_QMF_FILTER[j + 0];
-                acc1 += self.tmp[i + j + 1] * ATRAC3_QMF_FILTER[j + 1];
-            }
-            dst[i + 0] = acc1 * consts::SQRT_2 / 256.0;
-            dst[i + 1] = acc0 * consts::SQRT_2 / 256.0;
-        }
-    }
-    fn do_qmf(&mut self, dst: &mut [f32], delay: &mut [f32], swap: bool) {
-        self.qmf_prepare(dst, delay, 512, swap);
-        self.qmf_synth(dst, 512);
-        for i in 0..46 {
-            delay[i] = self.tmp[512 + i];
-        }
-    }
-    fn do_qmf_out(&mut self, dst: &mut [f32], src: &[f32], delay: &mut [f32]) {
-        self.qmf_prepare(src, delay, 1024, false);
-        self.qmf_synth(dst, 1024);
-        for i in 0..46 {
-            delay[i] = self.tmp[1024 + i];
-        }
-    }
-}
-
-struct Atrac3Decoder {
-    info:       Rc<NACodecInfo>,
-    channels:   usize,
-    chmap:      NAChannelMap,
-    samples:    usize,
-    mode:       Mode,
-    scrambled:  bool,
-
-    codebooks:  [Codebook<u8>; 7],
-    dsp:        DSP,
-    ch_data:    [Channel; 2],
-    scalefactors:   [f32; 64],
-
-    mci_prev:   [usize; 4],
-    mci_cur:    [usize; 4],
-    mci_next:   [usize; 4],
-
-    weighting_delay:    [u8; 6],
-
-    pkt_buf:    Vec<u8>,
-}
-
-struct Atrac3CodebookReader {
-    bits:  &'static [u8],
-    codes: &'static [u8],
-}
-impl CodebookDescReader<u8> for Atrac3CodebookReader {
-    fn bits(&mut self, idx: usize) -> u8  { self.bits[idx] }
-    fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 }
-    fn sym (&mut self, idx: usize) -> u8 { idx as u8 }
-    fn len(&mut self) -> usize { self.bits.len() }
-}
-
-impl Atrac3Decoder {
-    fn new() -> Self {
-        let mut scalefactors: [f32; 64] = [0.0; 64];
-        for i in 0..scalefactors.len() {
-            scalefactors[i] = 2.0f32.powf(((i as f32) - 15.0) / 3.0);
-        }
-
-        let mut cb0 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[0], bits: ATRAC3_HUFF_BITS[0] };
-        let mut cb1 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[1], bits: ATRAC3_HUFF_BITS[1] };
-        let mut cb2 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[2], bits: ATRAC3_HUFF_BITS[2] };
-        let mut cb3 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[3], bits: ATRAC3_HUFF_BITS[3] };
-        let mut cb4 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[4], bits: ATRAC3_HUFF_BITS[4] };
-        let mut cb5 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[5], bits: ATRAC3_HUFF_BITS[5] };
-        let mut cb6 = Atrac3CodebookReader { codes: ATRAC3_HUFF_CODES[6], bits: ATRAC3_HUFF_BITS[6] };
-        Self {
-            info:       NACodecInfo::new_dummy(),
-            chmap:      NAChannelMap::new(),
-            channels:   0,
-            samples:    0,
-            mode:       Mode::Mono,
-            scrambled:  false,
-
-            dsp:        DSP::new(),
-            ch_data:    [Channel::new(), Channel::new()],
-            codebooks:  [Codebook::new(&mut cb0, CodebookMode::MSB).unwrap(),
-                         Codebook::new(&mut cb1, CodebookMode::MSB).unwrap(),
-                         Codebook::new(&mut cb2, CodebookMode::MSB).unwrap(),
-                         Codebook::new(&mut cb3, CodebookMode::MSB).unwrap(),
-                         Codebook::new(&mut cb4, CodebookMode::MSB).unwrap(),
-                         Codebook::new(&mut cb5, CodebookMode::MSB).unwrap(),
-                         Codebook::new(&mut cb6, CodebookMode::MSB).unwrap() ],
-
-            mci_prev:   [3; 4],
-            mci_cur:    [3; 4],
-            mci_next:   [3; 4],
-
-            weighting_delay: ATRAC3_WEIGHTING_DELAYS,
-            pkt_buf:    Vec::with_capacity(65536),
-            scalefactors,
-        }
-    }
-    fn rev_matrix(&mut self) {
-        for i in 0..4 {
-            let c0 = self.mci_prev[i];
-            let c1 = self.mci_cur[i];
-            let off;
-            if c0 != c1 {
-                let l0 = ATRAC3_MATRIX_COEFFS[c0 * 2 + 0];
-                let r0 = ATRAC3_MATRIX_COEFFS[c1 * 2 + 0];
-                let l1 = ATRAC3_MATRIX_COEFFS[c0 * 2 + 1];
-                let r1 = ATRAC3_MATRIX_COEFFS[c1 * 2 + 1];
-                for idx in 0..8 {
-                    let t0 = self.ch_data[0].data[idx + i * 256];
-                    let t1 = self.ch_data[1].data[idx + i * 256];
-                    let n1 = t0 * interp(l0, r0, idx) + t1 * interp(l1, r1, idx);
-                    self.ch_data[0].data[idx + i * 256] = n1;
-                    self.ch_data[1].data[idx + i * 256] = t0 * 2.0 - n1;
-                }
-                off = i * 256 + 8;
-            } else {
-                off = i * 256;
-            }
-            match c1 {
-                0 => {
-                        for i in off..256 {
-                            let t0 = self.ch_data[0].data[i];
-                            let t1 = self.ch_data[1].data[i];
-                            self.ch_data[0].data[i] =       t1  * 2.0;
-                            self.ch_data[1].data[i] = (t0 - t1) * 2.0;
-                        }
-                    },
-                1 => {
-                        for i in off..256 {
-                            let t0 = self.ch_data[0].data[i];
-                            let t1 = self.ch_data[1].data[i];
-                            self.ch_data[0].data[i] = (t0 + t1) *  2.0;
-                            self.ch_data[1].data[i] =       t1  * -2.0;
-                        }
-                    },
-                _ => {
-                        for i in off..256 {
-                            let t0 = self.ch_data[0].data[i];
-                            let t1 = self.ch_data[1].data[i];
-                            self.ch_data[0].data[i] = t0 + t1;
-                            self.ch_data[1].data[i] = t0 - t1;
-                        }
-                    },
-            };
-        }
-    }
-    fn weigh_channels(&mut self) {
-        if (self.weighting_delay[1] == 7) && (self.weighting_delay[3] == 7) { return; }
-        let pw: [f32; 2];
-        if self.weighting_delay[1] == 7 {
-            pw = [1.0; 2];
-        } else {
-            let w = (self.weighting_delay[1] as f32) / 7.0;
-            let iw = (2.0 - w * w).sqrt();
-            if self.weighting_delay[0] == 0 {
-                pw = [w, iw];
-            } else {
-                pw = [iw, w];
-            }
-        }
-        let cw: [f32; 2];
-        if self.weighting_delay[3] == 7 {
-            cw = [1.0; 2];
-        } else {
-            let w = (self.weighting_delay[3] as f32) / 7.0;
-            let iw = (2.0 - w * w).sqrt();
-            if self.weighting_delay[2] == 0 {
-                cw = [w, iw];
-            } else {
-                cw = [iw, w];
-            }
-        }
-
-        for i in 0..4 {
-            let off = i * 256;
-            for j in 0..8 {
-                self.ch_data[0].data[off + j] *= interp(pw[0], pw[1], j);
-                self.ch_data[1].data[off + j] *= interp(pw[0], pw[1], j);
-            }
-            for j in 8..256 {
-                self.ch_data[0].data[off + j] *= cw[0];
-                self.ch_data[1].data[off + j] *= cw[1];
-            }
-        }
-    }
-}
-
-fn interp(a: f32, b: f32, pos: usize) -> f32 {
-    a + ((pos as f32) / 8.0) * (b - a)
-}
-
-impl NADecoder for Atrac3Decoder {
-    fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
-        if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() {
-            self.info = info.clone();
-            let edata = info.get_extradata().unwrap();
-            validate!(edata.len() >= 4);
-
-            let mut mr = MemoryReader::new_read(&edata);
-            let mut br = ByteReader::new(&mut mr);
-
-            match edata.len() {
-                10 => {
-                        let version                     = br.read_u32be()?;
-                        validate!(version == 4);
-                        self.samples                    = br.read_u16be()? as usize;
-                        let delay                       = br.read_u16be()? as usize;
-                        validate!(delay == ATRAC3_DEFAULT_DELAY);
-                        let mode                        = br.read_u16be()?;
-                        self.mode = match mode {
-                                0 => Mode::Mono,
-                                2 => Mode::Stereo,
-                                0x12 => Mode::JointStereo,
-                                _ => return Err(DecoderError::InvalidData),
-                            };
-                        self.channels = if self.mode == Mode::Mono { 1 } else { 2 };
-                        self.scrambled = true;
-                    },
-                14 | 16 => {
-                        if edata.len() == 16 { br.read_skip(2)?; }
-                        self.samples                    = br.read_u32be()? as usize;
-                        let mode                        = br.read_u16be()?;
-                        self.mode = if mode != 0 { Mode::JointStereo } else { Mode::Stereo };
-                        self.channels = 2;
-                                                          br.read_skip(2)?;
-                        let ffactor                     = br.read_u16be()? as usize;
-                        validate!((ffactor > 0) && (ffactor <= 16));
-                        // calculate block_align / channels / ffactor, validate it's 96/152/192
-                    },
-                _ => { return Err(DecoderError::InvalidData) }
-            };
-            validate!(self.samples == ATRAC3_FRAME_SIZE * self.channels);
-            if self.mode == Mode::Mono {
-                self.chmap.add_channel(NAChannelType::C);
-            } else {
-                self.chmap.add_channel(NAChannelType::L);
-                self.chmap.add_channel(NAChannelType::R);
-            }
-            let ainfo = NAAudioInfo::new(ainfo.get_sample_rate(), self.channels as u8,
-                                         SND_F32P_FORMAT, self.samples);
-            self.info = info.replace_info(NACodecTypeInfo::Audio(ainfo));
-            Ok(())
-        } else {
-            Err(DecoderError::InvalidData)
-        }
-    }
-    fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
-        let info = pkt.get_stream().get_info();
-        validate!(info.get_properties().is_audio());
-        let pktbuf = pkt.get_buffer();
-        validate!(pktbuf.len() > 5);
-
-        let frame_size = pktbuf.len();
-        self.pkt_buf.resize(frame_size, 0);
-        if self.scrambled {
-            for (i, s) in pktbuf.iter().enumerate() {
-                self.pkt_buf[i] = s ^ ATRAC3_XOR_KEY[i & 3];
-            }
-        } else {
-            let dst = &mut self.pkt_buf[0..frame_size];
-            dst.copy_from_slice(pktbuf.as_slice());
-        }
-
-        {
-            let mut br = BitReader::new(self.pkt_buf.as_slice(), frame_size, BitReaderMode::BE);
-            let id                                  = br.read(6)?;
-            validate!(id == 0x28);
-            self.ch_data[0].decode_unit(&mut br, &self.codebooks, &self.scalefactors)?;
-            self.ch_data[0].synth(&mut self.dsp);
-        }
-        if self.channels == 2 {
-            let off;
-            if self.mode == Mode::JointStereo {
-                for i in 0..frame_size / 2 {
-                    let b0 = self.pkt_buf[i];
-                    let b1 = self.pkt_buf[frame_size - i - 1];
-                    self.pkt_buf[i]                     = b1;
-                    self.pkt_buf[frame_size - i - 1]    = b0;
-                }
-                let mut i = 0;
-                while (i < frame_size) && (self.pkt_buf[i] == 0xF8) { i += 1; }
-                validate!(frame_size - i > 4);
-                off = i;
-            } else {
-                off = frame_size / 2;
-            }
-            let mut br = BitReader::new(&self.pkt_buf[off..], frame_size - off, BitReaderMode::BE);
-            if self.mode == Mode::JointStereo {
-                let id                                  = br.read(2)?;
-                validate!(id == 0x3);
-            } else {
-                let id                                  = br.read(6)?;
-                validate!(id == 0x28);
-            }
-            if self.mode == Mode::JointStereo {
-                for i in 0..self.weighting_delay.len() - 2 {
-                    self.weighting_delay[i] = self.weighting_delay[i + 2];
-                }
-                self.weighting_delay[4]                 = br.read(1)? as u8;
-                self.weighting_delay[5]                 = br.read(3)? as u8;
-                self.mci_prev = self.mci_cur;
-                self.mci_cur  = self.mci_next;
-                for i in 0..4 {
-                    self.mci_next[i]                    = br.read(2)? as usize;
-                }
-            }
-            self.ch_data[1].decode_unit(&mut br, &self.codebooks, &self.scalefactors)?;
-            self.ch_data[1].synth(&mut self.dsp);
-        }
-        if self.mode == Mode::JointStereo {
-            self.rev_matrix();
-            self.weigh_channels();
-        }
-
-        let ainfo = self.info.get_properties().get_audio_info().unwrap();
-
-        let mut abuf = alloc_audio_buffer(ainfo, ATRAC3_FRAME_SIZE, self.chmap.clone())?;
-        let mut adata = abuf.get_abuf_f32().unwrap();
-        let mut output = adata.get_data_mut();
-
-        for ch in 0..self.channels {
-            let dpos = abuf.get_offset(ch);
-            self.ch_data[ch].do_qmf(&mut self.dsp, &mut output[dpos..][..ATRAC3_FRAME_SIZE]);
-        }
-
-        let mut frm = NAFrame::new_from_pkt(pkt, self.info.replace_info(NACodecTypeInfo::Audio(ainfo)), abuf);
-        frm.set_keyframe(true);
-        Ok(Rc::new(RefCell::new(frm)))
-    }
-}
-
-pub fn get_decoder() -> Box<NADecoder> {
-    Box::new(Atrac3Decoder::new())
-}
-
-#[cfg(test)]
-mod test {
-    use crate::test::dec_video::*;
-    #[test]
-    fn test_atrac3() {
-        let file = "assets/RV/rv30_atrc_384x208_realproducer_plus_8.51.rm";
-//        let file = "assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm";
-        test_decode_audio("realmedia", file, Some(12000), "atrac3");
-    }
-}
-
-const ATRAC3_XOR_KEY: [u8; 4] = [ 0x53, 0x7F, 0x61, 0x03 ];
-
-const ATRAC3_HUFF_CODES: [&[u8]; 7] = [
-    &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x1C, 0x1D, 0x1E, 0x1F ],
-    &[ 0x00, 0x04, 0x05, 0x06, 0x07 ],
-    &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x0E, 0x0F ],
-    &[ 0x00, 0x04, 0x05, 0x0C, 0x0D, 0x1C, 0x1D, 0x1E, 0x1F ], // same as 0
-    &[ 0x00, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B, 0x1C, 0x1D, 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x0D ],
-    &[ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x14,
-       0x15, 0x16, 0x17, 0x18, 0x19, 0x34, 0x35, 0x36,
-       0x37, 0x38, 0x39, 0x3A, 0x3B, 0x78, 0x79, 0x7A,
-       0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x08, 0x09 ],
-    &[ 0x00, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
-       0x0F, 0x10, 0x11, 0x24, 0x25, 0x26, 0x27, 0x28,
-       0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
-       0x31, 0x32, 0x33, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
-       0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
-       0x75, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2,
-       0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA,
-       0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x02, 0x03 ]
-];
-const ATRAC3_HUFF_BITS: [&[u8]; 7] = [
-    &[ 1, 3, 3, 4, 4, 5, 5, 5, 5 ],
-    &[ 1, 3, 3, 3, 3 ],
-    &[ 1, 3, 3, 4, 4, 4, 4 ],
-    &[ 1, 3, 3, 4, 4, 5, 5, 5, 5 ],
-    &[ 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 4, 4 ],
-    &[ 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4 ],
-    &[ 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
-       7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4 ],
-];
-
-const ATRAC3_MAX_QUANT: [f32; 8] = [ 0.0, 1.0/1.5, 1.0/2.5, 1.0/3.5, 1.0/4.5, 1.0/7.5, 1.0/15.5, 1.0/31.5 ];
-
-const ATRAC3_SUBBANDS: [usize; 32 + 1] = [
-      0,   8,  16,  24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, 176,
-    192, 224, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896,
-   1024
-];
-
-const ATRAC3_MATRIX_COEFFS: [f32; 8] = [ 0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0 ];
-
-const ATRAC3_QMF_FILTER: [f32; 48] = [
-    -0.000029238139, -0.000184109580, -0.000112315138,  0.000602345390,
-     0.000484503806, -0.001705877949, -0.001041114796,  0.004068033770,
-     0.001566677820, -0.008430772461, -0.001512299757,  0.015680588782,
-    -0.000122339843, -0.026883240789,  0.004925364163,  0.043472178280,
-    -0.015603342094, -0.068180441856,  0.037618979812,  0.108652018011,
-    -0.087192758918, -0.198768734932,  0.264158189297,  0.928483188152,
-     0.928483188152,  0.264158189297, -0.198768734932, -0.087192758918,
-     0.108652018011,  0.037618979812, -0.068180441856, -0.015603342094,
-     0.043472178280,  0.004925364163, -0.026883240789, -0.000122339843,
-     0.015680588782, -0.001512299757, -0.008430772461,  0.001566677820,
-     0.004068033770, -0.001041114796, -0.001705877949,  0.000484503806,
-     0.000602345390, -0.000112315138, -0.000184109580, -0.000029238139
-];