public override byte[] Decode( MpegFrame frame, BitReader reader ) { byte[,] allocation = new byte[subbands, 2]; byte[,] scaleIndices = new byte[subbands, 2]; channels = frame.Channels; int[,,] samples = new int[samplesPerSubband, subbands, channels]; byte[] output = new byte[totalSamples * channels * 2]; this.reader = reader; int index = 0; if( frame.ChannelMode == ChannelMode.SingleChannel || frame.ChannelMode == ChannelMode.Stereo || frame.ChannelMode == ChannelMode.DualChannel ) { ReadBitAllocation( allocation ); ReadScaleFactors( allocation, scaleIndices ); ReadSamples( allocation, samples ); for( int s = 0; s < samplesPerSubband; s++ ) { double[,] bandTbl = new double[channels, subbands]; RequantiseSamples( s, bandTbl, allocation, samples, scaleIndices ); if( channels == 1 ) { double[] samples0 = Common.SynthesisSubbandFilter( 0, bandTbl, V0, subbands ); for( int sb = 0; sb < subbands; sb++ ) { Common.OutputSample( samples0[sb], output, ref index ); } } else { double[] samples0 = Common.SynthesisSubbandFilter( 0, bandTbl, V0, subbands ); double[] samples1 = Common.SynthesisSubbandFilter( 1, bandTbl, V1, subbands ); for( int sb = 0; sb < subbands; sb++ ) { Common.OutputSample( samples0[sb], output, ref index ); Common.OutputSample( samples1[sb], output, ref index ); } } } return output; } else { throw new NotImplementedException( "joint stereo implementation not done"); } }
public abstract byte[] Decode( MpegFrame frame, BitReader reader );
public IEnumerable<AudioChunk> StreamData( Stream source ) { info = new AudioChunk(); PrimitiveReader reader = new PrimitiveReader( source ); while( true ) { // Read frame header BitReader bitReader = new BitReader( reader ); bitReader.BigEndian = true; //Console.WriteLine( "start pos" + reader.Position ); // Skip any padding('00') bytes before the start of a frame byte data = 0; while( ( data = reader.ReadByte() ) == 0 ); // Make sure that the 'data' byte is the first 8 bits of the sync word. if( data != 0xFF ) { throw new InvalidDataException( "Invalid frame sync value." ); } int frameSync = bitReader.ReadBits( 3/*11*/ ); if( frameSync != 0x7/*FF*/ ) { throw new InvalidDataException( "Invalid frame sync value." ); } int versionId = bitReader.ReadBits( 2 ); int layerIndex = bitReader.ReadBits( 2 ); bool crcProtection = bitReader.ReadBit() == 0; int bitrateIndex = bitReader.ReadBits( 4 ); int samplingRateIndex = bitReader.ReadBits( 2 ); bool padded = bitReader.ReadBit() != 0; int privateBit = bitReader.ReadBit(); int channelMode = bitReader.ReadBits( 2 ); int modeExtension = bitReader.ReadBits( 2 ); int copyrightBit = bitReader.ReadBit(); int originalBit = bitReader.ReadBit(); int emphasis = bitReader.ReadBits( 2 ); int bitrate = GetBitRate( (MpegVersion)versionId, layerIndex, bitrateIndex ); info.Frequency = samplingRates[versionId][samplingRateIndex]; ushort crc = 0; if( crcProtection ) { crc = (ushort)bitReader.ReadBits( 16 ); } MpegFrame frame = new MpegFrame(); frame.Bitrate = bitrate; frame.ChannelMode = (ChannelMode)channelMode; frame.Channels = Common.GetNumberOfChannels( frame.ChannelMode ); frame.CrcProtected = crcProtection; frame.Padding = padded; frame.ModeExtension = modeExtension; frame.SampleRate = info.Frequency; frame.Emphasis = emphasis; frame.Version = (MpegVersion)versionId; LayerIndex index2 = (LayerIndex)layerIndex; info.Data = null; //Console.WriteLine( "padding: {0}, type: {1}, sr: {2}, br: {3}", //frame.Padding, index2, frame.SampleRate, frame.Bitrate ); if( layerIndex == (int)LayerIndex.Layer1 ) { info.Data = decoder1.Decode( frame, bitReader ); } else if( layerIndex == (int)LayerIndex.Layer2 ) { info.Data = decoder2.Decode( frame, bitReader ); } else if( layerIndex == (int)LayerIndex.Layer3 ) { throw new NotSupportedException( "Layer III not supported" ); } else { throw new InvalidDataException( "Invalid layer" ); } info.Channels = frame.Channels; info.BitsPerSample = 16; //if( bitReader.offset == 8 ) { //reader.ReadByte(); //} yield return info; } }