Implementation of Bit Reservoir for Layer III.

The implementation stores single bits as a word in the buffer. If a bit is set, the corresponding word in the buffer will be non-zero. If a bit is clear, the corresponding word is zero. Although this may seem waseful, this can be a factor of two quicker than packing 8 bits to a byte and extracting.

예제 #1
0
 /// <summary> Notify decoder that a seek is being made.
 /// </summary>
 public void seek_notify()
 {
     frame_start = 0;
     for (int ch = 0; ch < 2; ch++)
         for (int j = 0; j < 576; j++)
             prevblck[ch][j] = 0.0f;
     br = new BitReserve();
 }
예제 #2
0
        /// <summary> Constructor.
        /// </summary>
        // REVIEW: these constructor arguments should be moved to the
        // decodeFrame() method, where possible, so that one
        public LayerIIIDecoder(Bitstream stream0, Header header0, SynthesisFilter filtera, SynthesisFilter filterb, Obuffer buffer0, int which_ch0)
        {
            InitBlock();
            huffcodetab.inithuff();
            is_1d = new int[SBLIMIT * SSLIMIT + 4];
            ro = new float[2][][];
            for (int i = 0; i < 2; i++)
            {
                ro[i] = new float[SBLIMIT][];
                for (int i2 = 0; i2 < SBLIMIT; i2++)
                {
                    ro[i][i2] = new float[SSLIMIT];
                }
            }
            lr = new float[2][][];
            for (int i3 = 0; i3 < 2; i3++)
            {
                lr[i3] = new float[SBLIMIT][];
                for (int i4 = 0; i4 < SBLIMIT; i4++)
                {
                    lr[i3][i4] = new float[SSLIMIT];
                }
            }
            out_1d = new float[SBLIMIT * SSLIMIT];
            prevblck = new float[2][];
            for (int i5 = 0; i5 < 2; i5++)
            {
                prevblck[i5] = new float[SBLIMIT * SSLIMIT];
            }
            k = new float[2][];
            for (int i6 = 0; i6 < 2; i6++)
            {
                k[i6] = new float[SBLIMIT * SSLIMIT];
            }
            nonzero = new int[2];

            //III_scalefact_t
            III_scalefac_t = new temporaire2[2];
            III_scalefac_t[0] = new temporaire2();
            III_scalefac_t[1] = new temporaire2();
            scalefac = III_scalefac_t;
            // L3TABLE INIT

            sfBandIndex = new SBI[9]; // SZD: MPEG2.5 +3 indices
            int[] l0 = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576};
            int[] s0 = new int[]{0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192};
            int[] l1 = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 330, 394, 464, 540, 576};
            int[] s1 = new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192};
            int[] l2 = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576};
            int[] s2 = new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192};

            int[] l3 = new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 576};
            int[] s3 = new int[]{0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192};
            int[] l4 = new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 576};
            int[] s4 = new int[]{0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192};
            int[] l5 = new int[]{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576};
            int[] s5 = new int[]{0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192};
            // SZD: MPEG2.5
            int[] l6 = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576};
            int[] s6 = new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192};
            int[] l7 = new int[]{0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576};
            int[] s7 = new int[]{0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192};
            int[] l8 = new int[]{0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576};
            int[] s8 = new int[]{0, 8, 16, 24, 36, 52, 72, 96, 124, 160, 162, 164, 166, 192};

            sfBandIndex[0] = new SBI(l0, s0);
            sfBandIndex[1] = new SBI(l1, s1);
            sfBandIndex[2] = new SBI(l2, s2);

            sfBandIndex[3] = new SBI(l3, s3);
            sfBandIndex[4] = new SBI(l4, s4);
            sfBandIndex[5] = new SBI(l5, s5);
            //SZD: MPEG2.5
            sfBandIndex[6] = new SBI(l6, s6);
            sfBandIndex[7] = new SBI(l7, s7);
            sfBandIndex[8] = new SBI(l8, s8);
            // END OF L3TABLE INIT

            if (reorder_table == null)
            {
                // SZD: generate LUT
                reorder_table = new int[9][];
                for (int i = 0; i < 9; i++)
                    reorder_table[i] = reorder(sfBandIndex[i].s);
            }

            // Sftable
            int[] ll0 = new int[]{0, 6, 11, 16, 21};
            int[] ss0 = new int[]{0, 6, 12};
            sftable = new Sftable(this, ll0, ss0);
            // END OF Sftable

            // scalefac_buffer
            scalefac_buffer = new int[54];
            // END OF scalefac_buffer

            stream = stream0;
            header = header0;
            filter1 = filtera;
            filter2 = filterb;
            buffer = buffer0;
            which_channels = which_ch0;

            frame_start = 0;
            channels = (header.mode() == Header.SINGLE_CHANNEL)?1:2;
            max_gr = (header.version() == Header.MPEG1)?2:1;

            sfreq = header.sample_frequency() + ((header.version() == Header.MPEG1)?3:(header.version() == Header.MPEG25_LSF)?6:0); // SZD

            if (channels == 2)
            {
                switch (which_channels)
                {

                    case (int)OutputChannelsEnum.LEFT_CHANNEL:
                    case (int)OutputChannelsEnum.DOWNMIX_CHANNELS:
                        first_channel = last_channel = 0;
                        break;

                    case (int)OutputChannelsEnum.RIGHT_CHANNEL:
                        first_channel = last_channel = 1;
                        break;

                    case (int)OutputChannelsEnum.BOTH_CHANNELS:
                    default:
                        first_channel = 0;
                        last_channel = 1;
                        break;
                    }
            }
            else
            {
                first_channel = last_channel = 0;
            }

            for (int ch = 0; ch < 2; ch++)
                for (int j = 0; j < 576; j++)
                    prevblck[ch][j] = 0.0f;

            nonzero[0] = nonzero[1] = 576;

            br = new BitReserve();
            si = new III_side_info_t();
        }
