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]; } }
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; }
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; } } } }
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); } } } }