]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/ts102366.rs
binkaud: fix monaural RDFT decoding (and add a test while at it)
[nihav.git] / src / codecs / ts102366.rs
diff --git a/src/codecs/ts102366.rs b/src/codecs/ts102366.rs
deleted file mode 100644 (file)
index 8e9d75c..0000000
+++ /dev/null
@@ -1,1485 +0,0 @@
-use formats::*;
-use frame::*;
-use super::*;
-use io::bitreader::*;
-use dsp::fft::*;
-use std::str::FromStr;
-use std::f32::consts;
-
-const BLOCK_LEN: usize = 256;
-const NBLOCKS:   usize = 6;
-const MAX_CHANNELS: usize = 5;
-const MAX_CPLBANDS: usize = 18;
-const MAX_BANDS:    usize = 50;
-
-const MAGIC_BYTE0: u8 = 0x0B;
-const MAGIC_BYTE1: u8 = 0x77;
-
-const STRATEGY_REUSE: u8 = 0;
-
-const LFE_CHANNEL:  usize = MAX_CHANNELS;
-const CPL_CHANNEL:  usize = MAX_CHANNELS + 1;
-
-struct IMDCTContext {
-    xsincos:    [FFTComplex; BLOCK_LEN/2],
-    fft:        FFT,
-    size:       usize,
-}
-
-struct IMDCTWorkspace {
-    z:      [FFTComplex; BLOCK_LEN / 2],
-    y:      [FFTComplex; BLOCK_LEN / 2],
-    out:    [f32; BLOCK_LEN * 2],
-}
-
-impl IMDCTContext {
-    fn new(bits: usize) -> Self {
-        let size = 1 << bits;
-        let size4 = 1 << (bits - 2);
-        let mut xsincos: [FFTComplex; 512/4] = [FFTC_ZERO; 512/4];
-        for k in 0..size4 {
-            let factor = 2.0 * consts::PI * ((8 * k + 1) as f32) / ((8 * size) as f32);
-            xsincos[k].re = -factor.cos();
-            xsincos[k].im = -factor.sin();
-        }
-        let fft = FFTBuilder::new_fft(FFTMode::SplitRadix, size/4);
-        IMDCTContext { xsincos: xsincos, size: size, fft: fft }
-    }
-    #[allow(non_snake_case)]
-    fn do_imdct(&mut self, coeffs: &[i32; BLOCK_LEN], tmp: &mut IMDCTWorkspace) {
-        do_imdct_core(&mut self.fft, &self.xsincos, self.size, false, coeffs, &mut tmp.z, &mut tmp.y);
-        let w = &TS102366_WINDOW;
-        let N2 = self.size / 2;
-        let N4 = self.size / 4;
-        let N8 = self.size / 8;
-        for n in 0..N8 {
-            tmp.out[         2 * n]     = -tmp.y[N8 + n]    .im * w[     2 * n];
-            tmp.out[         2 * n + 1] =  tmp.y[N8 - n - 1].re * w[     2 * n + 1];
-            tmp.out[    N4 + 2 * n]     = -tmp.y[     n]    .re * w[N4 + 2 * n];
-            tmp.out[    N4 + 2 * n + 1] =  tmp.y[N4 - n - 1].im * w[N4 + 2 * n + 1];
-            tmp.out[    N2 + 2 * n]     = -tmp.y[N8 + n]    .re * w[N2 - 2 * n - 1];
-            tmp.out[    N2 + 2 * n + 1] =  tmp.y[N8 - n - 1].im * w[N2 - 2 * n - 2];
-            tmp.out[3 * N4 + 2 * n]     =  tmp.y[     n]    .im * w[N4 - 2 * n - 1];
-            tmp.out[3 * N4 + 2 * n + 1] = -tmp.y[N4 - n - 1].re * w[N4 - 2 * n - 2];
-        }
-    }
-    #[allow(non_snake_case)]
-    fn do_imdct_ileave(&mut self, coeffs: &[i32; BLOCK_LEN], tmp: &mut IMDCTWorkspace) {
-        let mut ziter = tmp.z.chunks_mut(self.size / 4);
-        let z1 = ziter.next().unwrap();
-        let z2 = ziter.next().unwrap();
-        let mut yiter = tmp.y.chunks_mut(self.size / 4);
-        let y1 = yiter.next().unwrap();
-        let y2 = yiter.next().unwrap();
-        do_imdct_core(&mut self.fft, &self.xsincos, self.size, true, coeffs,       z1, y1);
-        do_imdct_core(&mut self.fft, &self.xsincos, self.size, true, &coeffs[1..], z2, y2);
-        let w = &TS102366_WINDOW;
-        let N2 = self.size / 2;
-        let N4 = self.size / 4;
-        let N8 = self.size / 8;
-        for n in 0..N8 {
-            tmp.out[         2 * n]     = -y1[     n]    .im * w[     2 * n];
-            tmp.out[         2 * n + 1] =  y1[N8 - n - 1].re * w[     2 * n + 1];
-            tmp.out[    N4 + 2 * n]     = -y1[     n]    .re * w[N4 + 2 * n];
-            tmp.out[    N4 + 2 * n + 1] =  y1[N8 - n - 1].im * w[N4 + 2 * n + 1];
-            tmp.out[    N2 + 2 * n]     = -y2[     n]    .re * w[N2 - 2 * n - 1];
-            tmp.out[    N2 + 2 * n + 1] =  y2[N8 - n - 1].im * w[N2 - 2 * n - 2];
-            tmp.out[3 * N4 + 2 * n]     =  y2[     n]    .im * w[N4 - 2 * n - 1];
-            tmp.out[3 * N4 + 2 * n + 1] = -y2[N8 - n - 1].re * w[N4 - 2 * n - 2];
-        }
-    }
-}
-
-#[allow(non_snake_case)]
-fn do_imdct_core(fft: &mut FFT, xsc: &[FFTComplex; BLOCK_LEN/2], size: usize, ilace: bool, coeffs: &[i32], z: &mut [FFTComplex], y: &mut [FFTComplex]) {
-    let N  = size;
-    let N2 = size / 2;
-    let N4 = size / 4;
-    let scale = 1.0 / ((1 << 24) as f32);
-    for k in 0..N4 {
-        let (c0, c1) = if !ilace {
-                ((coeffs[N2 - 2 * k - 1] as f32) * scale ,
-                 (coeffs[     2 * k]     as f32) * scale)
-            } else {
-                ((coeffs[N - 4 * k - 2] as f32) * scale,
-                 (coeffs[    4 * k]     as f32) * scale)
-            };
-        z[k].re = c0 * xsc[k].re - c1 * xsc[k].im;
-        z[k].im = c0 * xsc[k].im + c1 * xsc[k].re;
-    }
-    fft.do_fft_inplace(z, false);
-    for k in 0..N4 {
-        y[k] = z[k] * xsc[k];
-    }
-}
-
-struct AudioDecoder {
-    info:       Rc<NACodecInfo>,
-    ablk:       AudioBlock,
-    imdct512:   IMDCTContext,
-    imdct256:   IMDCTContext,
-    tmp:        IMDCTWorkspace,
-    delay:      [[f32; BLOCK_LEN]; MAX_CHANNELS + 1],
-}
-
-impl AudioDecoder {
-    fn new() -> Self {
-        AudioDecoder {
-            info:       NACodecInfo::new_dummy(),
-            ablk:       AudioBlock::new(),
-            imdct512:   IMDCTContext::new(9),
-            imdct256:   IMDCTContext::new(8),
-            tmp:        IMDCTWorkspace {
-                            z:      [FFTC_ZERO; BLOCK_LEN / 2],
-                            y:      [FFTC_ZERO; BLOCK_LEN / 2],
-                            out:    [0.0; BLOCK_LEN * 2],
-                        },
-            delay:      [[0.0; BLOCK_LEN]; MAX_CHANNELS + 1],
-        }
-    }
-}
-
-const SAMPLE_RATES: [u32; 4] = [ 48000, 44100, 32000, 0 ];
-
-const FRAME_SIZES: [[usize; 64]; 4] = [
-    [
-          64,   64,   80,   80,   96,   96,  112,  112,
-         128,  128,  160,  160,  192,  192,  224,  224,
-         256,  256,  320,  320,  384,  384,  448,  448,
-         512,  512,  640,  640,  768,  768,  896,  896,
-        1024, 1024, 1152, 1152, 1280, 1280,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    ], [
-          69,   70,   87,   88,  104,  105,  121,  122,
-         139,  140,  174,  175,  208,  209,  243,  244,
-         278,  279,  348,  349,  417,  418,  487,  488,
-         557,  558,  696,  697,  835,  836,  975,  976,
-        1114, 1115, 1253, 1254, 1393, 1394,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    ], [
-          96,   96,  120,  120,  144,  144,  168,  168,
-         192,  192,  240,  240,  288,  288,  336,  336,
-         384,  384,  480,  480,  576,  576,  672,  672,
-         768,  768,  960,  960, 1152, 1152, 1344, 1344,
-        1536, 1536, 1728, 1728, 1920, 1920,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    ], [ 0; 64 ],
-];
-
-#[derive(Debug,Clone,Copy)]
-struct Syncinfo {
-    crc1:       u16,
-    fscod:      u8,
-    frmsizecod: u8,
-    samplerate: u32,
-    frame_size: usize,
-}
-
-impl Syncinfo {
-    fn read(br: &mut BitReader) -> DecoderResult<Self> {
-        let syncword        = br.read(16)?;
-        validate!(syncword == ((MAGIC_BYTE0 as u32) * 256) + (MAGIC_BYTE1 as u32));
-        let crc1            = br.read(16)? as u16;
-        let fscod           = br.read(2)? as usize;
-        let frmsizecod      = br.read(6)? as usize;
-        Ok(Syncinfo { crc1: crc1, fscod: fscod as u8, frmsizecod: frmsizecod as u8,
-                      samplerate: SAMPLE_RATES[fscod], frame_size: FRAME_SIZES[fscod][frmsizecod] * 2 })
-    }
-    fn is_valid(&self) -> bool {
-        (self.samplerate != 0) && (self.frame_size != 0)
-    }
-}
-
-trait ReadOptional {
-    fn read_optional8(&mut self) -> BitReaderResult<Option<u8>>;
-    fn read_optional16(&mut self, bits: u8) -> BitReaderResult<Option<u16>>;
-}
-
-impl<'a> ReadOptional for BitReader<'a> {
-    fn read_optional8(&mut self) -> BitReaderResult<Option<u8>> {
-        if self.read_bool()? {
-            Ok(Some(self.read(8)? as u8))
-        } else {
-            Ok(None)
-        }
-    }
-    fn read_optional16(&mut self, bits: u8) -> BitReaderResult<Option<u16>> {
-        if self.read_bool()? {
-            Ok(Some(self.read(bits)? as u16))
-        } else {
-            Ok(None)
-        }
-    }
-}
-
-#[derive(Debug,Clone,Copy,PartialEq)]
-enum ACMode {
-    DualMono,
-    Mono,
-    Stereo,
-    Mode3_0,
-    Mode2_1,
-    Mode3_1,
-    Mode2_2,
-    Mode3_2,
-}
-
-impl ACMode {
-    fn get_num_channels(&self) -> usize {
-        match *self {
-            ACMode::DualMono    => 2,
-            ACMode::Mono        => 1,
-            ACMode::Stereo      => 2,
-            ACMode::Mode3_0     => 3,
-            ACMode::Mode2_1     => 3,
-            ACMode::Mode3_1     => 4,
-            ACMode::Mode2_2     => 4,
-            ACMode::Mode3_2     => 5,
-        }
-    }
-    fn get_channel_map_str(&self) -> &'static str {
-        match *self {
-            ACMode::DualMono    => "C,C",
-            ACMode::Mono        => "C",
-            ACMode::Stereo      => "L,R",
-            ACMode::Mode3_0     => "L,C,R",
-            ACMode::Mode2_1     => "L,R,Cs",
-            ACMode::Mode3_1     => "L,C,R,Cs",
-            ACMode::Mode2_2     => "L,R,Ls,Rs",
-            ACMode::Mode3_2     => "L,C,R,Ls,Rs",
-        }
-    }
-    fn get_channel_map(&self, has_lfe: bool) -> NAChannelMap {
-        let mut chmap = NAChannelMap::from_str(self.get_channel_map_str()).unwrap();
-        if has_lfe {
-            chmap.add_channel(NAChannelType::LFE);
-        }
-        chmap
-    }
-    fn is_3_x(&self) -> bool {
-        match *self {
-            ACMode::Mode3_0 |
-            ACMode::Mode3_1 |
-            ACMode::Mode3_2     => true,
-            _                   => false,
-        }
-    }
-    fn is_surround(&self) -> bool {
-        match *self {
-            ACMode::Mode2_1 |
-            ACMode::Mode3_1 |
-            ACMode::Mode2_2 |
-            ACMode::Mode3_2     => true,
-            _                   => false,
-        }
-    }
-}
-
-const AC_MODES: [ACMode; 8] = [
-    ACMode::DualMono, ACMode::Mono, ACMode::Stereo,
-    ACMode::Mode3_0, ACMode::Mode2_1,
-    ACMode::Mode3_1, ACMode::Mode2_2,
-    ACMode::Mode3_2
-];
-
-#[derive(Debug,Clone,Copy)]
-struct Mixinfo {
-    dialnorm:   u8,
-    compr:      Option<u8>,
-    langcod:    Option<u8>,
-    mixlevel:   Option<u8>,
-    roomtyp:    Option<u8>,
-}
-
-impl Mixinfo {
-    fn read(br: &mut BitReader) -> DecoderResult<Self> {
-        let dialnorm                = br.read(5)? as u8;
-        let compr                   = br.read_optional8()?;
-        let langcod                 = br.read_optional8()?;
-        let (mixlevel, roomtyp) = if br.read_bool()? {
-                let mlev            = br.read(5)? as u8;
-                let rt              = br.read(2)? as u8;
-                validate!(rt < 3);
-                (Some(mlev), Some(rt))
-            } else {
-                (None, None)
-            };
-        Ok(Mixinfo { dialnorm, compr, langcod, mixlevel, roomtyp })
-    }
-}
-
-#[derive(Debug,Clone,Copy)]
-struct BSI {
-    bsid:       u8,
-    shift:      u8,
-    bsmod:      u8,
-    acmod:      ACMode,
-    cmixlev:    Option<u8>,
-    surmixlev:  Option<u8>,
-    dsurmod:    Option<u8>,
-    lfeon:      bool,
-    mixinfo:    Mixinfo,
-    mixinfo2:   Option<Mixinfo>,
-    copysmth:   bool,
-    origbs:     bool,
-    timecod1:   Option<u16>,
-    timecod2:   Option<u16>,
-    has_addb:   bool,
-}
-
-impl BSI {
-    fn read(br: &mut BitReader) -> DecoderResult<BSI> {
-        let bsid                    = br.read(5)? as u8;
-        validate!(bsid <= 10);
-        let shift = if bsid < 9 { 0 } else { bsid - 9 + 1 };
-        let bsmod                   = br.read(3)? as u8;
-        let acmod_id                = br.read(3)? as usize;
-        validate!(acmod_id < AC_MODES.len());
-        let acmod = AC_MODES[acmod_id];
-        let cmixlev = if acmod.is_3_x() {
-                let cl              = br.read(2)? as u8;
-                validate!(cl < 3);
-                Some(cl)
-            } else { None };
-        let surmixlev = if acmod.is_surround() {
-                let sml             = br.read(2)? as u8;
-                validate!(sml < 3);
-                Some(sml)
-            } else { None };
-        let dsurmod = if acmod == ACMode::Stereo {
-                let dsm             = br.read(2)? as u8;
-                validate!(dsm < 3);
-                Some(dsm)
-            } else { None };
-        let lfeon                   = br.read_bool()?;
-        let mixinfo                 = Mixinfo::read(br)?;
-        let mixinfo2 = if acmod == ACMode::DualMono {
-                Some(Mixinfo::read(br)?)
-            } else {
-                None
-            };
-        let copysmth                = br.read_bool()?;
-        let origbs                  = br.read_bool()?;
-        let timecod1                = br.read_optional16(14)?;
-        let timecod2                = br.read_optional16(14)?;
-        let has_addb                = br.read_bool()?;
-        Ok(BSI{
-            bsid, shift, bsmod, acmod, lfeon,
-            cmixlev, surmixlev, dsurmod,
-            mixinfo: mixinfo, mixinfo2: mixinfo2,
-            copysmth, origbs, timecod1, timecod2, has_addb,
-            })
-    }
-}
-
-#[derive(Clone, Copy)]
-struct ChannelData {
-    blksw:      bool,
-    dithflag:   bool,
-
-    chincpl:    bool,
-    cplcoe:     bool,
-    cplcoexp:   [u8; MAX_CPLBANDS],
-    cplcomant:  [u8; MAX_CPLBANDS],
-    mstrcplco:  u8,
-
-    chbwcod:    u8,
-
-    expstr:     u8,
-    gainrng:    u8,
-    startmant:  usize,
-    endmant:    usize,
-    groups:     usize,
-
-    fsnroffst:  u8,
-    fgaincod:   usize,
-    snroffset:  i32,
-
-    deltbae:    u8,
-    deltnseg:   usize,
-    deltoffst:  [u8; 8],
-    deltlen:    [usize; 8],
-    deltba:     [u8; 8],
-
-    bap:        [u8; 256],
-    exps:       [u8; 256],
-    mant:       [i32; 256],
-
-    psd:        [i16; 256],
-    bndpsd:     [i32; 64],
-}
-
-const GROUPS: [usize; 4] = [ 0, 3, 6, 12 ];
-const GROUP_BIAS: [usize; 4] = [ 0, 0, 3, 9 ];
-
-fn decode_exps(br: &mut BitReader, dst: &mut [u8], mut prev: u8, grplen: usize) -> DecoderResult<()> {
-    let repeat = grplen / 3;
-
-    for out in dst.chunks_mut(grplen) {
-        let val                                         = br.read(7)? as u8;
-        validate!(val < 125);
-        let diff: [u8; 3] = [ val / 25,  (val / 5) % 5, val % 5 ];
-        for (i, exps) in out.chunks_mut(repeat).enumerate() {
-            exps[0] = (prev + diff[i]).wrapping_sub(2);
-            validate!(exps[0] <= 24);
-            for j in 1..repeat {
-                exps[j] = exps[0];
-            }
-            prev = exps[0];
-        }
-    }
-
-    Ok(())
-}
-
-macro_rules! read_bap {
-    ($br: expr, $tab:ident, $nbits:expr) => ({
-            let val                                     = $br.read($nbits)? as usize;
-            validate!(val < $tab.len());
-            $tab[val]
-        });
-    ($br:expr, $tab:ident, $nbits:expr, $bufidx:expr, $bap_buf:expr, $bap_buf_fill:expr) => (
-            if $bap_buf_fill[$bufidx] > 0 {
-                $bap_buf_fill[$bufidx] -= 1;
-                $bap_buf[$bufidx][$bap_buf_fill[$bufidx]]
-            } else {
-                let val                                 = $br.read($nbits)? as usize;
-                validate!(val < $tab.len());
-                for i in 1..$tab[0].len() {
-                    $bap_buf[$bufidx][i - 1] = $tab[val][i];
-                }
-                $bap_buf_fill[$bufidx] = $tab[0].len() - 1;
-                $tab[val][0]
-            }
-        );
-}
-
-impl ChannelData {
-    fn new() -> Self {
-        ChannelData {
-            blksw:      false,
-            dithflag:   false,
-
-            chincpl:    false,
-            cplcoe:     false,
-            cplcoexp:   [0; MAX_CPLBANDS],
-            cplcomant:  [0; MAX_CPLBANDS],
-            mstrcplco:  0,
-
-            chbwcod:    0,
-
-            expstr:     0,
-            gainrng:    0,
-            startmant:  0,
-            endmant:    0,
-            groups:     0,
-
-            fsnroffst:  0,
-            fgaincod:   0,
-            snroffset:  0,
-
-            deltbae:    0,
-            deltnseg:   0,
-            deltoffst:  [0; 8],
-            deltlen:    [0; 8],
-            deltba:     [0; 8],
-
-            bap:        [0; 256],
-            exps:       [0; 256],
-            mant:       [0; 256],
-
-            psd:        [0; 256],
-            bndpsd:     [0; 64],
-        }
-    }
-    fn read_strategy(&mut self, br: &mut BitReader, blk_no: usize) -> DecoderResult<()> {
-        self.expstr                                     = br.read(2)? as u8;
-        validate!(blk_no != 0 || self.expstr != STRATEGY_REUSE);
-        if self.expstr != STRATEGY_REUSE {
-            if self.startmant > 0 {
-                self.groups = (self.endmant - self.startmant) / GROUPS[self.expstr as usize];
-            } else if self.endmant != 0{
-                let idx = self.expstr as usize;
-                self.groups = (self.endmant + GROUP_BIAS[idx] - 1) / GROUPS[idx];
-            } else {
-                self.groups = 0;
-            }
-        }
-        Ok(())
-    }
-    fn read_exps(&mut self, br: &mut BitReader, is_cpl: bool, is_lfe: bool) -> DecoderResult<()> {
-        if self.expstr == STRATEGY_REUSE { return Ok(()); }
-        let grpsize = GROUPS[self.expstr as usize];
-        self.exps = [0; 256];
-        if is_cpl {
-            let first                                   = (br.read(4)? as u8) << 1;
-            let out = &mut self.exps[self.startmant..self.endmant];
-            decode_exps(br, out, first, grpsize)?;
-        } else if !is_lfe {
-            self.exps[0]                                = br.read(4)? as u8;
-            let first = self.exps[0];
-            let out = &mut self.exps[1..self.endmant];
-            decode_exps(br, out, first, grpsize)?;
-            self.gainrng                                = br.read(2)? as u8;
-        } else {
-            self.exps[0]                                = br.read(4)? as u8;
-            let first = self.exps[0];
-            let out = &mut self.exps[1..7];
-            decode_exps(br, out, first, grpsize)?;
-        }
-        Ok(())
-    }
-    fn read_snr(&mut self, br: &mut BitReader) -> DecoderResult<()> {
-        self.fsnroffst                                  = br.read(4)? as u8;
-        self.fgaincod                                   = br.read(3)? as usize;
-        Ok(())
-    }
-    fn read_deltbai(&mut self, br: &mut BitReader) -> DecoderResult<()> {
-        if self.deltbae == 1 {
-            self.deltnseg                               = (br.read(3)? as usize) + 1;
-            for seg in 0..self.deltnseg {
-                self.deltoffst[seg]                     = br.read(5)? as u8;
-                self.deltlen[seg]                       = br.read(4)? as usize;
-                self.deltba[seg]                        = br.read(3)? as u8;
-            }
-        }
-        Ok(())
-    }
-
-    fn compute_bndpsd(&mut self) {
-        let start       = self.startmant;
-        let end         = self.endmant;
-        let exps        = &mut self.exps;
-        let psd         = &mut self.psd;
-        let bndpsd      = &mut self.bndpsd;
-
-        for bin in start..end {
-            psd[bin] = 3072 - ((exps[bin] as i16) << 7);
-        }
-
-        let mut bin = start;
-        let mut band = TS102366_BIN_TO_BAND[bin] as usize;
-        let mut lastbin;
-        loop {
-            lastbin = ((TS102366_BAND_START[band] as usize) + (TS102366_BAND_SIZE[band] as usize)).min(end);
-            bndpsd[band] = psd[bin] as i32;
-            bin += 1;
-            while bin < lastbin {
-                bndpsd[band] = logadd(bndpsd[band], psd[bin] as i32);
-                bin += 1;
-            }
-            band += 1;
-            if lastbin >= end { break; }
-        }
-    }
-    fn compute_mask(&mut self, mask: &mut [i32; MAX_BANDS], fscod: usize, sgain: u16, fdecay: u8, sdecay: u8,
-                    dbknee: u16, cplfleak: u16, cplsleak: u16, shift: u8) {
-        let fgain = TS102366_FAST_GAIN[self.fgaincod] as i32;
-
-        let bndstart = TS102366_BIN_TO_BAND[self.startmant] as usize;
-        let bndend   = (TS102366_BIN_TO_BAND[self.endmant - 1] as usize) + 1;
-
-        let mut excite: [i32; MAX_BANDS] = [0; MAX_BANDS];
-
-        let begin;
-        let mut fast_leak;
-        let mut slow_leak;
-        if bndstart == 0 {
-            let lowcomp0 = calc_lowcomp(0, self.bndpsd[0], self.bndpsd[1], 0);
-            excite[0] = self.bndpsd[0] - fgain - lowcomp0;
-            let lowcomp1 = calc_lowcomp(lowcomp0, self.bndpsd[1], self.bndpsd[2], 1);
-            excite[1] = self.bndpsd[1] - fgain - lowcomp1;
-            let mut sband = 7;
-            let mut lowcomp = lowcomp1;
-            fast_leak = 0;
-            slow_leak = 0;
-            for band in 2..7 {
-                let not_lfe_case = (bndend != 7) || (band != 6);
-                if not_lfe_case {
-                    lowcomp = calc_lowcomp(lowcomp, self.bndpsd[band], self.bndpsd[band + 1], band);
-                }
-                fast_leak = self.bndpsd[band] - fgain;
-                slow_leak = self.bndpsd[band] - (sgain as i32);
-                excite[band] = fast_leak - lowcomp;
-                if not_lfe_case {
-                    if self.bndpsd[band] <= self.bndpsd[band + 1] {
-                        sband = band + 1;
-                        break;
-                    }
-                }
-            }
-            for band in sband..bndend.min(22) {
-                if (bndend != 7) || (band != 6) {
-                    lowcomp = calc_lowcomp(lowcomp, self.bndpsd[band], self.bndpsd[band + 1], band);
-                }
-                fast_leak = (fast_leak - (fdecay as i32)).max(self.bndpsd[band] - (fgain as i32));
-                slow_leak = (slow_leak - (sdecay as i32)).max(self.bndpsd[band] - (sgain as i32));
-                excite[band] = slow_leak.max(fast_leak - lowcomp);
-            }
-            begin = 22;
-        } else {
-            begin = bndstart;
-            fast_leak = cplfleak as i32;
-            slow_leak = cplsleak as i32;
-        }
-        for band in begin..bndend {
-            fast_leak = (fast_leak - (fdecay as i32)).max(self.bndpsd[band] - (fgain as i32));
-            slow_leak = (slow_leak - (sdecay as i32)).max(self.bndpsd[band] - (sgain as i32));
-            excite[band] = fast_leak.max(slow_leak);
-        }
-        for band in bndstart..bndend {
-            if self.bndpsd[band] < (dbknee as i32) {
-                excite[band] += ((dbknee as i32) - self.bndpsd[band]) >> 2;
-            }
-            mask[band] = excite[band].max(TS102366_HTH[fscod][band >> shift] as i32);
-        }
-    }
-    fn apply_delta_info(&mut self, mask: &mut [i32; MAX_BANDS]) {
-        if self.deltbae == 0 || self.deltbae == 1 {
-            let mut band = TS102366_BIN_TO_BAND[self.startmant] as usize;
-            for seg in 0..self.deltnseg {
-                band += self.deltoffst[seg] as usize;
-                let delta = if self.deltba[seg] >= 4 {
-                        ((self.deltba[seg] as i32) - 3) << 7
-                    } else {
-                        ((self.deltba[seg] as i32) - 4) << 7
-                    };
-                if band + self.deltlen[seg] > MAX_BANDS { break; }
-                for _ in 0..self.deltlen[seg] {
-                    mask[band] += delta;
-                    band += 1;
-                }
-            }
-        }
-    }
-    fn calc_snr_offset(&mut self, csnroffst: u8) {
-        self.snroffset = ((((csnroffst as i32) - 15) << 4) + (self.fsnroffst as i32)) << 2;
-    }
-    fn compute_bap(&mut self, mask: &mut [i32; MAX_BANDS], floor: u16) {
-        let end = self.endmant;
-        let mut band = TS102366_BIN_TO_BAND[self.startmant] as usize;
-        let mut bin = self.startmant;
-        let mut lastbin;
-        loop {
-            lastbin = ((TS102366_BAND_START[band] as usize) + (TS102366_BAND_SIZE[band] as usize)).min(end);
-            mask[band] = (mask[band] - self.snroffset - (floor as i32)).max(0) & 0x1FE0;
-            mask[band] += floor as i32;
-            while bin < lastbin {
-                let addr = (((self.psd[bin] as i32) - mask[band]) >> 5).min(63).max(0) as usize;
-                self.bap[bin] = TS102366_BAPTAB[addr];
-                bin += 1;
-            }
-            if lastbin == end { break; }
-            band += 1;
-        }
-    }
-    fn read_mant(&mut self, br: &mut BitReader, bap_buf: &mut [[i32; 2]; 3], bap_buf_fill: &mut [usize; 3]) -> DecoderResult<()> {
-        self.mant = [0; BLOCK_LEN];
-        for bin in self.startmant..self.endmant {
-            self.mant[bin] = match self.bap[bin] {
-                    0 => {
-                            if self.dithflag {
-                                42 // todo dither
-                            } else {
-                                0
-                            }
-                        },
-                    1 => { read_bap!(br, TS102366_QUANT3_MAP,  5, 0, bap_buf, bap_buf_fill) },
-                    2 => { read_bap!(br, TS102366_QUANT5_MAP,  7, 1, bap_buf, bap_buf_fill) },
-                    3 => { read_bap!(br, TS102366_QUANT7_MAP,  3) },
-                    4 => { read_bap!(br, TS102366_QUANT11_MAP, 7, 2, bap_buf, bap_buf_fill) },
-                    5 => { read_bap!(br, TS102366_QUANT15_MAP, 4) },
-                    _ => {
-                            validate!(self.bap[bin] < 15);
-                            let nbits = TS102366_BAP_BITS[(self.bap[bin] as usize) - 6];
-                            let val                     = br.read(nbits)? as i16;
-                            ((val << (16 - nbits)) as i32) << 9
-                        },
-                };
-            self.mant[bin] >>= self.exps[bin];
-        }
-        Ok(())
-    }
-
-    fn synth(&mut self, imdct512: &mut IMDCTContext, imdct256: &mut IMDCTContext, tmp: &mut IMDCTWorkspace, delay: &mut [f32; BLOCK_LEN], dst: &mut [f32]) {
-        if !self.blksw {
-            imdct512.do_imdct(&self.mant, tmp);
-        } else {
-            imdct256.do_imdct_ileave(&self.mant, tmp);
-        }
-        overlap(delay, &tmp.out, dst);
-    }
-}
-
-fn logadd(acc: i32, add: i32) -> i32 {
-    let c = acc - add;
-    let addr = (c.abs() >> 1).min(255);
-    if c >= 0 {
-        acc + (TS102366_LATAB[addr as usize] as i32)
-    } else {
-        add + (TS102366_LATAB[addr as usize] as i32)
-    }
-}
-
-fn calc_lowcomp(a: i32, b0: i32, b1: i32, band: usize) -> i32 {
-    if band < 7 {
-        if (b0 + 256) == b1 {
-            384
-        } else if b0 > b1 {
-            0.max(a - 64)
-        } else {
-            a
-        }
-    } else if band < 20 {
-        if (b0 + 256) == b1 {
-            320
-        } else if b0 > b1 {
-            0.max(a - 64)
-        } else {
-            a
-        }
-    } else {
-        0.max(a - 128)
-    }
-}
-
-fn overlap(delay: &mut [f32; BLOCK_LEN], src: &[f32; BLOCK_LEN * 2], out: &mut [f32]) {
-    {
-        let dly = &delay;
-        for ((d, s), o) in dly.into_iter().zip(src.into_iter()).zip(out.iter_mut()) {
-            *o = (*d + *s) * 2.0;
-        }
-    }
-    delay.copy_from_slice(&src[BLOCK_LEN..]);
-}
-
-#[derive(Clone)]
-struct AudioBlock {
-    dynrng:     Option<u8>,
-    dynrng2:    Option<u8>,
-
-    cplstre:    bool,
-    cplinu:     bool,
-    phsflginu:  bool,
-    cplbegf:    usize,
-    cplendf:    usize,
-    ncplsubnd:  usize,
-    ncplbnd:    usize,
-    cplbndstrc: [bool; MAX_CPLBANDS],
-
-    phsflg:     [bool; MAX_CPLBANDS],
-    rematstr:   bool,
-    rematflg:   [bool; 4],
-
-    chdata:     [ChannelData; MAX_CHANNELS + 2],
-
-    baie:       bool,
-    fdcycod:    usize,
-    sdcycod:    usize,
-    sgaincod:   usize,
-    dbpbcod:    usize,
-    floorcod:   usize,
-    snroffste:  bool,
-    csnroffst:  u8,
-    cplleake:   bool,
-    cplfleak:   u8,
-    cplsleak:   u8,
-
-    deltbaie:   bool,
-
-    bap_buf:        [[i32; 2]; 3],
-    bap_buf_fill:   [usize; 3],
-}
-
-impl AudioBlock {
-    fn new() -> Self {
-        AudioBlock {
-            chdata:     [ChannelData::new(); MAX_CHANNELS + 2],
-
-            dynrng:     None,
-            dynrng2:    None,
-
-            cplstre:    false,
-            cplinu:     false,
-            phsflginu:  false,
-            cplbegf:    0,
-            cplendf:    0,
-            ncplsubnd:  0,
-            ncplbnd:    0,
-            cplbndstrc: [false; MAX_CPLBANDS],
-
-            phsflg:     [false; MAX_CPLBANDS],
-            rematstr:   false,
-            rematflg:   [false; 4],
-
-            baie:       false,
-            sdcycod:    0,
-            fdcycod:    0,
-            sgaincod:   0,
-            dbpbcod:    0,
-            floorcod:   0,
-            snroffste:  false,
-            csnroffst:  0,
-            cplleake:   false,
-            cplfleak:   0,
-            cplsleak:   0,
-
-            deltbaie:   false,
-
-            bap_buf:        [[0; 2]; 3],
-            bap_buf_fill:   [0; 3],
-        }
-    }
-    fn read(&mut self, br: &mut BitReader, bsi: &BSI, fscod: usize, blk_no: usize) -> DecoderResult<bool> {
-        let channels = bsi.acmod.get_num_channels();
-        let is_stereo = bsi.acmod == ACMode::Stereo;
-        
-        for ch in 0..channels {
-            self.chdata[ch].blksw                   = br.read_bool()?;
-        }
-        // dynamic range information
-        for ch in 0..channels {
-            self.chdata[ch].dithflag                = br.read_bool()?;
-        }
-        self.dynrng                                 = br.read_optional8()?;
-        if bsi.acmod == ACMode::DualMono {
-            self.dynrng2                            = br.read_optional8()?;
-        }
-        // coupling strategy information
-        self.cplstre                                = br.read_bool()?;
-        validate!((blk_no != 0) || self.cplstre);
-        if self.cplstre {
-            self.cplinu                             = br.read_bool()?;
-            if self.cplinu {
-                for ch in 0..channels {
-                    self.chdata[ch].chincpl         = br.read_bool()?;
-                }
-                if is_stereo {
-                    self.phsflginu                  = br.read_bool()?;
-                }
-                self.cplbegf                        = br.read(4)? as usize;
-                self.cplendf                        = (br.read(4)? as usize) + 3;
-                validate!(self.cplendf >= self.cplbegf);
-                self.ncplsubnd = self.cplendf - self.cplbegf;
-                self.ncplbnd = self.ncplsubnd;
-                self.chdata[CPL_CHANNEL].startmant = self.cplbegf * 12 + 37;
-                self.chdata[CPL_CHANNEL].endmant   = self.cplendf * 12 + 37;
-                for bnd in 1..self.ncplsubnd {
-                    self.cplbndstrc[bnd]            = br.read_bool()?;
-                    if self.cplbndstrc[bnd] {
-                        self.ncplbnd -= 1;
-                    }
-                }
-            }
-        }
-        // coupling coordinates
-        if self.cplinu {
-            for c in 0..channels {
-                let ch = &mut self.chdata[c];
-                if ch.chincpl {
-                    ch.cplcoe                       = br.read_bool()?;
-                    if ch.cplcoe {
-                        ch.mstrcplco                = br.read(2)? as u8;
-                        for bnd in 0..self.ncplbnd {
-                            ch.cplcoexp [bnd]       = br.read(4)? as u8;
-                            ch.cplcomant[bnd]       = br.read(4)? as u8;
-                        }
-                    }
-                }
-            }
-            if is_stereo && self.phsflginu && (self.chdata[0].cplcoe || self.chdata[1].cplcoe) {
-                for bnd in 0..self.ncplbnd {
-                    self.phsflg[bnd]                = br.read_bool()?;
-                }
-            }
-        }
-        // stereo rematrixing
-        if is_stereo {
-            self.rematstr                           = br.read_bool()?;
-            if self.rematstr {
-                if self.cplbegf > 2 || !self.cplinu {
-                    for rbnd in 0..4 {
-                        self.rematflg[rbnd]         = br.read_bool()?;
-                    }
-                }
-                if self.cplbegf > 0 && self.cplbegf <= 2 && self.cplinu {
-                    for rbnd in 0..3 {
-                        self.rematflg[rbnd]         = br.read_bool()?;
-                    }
-                }
-                if self.cplbegf == 0 && self.cplinu {
-                    for rbnd in 0..2 {
-                        self.rematflg[rbnd]         = br.read_bool()?;
-                    }
-                }
-            }
-        }
-        // exponent strategy
-        if self.cplinu {
-            self.chdata[CPL_CHANNEL].read_strategy(br, blk_no)?;
-        }
-        for ch in 0..channels {
-            self.chdata[ch].read_strategy(br, blk_no)?;
-        }
-        if bsi.lfeon {
-            self.chdata[LFE_CHANNEL].expstr         = br.read(1)? as u8;
-            validate!(blk_no != 0 || self.chdata[LFE_CHANNEL].expstr != STRATEGY_REUSE);
-            self.chdata[LFE_CHANNEL].groups = 2;
-            self.chdata[LFE_CHANNEL].startmant = 0;
-            self.chdata[LFE_CHANNEL].endmant = 7;
-        }
-        let cpl_startmant = self.chdata[CPL_CHANNEL].startmant;
-        for c in 0..channels {
-            let ch = &mut self.chdata[c];
-            if ch.expstr != STRATEGY_REUSE && !ch.chincpl {
-                ch.chbwcod                          = br.read(6)? as u8;
-            }
-            if !ch.chincpl {
-                ch.startmant = 0;
-                ch.endmant   = ((ch.chbwcod as usize) + 12) * 3 + 37;
-            } else {
-                ch.startmant = 0;
-                ch.endmant   = cpl_startmant;
-            }
-        }
-        // set number of mantissas
-        if self.cplinu {
-            self.chdata[CPL_CHANNEL].read_exps(br, true, false)?;
-        }
-        for ch in 0..channels {
-            self.chdata[ch].read_exps(br, false, false)?;
-        }
-        if bsi.lfeon {
-            self.chdata[LFE_CHANNEL].read_exps(br, false, true)?;
-        }
-        // bit allocation parameters
-        self.baie                                   = br.read_bool()?;
-        if self.baie {
-            self.sdcycod                            = br.read(2)? as usize;
-            self.fdcycod                            = br.read(2)? as usize;
-            self.sgaincod                           = br.read(2)? as usize;
-            self.dbpbcod                            = br.read(2)? as usize;
-            self.floorcod                           = br.read(3)? as usize;
-        }
-        self.snroffste                              = br.read_bool()?;
-        if self.snroffste {
-            self.csnroffst                          = br.read(6)? as u8;
-            if self.cplinu {
-                self.chdata[CPL_CHANNEL].read_snr(br)?;
-            }
-            for ch in 0..channels {
-                self.chdata[ch].read_snr(br)?;
-            }
-            if bsi.lfeon {
-                self.chdata[LFE_CHANNEL].read_snr(br)?;
-            }
-        }
-        if self.cplinu {
-            self.cplleake                           = br.read_bool()?;
-            if self.cplleake {
-                self.cplfleak                       = br.read(3)? as u8;
-                self.cplsleak                       = br.read(3)? as u8;
-            }
-        }
-        // delta bit allocation information
-        self.deltbaie                               = br.read_bool()?;
-        if self.deltbaie {
-            if self.cplinu {
-                self.chdata[CPL_CHANNEL].deltbae    = br.read(2)? as u8;
-                validate!(blk_no != 0 || self.chdata[CPL_CHANNEL].deltbae != 0);
-                validate!(self.chdata[CPL_CHANNEL].deltbae != 3);
-            }
-            for ch in 0..channels {
-                self.chdata[ch].deltbae             = br.read(2)? as u8;
-                validate!(blk_no != 0 || self.chdata[ch].deltbae != 0);
-                validate!(self.chdata[ch].deltbae != 3);
-            }
-            if self.cplinu {
-                self.chdata[CPL_CHANNEL].read_deltbai(br)?;
-            }
-            for ch in 0..channels {
-                self.chdata[ch].read_deltbai(br)?;
-            }
-        }
-        // dummy data
-        if br.read_bool()? {
-            let skipl                               = br.read(9)?;
-            br.skip(skipl * 8)?;
-        }
-
-        let all_zero = self.calc_bitalloc(bsi, channels, fscod);
-        if all_zero { return Ok(true); }
-
-        // quantised mantissa values
-        let mut got_cplchan = false;
-        for i in 0..self.bap_buf_fill.len() { self.bap_buf_fill[i] = 0; }
-        for c in 0..channels {
-            {
-                let ch = &mut self.chdata[c];
-                ch.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
-            }
-            if self.cplinu && self.chdata[c].chincpl && !got_cplchan {
-                let cplch = &mut self.chdata[CPL_CHANNEL];
-                cplch.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
-                got_cplchan = true;
-            }
-        }
-        if bsi.lfeon {
-            let lfech = &mut self.chdata[LFE_CHANNEL];
-            lfech.read_mant(br, &mut self.bap_buf, &mut self.bap_buf_fill)?;
-        }
-        Ok(false)
-    }
-    fn calc_bitalloc(&mut self, bsi: &BSI, channels: usize, fscod: usize) -> bool {
-        let sdecay1 = TS102366_SLOW_DECAY[self.sdcycod];
-        let fdecay1 = TS102366_FAST_DECAY[self.fdcycod];
-
-        let sdecay  = sdecay1 >> bsi.shift;
-        let fdecay  = fdecay1 >> bsi.shift;
-        let sgain   = TS102366_SLOW_GAIN[self.sgaincod];
-        let dbknee  = TS102366_DBP_TAB[self.dbpbcod];
-        let floor   = TS102366_FLOOR_TAB[self.floorcod];
-
-        let mut all_zero = self.csnroffst == 0;
-        if !all_zero && self.chdata[LFE_CHANNEL].fsnroffst == 0 {
-            for ch in 0..channels {
-                if self.chdata[ch].fsnroffst != 0 {
-                    all_zero = false;
-                    break;
-                }
-            }
-        }
-        if all_zero { return true; }
-
-        let mut mask: [i32; MAX_BANDS] = [0; MAX_BANDS];
-
-        if self.cplinu {
-            self.chdata[CPL_CHANNEL].compute_bndpsd();
-            self.chdata[CPL_CHANNEL].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee,
-                                                  ((self.cplfleak as u16) << 8) + 768, ((self.cplsleak as u16) << 8) + 768, bsi.shift);
-            self.chdata[CPL_CHANNEL].apply_delta_info(&mut mask);
-            self.chdata[CPL_CHANNEL].calc_snr_offset(self.csnroffst);
-            self.chdata[CPL_CHANNEL].compute_bap(&mut mask, floor);
-        }
-        for ch in 0..channels {
-            self.chdata[ch].compute_bndpsd();
-            self.chdata[ch].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee, 0, 0, bsi.shift);
-            self.chdata[ch].apply_delta_info(&mut mask);
-            self.chdata[ch].calc_snr_offset(self.csnroffst);
-            self.chdata[ch].compute_bap(&mut mask, floor);
-        }
-        if bsi.lfeon {
-            self.chdata[LFE_CHANNEL].compute_bndpsd();
-            self.chdata[LFE_CHANNEL].compute_mask(&mut mask, fscod, sgain, fdecay, sdecay, dbknee,
-                                                  0, 0, bsi.shift);
-            self.chdata[LFE_CHANNEL].calc_snr_offset(self.csnroffst);
-            self.chdata[LFE_CHANNEL].compute_bap(&mut mask, floor);
-        }
-
-        false
-    }
-    fn couple_channels(&mut self, acmod: ACMode) {
-        if !self.cplinu { return; }
-        for ch in 0..acmod.get_num_channels() {
-            if !self.chdata[ch].chincpl { continue; }
-            let mut pband = 0;
-            for band in self.cplbegf..self.cplendf {
-                let cband = band - self.cplbegf;
-                let comant = self.chdata[ch].cplcomant[cband];
-                let mut cotemp = (if self.chdata[ch].cplcoexp[cband] == 15 { comant << 1 } else { comant + 16 }) as i32;
-                if (acmod == ACMode::Stereo) && (ch == 1) && self.phsflginu && self.phsflg[pband] {
-                    cotemp = -cotemp;
-                }
-                if !self.cplbndstrc[cband] {
-                    pband += 1;
-                }
-                let exp = self.chdata[ch].cplcoexp[cband] + 3 * self.chdata[ch].mstrcplco + 5 - 3;
-                let start = band * 12 + 37;
-                for bin in 0..12 {
-                    self.chdata[ch].mant[start + bin] = self.chdata[CPL_CHANNEL].mant[start + bin] * cotemp >> exp;
-                }
-//todo dither
-            }
-        }
-    }
-    fn synth_audio_block(&mut self, imdct512: &mut IMDCTContext, imdct256: &mut IMDCTContext, tmp: &mut IMDCTWorkspace, channel: usize, delay: &mut [f32; BLOCK_LEN], dst: &mut [f32]) {
-        self.chdata[channel].synth(imdct512, imdct256, tmp, delay, dst);
-    }
-}
-
-impl NADecoder for AudioDecoder {
-    fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
-        if let NACodecTypeInfo::Audio(_) = info.get_properties() {
-            self.info = info.clone();
-            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 mut br;
-        if (pktbuf[0] == MAGIC_BYTE0) && (pktbuf[1] == MAGIC_BYTE1) {
-            br = BitReader::new(pktbuf.as_slice(), pktbuf.len(), BitReaderMode::BE);
-        } else if (pktbuf[0] == MAGIC_BYTE1) && (pktbuf[1] == MAGIC_BYTE0) {
-            br = BitReader::new(pktbuf.as_slice(), pktbuf.len(), BitReaderMode::LE16MSB);
-        } else {
-            return Err(DecoderError::InvalidData);
-        }
-
-        let sinfo = Syncinfo::read(&mut br)?;
-        validate!(sinfo.is_valid());
-
-        let bsi = BSI::read(&mut br)?;
-        if bsi.has_addb {
-            let len                 = br.read(6)? as u32;
-            br.skip((len + 1) * 8)?;
-        }
-
-        let duration = BLOCK_LEN * NBLOCKS;
-
-        let core_channels = bsi.acmod.get_num_channels();
-        let channels = core_channels + if bsi.lfeon { 1 } else { 0 };
-
-        let ainfo = NAAudioInfo::new(sinfo.samplerate >> bsi.shift, channels as u8,
-                                     SND_F32P_FORMAT, BLOCK_LEN);
-
-        let mut abuf = alloc_audio_buffer(ainfo, duration, bsi.acmod.get_channel_map(bsi.lfeon))?;
-        let mut adata = abuf.get_abuf_f32().unwrap();
-        let mut output = adata.get_data_mut();
-
-        self.ablk = AudioBlock::new();
-        for blk in 0..NBLOCKS {
-            let all_zero = self.ablk.read(&mut br, &bsi, sinfo.fscod as usize, blk)?;
-            let off = blk * BLOCK_LEN;
-            self.ablk.couple_channels(bsi.acmod);
-            for ch in 0..core_channels {
-                let dpos = abuf.get_offset(ch) + off;
-                let dst = &mut output[dpos..][..BLOCK_LEN];
-                if !all_zero {
-                    self.ablk.synth_audio_block(&mut self.imdct512, &mut self.imdct256, &mut self.tmp, ch, &mut self.delay[ch], dst);
-                } else {
-                    self.delay[ch] = [0.0; BLOCK_LEN];
-                    for i in 0..BLOCK_LEN { dst[i] = 0.0; }
-                }
-            }
-            if bsi.lfeon {
-                let dpos = abuf.get_offset(core_channels) + off;
-                let dst = &mut output[dpos..][..BLOCK_LEN];
-                if !all_zero {
-                    self.ablk.synth_audio_block(&mut self.imdct512, &mut self.imdct256, &mut self.tmp, LFE_CHANNEL, &mut self.delay[LFE_CHANNEL], dst);
-                } else {
-                    self.delay[LFE_CHANNEL] = [0.0; BLOCK_LEN];
-                    for i in 0..BLOCK_LEN { dst[i] = 0.0; }
-                }
-            }
-        }
-//todo skip auxdata
-//todo do errorcheck
-
-        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(AudioDecoder::new())
-}
-
-#[cfg(test)]
-mod test {
-    use test::dec_video::*;
-    #[test]
-    fn test_ts102366() {
-        let file = "assets/RV/sp_sample1.rm";
-        test_decode_audio("realmedia", file, Some(12000), "ac3");
-    }
-}
-
-const TS102366_SLOW_DECAY: [u8; 4] = [ 0x0F, 0x11, 0x13, 0x15 ];
-const TS102366_FAST_DECAY: [u8; 4] = [ 0x3F, 0x53, 0x67, 0x7B ];
-const TS102366_SLOW_GAIN: [u16; 4] = [ 0x540, 0x4D8, 0x478, 0x410 ];
-const TS102366_FAST_GAIN: [u16; 8] = [ 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 ];
-const TS102366_DBP_TAB:   [u16; 4] = [ 0x000, 0x700, 0x900, 0xB00 ];
-const TS102366_FLOOR_TAB: [u16; 8] = [ 0x02F0, 0x02B0, 0x0270, 0x0230, 0x01F0, 0x0170, 0x00F0, 0xF800 ];
-
-const TS102366_BIN_TO_BAND: [u8; 256] = [
-     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
-    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
-    20, 21, 22, 23, 24, 25, 26, 27, 28, 28,
-    28, 29, 29, 29, 30, 30, 30, 31, 31, 31,
-    32, 32, 32, 33, 33, 33, 34, 34, 34, 35,
-    35, 35, 35, 35, 35, 36, 36, 36, 36, 36,
-    36, 37, 37, 37, 37, 37, 37, 38, 38, 38,
-    38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
-    40, 40, 40, 40, 40, 41, 41, 41, 41, 41,
-    41, 41, 41, 41, 41, 41, 41, 42, 42, 42,
-    42, 42, 42, 42, 42, 42, 42, 42, 42, 43,
-    43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
-    43, 44, 44, 44, 44, 44, 44, 44, 44, 44,
-    44, 44, 44, 45, 45, 45, 45, 45, 45, 45,
-    45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-    45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
-    46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
-    46, 47, 47, 47, 47, 47, 47, 47, 47, 47,
-    47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
-    47, 47, 47, 47, 47, 48, 48, 48, 48, 48,
-    48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
-    48, 48, 48, 48, 48, 48, 48, 48, 48, 49,
-    49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-    49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
-    49, 49, 49, 0, 0, 0
-];
-const TS102366_BAND_SIZE: [u8; MAX_BANDS] = [
-    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  1,  1,  1,  1,  3,  3,
-    3,  3,  3,  3,  3,  6,  6,  6,  6,  6,
-    6, 12, 12, 12, 12, 24, 24, 24, 24, 24
-];
-const TS102366_BAND_START: [u8; MAX_BANDS] = [
-     0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
-    10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
-    20,  21,  22,  23,  24,  25,  26,  27,  28,  31,
-    34,  37,  40,  43,  46,  49,  55,  61,  67,  73,
-    79,  85,  97, 109, 121, 133, 157, 181, 205, 229
-];
-
-const TS102366_LATAB: [u16; 256] = [
-    0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
-    0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
-    0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
-    0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
-    0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
-    0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
-    0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
-    0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
-    0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
-    0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
-    0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
-    0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
-    0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
-    0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
-    0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
-    0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
-    0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
-    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
-    0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
-    0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
-    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
-    0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
-    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
-    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
-    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
-    0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-];
-const TS102366_HTH: [[u16; MAX_BANDS]; 3] = [
-  [
-    0x04D0, 0x04D0, 0x0440, 0x0400, 0x03E0, 0x03C0, 0x03B0, 0x03B0, 0x03A0, 0x03A0,
-    0x03A0, 0x03A0, 0x03A0, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0370, 0x0370,
-    0x0360, 0x0360, 0x0350, 0x0350, 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300,
-    0x02F0, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03E0, 0x0420,
-    0x0460, 0x0490, 0x04A0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800, 0x0840, 0x0840,
-  ], [
-    0x04F0, 0x04F0, 0x0460, 0x0410, 0x03E0, 0x03D0, 0x03C0, 0x03B0, 0x03B0, 0x03A0,
-    0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0380,
-    0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310,
-    0x0300, 0x02F0, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03E0,
-    0x0420, 0x0450, 0x04A0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630, 0x0840, 0x0840,
-  ], [
-    0x0580, 0x0580, 0x04B0, 0x0450, 0x0420, 0x03F0, 0x03E0, 0x03D0, 0x03C0, 0x03B0,
-    0x03B0, 0x03B0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0, 0x03A0,
-    0x0390, 0x0390, 0x0390, 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350,
-    0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02F0, 0x02F0, 0x02F0, 0x0300, 0x0310,
-    0x0330, 0x0350, 0x03C0, 0x0410, 0x0470, 0x04A0, 0x0460, 0x0440, 0x0450, 0x04E0,
-  ]
-];
-const TS102366_BAPTAB: [u8; 64] = [
-     0,  1,  1,  1,  1,  1,  2,  2,  3,  3,  3,  4,  4,  5,  5,  6,
-     6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,  9,  9,  9,  9, 10,
-    10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
-    14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15
-];
-
-const TS102366_QUANT3_MAP: [[i32; 3]; 27] = [
- [ -0x0AAAAAA, -0x0AAAAAA, -0x0AAAAAA ],
- [ -0x0AAAAAA, -0x0AAAAAA, 0x00000000 ],
- [ -0x0AAAAAA, -0x0AAAAAA, 0x00AAAAAA ],
- [ -0x0AAAAAA, 0x00000000, -0x0AAAAAA ],
- [ -0x0AAAAAA, 0x00000000, 0x00000000 ],
- [ -0x0AAAAAA, 0x00000000, 0x00AAAAAA ],
- [ -0x0AAAAAA, 0x00AAAAAA, -0x0AAAAAA ],
- [ -0x0AAAAAA, 0x00AAAAAA, 0x00000000 ],
- [ -0x0AAAAAA, 0x00AAAAAA, 0x00AAAAAA ],
- [ 0x00000000, -0x0AAAAAA, -0x0AAAAAA ],
- [ 0x00000000, -0x0AAAAAA, 0x00000000 ],
- [ 0x00000000, -0x0AAAAAA, 0x00AAAAAA ],
- [ 0x00000000, 0x00000000, -0x0AAAAAA ],
- [ 0x00000000, 0x00000000, 0x00000000 ],
- [ 0x00000000, 0x00000000, 0x00AAAAAA ],
- [ 0x00000000, 0x00AAAAAA, -0x0AAAAAA ],
- [ 0x00000000, 0x00AAAAAA, 0x00000000 ],
- [ 0x00000000, 0x00AAAAAA, 0x00AAAAAA ],
- [ 0x00AAAAAA, -0x0AAAAAA, -0x0AAAAAA ],
- [ 0x00AAAAAA, -0x0AAAAAA, 0x00000000 ],
- [ 0x00AAAAAA, -0x0AAAAAA, 0x00AAAAAA ],
- [ 0x00AAAAAA, 0x00000000, -0x0AAAAAA ],
- [ 0x00AAAAAA, 0x00000000, 0x00000000 ],
- [ 0x00AAAAAA, 0x00000000, 0x00AAAAAA ],
- [ 0x00AAAAAA, 0x00AAAAAA, -0x0AAAAAA ],
- [ 0x00AAAAAA, 0x00AAAAAA, 0x00000000 ],
- [ 0x00AAAAAA, 0x00AAAAAA, 0x00AAAAAA ]
-];
-const TS102366_QUANT5_MAP: [[i32; 3]; 125] = [
- [ -0x0CCCCCC, -0x0CCCCCC, -0x0CCCCCC ], [ -0x0CCCCCC, -0x0CCCCCC, -0x0666666 ], [ -0x0CCCCCC, -0x0CCCCCC, 0x00000000 ],
-                                         [ -0x0CCCCCC, -0x0CCCCCC, 0x00666666 ], [ -0x0CCCCCC, -0x0CCCCCC, 0x00CCCCCC ],
- [ -0x0CCCCCC, -0x0666666, -0x0CCCCCC ], [ -0x0CCCCCC, -0x0666666, -0x0666666 ], [ -0x0CCCCCC, -0x0666666, 0x00000000 ],
-                                         [ -0x0CCCCCC, -0x0666666, 0x00666666 ], [ -0x0CCCCCC, -0x0666666, 0x00CCCCCC ],
- [ -0x0CCCCCC, 0x00000000, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00000000, -0x0666666 ], [ -0x0CCCCCC, 0x00000000, 0x00000000 ],
-                                         [ -0x0CCCCCC, 0x00000000, 0x00666666 ], [ -0x0CCCCCC, 0x00000000, 0x00CCCCCC ],
- [ -0x0CCCCCC, 0x00666666, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00666666, -0x0666666 ], [ -0x0CCCCCC, 0x00666666, 0x00000000 ],
-                                         [ -0x0CCCCCC, 0x00666666, 0x00666666 ], [ -0x0CCCCCC, 0x00666666, 0x00CCCCCC ],
- [ -0x0CCCCCC, 0x00CCCCCC, -0x0CCCCCC ], [ -0x0CCCCCC, 0x00CCCCCC, -0x0666666 ], [ -0x0CCCCCC, 0x00CCCCCC, 0x00000000 ],
-                                         [ -0x0CCCCCC, 0x00CCCCCC, 0x00666666 ], [ -0x0CCCCCC, 0x00CCCCCC, 0x00CCCCCC ],
- [ -0x0666666, -0x0CCCCCC, -0x0CCCCCC ], [ -0x0666666, -0x0CCCCCC, -0x0666666 ], [ -0x0666666, -0x0CCCCCC, 0x00000000 ],
-                                         [ -0x0666666, -0x0CCCCCC, 0x00666666 ], [ -0x0666666, -0x0CCCCCC, 0x00CCCCCC ],
- [ -0x0666666, -0x0666666, -0x0CCCCCC ], [ -0x0666666, -0x0666666, -0x0666666 ], [ -0x0666666, -0x0666666, 0x00000000 ],
-                                         [ -0x0666666, -0x0666666, 0x00666666 ], [ -0x0666666, -0x0666666, 0x00CCCCCC ],
- [ -0x0666666, 0x00000000, -0x0CCCCCC ], [ -0x0666666, 0x00000000, -0x0666666 ], [ -0x0666666, 0x00000000, 0x00000000 ],
-                                         [ -0x0666666, 0x00000000, 0x00666666 ], [ -0x0666666, 0x00000000, 0x00CCCCCC ],
- [ -0x0666666, 0x00666666, -0x0CCCCCC ], [ -0x0666666, 0x00666666, -0x0666666 ], [ -0x0666666, 0x00666666, 0x00000000 ],
-                                         [ -0x0666666, 0x00666666, 0x00666666 ], [ -0x0666666, 0x00666666, 0x00CCCCCC ],
- [ -0x0666666, 0x00CCCCCC, -0x0CCCCCC ], [ -0x0666666, 0x00CCCCCC, -0x0666666 ], [ -0x0666666, 0x00CCCCCC, 0x00000000 ],
-                                         [ -0x0666666, 0x00CCCCCC, 0x00666666 ], [ -0x0666666, 0x00CCCCCC, 0x00CCCCCC ],
- [ 0x00000000, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00000000, -0x0CCCCCC, -0x0666666 ], [ 0x00000000, -0x0CCCCCC, 0x00000000 ],
-                                         [ 0x00000000, -0x0CCCCCC, 0x00666666 ], [ 0x00000000, -0x0CCCCCC, 0x00CCCCCC ],
- [ 0x00000000, -0x0666666, -0x0CCCCCC ], [ 0x00000000, -0x0666666, -0x0666666 ], [ 0x00000000, -0x0666666, 0x00000000 ],
-                                         [ 0x00000000, -0x0666666, 0x00666666 ], [ 0x00000000, -0x0666666, 0x00CCCCCC ],
- [ 0x00000000, 0x00000000, -0x0CCCCCC ], [ 0x00000000, 0x00000000, -0x0666666 ], [ 0x00000000, 0x00000000, 0x00000000 ],
-                                         [ 0x00000000, 0x00000000, 0x00666666 ], [ 0x00000000, 0x00000000, 0x00CCCCCC ],
- [ 0x00000000, 0x00666666, -0x0CCCCCC ], [ 0x00000000, 0x00666666, -0x0666666 ], [ 0x00000000, 0x00666666, 0x00000000 ],
-                                         [ 0x00000000, 0x00666666, 0x00666666 ], [ 0x00000000, 0x00666666, 0x00CCCCCC ],
- [ 0x00000000, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00000000, 0x00CCCCCC, -0x0666666 ], [ 0x00000000, 0x00CCCCCC, 0x00000000 ],
-                                         [ 0x00000000, 0x00CCCCCC, 0x00666666 ], [ 0x00000000, 0x00CCCCCC, 0x00CCCCCC ],
- [ 0x00666666, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00666666, -0x0CCCCCC, -0x0666666 ], [ 0x00666666, -0x0CCCCCC, 0x00000000 ],
-                                         [ 0x00666666, -0x0CCCCCC, 0x00666666 ], [ 0x00666666, -0x0CCCCCC, 0x00CCCCCC ],
- [ 0x00666666, -0x0666666, -0x0CCCCCC ], [ 0x00666666, -0x0666666, -0x0666666 ], [ 0x00666666, -0x0666666, 0x00000000 ],
-                                         [ 0x00666666, -0x0666666, 0x00666666 ], [ 0x00666666, -0x0666666, 0x00CCCCCC ],
- [ 0x00666666, 0x00000000, -0x0CCCCCC ], [ 0x00666666, 0x00000000, -0x0666666 ], [ 0x00666666, 0x00000000, 0x00000000 ],
-                                         [ 0x00666666, 0x00000000, 0x00666666 ], [ 0x00666666, 0x00000000, 0x00CCCCCC ],
- [ 0x00666666, 0x00666666, -0x0CCCCCC ], [ 0x00666666, 0x00666666, -0x0666666 ], [ 0x00666666, 0x00666666, 0x00000000 ],
-                                         [ 0x00666666, 0x00666666, 0x00666666 ], [ 0x00666666, 0x00666666, 0x00CCCCCC ],
- [ 0x00666666, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00666666, 0x00CCCCCC, -0x0666666 ], [ 0x00666666, 0x00CCCCCC, 0x00000000 ],
-                                         [ 0x00666666, 0x00CCCCCC, 0x00666666 ], [ 0x00666666, 0x00CCCCCC, 0x00CCCCCC ],
- [ 0x00CCCCCC, -0x0CCCCCC, -0x0CCCCCC ], [ 0x00CCCCCC, -0x0CCCCCC, -0x0666666 ], [ 0x00CCCCCC, -0x0CCCCCC, 0x00000000 ],
-                                         [ 0x00CCCCCC, -0x0CCCCCC, 0x00666666 ], [ 0x00CCCCCC, -0x0CCCCCC, 0x00CCCCCC ],
- [ 0x00CCCCCC, -0x0666666, -0x0CCCCCC ], [ 0x00CCCCCC, -0x0666666, -0x0666666 ], [ 0x00CCCCCC, -0x0666666, 0x00000000 ],
-                                         [ 0x00CCCCCC, -0x0666666, 0x00666666 ], [ 0x00CCCCCC, -0x0666666, 0x00CCCCCC ],
- [ 0x00CCCCCC, 0x00000000, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00000000, -0x0666666 ], [ 0x00CCCCCC, 0x00000000, 0x00000000 ],
-                                         [ 0x00CCCCCC, 0x00000000, 0x00666666 ], [ 0x00CCCCCC, 0x00000000, 0x00CCCCCC ],
- [ 0x00CCCCCC, 0x00666666, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00666666, -0x0666666 ], [ 0x00CCCCCC, 0x00666666, 0x00000000 ],
-                                         [ 0x00CCCCCC, 0x00666666, 0x00666666 ], [ 0x00CCCCCC, 0x00666666, 0x00CCCCCC ],
- [ 0x00CCCCCC, 0x00CCCCCC, -0x0CCCCCC ], [ 0x00CCCCCC, 0x00CCCCCC, -0x0666666 ], [ 0x00CCCCCC, 0x00CCCCCC, 0x00000000 ],
-                                         [ 0x00CCCCCC, 0x00CCCCCC, 0x00666666 ], [ 0x00CCCCCC, 0x00CCCCCC, 0x00CCCCCC ],
-];
-const TS102366_QUANT7_MAP: [i32; 7] = [
-    -0xDB6DB6, -0x924924, -0x492492, 0x000000, 0x492492, 0x924924, 0xDB6DB6
-];
-const TS102366_QUANT11_MAP: [[i32; 2]; 121] = [
- [ -0x0E8BA2E, -0x0E8BA2E ], [ -0x0E8BA2E, -0x0BA2E8B ], [ -0x0E8BA2E, -0x08BA2E8 ],
- [ -0x0E8BA2E, -0x05D1745 ], [ -0x0E8BA2E, -0x02E8BA2 ], [ -0x0E8BA2E, 0x00000000 ],
- [ -0x0E8BA2E, 0x002E8BA2 ], [ -0x0E8BA2E, 0x005D1745 ], [ -0x0E8BA2E, 0x008BA2E8 ],
- [ -0x0E8BA2E, 0x00BA2E8B ], [ -0x0E8BA2E, 0x00E8BA2E ], [ -0x0BA2E8B, -0x0E8BA2E ],
- [ -0x0BA2E8B, -0x0BA2E8B ], [ -0x0BA2E8B, -0x08BA2E8 ], [ -0x0BA2E8B, -0x05D1745 ],
- [ -0x0BA2E8B, -0x02E8BA2 ], [ -0x0BA2E8B, 0x00000000 ], [ -0x0BA2E8B, 0x002E8BA2 ],
- [ -0x0BA2E8B, 0x005D1745 ], [ -0x0BA2E8B, 0x008BA2E8 ], [ -0x0BA2E8B, 0x00BA2E8B ],
- [ -0x0BA2E8B, 0x00E8BA2E ], [ -0x08BA2E8, -0x0E8BA2E ], [ -0x08BA2E8, -0x0BA2E8B ],
- [ -0x08BA2E8, -0x08BA2E8 ], [ -0x08BA2E8, -0x05D1745 ], [ -0x08BA2E8, -0x02E8BA2 ],
- [ -0x08BA2E8, 0x00000000 ], [ -0x08BA2E8, 0x002E8BA2 ], [ -0x08BA2E8, 0x005D1745 ],
- [ -0x08BA2E8, 0x008BA2E8 ], [ -0x08BA2E8, 0x00BA2E8B ], [ -0x08BA2E8, 0x00E8BA2E ],
- [ -0x05D1745, -0x0E8BA2E ], [ -0x05D1745, -0x0BA2E8B ], [ -0x05D1745, -0x08BA2E8 ],
- [ -0x05D1745, -0x05D1745 ], [ -0x05D1745, -0x02E8BA2 ], [ -0x05D1745, 0x00000000 ],
- [ -0x05D1745, 0x002E8BA2 ], [ -0x05D1745, 0x005D1745 ], [ -0x05D1745, 0x008BA2E8 ],
- [ -0x05D1745, 0x00BA2E8B ], [ -0x05D1745, 0x00E8BA2E ], [ -0x02E8BA2, -0x0E8BA2E ],
- [ -0x02E8BA2, -0x0BA2E8B ], [ -0x02E8BA2, -0x08BA2E8 ], [ -0x02E8BA2, -0x05D1745 ],
- [ -0x02E8BA2, -0x02E8BA2 ], [ -0x02E8BA2, 0x00000000 ], [ -0x02E8BA2, 0x002E8BA2 ],
- [ -0x02E8BA2, 0x005D1745 ], [ -0x02E8BA2, 0x008BA2E8 ], [ -0x02E8BA2, 0x00BA2E8B ],
- [ -0x02E8BA2, 0x00E8BA2E ], [ 0x00000000, -0x0E8BA2E ], [ 0x00000000, -0x0BA2E8B ],
- [ 0x00000000, -0x08BA2E8 ], [ 0x00000000, -0x05D1745 ], [ 0x00000000, -0x02E8BA2 ],
- [ 0x00000000, 0x00000000 ], [ 0x00000000, 0x002E8BA2 ], [ 0x00000000, 0x005D1745 ],
- [ 0x00000000, 0x008BA2E8 ], [ 0x00000000, 0x00BA2E8B ], [ 0x00000000, 0x00E8BA2E ],
- [ 0x002E8BA2, -0x0E8BA2E ], [ 0x002E8BA2, -0x0BA2E8B ], [ 0x002E8BA2, -0x08BA2E8 ],
- [ 0x002E8BA2, -0x05D1745 ], [ 0x002E8BA2, -0x02E8BA2 ], [ 0x002E8BA2, 0x00000000 ],
- [ 0x002E8BA2, 0x002E8BA2 ], [ 0x002E8BA2, 0x005D1745 ], [ 0x002E8BA2, 0x008BA2E8 ],
- [ 0x002E8BA2, 0x00BA2E8B ], [ 0x002E8BA2, 0x00E8BA2E ], [ 0x005D1745, -0x0E8BA2E ],
- [ 0x005D1745, -0x0BA2E8B ], [ 0x005D1745, -0x08BA2E8 ], [ 0x005D1745, -0x05D1745 ],
- [ 0x005D1745, -0x02E8BA2 ], [ 0x005D1745, 0x00000000 ], [ 0x005D1745, 0x002E8BA2 ],
- [ 0x005D1745, 0x005D1745 ], [ 0x005D1745, 0x008BA2E8 ], [ 0x005D1745, 0x00BA2E8B ],
- [ 0x005D1745, 0x00E8BA2E ], [ 0x008BA2E8, -0x0E8BA2E ], [ 0x008BA2E8, -0x0BA2E8B ],
- [ 0x008BA2E8, -0x08BA2E8 ], [ 0x008BA2E8, -0x05D1745 ], [ 0x008BA2E8, -0x02E8BA2 ],
- [ 0x008BA2E8, 0x00000000 ], [ 0x008BA2E8, 0x002E8BA2 ], [ 0x008BA2E8, 0x005D1745 ],
- [ 0x008BA2E8, 0x008BA2E8 ], [ 0x008BA2E8, 0x00BA2E8B ], [ 0x008BA2E8, 0x00E8BA2E ],
- [ 0x00BA2E8B, -0x0E8BA2E ], [ 0x00BA2E8B, -0x0BA2E8B ], [ 0x00BA2E8B, -0x08BA2E8 ],
- [ 0x00BA2E8B, -0x05D1745 ], [ 0x00BA2E8B, -0x02E8BA2 ], [ 0x00BA2E8B, 0x00000000 ],
- [ 0x00BA2E8B, 0x002E8BA2 ], [ 0x00BA2E8B, 0x005D1745 ], [ 0x00BA2E8B, 0x008BA2E8 ],
- [ 0x00BA2E8B, 0x00BA2E8B ], [ 0x00BA2E8B, 0x00E8BA2E ], [ 0x00E8BA2E, -0x0E8BA2E ],
- [ 0x00E8BA2E, -0x0BA2E8B ], [ 0x00E8BA2E, -0x08BA2E8 ], [ 0x00E8BA2E, -0x05D1745 ],
- [ 0x00E8BA2E, -0x02E8BA2 ], [ 0x00E8BA2E, 0x00000000 ], [ 0x00E8BA2E, 0x002E8BA2 ],
- [ 0x00E8BA2E, 0x005D1745 ], [ 0x00E8BA2E, 0x008BA2E8 ], [ 0x00E8BA2E, 0x00BA2E8B ],
- [ 0x00E8BA2E, 0x00E8BA2E ],
-];
-const TS102366_QUANT15_MAP: [i32; 15] = [
- -0x0EEEEEE, -0x0CCCCCC, -0x0AAAAAA, -0x0888888, -0x0666666, -0x0444444, -0x0222222, 0x00000000,
-             0x00222222, 0x00444444, 0x00666666, 0x00888888, 0x00AAAAAA, 0x00CCCCCC, 0x00EEEEEE,
-];
-const TS102366_BAP_BITS: [u8; 10] = [ 5, 6, 7, 8, 9, 10, 11, 12, 14, 16 ];
-
-const TS102366_WINDOW: [f32; 256] = [
-    0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
-    0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
-    0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
-    0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
-    0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
-    0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
-    0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
-    0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
-    0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
-    0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
-    0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
-    0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
-    0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
-    0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
-    0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
-    0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
-    0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
-    0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
-    0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
-    0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
-    0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
-    0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
-    0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
-    0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
-    0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
-    0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
-    0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
-    0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
-    0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
-    0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
-    0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
-    1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
-];