示例#1
0
        void ReadAllocation(IMpegFrame frame, int[] rateTable)
        {
            var _subBandCount = rateTable.Length;

            if (_jsbound > _subBandCount)
            {
                _jsbound = _subBandCount;
            }

            Array.Clear(_allocation[0], 0, SBLIMIT);
            Array.Clear(_allocation[1], 0, SBLIMIT);

            int sb = 0;

            for (; sb < _jsbound; sb++)
            {
                var table = _allocLookupTable[rateTable[sb]];
                var bits  = table[0];
                for (int ch = 0; ch < _channels; ch++)
                {
                    _allocation[ch][sb] = table[frame.ReadBits(bits) + 1];
                }
            }
            for (; sb < _subBandCount; sb++)
            {
                var table = _allocLookupTable[rateTable[sb]];
                _allocation[0][sb] = _allocation[1][sb] = table[frame.ReadBits(table[0]) + 1];
            }
        }
示例#2
0
        void ReadSamples(IMpegFrame frame)
        {
            // load in all the data for this frame (1152 samples in this case)
            // NB: we flatten these into output order
            for (int ss = 0, idx = 0; ss < SSLIMIT; ss++, idx += SBLIMIT * (_granuleCount - 1))
            {
                for (int sb = 0; sb < SBLIMIT; sb++, idx++)
                {
                    for (int ch = 0; ch < _channels; ch++)
                    {
                        if (ch == 0 || sb < _jsbound)
                        {
                            var alloc = _allocation[ch][sb];
                            if (alloc != 0)
                            {
                                if (alloc < 0)
                                {
                                    // grouping (Layer II only, so we don't have to play with the granule count)
                                    var val    = frame.ReadBits(-alloc);
                                    var levels = (1 << (-alloc / 2 + -alloc % 2 - 1)) + 1;

                                    _samples[ch][idx] = val % levels;
                                    val /= levels;
                                    _samples[ch][idx + SBLIMIT]     = val % levels;
                                    _samples[ch][idx + SBLIMIT * 2] = val / levels;
                                }
                                else
                                {
                                    // non-grouping
                                    for (int gr = 0; gr < _granuleCount; gr++)
                                    {
                                        _samples[ch][idx + SBLIMIT * gr] = frame.ReadBits(alloc);
                                    }
                                }
                            }
                            else
                            {
                                // no energy...  zero out the samples
                                for (int gr = 0; gr < _granuleCount; gr++)
                                {
                                    _samples[ch][idx + SBLIMIT * gr] = 0;
                                }
                            }
                        }
                        else
                        {
                            // copy chan 0 to chan 1
                            for (int gr = 0; gr < _granuleCount; gr++)
                            {
                                _samples[1][idx + SBLIMIT * gr] = _samples[0][idx + SBLIMIT * gr];
                            }
                        }
                    }
                }
            }
        }
        public void AddBits(IMpegFrame frame)
        {
            var slots = GetSlots(frame);
            while (--slots >= 0)
            {
                var temp = frame.ReadBits(8);
                if (temp == -1) throw new System.IO.InvalidDataException("Frame did not have enough bytes!");
                _buf[++_end] = (byte)temp;
                if (_end == _buf.Length - 1) _end = -1;
            }

            if (_bitsLeft == 0) _bitsLeft = 8;
        }
示例#4
0
        void ReadScaleFactors(IMpegFrame frame)
        {
            for (int sb = 0; sb < SBLIMIT; sb++)
            {
                for (int ch = 0; ch < _channels; ch++)
                {
                    switch (_scfsi[ch][sb])
                    {
                    case 0:
                        // all three
                        _scalefac[ch][0][sb] = frame.ReadBits(6);
                        _scalefac[ch][1][sb] = frame.ReadBits(6);
                        _scalefac[ch][2][sb] = frame.ReadBits(6);
                        break;

                    case 1:
                        // only two (2 = 1)
                        _scalefac[ch][0][sb]     =
                            _scalefac[ch][1][sb] = frame.ReadBits(6);
                        _scalefac[ch][2][sb]     = frame.ReadBits(6);
                        break;

                    case 2:
                        // only one (3 = 2 = 1)
                        _scalefac[ch][0][sb]         =
                            _scalefac[ch][1][sb]     =
                                _scalefac[ch][2][sb] = frame.ReadBits(6);
                        break;

                    case 3:
                        // only two (3 = 2)
                        _scalefac[ch][0][sb]     = frame.ReadBits(6);
                        _scalefac[ch][1][sb]     =
                            _scalefac[ch][2][sb] = frame.ReadBits(6);
                        break;

                    default:
                        // none
                        _scalefac[ch][0][sb] = 63;
                        _scalefac[ch][1][sb] = 63;
                        _scalefac[ch][2][sb] = 63;
                        break;
                    }
                }
            }
        }
