public unsafe FlacMetadataStreamInfo(Stream stream, Int32 length, bool lastBlock) : base(FlacMetaDataType.StreamInfo, lastBlock, length) { //http://flac.sourceforge.net/format.html#metadata_block_streaminfo BinaryReader reader = new BinaryReader(stream, Encoding.ASCII); try { MinBlockSize = reader.ReadInt16(); MaxBlockSize = reader.ReadInt16(); } catch (IOException e) { throw new FlacException(e, FlacLayer.Metadata); } int bytesToRead = (240 / 8) - 16; byte[] buffer = reader.ReadBytes(bytesToRead); if (buffer.Length != bytesToRead) throw new FlacException(new EndOfStreamException("Could not read StreamInfo-content"), FlacLayer.Metadata); fixed(byte *b = buffer) { FlacBitReader bitreader = new FlacBitReader(b, 0); MinFrameSize = bitreader.ReadBits(24); MaxFrameSize = bitreader.ReadBits(24); SampleRate = (int)bitreader.ReadBits(20); Channels = 1 + (int)bitreader.ReadBits(3); BitsPerSample = 1 + (int)bitreader.ReadBits(5); TotalSamples = (long)bitreader.ReadBits64(36); MD5 = new String(reader.ReadChars(16)); } }
/// <summary> /// Initializes a new instance of the <see cref="FlacMetadataStreamInfo" /> class. /// </summary> /// <param name="stream">The stream which contains the <see cref="FlacMetadataStreamInfo"/>.</param> /// <param name="length">The length of the <see cref="FlacMetadataStreamInfo"/> inside of the stream in bytes. Does not include the metadata header.</param> /// <param name="lastBlock"> /// A value which indicates whether this is the last <see cref="FlacMetadata" /> block inside of /// the stream. <c>true</c> means that this is the last <see cref="FlacMetadata" /> block inside of the stream. /// </param> public unsafe FlacMetadataStreamInfo(Stream stream, int length, bool lastBlock) : base(FlacMetaDataType.StreamInfo, lastBlock, length) { //http://flac.sourceforge.net/format.html#metadata_block_streaminfo var reader = new BinaryReader(stream, Encoding.ASCII); try { MinBlockSize = reader.ReadInt16(); MaxBlockSize = reader.ReadInt16(); } catch (IOException e) { throw new FlacException(e, FlacLayer.Metadata); } const int bytesToRead = (240 / 8) - 16; byte[] buffer = reader.ReadBytes(bytesToRead); if (buffer.Length != bytesToRead) { throw new FlacException(new EndOfStreamException("Could not read StreamInfo-content"), FlacLayer.Metadata); } fixed (byte* b = buffer) { var bitreader = new FlacBitReader(b, 0); MinFrameSize = (int) bitreader.ReadBits(24); MaxFrameSize = (int) bitreader.ReadBits(24); SampleRate = (int) bitreader.ReadBits(20); Channels = 1 + (int) bitreader.ReadBits(3); BitsPerSample = 1 + (int) bitreader.ReadBits(5); TotalSamples = (long) bitreader.ReadBits64(36); Md5 = new String(reader.ReadChars(16)); } }
public FlacSubFrameConstant(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample) : base(header) { unchecked { var value = (int)reader.ReadBits(bitsPerSample); data.DestinationBuffer.Span.Fill(value); } }
public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order) : base(header) { //warmup _warmup = new int[FlacConstant.MAX_LPC_ORDER]; for (int i = 0; i < order; i++) { _warmup[i] = data.residualBuffer[i] = reader.ReadBitsSigned(bps); } //header int u32 = (int)reader.ReadBits(FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN); if (u32 == (1 << FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { Debug.WriteLine("Invalid FlacLPC qlp coeff precision."); return; //return false; } _qlpCoeffPrecision = u32 + 1; int level = reader.ReadBitsSigned(FlacConstant.SUBFRAME_LPC_QLP_SHIFT_LEN); if (level < 0) throw new Exception("negative shift"); _lpcShiftNeeded = level; _qlpCoeffs = new int[FlacConstant.MAX_LPC_ORDER]; //qlp coeffs for (int i = 0; i < order; i++) { _qlpCoeffs[i] = reader.ReadBitsSigned(_qlpCoeffPrecision); } //QLPCoeffs = coeffs; Residual = new FlacResidual(reader, header, data, order); for (int i = 0; i < order; i++) { data.destBuffer[i] = data.residualBuffer[i]; } if (bps + _qlpCoeffPrecision + CSMath.ILog(order) <= 32) { if (bps <= 16 && _qlpCoeffPrecision <= 16) RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order); //Restore(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); else RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order); } else { RestoreLPCSignalWide(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order);//RestoreWide(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); } //Warmup = warmup; }
public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order) : base(header) { for (int i = 0; i < order; i++) { data.residualBuffer[i] = data.destBuffer[i] = reader.ReadBitsSigned(bps); } Residual = new FlacResidual(reader, header, data, order); RestoreSignal(data, header.BlockSize - order, order); }
public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order) : base(header) { var warmup = new int[order]; for (int i = 0; i < order; i++) { warmup[i] = data.ResidualBuffer[i] = reader.ReadBitsSigned(bitsPerSample); } int coefPrecision = (int)reader.ReadBits(4) + 1; if (coefPrecision == 0x0F) { Debug.WriteLine("Invalid linear predictor coefficients' precision. Must not be 0x0F."); return; } int shiftNeeded = reader.ReadBitsSigned(5); if (shiftNeeded < 0) throw new FlacException("\"Quantized linear predictor coefficient shift needed.\" was negative.", FlacLayer.SubFrame); var q = new int[order]; for (int i = 0; i < order; i++) { q[i] = reader.ReadBitsSigned(coefPrecision); } //decode the residual var residual = new FlacResidual(reader, header, data, order); for (int i = 0; i < order; i++) { data.DestinationBuffer[i] = data.ResidualBuffer[i]; } int* residualBuffer0 = data.ResidualBuffer + order; int* destinationBuffer0 = data.DestinationBuffer + order; int blockSizeToProcess = header.BlockSize - order; if (bitsPerSample + coefPrecision + Log2(order) <= 32) { RestoreLPCSignal32(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded); } else { RestoreLPCSignal64(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded); } #if FLAC_DEBUG QLPCoeffPrecision = coefPrecision; LPCShiftNeeded = shiftNeeded; Warmup = warmup; Residual = residual; QLPCoeffs = q; #endif }
public FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order) : base(header) { unchecked { var resi = data.ResidualBuffer.Span; var dest = data.DestinationBuffer.Span; for (var i = 0; i < order; i++) { resi[i] = reader.ReadBitsSigned(bitsPerSample); } var coefPrecision = (int)reader.ReadBits(4); if (coefPrecision == 0x0F) { throw new FlacException( "Invalid \"quantized linear predictor coefficients' precision in bits\" was invalid. Must not be 0x0F.", FlacLayer.SubFrame); } coefPrecision += 1; var shiftNeeded = reader.ReadBitsSigned(5); if (shiftNeeded < 0) { throw new FlacException( "'\"Quantized linear predictor coefficient shift needed in bits\" was negative.", FlacLayer.SubFrame); } var q = new int[order]; for (var i = 0; i < order; i++) { q[i] = reader.ReadBitsSigned(coefPrecision); } //decode the residual new FlacResidual(reader, header, data, order); resi.Slice(0, order).CopyTo(dest); var blockSizeToProcess = header.BlockSize - order; if (bitsPerSample + coefPrecision + Log2(order) <= 32) { RestoreLPCSignal32(resi, dest, blockSizeToProcess, order, q, shiftNeeded); } else { RestoreLPCSignal64(resi, dest, blockSizeToProcess, order, q, shiftNeeded); } } }
public unsafe static FlacMetadata FromStream(Stream stream) { bool lastBlock = false; FlacMetaDataType type = FlacMetaDataType.Undef; int length = 0; byte[] b = new byte[4]; if (stream.Read(b, 0, 4) <= 0) { throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata); fixed(byte *headerBytes = b) { FlacBitReader bitReader = new FlacBitReader(headerBytes, 0); lastBlock = bitReader.ReadBits(1) == 1; type = (FlacMetaDataType)bitReader.ReadBits(7); length = (int)bitReader.ReadBits(24); ////1000 0000 //if (((b[0] & 0x80) >> 7) == 1) // lastBlock = true; //type = (FlacMetaDataType)(b[0] & 0x7F); //int length = (b[1] + (b[2] << 8) + (b[3] << 16)); } FlacMetadata data; long streamStartPosition = stream.Position; if ((int)type < 0 || (int)type > 6) return(null); } else { switch (type) { case FlacMetaDataType.StreamInfo: data = new FlacMetadataStreamInfo(stream, length, lastBlock); break; case FlacMetaDataType.Seektable: data = new FlacMetadataSeekTable(stream, length, lastBlock); break; default: data = new FlacMetadata(type, lastBlock, length); break; } } stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current); return(data); }
private unsafe void ReadSubFrames(int *ptrDestBuffer, int *ptrResidualBuffer) { List <FlacSubFrameBase> subFrames = new List <FlacSubFrameBase>(); //alocateOutput var data = AllocOuputMemory(ptrDestBuffer, ptrResidualBuffer); _subFrameData = data; byte[] buffer = new byte[0x20000]; if ((_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) > buffer.Length) { buffer = new byte[(_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) - FlacConstant.FrameHeaderSize]; } int read = _stream.Read(buffer, 0, (int)Math.Min(buffer.Length, _stream.Length - _stream.Position)); fixed(byte *ptrBuffer = buffer) { FlacBitReader reader = new FlacBitReader(ptrBuffer, 0); for (int c = 0; c < Header.Channels; c++) { int bitsPerSample = Header.BitsPerSample; if (Header.ChannelAssignment == ChannelAssignment.MidSide || Header.ChannelAssignment == ChannelAssignment.LeftSide) { bitsPerSample += c; } else if (Header.ChannelAssignment == ChannelAssignment.RightSide) { bitsPerSample += 1 - c; } var subframe = FlacSubFrameBase.GetSubFrame(reader, data[c], Header, bitsPerSample); subFrames.Add(subframe); } reader.Flush(); //Zero-padding to byte alignment. //footer Crc16 = (short)reader.ReadBits(16); _stream.Position -= read - reader.Position; MapToChannels(_subFrameData); } #if FLAC_DEBUG _subFrames = subFrames.AsReadOnly(); #endif }
public static unsafe FlacMetadata FromStream(Stream stream) { bool lastBlock = false; FlacMetaDataType type = FlacMetaDataType.Undef; int length = 0; byte[] b = new byte[4]; if (stream.Read(b, 0, 4) <= 0) throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata); fixed (byte* headerBytes = b) { FlacBitReader bitReader = new FlacBitReader(headerBytes, 0); lastBlock = bitReader.ReadBits(1) == 1; type = (FlacMetaDataType)bitReader.ReadBits(7); length = (int)bitReader.ReadBits(24); ////1000 0000 //if (((b[0] & 0x80) >> 7) == 1) // lastBlock = true; //type = (FlacMetaDataType)(b[0] & 0x7F); //int length = (b[1] + (b[2] << 8) + (b[3] << 16)); } FlacMetadata data; long streamStartPosition = stream.Position; if ((int)type < 0 || (int)type > 6) return null; else { switch (type) { case FlacMetaDataType.StreamInfo: data = new FlacMetadataStreamInfo(stream, length, lastBlock); break; case FlacMetaDataType.Seektable: data = new FlacMetadataSeekTable(stream, length, lastBlock); break; default: data = new FlacMetadata(type, lastBlock, length); break; } } stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current); return data; }
private unsafe int ReadSubFrames() { List <FlacSubFrameBase> subFrames = new List <FlacSubFrameBase>(); //alocateOutput var data = AllocOuputMemory(); _data = data; byte[] buffer = new byte[0x20000]; if ((_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) > buffer.Length) { buffer = new byte[(_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) - FlacConstant.FrameHeaderSize]; } int read = _stream.Read(buffer, 0, (int)Math.Min(buffer.Length, _stream.Length - _stream.Position)); fixed(byte *ptrBuffer = buffer) { FlacBitReader reader = new FlacBitReader(ptrBuffer, 0); ChannelAssignment channelAssignment = Header.ChannelAssignment; for (int c = 0; c < Header.Channels; c++) { int bps = Header.BitsPerSample; if (Header.ChannelAssignment == ChannelAssignment.MidSide || Header.ChannelAssignment == ChannelAssignment.LeftSide) { bps += c; } else if (Header.ChannelAssignment == ChannelAssignment.RightSide) { bps += 1 - c; } var subframe = FlacSubFrameBase.GetSubFrame(reader, data[c], Header, bps); subFrames.Add(subframe); } reader.Flush(); CRC16 = (ushort)reader.ReadBits(16); _stream.Position -= read - reader.Position; SamplesToBytes(_data); return(reader.Position); } }
public FlacResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order) { var codingMethod = (FlacResidualCodingMethod)reader.ReadBits(2); // 2 Bit if (codingMethod == FlacResidualCodingMethod.PartitionedRice || codingMethod == FlacResidualCodingMethod.PartitionedRice2) { var partitionOrder = (int)reader.ReadBits(4); //"Partition order." see https://xiph.org/flac/format.html#partitioned_rice and https://xiph.org/flac/format.html#partitioned_rice2 FlacPartitionedRice.ProcessResidual(reader, header, data, order, partitionOrder, codingMethod); } else { throw new FlacException("Not supported RICE-Coding-Method. Stream unparseable!", FlacLayer.SubFrame); } }
public unsafe FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order) : base(header) { for (int i = 0; i < order; i++) //order = predictor order { data.ResidualBuffer[i] = data.DestinationBuffer[i] = reader.ReadBitsSigned(bitsPerSample); } var residual = new FlacResidual(reader, header, data, order); //necessary for decoding RestoreSignal(data, header.BlockSize - order, order); #if FLAC_DEBUG Residual = residual; #endif }
public FlacSubFrameVerbatim(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample) : base(header) { unchecked { var dest = data.DestinationBuffer.Span; var resi = data.ResidualBuffer.Span; for (var i = 0; i < header.BlockSize; i++) { var x = (int)reader.ReadBits(bitsPerSample); dest[i] = resi[i] = x; } } }
public FlacSubFrameFixed(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order) : base(header) { unchecked { var resi = data.ResidualBuffer.Span; var dest = data.DestinationBuffer.Span; for (var i = 0; i < order; i++) //order = predictor order { resi[i] = dest[i] = reader.ReadBitsSigned(bitsPerSample); } new FlacResidual(reader, header, data, order); //necessary for decoding RestoreSignal(data, header.BlockSize - order, order); } }
public unsafe bool ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order) { data.Content.UpdateSize(PartitionOrder); int porder = PartitionOrder; FlacEntropyCoding codingMethod = CodingMethod; int psize = header.BlockSize >> porder; int res_cnt = psize - order; int ricelength = 4 + (int)codingMethod; //4bit = RICE I | 5bit = RICE II //residual int j = order; int *r = data.residualBuffer + j; int partitioncount = 1 << porder; for (int p = 0; p < partitioncount; p++) { if (p == 1) { res_cnt = psize; } int n = Math.Min(res_cnt, header.BlockSize - j); int k = Content.parameters[p] = (int)reader.ReadBits(ricelength); if (k == (1 << ricelength) - 1) { k = (int)reader.ReadBits(5); for (int i = n; i > 0; i--) { *(r) = reader.ReadBitsSigned((int)k); } } else { ReadFlacRiceBlock(reader, n, (int)k, r); r += n; } j += n; } return(true); }
private unsafe void ReadFlacRiceBlock(FlacBitReader reader, int nvals, int riceParameter, int *ptrDest) { fixed(byte *putable = FlacBitReader.UnaryTable) { uint mask = (1u << riceParameter) - 1; if (riceParameter == 0) { for (int i = 0; i < nvals; i++) { *(ptrDest++) = reader.ReadUnarySigned(); } } else { for (int i = 0; i < nvals; i++) { uint bits = putable[reader.Cache >> 24]; uint msbs = bits; while (bits == 8) { reader.SeekBits(8); bits = putable[reader.Cache >> 24]; msbs += bits; } uint uval = 0; if (riceParameter <= 16) { int btsk = riceParameter + (int)bits + 1; uval = (msbs << riceParameter) | ((reader.Cache >> (32 - btsk)) & mask); reader.SeekBits(btsk); } else { reader.SeekBits((int)(msbs & 7) + 1); uval = (msbs << riceParameter) | ((reader.Cache >> (32 - riceParameter))); reader.SeekBits(riceParameter); } *(ptrDest++) = (int)(uval >> 1 ^ -(int)(uval & 1)); } } } }
private unsafe void ReadFlacRiceBlock(FlacBitReader reader, int nvals, int riceParameter, int* ptrDest) { fixed (byte* putable = FlacBitReader.UnaryTable) { uint mask = (1u << riceParameter) - 1; if (riceParameter == 0) { for (int i = 0; i < nvals; i++) { *(ptrDest++) = reader.ReadUnarySigned(); } } else { for (int i = 0; i < nvals; i++) { uint bits = putable[reader.Cache >> 24]; uint msbs = bits; while (bits == 8) { reader.SeekBits(8); bits = putable[reader.Cache >> 24]; msbs += bits; } uint uval = 0; if (riceParameter <= 16) { int btsk = riceParameter + (int)bits + 1; uval = (msbs << riceParameter) | ((reader.Cache >> (32 - btsk)) & mask); reader.SeekBits(btsk); } else { reader.SeekBits((int)(msbs & 7) + 1); uval = (msbs << riceParameter) | ((reader.Cache >> (32 - riceParameter))); reader.SeekBits(riceParameter); } *(ptrDest++) = (int)(uval >> 1 ^ -(int)(uval & 1)); } } } }
/// <summary> /// Reads and returns a single <see cref="FlacMetadata"/> from the specified <paramref name="stream"/>. /// </summary> /// <param name="stream">The stream which contains the <see cref="FlacMetadata"/>.</param> /// <returns>Returns the read <see cref="FlacMetadata"/>.</returns> public static unsafe FlacMetadata FromStream(Stream stream) { bool lastBlock; FlacMetaDataType type; int length; byte[] b = new byte[4]; if (stream.Read(b, 0, 4) <= 0) throw new FlacException(new EndOfStreamException("Could not read metadata"), FlacLayer.Metadata); fixed (byte* headerBytes = b) { FlacBitReader bitReader = new FlacBitReader(headerBytes, 0); lastBlock = bitReader.ReadBits(1) == 1; type = (FlacMetaDataType)bitReader.ReadBits(7); length = (int)bitReader.ReadBits(24); } FlacMetadata data; long streamStartPosition = stream.Position; if ((int)type < 0 || (int)type > 6) return null; switch (type) { case FlacMetaDataType.StreamInfo: data = new FlacMetadataStreamInfo(stream, length, lastBlock); break; case FlacMetaDataType.Seektable: data = new FlacMetadataSeekTable(stream, length, lastBlock); break; default: data = new FlacMetadata(type, lastBlock, length); break; } stream.Seek(length - (stream.Position - streamStartPosition), SeekOrigin.Current); return data; }
public unsafe bool ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order) { data.Content.UpdateSize(PartitionOrder); int porder = PartitionOrder; FlacEntropyCoding codingMethod = CodingMethod; int psize = header.BlockSize >> porder; int res_cnt = psize - order; int ricelength = 4 + (int)codingMethod; //4bit = RICE I | 5bit = RICE II //residual int j = order; int* r = data.residualBuffer + j; int partitioncount = 1 << porder; for (int p = 0; p < partitioncount; p++) { if (p == 1) res_cnt = psize; int n = Math.Min(res_cnt, header.BlockSize - j); int k = Content.parameters[p] = (int)reader.ReadBits(ricelength); if (k == (1 << ricelength) - 1) { k = (int)reader.ReadBits(5); for (int i = n; i > 0; i--) { *(r) = reader.ReadBitsSigned((int)k); } } else { ReadFlacRiceBlock(reader, n, (int)k, r); r += n; } j += n; } return true; }
/// <summary> /// Initializes the properties of the <see cref="FlacMetadata"/> by reading them from the <paramref name="stream"/>. /// </summary> /// <param name="stream">The stream which contains the metadata.</param> protected override unsafe void InitializeByStream(Stream stream) { //http://flac.sourceforge.net/format.html#metadata_block_streaminfo var reader = new BinaryReader(stream, Encoding.ASCII); try { MinBlockSize = reader.ReadInt16(); MaxBlockSize = reader.ReadInt16(); } catch (IOException e) { throw new FlacException(e, FlacLayer.Metadata); } const int bytesToRead = (240 / 8) - 16; var buffer = reader.ReadBytes(bytesToRead); if (buffer.Length != bytesToRead) { throw new FlacException(new EndOfStreamException("Could not read StreamInfo-content"), FlacLayer.Metadata); } fixed(byte *b = buffer) { var bitreader = new FlacBitReader(b, 0); MinFrameSize = (int)bitreader.ReadBits(24); MaxFrameSize = (int)bitreader.ReadBits(24); SampleRate = (int)bitreader.ReadBits(20); Channels = 1 + (int)bitreader.ReadBits(3); BitsPerSample = 1 + (int)bitreader.ReadBits(5); TotalSamples = (long)bitreader.ReadBits64(36); Md5 = new string(reader.ReadChars(16)); } }
public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bitsPerSample, int order) : base(header) { var warmup = new int[order]; for (int i = 0; i < order; i++) { warmup[i] = data.ResidualBuffer[i] = reader.ReadBitsSigned(bitsPerSample); } int coefPrecision = (int)reader.ReadBits(4); if (coefPrecision == 0x0F) { throw new FlacException("Invalid \"quantized linear predictor coefficients' precision in bits\" was invalid. Must not be 0x0F.", FlacLayer.SubFrame); } coefPrecision += 1; int shiftNeeded = reader.ReadBitsSigned(5); if (shiftNeeded < 0) { throw new FlacException("'\"Quantized linear predictor coefficient shift needed in bits\" was negative.", FlacLayer.SubFrame); } var q = new int[order]; for (int i = 0; i < order; i++) { q[i] = reader.ReadBitsSigned(coefPrecision); } //decode the residual var residual = new FlacResidual(reader, header, data, order); for (int i = 0; i < order; i++) { data.DestinationBuffer[i] = data.ResidualBuffer[i]; } int *residualBuffer0 = data.ResidualBuffer + order; int *destinationBuffer0 = data.DestinationBuffer + order; int blockSizeToProcess = header.BlockSize - order; if (bitsPerSample + coefPrecision + Log2(order) <= 32) { RestoreLPCSignal32(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded); } else { RestoreLPCSignal64(residualBuffer0, destinationBuffer0, blockSizeToProcess, order, q, shiftNeeded); } #if FLAC_DEBUG QLPCoeffPrecision = coefPrecision; LPCShiftNeeded = shiftNeeded; Warmup = warmup; Residual = residual; QLPCoeffs = q; #endif }
public unsafe static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bps) { uint x; int wastedBits = 0, totalBits = 0, order = 0; x = reader.ReadBits(8); bool haswastedBits = (x & 1) != 0; x &= 0xFE; //1111 1110 if (haswastedBits) { int u = (int)reader.ReadUnary(); wastedBits = u + 1; bps -= wastedBits; totalBits = bps; } if ((x & 0x80) != 0) { Debug.WriteLine("Flacdecoder lost sync while reading FlacSubFrameHeader. [x & 0x80]."); return(null); } FlacSubFrameBase subFrame = null; if ((x > 2 && x < 16) || (x > 24 && x < 64)) { Debug.WriteLine("Invalid FlacSubFrameHeader. [" + x.ToString("x") + "]"); return(null); } else if (x == 0) { subFrame = new FlacSubFrameConstant(reader, header, data, bps); } else if (x == 2) { //verbatim subFrame = new FlacSubFrameVerbatim(reader, header, data, bps); } else if (x >= 16 && x <= 24) { //fixed order = (int)((x >> 1) & 7); subFrame = new FlacSubFrameFixed(reader, header, data, bps, order); } else if (x >= 64) { //lpc order = (int)(((x >> 1) & 31) + 1); subFrame = new FlacSubFrameLPC(reader, header, data, bps, order); } else { Debug.WriteLine("Invalid Flac-SubframeType: x = " + x + "."); return(null); } if (haswastedBits) { int *ptrDest = data.destBuffer; for (int i = 0; i < header.BlockSize; i++) { *(ptrDest++) <<= wastedBits; } } //System.Diagnostics.Debug.WriteLine(subFrame.GetType().Name); if (subFrame != null) { subFrame.WastedBits = wastedBits; } else { Debug.WriteLine("Unknown error while reading FlacSubFrameHeader"); } return(subFrame); }
public static unsafe FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bitsPerSample) { int wastedBits = 0, order; uint firstByte = reader.ReadBits(8); if ((firstByte & 0x80) != 0) //Zero bit padding, to prevent sync-fooling string of 1s { Debug.WriteLine("Flacdecoder subframe-header got no zero-bit padding."); return null; } bool hasWastedBits = (firstByte & 1) != 0; //Wasted bits-per-sample' flag if (hasWastedBits) { int k = (int)reader.ReadUnary(); wastedBits = k + 1; //"k-1" follows -> add 1 bitsPerSample -= wastedBits; } FlacSubFrameBase subFrame; var subframeType = (firstByte & 0x7E) >> 1; //0111 1110 if (subframeType == 0) //000000 { subFrame = new FlacSubFrameConstant(reader, header, data, bitsPerSample); } else if (subframeType == 1) //000001 { subFrame = new FlacSubFrameVerbatim(reader, header, data, bitsPerSample); } else if ((subframeType & 0x08) != 0) //001000 = 0x08 { order = (int) (subframeType & 0x07); subFrame = new FlacSubFrameFixed(reader, header, data, bitsPerSample, order); } else if ((subframeType & 0x20) != 0) //100000 = 0x20 { order = (int) (subframeType & 0x1F) + 1; subFrame = new FlacSubFrameLPC(reader, header, data, bitsPerSample, order); } else { Debug.WriteLine(String.Format("Invalid Flac-SubframeType. SubframeType: 0x{0:x}.", subframeType)); return null; } if (hasWastedBits) { int* destination = data.DestinationBuffer; for (int i = 0; i < header.BlockSize; i++) { *(destination++) <<= wastedBits; } } #if FLAC_DEBUG subFrame.WastedBits = wastedBits; #endif return subFrame; }
public static unsafe FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bps) { uint x; int wastedBits = 0, totalBits = 0, order = 0; x = reader.ReadBits(8); bool haswastedBits = (x & 1) != 0; x &= 0xFE; //1111 1110 if (haswastedBits) { int u = (int)reader.ReadUnary(); wastedBits = u + 1; bps -= wastedBits; totalBits = bps; } if ((x & 0x80) != 0) { Debug.WriteLine("Flacdecoder lost sync while reading FlacSubFrameHeader. [x & 0x80]."); return null; } FlacSubFrameBase subFrame = null; if ((x > 2 && x < 16) || (x > 24 && x < 64)) { Debug.WriteLine("Invalid FlacSubFrameHeader. [" + x.ToString("x") + "]"); return null; } else if (x == 0) { subFrame = new FlacSubFrameConstant(reader, header, data, bps); } else if (x == 2) { //verbatim subFrame = new FlacSubFrameVerbatim(reader, header, data, bps); } else if (x >= 16 && x <= 24) { //fixed order = (int)((x >> 1) & 7); subFrame = new FlacSubFrameFixed(reader, header, data, bps, order); } else if (x >= 64) { //lpc order = (int)(((x >> 1) & 31) + 1); subFrame = new FlacSubFrameLPC(reader, header, data, bps, order); } else { Debug.WriteLine("Invalid Flac-SubframeType: x = " + x + "."); return null; } if (haswastedBits) { int* ptrDest = data.destBuffer; for (int i = 0; i < header.BlockSize; i++) { *(ptrDest++) <<= wastedBits; } } //System.Diagnostics.Debug.WriteLine(subFrame.GetType().Name); if (subFrame != null) subFrame.WastedBits = wastedBits; else Debug.WriteLine("Unknown error while reading FlacSubFrameHeader"); return subFrame; }
protected unsafe virtual bool ParseHeader(ref byte *headerBuffer, FlacMetadataStreamInfo streamInfo) { const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)"; int x = -1; //tmp value to store in if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits { if ((headerBuffer[1] & 0x02) != 0) // ...10 2. letzes bits muss 0 sein { Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation); return(false); } byte * __headerbufferPtr = headerBuffer; FlacBitReader reader = new FlacBitReader(__headerbufferPtr, 0); #region blocksize //blocksize x = headerBuffer[2] >> 4; int blocksize = -1; if (x == 0) { Error("Invalid Blocksize value: 0", loggerLocation); return(false); } else if (x == 1) { blocksize = 192; } else if (x >= 2 && x <= 5) { blocksize = 576 << (x - 2); } else if (x == 6 || x == 7) { blocksize_hint = x; } else if (x >= 8 && x <= 15) { blocksize = 256 << (x - 8); } else { Error("Invalid Blocksize value: " + x, loggerLocation); return(false); } BlockSize = blocksize; #endregion blocksize #region samplerate //samplerate x = headerBuffer[2] & 0x0F; int sampleRate = -1; if (x == 0) { if (streamInfo != null) { sampleRate = streamInfo.SampleRate; } else { Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation); return(false); } } else if (x >= 1 && x <= 11) { sampleRate = FlacConstant.SampleRateTable[x]; } else if (x >= 12 && x <= 14) { sampleRate_hint = x; } else { Error("Invalid SampleRate value: " + x, loggerLocation); return(false); } SampleRate = sampleRate; #endregion samplerate #region channels x = headerBuffer[3] >> 4; //cc: unsigned int channels = -1; if ((x & 8) != 0) { channels = 2; if ((x & 7) > 2 || (x & 7) < 0) { Error("Invalid ChannelAssignment", loggerLocation); return(false); } else { ChannelAssignment = (ChannelAssignment)((x & 7) + 1); } } else { channels = x + 1; ChannelAssignment = ChannelAssignment.Independent; } Channels = channels; #endregion channels #region bitspersample x = (headerBuffer[3] & 0x0E) >> 1; int bitsPerSample = -1; if (x == 0) { if (streamInfo != null) { bitsPerSample = streamInfo.BitsPerSample; } else { Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation); return(false); } } else if (x == 3 || x >= 7 || x < 0) { Error("Invalid BitsPerSampleIndex", loggerLocation); return(false); } else { bitsPerSample = FlacConstant.BitPerSampleTable[x]; } BitsPerSample = bitsPerSample; #endregion bitspersample if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0 { Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation); return(false); } //reader.SkipBits(4 * 8); //erste 3 bytes headerbytes überspringen, da diese schon ohne reader verarbeitet reader.ReadBits(32); //BYTE 4 #region utf8 //variable blocksize if ((headerBuffer[1] & 0x01) != 0 || (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize)) { ulong samplenumber; if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue) { NumberType = FlacNumberType.SampleNumber; SampleNumber = samplenumber; } else { Error("Invalid UTF8 Samplenumber coding.", loggerLocation); return(false); } } else //fixed blocksize { uint framenumber;// = reader.ReadUTF8(); if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue) { NumberType = FlacNumberType.FrameNumber; FrameNumber = framenumber; } else { Error("Invalid UTF8 Framenumber coding.", loggerLocation); return(false); } } #endregion utf8 #region read hints //blocksize am ende des frameheaders if (blocksize_hint != 0) { x = (int)reader.ReadBits(8); if (blocksize_hint == 7) { x = (x << 8) | (int)reader.ReadBits(8); } BlockSize = x + 1; } //samplerate am ende des frameheaders if (sampleRate_hint != 0) { x = (int)reader.ReadBits(8); if (sampleRate_hint != 12) { x = (x << 8) | (int)reader.ReadBits(8); } if (sampleRate_hint == 12) { SampleRate = x * 1000; } else if (sampleRate_hint == 13) { SampleRate = x; } else { SampleRate = x * 10; } } #endregion read hints //if (Channels == 1 && BitsPerSample == 24 && SampleRate == 44100) // System.Diagnostics.Debugger.Break(); if (DoCRC) { var crc8 = CSMath.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position); CRC8 = (byte)reader.ReadBits(8); if (CRC8 != crc8) { Error("CRC8 missmatch", loggerLocation); return(false); } } headerBuffer += reader.Position; return(true); } Error("Invalid Syncbits", loggerLocation); return(false); }
public unsafe FlacSubFrameLPC(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int bps, int order) : base(header) { //warmup _warmup = new int[FlacConstant.MAX_LPC_ORDER]; for (int i = 0; i < order; i++) { _warmup[i] = data.residualBuffer[i] = reader.ReadBitsSigned(bps); } //header int u32 = (int)reader.ReadBits(FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN); if (u32 == (1 << FlacConstant.SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN) - 1) { Debug.WriteLine("Invalid FlacLPC qlp coeff precision."); return; //return false; } _qlpCoeffPrecision = u32 + 1; int level = reader.ReadBitsSigned(FlacConstant.SUBFRAME_LPC_QLP_SHIFT_LEN); if (level < 0) { throw new Exception("negative shift"); } _lpcShiftNeeded = level; _qlpCoeffs = new int[FlacConstant.MAX_LPC_ORDER]; //qlp coeffs for (int i = 0; i < order; i++) { _qlpCoeffs[i] = reader.ReadBitsSigned(_qlpCoeffPrecision); } //QLPCoeffs = coeffs; Residual = new FlacResidual(reader, header, data, order); for (int i = 0; i < order; i++) { data.destBuffer[i] = data.residualBuffer[i]; } if (bps + _qlpCoeffPrecision + CSMath.ILog(order) <= 32) { if (bps <= 16 && _qlpCoeffPrecision <= 16) { RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order); //Restore(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); } else { RestoreLPCSignal(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order); } } else { RestoreLPCSignalWide(data.residualBuffer + order, data.destBuffer + order, header.BlockSize - order, order);//RestoreWide(data.residualBuffer + order, data.destBuffer, Header.BlockSize - order, order, order); } //Warmup = warmup; }
public unsafe static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bitsPerSample) { int wastedBits = 0, order; uint firstByte = reader.ReadBits(8); if ((firstByte & 0x80) != 0) //Zero bit padding, to prevent sync-fooling string of 1s { Debug.WriteLine("Flacdecoder subframe-header got no zero-bit padding."); return(null); } bool hasWastedBits = (firstByte & 1) != 0; //Wasted bits-per-sample' flag if (hasWastedBits) { int k = (int)reader.ReadUnary(); wastedBits = k + 1; //"k-1" follows -> add 1 bitsPerSample -= wastedBits; } FlacSubFrameBase subFrame; var subframeType = (firstByte & 0x7E) >> 1; //0111 1110 if (subframeType == 0) //000000 { subFrame = new FlacSubFrameConstant(reader, header, data, bitsPerSample); } else if (subframeType == 1) //000001 { subFrame = new FlacSubFrameVerbatim(reader, header, data, bitsPerSample); } else if ((subframeType & 0x08) != 0) //001000 = 0x08 { order = (int)(subframeType & 0x07); subFrame = new FlacSubFrameFixed(reader, header, data, bitsPerSample, order); } else if ((subframeType & 0x20) != 0) //100000 = 0x20 { order = (int)(subframeType & 0x1F) + 1; subFrame = new FlacSubFrameLPC(reader, header, data, bitsPerSample, order); } else { Debug.WriteLine(String.Format("Invalid Flac-SubframeType. SubframeType: 0x{0:x}.", subframeType)); return(null); } if (hasWastedBits) { int *destination = data.DestinationBuffer; for (int i = 0; i < header.BlockSize; i++) { *(destination++) <<= wastedBits; } } #if FLAC_DEBUG subFrame.WastedBits = wastedBits; #endif return(subFrame); }
private unsafe bool ParseHeader(ref byte *headerBuffer, FlacMetadataStreamInfo streamInfo) { const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)"; int val; if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits { if ((headerBuffer[1] & 0x02) != 0) { Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation); return(false); } byte * __headerbufferPtr = headerBuffer; FlacBitReader reader = new FlacBitReader(__headerbufferPtr, 0); #region blocksize //blocksize val = headerBuffer[2] >> 4; int blocksize = -1; if (val == 0) { Error("Invalid Blocksize value: 0", loggerLocation); return(false); } if (val == 1) { blocksize = 192; } else if (val >= 2 && val <= 5) { blocksize = 576 << (val - 2); } else if (val == 6 || val == 7) { _blocksizeHint = val; } else if (val >= 8 && val <= 15) { blocksize = 256 << (val - 8); } else { Error("Invalid Blocksize value: " + val, loggerLocation); return(false); } BlockSize = blocksize; #endregion blocksize #region samplerate //samplerate val = headerBuffer[2] & 0x0F; int sampleRate = -1; if (val == 0) { if (streamInfo != null) { sampleRate = streamInfo.SampleRate; } else { Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation); return(false); } } else if (val >= 1 && val <= 11) { sampleRate = FlacConstant.SampleRateTable[val]; } else if (val >= 12 && val <= 14) { _sampleRateHint = val; } else { Error("Invalid SampleRate value: " + val, loggerLocation); return(false); } SampleRate = sampleRate; #endregion samplerate #region channels val = headerBuffer[3] >> 4; //cc: unsigned int channels; if ((val & 8) != 0) { channels = 2; if ((val & 7) > 2 || (val & 7) < 0) { Error("Invalid ChannelAssignment", loggerLocation); return(false); } ChannelAssignment = (ChannelAssignment)((val & 7) + 1); } else { channels = val + 1; ChannelAssignment = ChannelAssignment.Independent; } Channels = channels; #endregion channels #region bitspersample val = (headerBuffer[3] & 0x0E) >> 1; int bitsPerSample; if (val == 0) { if (streamInfo != null) { bitsPerSample = streamInfo.BitsPerSample; } else { Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation); return(false); } } else if (val == 3 || val >= 7 || val < 0) { Error("Invalid BitsPerSampleIndex", loggerLocation); return(false); } else { bitsPerSample = FlacConstant.BitPerSampleTable[val]; } BitsPerSample = bitsPerSample; #endregion bitspersample if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0 { Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation); return(false); } reader.ReadBits(32); //skip the first 4 bytes since they got already processed //BYTE 4 #region utf8 //variable blocksize if ((headerBuffer[1] & 0x01) != 0 || (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize)) { ulong samplenumber; if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue) { BlockingStrategy = BlockingStrategy.VariableBlockSize; SampleNumber = (long)samplenumber; } else { Error("Invalid UTF8 Samplenumber coding.", loggerLocation); return(false); } } else //fixed blocksize { uint framenumber; if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue) { BlockingStrategy = BlockingStrategy.FixedBlockSize; FrameNumber = (int)framenumber; } else { Error("Invalid UTF8 Framenumber coding.", loggerLocation); return(false); } } #endregion utf8 #region read hints //blocksize am ende des frameheaders if (_blocksizeHint != 0) { val = (int)reader.ReadBits(8); if (_blocksizeHint == 7) { val = (val << 8) | (int)reader.ReadBits(8); } BlockSize = val + 1; } //samplerate if (_sampleRateHint != 0) { val = (int)reader.ReadBits(8); if (_sampleRateHint != 12) { val = (val << 8) | (int)reader.ReadBits(8); } if (_sampleRateHint == 12) { SampleRate = val * 1000; } else if (_sampleRateHint == 13) { SampleRate = val; } else { SampleRate = val * 10; } } #endregion read hints if (DoCrc) { var crc8 = Utils.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position); Crc8 = (byte)reader.ReadBits(8); if (Crc8 != crc8) { Error("CRC8 missmatch", loggerLocation); return(false); } } else { Crc8 = (byte)reader.ReadBits(8); } headerBuffer += reader.Position; return(true); } Error("Invalid Syncbits", loggerLocation); return(false); }
private unsafe bool ParseHeader(ref byte* headerBuffer, FlacMetadataStreamInfo streamInfo) { const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)"; int val; if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits { if ((headerBuffer[1] & 0x02) != 0) { Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation); return false; } byte* __headerbufferPtr = headerBuffer; FlacBitReader reader = new FlacBitReader(__headerbufferPtr, 0); #region blocksize //blocksize val = headerBuffer[2] >> 4; int blocksize = -1; if (val == 0) { Error("Invalid Blocksize value: 0", loggerLocation); return false; } if (val == 1) blocksize = 192; else if (val >= 2 && val <= 5) blocksize = 576 << (val - 2); else if (val == 6 || val == 7) _blocksizeHint = val; else if (val >= 8 && val <= 15) blocksize = 256 << (val - 8); else { Error("Invalid Blocksize value: " + val, loggerLocation); return false; } BlockSize = blocksize; #endregion blocksize #region samplerate //samplerate val = headerBuffer[2] & 0x0F; int sampleRate = -1; if (val == 0) { if (streamInfo != null) sampleRate = streamInfo.SampleRate; else { Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation); return false; } } else if (val >= 1 && val <= 11) sampleRate = FlacConstant.SampleRateTable[val]; else if (val >= 12 && val <= 14) _sampleRateHint = val; else { Error("Invalid SampleRate value: " + val, loggerLocation); return false; } SampleRate = sampleRate; #endregion samplerate #region channels val = headerBuffer[3] >> 4; //cc: unsigned int channels; if ((val & 8) != 0) { channels = 2; if ((val & 7) > 2 || (val & 7) < 0) { Error("Invalid ChannelAssignment", loggerLocation); return false; } ChannelAssignment = (ChannelAssignment)((val & 7) + 1); } else { channels = val + 1; ChannelAssignment = ChannelAssignment.Independent; } Channels = channels; #endregion channels #region bitspersample val = (headerBuffer[3] & 0x0E) >> 1; int bitsPerSample; if (val == 0) { if (streamInfo != null) bitsPerSample = streamInfo.BitsPerSample; else { Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation); return false; } } else if (val == 3 || val >= 7 || val < 0) { Error("Invalid BitsPerSampleIndex", loggerLocation); return false; } else bitsPerSample = FlacConstant.BitPerSampleTable[val]; BitsPerSample = bitsPerSample; #endregion bitspersample if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0 { Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation); return false; } reader.ReadBits(32); //skip the first 4 bytes since they got already processed //BYTE 4 #region utf8 //variable blocksize if ((headerBuffer[1] & 0x01) != 0 || (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize)) { ulong samplenumber; if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue) { BlockingStrategy = BlockingStrategy.VariableBlockSize; SampleNumber = (long) samplenumber; } else { Error("Invalid UTF8 Samplenumber coding.", loggerLocation); return false; } } else //fixed blocksize { uint framenumber; if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue) { BlockingStrategy = BlockingStrategy.FixedBlockSize; FrameNumber = (int) framenumber; } else { Error("Invalid UTF8 Framenumber coding.", loggerLocation); return false; } } #endregion utf8 #region read hints //blocksize am ende des frameheaders if (_blocksizeHint != 0) { val = (int)reader.ReadBits(8); if (_blocksizeHint == 7) { val = (val << 8) | (int)reader.ReadBits(8); } BlockSize = val + 1; } //samplerate if (_sampleRateHint != 0) { val = (int)reader.ReadBits(8); if (_sampleRateHint != 12) { val = (val << 8) | (int)reader.ReadBits(8); } if (_sampleRateHint == 12) SampleRate = val * 1000; else if (_sampleRateHint == 13) SampleRate = val; else SampleRate = val * 10; } #endregion read hints if (DoCrc) { var crc8 = Utils.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position); Crc8 = (byte) reader.ReadBits(8); if (Crc8 != crc8) { Error("CRC8 missmatch", loggerLocation); return false; } } else { Crc8 = (byte) reader.ReadBits(8); } headerBuffer += reader.Position; return true; } Error("Invalid Syncbits", loggerLocation); return false; }
private unsafe void ReadSubFrames() { List<FlacSubFrameBase> subFrames = new List<FlacSubFrameBase>(); //alocateOutput var data = AllocOuputMemory(); _subFrames = data; byte[] buffer = new byte[0x20000]; if ((_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) > buffer.Length) { buffer = new byte[(_streamInfo.MaxFrameSize * Header.Channels * Header.BitsPerSample * 2 >> 3) - FlacConstant.FrameHeaderSize]; } int read = _stream.Read(buffer, 0, (int)Math.Min(buffer.Length, _stream.Length - _stream.Position)); fixed (byte* ptrBuffer = buffer) { FlacBitReader reader = new FlacBitReader(ptrBuffer, 0); for (int c = 0; c < Header.Channels; c++) { int bitsPerSample = Header.BitsPerSample; if (Header.ChannelAssignment == ChannelAssignment.MidSide || Header.ChannelAssignment == ChannelAssignment.LeftSide) bitsPerSample += c; else if (Header.ChannelAssignment == ChannelAssignment.RightSide) bitsPerSample += 1 - c; var subframe = FlacSubFrameBase.GetSubFrame(reader, data[c], Header, bitsPerSample); subFrames.Add(subframe); } reader.Flush(); Crc16 = (short) reader.ReadBits(16); _stream.Position -= read - reader.Position; MapToChannels(_subFrames); } }
public static FlacSubFrameBase GetSubFrame(FlacBitReader reader, FlacSubFrameData data, FlacFrameHeader header, int bitsPerSample) { unchecked { int wastedBits = 0, order; var firstByte = reader.ReadBits(8); if ((firstByte & 0x80) != 0) //Zero bit padding, to prevent sync-fooling string of 1s { Debug.WriteLine("Flacdecoder subframe-header got no zero-bit padding."); return(null); } var hasWastedBits = (firstByte & 1) != 0; //Wasted bits-per-sample' flag if (hasWastedBits) { var k = (int)reader.ReadUnary(); wastedBits = k + 1; //"k-1" follows -> add 1 bitsPerSample -= wastedBits; } FlacSubFrameBase subFrame; var subframeType = (firstByte & 0x7E) >> 1; //0111 1110 if (subframeType == 0) //000000 { subFrame = new FlacSubFrameConstant(reader, header, data, bitsPerSample); } else if (subframeType == 1) //000001 { subFrame = new FlacSubFrameVerbatim(reader, header, data, bitsPerSample); } else if ((subframeType & 0x20) != 0) //100000 = 0x20 { order = (int)(subframeType & 0x1F) + 1; subFrame = new FlacSubFrameLPC(reader, header, data, bitsPerSample, order); } else if ((subframeType & 0x08) != 0) //001000 = 0x08 { order = (int)(subframeType & 0x07); if (order > 4) { return(null); } subFrame = new FlacSubFrameFixed(reader, header, data, bitsPerSample, order); } else { Debug.WriteLine($"Invalid Flac-SubframeType. SubframeType: 0x{subframeType:x}."); return(null); } if (hasWastedBits) { var destination = data.DestinationBuffer.Span; for (var i = 0; i < header.BlockSize; i++) { destination[i] <<= wastedBits; } } return(subFrame); } }
protected unsafe virtual bool ParseHeader(ref byte* headerBuffer, FlacMetadataStreamInfo streamInfo) { const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)"; int x = -1; //tmp value to store in if (headerBuffer[0] == 0xFF && headerBuffer[1] >> 1 == 0x7C) //sync bits { if ((headerBuffer[1] & 0x02) != 0) // ...10 2. letzes bits muss 0 sein { Error("Invalid FlacFrame. Reservedbit_0 is 1", loggerLocation); return false; } byte* __headerbufferPtr = headerBuffer; FlacBitReader reader = new FlacBitReader(__headerbufferPtr, 0); #region blocksize //blocksize x = headerBuffer[2] >> 4; int blocksize = -1; if (x == 0) { Error("Invalid Blocksize value: 0", loggerLocation); return false; } else if (x == 1) blocksize = 192; else if (x >= 2 && x <= 5) blocksize = 576 << (x - 2); else if (x == 6 || x == 7) blocksize_hint = x; else if (x >= 8 && x <= 15) blocksize = 256 << (x - 8); else { Error("Invalid Blocksize value: " + x, loggerLocation); return false; } BlockSize = blocksize; #endregion blocksize #region samplerate //samplerate x = headerBuffer[2] & 0x0F; int sampleRate = -1; if (x == 0) { if (streamInfo != null) sampleRate = streamInfo.SampleRate; else { Error("Missing Samplerate. Samplerate Index = 0 && streamInfoMetaData == null.", loggerLocation); return false; } } else if (x >= 1 && x <= 11) sampleRate = FlacConstant.SampleRateTable[x]; else if (x >= 12 && x <= 14) sampleRate_hint = x; else { Error("Invalid SampleRate value: " + x, loggerLocation); return false; } SampleRate = sampleRate; #endregion samplerate #region channels x = headerBuffer[3] >> 4; //cc: unsigned int channels = -1; if ((x & 8) != 0) { channels = 2; if ((x & 7) > 2 || (x & 7) < 0) { Error("Invalid ChannelAssignment", loggerLocation); return false; } else ChannelAssignment = (ChannelAssignment)((x & 7) + 1); } else { channels = x + 1; ChannelAssignment = ChannelAssignment.Independent; } Channels = channels; #endregion channels #region bitspersample x = (headerBuffer[3] & 0x0E) >> 1; int bitsPerSample = -1; if (x == 0) { if (streamInfo != null) bitsPerSample = streamInfo.BitsPerSample; else { Error("Missing BitsPerSample. Index = 0 && streamInfoMetaData == null.", loggerLocation); return false; } } else if (x == 3 || x >= 7 || x < 0) { Error("Invalid BitsPerSampleIndex", loggerLocation); return false; } else bitsPerSample = FlacConstant.BitPerSampleTable[x]; BitsPerSample = bitsPerSample; #endregion bitspersample if ((headerBuffer[3] & 0x01) != 0) // reserved bit -> 0 { Error("Invalid FlacFrame. Reservedbit_1 is 1", loggerLocation); return false; } //reader.SkipBits(4 * 8); //erste 3 bytes headerbytes überspringen, da diese schon ohne reader verarbeitet reader.ReadBits(32); //BYTE 4 #region utf8 //variable blocksize if ((headerBuffer[1] & 0x01) != 0 || (streamInfo != null && streamInfo.MinBlockSize != streamInfo.MaxBlockSize)) { ulong samplenumber; if (reader.ReadUTF8_64(out samplenumber) && samplenumber != ulong.MaxValue) { NumberType = FlacNumberType.SampleNumber; SampleNumber = samplenumber; } else { Error("Invalid UTF8 Samplenumber coding.", loggerLocation); return false; } } else //fixed blocksize { uint framenumber;// = reader.ReadUTF8(); if (reader.ReadUTF8_32(out framenumber) && framenumber != uint.MaxValue) { NumberType = FlacNumberType.FrameNumber; FrameNumber = framenumber; } else { Error("Invalid UTF8 Framenumber coding.", loggerLocation); return false; } } #endregion utf8 #region read hints //blocksize am ende des frameheaders if (blocksize_hint != 0) { x = (int)reader.ReadBits(8); if (blocksize_hint == 7) { x = (x << 8) | (int)reader.ReadBits(8); } BlockSize = x + 1; } //samplerate am ende des frameheaders if (sampleRate_hint != 0) { x = (int)reader.ReadBits(8); if (sampleRate_hint != 12) { x = (x << 8) | (int)reader.ReadBits(8); } if (sampleRate_hint == 12) SampleRate = x * 1000; else if (sampleRate_hint == 13) SampleRate = x; else SampleRate = x * 10; } #endregion read hints //if (Channels == 1 && BitsPerSample == 24 && SampleRate == 44100) // System.Diagnostics.Debugger.Break(); if (DoCRC) { var crc8 = CSMath.CRC8.Instance.CalcCheckSum(reader.Buffer, 0, reader.Position); CRC8 = (byte)reader.ReadBits(8); if (CRC8 != crc8) { Error("CRC8 missmatch", loggerLocation); return false; } } headerBuffer += reader.Position; return true; } Error("Invalid Syncbits", loggerLocation); return false; }