private IEnumerator <int> ReadResidualData(FlacBitStreamReader bitReader, int blockSize, int predictorOrder) { const byte RiceCodingWith4BitParameter = 0; const byte RiceCodingWith5BitParameter = 1; uint residualRiceParamSizeType = bitReader.ReadBits(2); int residualRiceParamSize; if (residualRiceParamSizeType == RiceCodingWith4BitParameter) { residualRiceParamSize = 4; } else if (residualRiceParamSizeType == RiceCodingWith5BitParameter) { residualRiceParamSize = 5; } else { throw new FlacException("Reserved residual coding method"); } // rice and rice2 almost the same // read rice partitined method int partitionOrder = (int)bitReader.ReadBits(4); int partitionCount = 1 << partitionOrder; int sampleCount = blockSize >> partitionOrder; if (sampleCount < predictorOrder || sampleCount < 1 || (sampleCount << partitionOrder) != blockSize) { throw new FlacException("Invalid partition order"); } for (int i = 0; i < partitionCount; i++) { int skipSamples = i == 0 ? predictorOrder : 0; int riceParameter = (int)bitReader.ReadBits(residualRiceParamSize); if (riceParameter + 1 == 1 << residualRiceParamSize) { // escape mode int bitsPerSample = (int)bitReader.ReadBits(5); for (int j = skipSamples; j < sampleCount; j++) { yield return(bitReader.ReadSignedBits(bitsPerSample)); } } else { int maxRiceK = int.MaxValue >> riceParameter; for (int j = skipSamples; j < sampleCount; j++) { yield return(bitReader.ReadRice(riceParameter)); } } } }
private IEnumerable <int> ReadValuesVerbatim(FlacBitStreamReader bitReader, int blockSize, int bitsPerSample) { for (int i = 0; i < blockSize; i++) { int value = bitReader.ReadSignedBits(bitsPerSample); yield return(value); } }
public byte[] ReadFrameRawData() { if (recordType != FlacRecordType.Frame) { throw new FlacException("Cannot read non-frame data"); } MemoryStream ms = new MemoryStream(); ms.Write(lastFrameHeaderData, 0, lastFrameHeaderData.Length); // replace bitReader ushort currentCrc16 = bitReader.Complete(); bitReader = new FlacBitStreamReader( new SinkedStream(BaseStream, ms), currentCrc16); // read subframes for (int i = 0; i < FrameChannelCount; i++) { ReadSubframe(); SkipSampleValues(); } bitReader.Complete(); bitReader = null; // read footer byte[] crc16 = ReadExactly(2); recordType = FlacRecordType.FrameFooter; int frameDataLength = checked ((int)ms.Length); ms.Write(crc16, 0, crc16.Length); byte[] frameData = ms.ToArray(); // check CRC16 ushort dataCrc16 = CrcUtils.Crc16(0, frameData, 0, frameDataLength); int footerCrc = (crc16[0] << 8) | crc16[1]; if (dataCrc16 != footerCrc) { throw new FlacException("Invalid frame footer CRC16"); } return(frameData); }
private void ReadFrameFooter() { ushort crc16 = bitReader.Complete(); bitReader = null; byte[] data = ReadExactly(2); int footerCrc16 = data[0] << 8 | data[1]; if (crc16 != footerCrc16) { throw new FlacException("Invalid frame footer CRC16"); } subframeIndex = 0; this.recordType = FlacRecordType.FrameFooter; }
private void ReadFrame() { const int FrameHeaderLength = 2 + 1 + 1; const int FrameSync = 0xFFF8; const int FrameSyncMask = 0xFFFC; const int ReservedBlockSizeSamplesType = 0; const int InvalidSampleRateType = 15; int read; byte[] data = new byte[FrameHeaderLength]; if (recordType != FlacRecordType.Sync) { read = BaseStream.Read(data, 0, FrameHeaderLength); if (read < FrameHeaderLength) { if (read <= 0) { recordType = FlacRecordType.Eof; return; } throw new FlacException("Unexpected eof of stream: invalid frame header length"); } if (((data[0] << 8 | data[1]) & FrameSyncMask) != FrameSync) { throw new FlacException("Frame sync is expected"); } } else { const int SyncReadLength = 2; read = BaseStream.Read(data, SyncReadLength, FrameHeaderLength - SyncReadLength); if (read + SyncReadLength < FrameHeaderLength) { throw new FlacException("Unexpected eof of stream: invalid frame header length"); } data[0] = (byte)(FrameSync >> 8); data[1] = secondSyncByte; } if ((data[1] & 0x02) != 0) { throw new FlacException("Frame header reserved bit (15) shall not be 1"); } this.variableBlockSize = (data[1] & 0x01) != 0; int blockSizeSamplesType = data[2] >> 4; if (blockSizeSamplesType == ReservedBlockSizeSamplesType) { throw new FlacException("Frame header block size samples shall not be set to reserved"); } int previousBlockSize = this.blockSize; this.blockSize = FlacCommons.StaticBlockSizeSamples[blockSizeSamplesType]; int sampleRateType = data[2] & 0x0F; if (sampleRateType == InvalidSampleRateType) { throw new FlacException("Frame header sample rate type is invalid"); } this.sampleRate = FlacCommons.StaticSampleRates[sampleRateType]; int channelAssignmentType = data[3] >> 4; if (channelAssignmentType >= FlacCommons.StaticChannelAssignments.Length) { throw new FlacException("Frame header channel assignments are defined as reserved"); } this.channelAssignmentType = (SoundChannelAssignmentType)channelAssignmentType; this.channelAssignment = FlacCommons.StaticChannelAssignments[channelAssignmentType]; if (channelAssignment == null) { throw new FlacException("Frame header channel assignment are not defined"); } this.channelCount = channelAssignment.Length; int sampleSizeInBitsType = (data[3] >> 1) & 0x07; if (sampleSizeInBitsType == FlacCommons.StreaminfoSizeInBitsType) { this.sampleSizeInBits = Streaminfo.BitsPerSample; } else if (FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType] > 0) { this.sampleSizeInBits = FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType]; } else { throw new FlacException("Frame header sample size is defined as reserved"); } if ((data[3] & 1) != 0) { throw new FlacException("Frame header reserved bit (31) shall not be 1"); } MemoryStream ms = new MemoryStream(20); ms.Write(data, 0, FrameHeaderLength); byte[] numberData; if (variableBlockSize) { ReadUtf8Number(out this.sampleNumber, out numberData); if (numberData.Length > 7) { throw new FlacException("Invalid variable block size"); } } else { ReadUtf8Number(out this.frameNumber, out numberData); if (numberData.Length > 6) { throw new FlacException("Invalid frame number"); } this.sampleNumber = this.frameNumber == 0 ? 0 : previousBlockSize *this.frameNumber; } ms.Write(numberData, 0, numberData.Length); byte[] blockSizeData = null; switch (blockSizeSamplesType) { case FlacCommons.Bit8BlockSizeSamplesType: blockSizeData = ReadExactly(1); this.blockSize = (int)blockSizeData[0] + 1; break; case FlacCommons.Bit16BlockSizeSamplesType: blockSizeData = ReadExactly(2); this.blockSize = (blockSizeData[0] << 8 | blockSizeData[1]) + 1; break; } if (blockSizeData != null) { ms.Write(blockSizeData, 0, blockSizeData.Length); } byte[] sampleRateData = null; switch (sampleRateType) { case FlacCommons.StreaminfoSampleRateType: this.sampleRate = Streaminfo.SampleRate; break; case FlacCommons.Bit8SampleRateType: sampleRateData = ReadExactly(1); this.sampleRate = sampleRateData[0]; break; case FlacCommons.Bit16SampleRateType: sampleRateData = ReadExactly(2); this.sampleRate = sampleRateData[0] << 8 | sampleRateData[1]; break; case FlacCommons.Bit16Mult10SampleRateType: sampleRateData = ReadExactly(2); this.sampleRate = (sampleRateData[0] << 8 | sampleRateData[1]) * 10; break; } if (sampleRateData != null) { ms.Write(sampleRateData, 0, sampleRateData.Length); } byte[] readData = ms.ToArray(); byte crc8 = CrcUtils.Crc8(0, readData); int headerCrc8 = BaseStream.ReadByte(); if (headerCrc8 < 0) { throw new FlacException("Unexpected end of stream: frame CRC8 expected"); } else if (crc8 != headerCrc8) { throw new FlacException("Invalid frame CRC"); } ushort currentCrc16 = CrcUtils.Crc16( CrcUtils.Crc16(0, readData), (byte)headerCrc8); bitReader = new FlacBitStreamReader(BaseStream, currentCrc16); lastFrameHeaderData = new byte[readData.Length + 1]; Array.Copy(readData, lastFrameHeaderData, readData.Length); lastFrameHeaderData[readData.Length] = crc8; recordType = FlacRecordType.Frame; }
private IEnumerable<int> ReadValuesVerbatim(FlacBitStreamReader bitReader, int blockSize, int bitsPerSample) { for (int i = 0; i < blockSize; i++) { int value = bitReader.ReadSignedBits(bitsPerSample); yield return value; } }
private IEnumerator<int> ReadResidualData(FlacBitStreamReader bitReader, int blockSize, int predictorOrder) { const byte RiceCodingWith4BitParameter = 0; const byte RiceCodingWith5BitParameter = 1; uint residualRiceParamSizeType = bitReader.ReadBits(2); int residualRiceParamSize; if (residualRiceParamSizeType == RiceCodingWith4BitParameter) residualRiceParamSize = 4; else if (residualRiceParamSizeType == RiceCodingWith5BitParameter) residualRiceParamSize = 5; else throw new FlacException("Reserved residual coding method"); // rice and rice2 almost the same // read rice partitined method int partitionOrder = (int)bitReader.ReadBits(4); int partitionCount = 1 << partitionOrder; int sampleCount = blockSize >> partitionOrder; if (sampleCount < predictorOrder || sampleCount < 1 || (sampleCount << partitionOrder) != blockSize ) throw new FlacException("Invalid partition order"); for (int i = 0; i < partitionCount; i++) { int skipSamples = i == 0 ? predictorOrder : 0; int riceParameter = (int)bitReader.ReadBits(residualRiceParamSize); if (riceParameter + 1 == 1 << residualRiceParamSize) { // escape mode int bitsPerSample = (int)bitReader.ReadBits(5); for (int j = skipSamples; j < sampleCount; j++) { yield return bitReader.ReadSignedBits(bitsPerSample); } } else { int maxRiceK = int.MaxValue >> riceParameter; for (int j = skipSamples; j < sampleCount; j++) { yield return bitReader.ReadRice(riceParameter); } } } }
private void ReadFrameFooter() { ushort crc16 = bitReader.Complete(); bitReader = null; byte[] data = ReadExactly(2); int footerCrc16 = data[0] << 8 | data[1]; if (crc16 != footerCrc16) throw new FlacException("Invalid frame footer CRC16"); subframeIndex = 0; this.recordType = FlacRecordType.FrameFooter; }
private void ReadFrame() { const int FrameHeaderLength = 2 + 1 + 1; const int FrameSync = 0xFFF8; const int FrameSyncMask = 0xFFFC; const int ReservedBlockSizeSamplesType = 0; const int InvalidSampleRateType = 15; int read; byte[] data = new byte[FrameHeaderLength]; if (recordType != FlacRecordType.Sync) { read = BaseStream.Read(data, 0, FrameHeaderLength); if (read < FrameHeaderLength) { if (read <= 0) { recordType = FlacRecordType.Eof; return; } throw new FlacException("Unexpected eof of stream: invalid frame header length"); } if (((data[0] << 8 | data[1]) & FrameSyncMask) != FrameSync) throw new FlacException("Frame sync is expected"); } else { const int SyncReadLength = 2; read = BaseStream.Read(data, SyncReadLength, FrameHeaderLength - SyncReadLength); if(read + SyncReadLength < FrameHeaderLength) throw new FlacException("Unexpected eof of stream: invalid frame header length"); data[0] = (byte)(FrameSync >> 8); data[1] = secondSyncByte; } if((data[1] & 0x02) != 0) throw new FlacException("Frame header reserved bit (15) shall not be 1"); this.variableBlockSize = (data[1] & 0x01) != 0; int blockSizeSamplesType = data[2] >> 4; if(blockSizeSamplesType == ReservedBlockSizeSamplesType) throw new FlacException("Frame header block size samples shall not be set to reserved"); int previousBlockSize = this.blockSize; this.blockSize = FlacCommons.StaticBlockSizeSamples[blockSizeSamplesType]; int sampleRateType = data[2] & 0x0F; if(sampleRateType == InvalidSampleRateType) throw new FlacException("Frame header sample rate type is invalid"); this.sampleRate = FlacCommons.StaticSampleRates[sampleRateType]; int channelAssignmentType = data[3] >> 4; if (channelAssignmentType >= FlacCommons.StaticChannelAssignments.Length) throw new FlacException("Frame header channel assignments are defined as reserved"); this.channelAssignmentType = (SoundChannelAssignmentType)channelAssignmentType; this.channelAssignment = FlacCommons.StaticChannelAssignments[channelAssignmentType]; if (channelAssignment == null) throw new FlacException("Frame header channel assignment are not defined"); this.channelCount = channelAssignment.Length; int sampleSizeInBitsType = (data[3] >> 1) & 0x07; if (sampleSizeInBitsType == FlacCommons.StreaminfoSizeInBitsType) this.sampleSizeInBits = Streaminfo.BitsPerSample; else if (FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType] > 0) this.sampleSizeInBits = FlacCommons.StaticSampleSizeInBits[sampleSizeInBitsType]; else throw new FlacException("Frame header sample size is defined as reserved"); if((data[3] & 1) != 0) throw new FlacException("Frame header reserved bit (31) shall not be 1"); MemoryStream ms = new MemoryStream(20); ms.Write(data, 0, FrameHeaderLength); byte[] numberData; if (variableBlockSize) { ReadUtf8Number(out this.sampleNumber, out numberData); if (numberData.Length > 7) throw new FlacException("Invalid variable block size"); } else { ReadUtf8Number(out this.frameNumber, out numberData); if (numberData.Length > 6) throw new FlacException("Invalid frame number"); this.sampleNumber = this.frameNumber == 0 ? 0 : previousBlockSize * this.frameNumber; } ms.Write(numberData, 0, numberData.Length); byte[] blockSizeData = null; switch (blockSizeSamplesType) { case FlacCommons.Bit8BlockSizeSamplesType: blockSizeData = ReadExactly(1); this.blockSize = (int)blockSizeData[0] + 1; break; case FlacCommons.Bit16BlockSizeSamplesType: blockSizeData = ReadExactly(2); this.blockSize = (blockSizeData[0] << 8 | blockSizeData[1]) + 1; break; } if(blockSizeData != null) ms.Write(blockSizeData, 0, blockSizeData.Length); byte[] sampleRateData = null; switch (sampleRateType) { case FlacCommons.StreaminfoSampleRateType: this.sampleRate = Streaminfo.SampleRate; break; case FlacCommons.Bit8SampleRateType: sampleRateData = ReadExactly(1); this.sampleRate = sampleRateData[0]; break; case FlacCommons.Bit16SampleRateType: sampleRateData = ReadExactly(2); this.sampleRate = sampleRateData[0] << 8 | sampleRateData[1]; break; case FlacCommons.Bit16Mult10SampleRateType: sampleRateData = ReadExactly(2); this.sampleRate = (sampleRateData[0] << 8 | sampleRateData[1]) * 10; break; } if (sampleRateData != null) ms.Write(sampleRateData, 0, sampleRateData.Length); byte[] readData = ms.ToArray(); byte crc8 = CrcUtils.Crc8(0, readData); int headerCrc8 = BaseStream.ReadByte(); if (headerCrc8 < 0) throw new FlacException("Unexpected end of stream: frame CRC8 expected"); else if(crc8 != headerCrc8) throw new FlacException("Invalid frame CRC"); ushort currentCrc16 = CrcUtils.Crc16( CrcUtils.Crc16(0, readData), (byte)headerCrc8); bitReader = new FlacBitStreamReader(BaseStream, currentCrc16); lastFrameHeaderData = new byte[readData.Length + 1]; Array.Copy(readData, lastFrameHeaderData, readData.Length); lastFrameHeaderData[readData.Length] = crc8; recordType = FlacRecordType.Frame; }
public byte[] ReadFrameRawData() { if(recordType != FlacRecordType.Frame) throw new FlacException("Cannot read non-frame data"); MemoryStream ms = new MemoryStream(); ms.Write(lastFrameHeaderData, 0, lastFrameHeaderData.Length); // replace bitReader ushort currentCrc16 = bitReader.Complete(); bitReader = new FlacBitStreamReader( new SinkedStream(BaseStream, ms), currentCrc16); // read subframes for (int i = 0; i < FrameChannelCount; i++) { ReadSubframe(); SkipSampleValues(); } bitReader.Complete(); bitReader = null; // read footer byte[] crc16 = ReadExactly(2); recordType = FlacRecordType.FrameFooter; int frameDataLength = checked((int)ms.Length); ms.Write(crc16, 0, crc16.Length); byte[] frameData = ms.ToArray(); // check CRC16 ushort dataCrc16 = CrcUtils.Crc16(0, frameData, 0, frameDataLength); int footerCrc = (crc16[0] << 8) | crc16[1]; if(dataCrc16 != footerCrc) throw new FlacException("Invalid frame footer CRC16"); return frameData; }