예제 #3
0
        /// <summary> Do the huffman-decoding.
        /// note! for counta,countb -the 4 bit value is returned in y,
        /// discard x.
        /// </summary>
        public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br)
        {
            // array of all huffcodtable headers
            // 0..31 Huffman code table 0..31
            // 32,33 count1-tables

            int dmask = 1 << ((4 * 8) - 1);
            int hs = 4 * 8;
            int level;
            int point = 0;
            int error = 1;
            level = dmask;

            if (h.val == null)
                return 2;

            /* table 0 needs no bits */
            if (h.treelen == 0)
            {
                x[0] = y[0] = 0;
                return 0;
            }

            /* Lookup in Huffman table. */

            /*int bitsAvailable = 0;
            int bitIndex = 0;

            int bits[] = bitbuf;*/
            do
            {
                if (h.val[point][0] == 0)
                {
                    /*end of tree*/
                    x[0] = SupportClass.URShift(h.val[point][1], 4);
                    y[0] = h.val[point][1] & 0xf;
                    error = 0;
                    break;
                }

                // hget1bit() is called thousands of times, and so needs to be
                // ultra fast.
                /*
                if (bitIndex==bitsAvailable)
                {
                bitsAvailable = br.readBits(bits, 32);
                bitIndex = 0;
                }
                */
                //if (bits[bitIndex++]!=0)
                if (br.hget1bit() != 0)
                {
                    while (h.val[point][1] >= MXOFF)
                        point += h.val[point][1];
                    point += h.val[point][1];
                }
                else
                {
                    while (h.val[point][0] >= MXOFF)
                        point += h.val[point][0];
                    point += h.val[point][0];
                }
                level = SupportClass.URShift(level, 1);
                // MDM: ht[0] is always 0;
            }
            while ((level != 0) || (point < 0));

            // put back any bits not consumed
            /*
            int unread = (bitsAvailable-bitIndex);
            if (unread>0)
            br.rewindNbits(unread);
            */
            /* Process sign encodings for quadruples tables. */
            // System.out.println(h.tablename);
            if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3'))
            {
                v[0] = (y[0] >> 3) & 1;
                w[0] = (y[0] >> 2) & 1;
                x[0] = (y[0] >> 1) & 1;
                y[0] = y[0] & 1;

                /* v, w, x and y are reversed in the bitstream.
                switch them around to make test bistream work. */

                if (v[0] != 0)
                    if (br.hget1bit() != 0)
                        v[0] = - v[0];
                if (w[0] != 0)
                    if (br.hget1bit() != 0)
                        w[0] = - w[0];
                if (x[0] != 0)
                    if (br.hget1bit() != 0)
                        x[0] = - x[0];
                if (y[0] != 0)
                    if (br.hget1bit() != 0)
                        y[0] = - y[0];
            }
            else
            {
                // Process sign and escape encodings for dual tables.
                // x and y are reversed in the test bitstream.
                // Reverse x and y here to make test bitstream work.

                if (h.linbits != 0)
                    if ((h.xlen - 1) == x[0])
                        x[0] += br.hgetbits(h.linbits);
                if (x[0] != 0)
                    if (br.hget1bit() != 0)
                        x[0] = - x[0];
                if (h.linbits != 0)
                    if ((h.ylen - 1) == y[0])
                        y[0] += br.hgetbits(h.linbits);
                if (y[0] != 0)
                    if (br.hget1bit() != 0)
                        y[0] = - y[0];
            }
            return error;
        }