示例#5
0
        public bool AddBits(IMpegFrame frame, int overlap)
        {
            var originalEnd = _end;

            var slots = GetSlots(frame);

            while (--slots >= 0)
            {
                var temp = frame.ReadBits(8);
                if (temp == -1)
                {
                    throw new System.IO.InvalidDataException("Frame did not have enough bytes!");
                }
                _buf[++_end] = (byte)temp;
                if (_end == _buf.Length - 1)
                {
                    _end = -1;
                }
            }

            _bitsLeft = 8;
            if (originalEnd == -1)
            {
                // it's either the start of the stream or we've reset...  only return true if overlap says this frame is enough
                return(overlap == 0);
            }
            else
            {
                // it's not the start of the stream so calculate _start based on whether we have enough bytes left

                // if we have enough bytes, reset start to match overlap
                if ((originalEnd + 1 - _start + _buf.Length) % _buf.Length >= overlap)
                {
                    _start = (originalEnd + 1 - overlap + _buf.Length) % _buf.Length;
                    return(true);
                }
                // otherwise, just set start to match the start of the frame (we probably skipped a frame)
                else
                {
                    _start = originalEnd + overlap;
                    return(false);
                }
            }
        }
 protected override void ReadScaleFactorSelection(IMpegFrame frame, int[][] scfsi, int channels)
 {
     // we'll never have more than 30 active subbands
     for (int sb = 0; sb < 30; sb++)
     {
         for (int ch = 0; ch < channels; ch++)
         {
             if (scfsi[ch][sb] == 2)
             {
                 scfsi[ch][sb] = frame.ReadBits(2);
             }
         }
     }
 }
        void ReadSideInfo(IMpegFrame frame)
        {
            if (frame.Version == MpegVersion.Version1)
            {
                // main_data_begin      9
                _mainDataBegin = frame.ReadBits(9);

                // private_bits         3 or 5
                if (frame.ChannelMode == MpegChannelMode.Mono)
                {
                    _privBits = frame.ReadBits(5);
                    _channels = 1;
                }
                else
                {
                    _privBits = frame.ReadBits(3);
                    _channels = 2;
                }

                for (var ch = 0; ch < _channels; ch++)
                {
                    // scfsi[ch][0...3]     1 x4
                    _scfsi[ch][0] = frame.ReadBits(1);
                    _scfsi[ch][1] = frame.ReadBits(1);
                    _scfsi[ch][2] = frame.ReadBits(1);
                    _scfsi[ch][3] = frame.ReadBits(1);
                }

                for (var gr = 0; gr < 2; gr++)
                {
                    for (var ch = 0; ch < _channels; ch++)
                    {
                        // part2_3_length[gr][ch]        12
                        _part23Length[gr][ch] = frame.ReadBits(12);
                        // big_values[gr][ch]            9
                        _bigValues[gr][ch] = frame.ReadBits(9);
                        // global_gain[gr][ch]           8
                        _globalGain[gr][ch] = GAIN_TAB[frame.ReadBits(8)];
                        // scalefac_compress[gr][ch]     4
                        _scalefacCompress[gr][ch] = frame.ReadBits(4);
                        // blocksplit_flag[gr][ch]       1
                        _blockSplitFlag[gr][ch] = frame.ReadBits(1) == 1;
                        if (_blockSplitFlag[gr][ch])
                        {
                            //   block_type[gr][ch]              2
                            _blockType[gr][ch] = frame.ReadBits(2);
                            //   switch_point[gr][ch]            1
                            _mixedBlockFlag[gr][ch] = frame.ReadBits(1) == 1;
                            //   table_select[gr][ch][0..1]      5 x2
                            _tableSelect[gr][ch][0] = frame.ReadBits(5);
                            _tableSelect[gr][ch][1] = frame.ReadBits(5);
                            _tableSelect[gr][ch][2] = 0;
                            // set the region information
                            if (_blockType[gr][ch] == 2 && !_mixedBlockFlag[gr][ch])
                            {
                                _regionAddress1[gr][ch] = 8;
                            }
                            else
                            {
                                _regionAddress1[gr][ch] = 7;
                            }
                            _regionAddress2[gr][ch] = 20 - _regionAddress1[gr][ch];
                            //   subblock_gain[gr][ch][0..2]     3 x3
                            _subblockGain[gr][ch][0] = frame.ReadBits(3) * -2f;
                            _subblockGain[gr][ch][1] = frame.ReadBits(3) * -2f;
                            _subblockGain[gr][ch][2] = frame.ReadBits(3) * -2f;
                        }
                        else
                        {
                            //   table_select[0..2][gr][ch]      5 x3
                            _tableSelect[gr][ch][0] = frame.ReadBits(5);
                            _tableSelect[gr][ch][1] = frame.ReadBits(5);
                            _tableSelect[gr][ch][2] = frame.ReadBits(5);
                            //   region_address1[gr][ch]         4
                            _regionAddress1[gr][ch] = frame.ReadBits(4);
                            //   region_address2[gr][ch]         3
                            _regionAddress2[gr][ch] = frame.ReadBits(3);
                            // set the block type so it doesn't accidentally carry
                            _blockType[gr][ch] = 0;

                            // make subblock gain equal unity
                            _subblockGain[gr][ch][0] = 0;
                            _subblockGain[gr][ch][1] = 0;
                            _subblockGain[gr][ch][2] = 0;
                        }
                        // preflag[gr][ch]               1
                        _preflag[gr][ch] = frame.ReadBits(1);
                        // scalefac_scale[gr][ch]        1
                        _scalefacScale[gr][ch] = .5f * (1f + frame.ReadBits(1));
                        // count1table_select[gr][ch]    1
                        _count1TableSelect[gr][ch] = frame.ReadBits(1);
                    }
                }
            }
            else    // MPEG 2+
            {
                // main_data_begin      8
                _mainDataBegin = frame.ReadBits(8);

                // private_bits         1 or 2
                if (frame.ChannelMode == MpegChannelMode.Mono)
                {
                    _privBits = frame.ReadBits(1);
                    _channels = 1;
                }
                else
                {
                    _privBits = frame.ReadBits(2);
                    _channels = 2;
                }

                for (var gr = 0; gr < 2; gr++)
                {
                    for (var ch = 0; ch < _channels; ch++)
                    {
                        // part2_3_length[gr][ch]        12
                        _part23Length[gr][ch] = frame.ReadBits(12);
                        // big_values[gr][ch]            9
                        _bigValues[gr][ch] = frame.ReadBits(9);
                        // global_gain[gr][ch]           8
                        _globalGain[gr][ch] = GAIN_TAB[frame.ReadBits(8)];
                        // scalefac_compress[gr][ch]     9
                        _scalefacCompress[gr][ch] = frame.ReadBits(9);
                        // blocksplit_flag[gr][ch]       1
                        _blockSplitFlag[gr][ch] = frame.ReadBits(1) == 1;
                        if (_blockSplitFlag[gr][ch])
                        {
                            //   block_type[gr][ch]              2
                            _blockType[gr][ch] = frame.ReadBits(2);
                            //   switch_point[gr][ch]            1
                            _mixedBlockFlag[gr][ch] = frame.ReadBits(1) == 1;
                            //   table_select[gr][ch][0..1]      5 x2
                            _tableSelect[gr][ch][0] = frame.ReadBits(5);
                            _tableSelect[gr][ch][1] = frame.ReadBits(5);
                            _tableSelect[gr][ch][2] = 0;
                            // set the region information
                            if (_blockType[gr][ch] == 2 && !_mixedBlockFlag[gr][ch])
                            {
                                _regionAddress1[gr][ch] = 8;
                            }
                            else
                            {
                                _regionAddress1[gr][ch] = 7;
                            }
                            _regionAddress2[gr][ch] = 20 - _regionAddress1[gr][ch];
                            //   subblock_gain[gr][ch][0..2]     3 x3
                            _subblockGain[gr][ch][0] = frame.ReadBits(3) * -2f;
                            _subblockGain[gr][ch][1] = frame.ReadBits(3) * -2f;
                            _subblockGain[gr][ch][2] = frame.ReadBits(3) * -2f;
                        }
                        else
                        {
                            //   table_select[0..2][gr][ch]      5 x3
                            _tableSelect[gr][ch][0] = frame.ReadBits(5);
                            _tableSelect[gr][ch][1] = frame.ReadBits(5);
                            _tableSelect[gr][ch][2] = frame.ReadBits(5);
                            //   region_address1[gr][ch]         4
                            _regionAddress1[gr][ch] = frame.ReadBits(4);
                            //   region_address2[gr][ch]         3
                            _regionAddress2[gr][ch] = frame.ReadBits(3);
                            // set the block type so it doesn't accidentally carry
                            _blockType[gr][ch] = 0;

                            // make subblock gain equal unity
                            _subblockGain[gr][ch][0] = 0;
                            _subblockGain[gr][ch][1] = 0;
                            _subblockGain[gr][ch][2] = 0;
                        }
                        // scalefac_scale[gr][ch]        1
                        _scalefacScale[gr][ch] = .5f * (1f + frame.ReadBits(1));
                        // count1table_select[gr][ch]    1
                        _count1TableSelect[gr][ch] = frame.ReadBits(1);
                    }
                }
            }
        }