private void ReadSamples(MpegFrame 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) { int[] samples = _samples[ch]; int 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) int val = frame.ReadBits(-alloc); int levels = (1 << (-alloc / 2 + -alloc % 2 - 1)) + 1; samples[idx] = val % levels; val /= levels; samples[idx + SBLIMIT] = val % levels; samples[idx + SBLIMIT * 2] = val / levels; } else { // non-grouping for (int gr = 0; gr < _granuleCount; gr++) { samples[idx + SBLIMIT * gr] = frame.ReadBits(alloc); } } } else { // no energy... zero out the samples for (int gr = 0; gr < _granuleCount; gr++) { samples[idx + SBLIMIT * gr] = 0; } } } else { int[] samples0 = _samples[0]; int[] samples1 = _samples[1]; // copy chan 0 to chan 1 for (int gr = 0; gr < _granuleCount; gr++) { samples1[idx + SBLIMIT * gr] = samples0[idx + SBLIMIT * gr]; } } } } } }
private void ReadAllocation(MpegFrame 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++) { int[] table = _allocLookupTable[rateTable[sb]]; int bits = table[0]; for (int ch = 0; ch < _channels; ch++) { _allocation[ch][sb] = table[frame.ReadBits(bits) + 1]; } } for (; sb < _subBandCount; sb++) { int[] table = _allocLookupTable[rateTable[sb]]; _allocation[0][sb] = _allocation[1][sb] = table[frame.ReadBits(table[0]) + 1]; } }
private void ReadScaleFactors(MpegFrame frame) { for (int sb = 0; sb < SBLIMIT; sb++) { for (int ch = 0; ch < _channels; ch++) { int[][] scalefac = _scalefac[ch]; switch (_scfsi[ch][sb]) { case 0: // all three scalefac[0][sb] = frame.ReadBits(6); scalefac[1][sb] = frame.ReadBits(6); scalefac[2][sb] = frame.ReadBits(6); break; case 1: // only two (2 = 1) scalefac[0][sb] = scalefac[1][sb] = frame.ReadBits(6); scalefac[2][sb] = frame.ReadBits(6); break; case 2: // only one (3 = 2 = 1) scalefac[0][sb] = scalefac[1][sb] = scalefac[2][sb] = frame.ReadBits(6); break; case 3: // only two (3 = 2) scalefac[0][sb] = frame.ReadBits(6); scalefac[1][sb] = scalefac[2][sb] = frame.ReadBits(6); break; default: // none scalefac[0][sb] = 63; scalefac[1][sb] = 63; scalefac[2][sb] = 63; break; } } } }
public bool AddBits(MpegFrame frame, int overlap) { int originalEnd = _end; int slots = GetSlots(frame); while (--slots >= 0) { int tmp = frame.ReadBits(8); if (tmp == -1) { ThrowFrameNotEnoughBytes(); } _buf[++_end] = (byte)tmp; if (_end == BufferSize - 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 + BufferSize) % BufferSize >= overlap) { _start = (originalEnd + 1 - overlap + BufferSize) % BufferSize; return(true); } // otherwise, just set start to match the start of the frame (we probably skipped a frame) else { _start = originalEnd; return(false); } } }
protected static bool GetCRC( MpegFrame frame, int[] rateTable, int[][] allocLookupTable, bool readScfsiBits, ref uint crc) { // ugh... we basically have to re-implement the allocation logic here. // keep up with how many active subbands we need to read selection info for var scfsiBits = 0; // only read as many subbands as we actually need; pay attention to the intensity stereo subbands var subbandCount = rateTable.Length; var jsbound = subbandCount; if (frame.ChannelMode == MpegChannelMode.JointStereo) { jsbound = frame.ChannelModeExtension * 4 + 4; } // read the full stereo subbands var channels = frame.ChannelMode == MpegChannelMode.Mono ? 1 : 2; var sb = 0; for (; sb < jsbound; sb++) { var bits = allocLookupTable[rateTable[sb]][0]; for (int ch = 0; ch < channels; ch++) { var alloc = frame.ReadBits(bits); if (alloc > 0) { scfsiBits += 2; } MpegFrame.UpdateCRC(alloc, bits, ref crc); } } // read the intensity stereo subbands for (; sb < subbandCount; sb++) { var bits = allocLookupTable[rateTable[sb]][0]; var alloc = frame.ReadBits(bits); if (alloc > 0) { scfsiBits += channels * 2; } MpegFrame.UpdateCRC(alloc, bits, ref crc); } // finally, read the scalefac selection bits if (readScfsiBits) { while (scfsiBits >= 2) { MpegFrame.UpdateCRC(frame.ReadBits(2), 2, ref crc); scfsiBits -= 2; } } return(true); }
static internal bool GetCRC(MpegFrame frame, ref uint crc) { var cnt = frame.GetSideDataSize(); while (--cnt >= 0) { MpegFrame.UpdateCRC(frame.ReadBits(8), 8, ref crc); } return true; }