private unsafe bool ParseHeader(ref byte *headerBuffer, FlacMetadataStreamInfo streamInfo) { const string loggerLocation = "FlacFrameHeader.ParseHeader(byte*, FlacMetadataStreamInfo)"; 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); } var __headerbufferPtr = headerBuffer; var reader = new FlacBitReader(__headerbufferPtr, 0); #region blocksize //blocksize var val = headerBuffer[2] >> 4; var 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; var 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)) { if (reader.ReadUTF8_64(out var samplenumber) && samplenumber != ulong.MaxValue) { BlockingStrategy = BlockingStrategy.VariableBlockSize; SampleNumber = (long)samplenumber; } else { Error("Invalid UTF8 Samplenumber coding.", loggerLocation); return(false); } } else //fixed blocksize { if (reader.ReadUTF8_32(out var framenumber) && framenumber != uint.MaxValue) { BlockingStrategy = BlockingStrategy.FixedBlockSize; FrameNumber = (int)framenumber; }
/// <summary> /// Initializes a new instance of the <see cref="FlacFrameHeader"/> class. /// </summary> /// <param name="buffer">The raw byte-data which contains the <see cref="FlacFrameHeader"/>.</param> /// <param name="streamInfo">The stream-info-metadata-block of the flac stream which provides some basic information about the flac framestream. Can be set to null.</param> /// <param name="doCrc">A value which indicates whether the crc8 checksum of the <see cref="FlacFrameHeader"/> should be calculated.</param> public unsafe FlacFrameHeader(ref byte *buffer, FlacMetadataStreamInfo streamInfo, bool doCrc) : this(ref buffer, streamInfo, doCrc, true) { }