private void Decode(Stream stream, FlacMetadataStreamInfo streamInfo) { Header = new FlacFrameHeader(stream, streamInfo); _stream = stream; _streamInfo = streamInfo; HasError = Header.HasError; if (!HasError) { ReadSubFrames(); FreeBuffers(); } }
public static void ProcessResidual(FlacBitReader reader, FlacFrameHeader header, FlacSubFrameData data, int order, int partitionOrder, FlacResidualCodingMethod codingMethod) { data.Content.UpdateSize(partitionOrder); var isRice2 = codingMethod == FlacResidualCodingMethod.PartitionedRice2; var riceParameterLength = isRice2 ? 5 : 4; var escapeCode = isRice2 ? 31 : 15; //11111 : 1111 var partitionCount = 1 << partitionOrder; //2^partitionOrder -> There will be 2^order partitions. -> "order" = partitionOrder in this case var residualBuffer = data.ResidualBuffer.Span.Slice(order); for (var p = 0; p < partitionCount; p++) { int samplesPerPartition; if (partitionOrder == 0) { samplesPerPartition = header.BlockSize - order; } else if (p > 0) { samplesPerPartition = header.BlockSize >> partitionOrder; } else { samplesPerPartition = (header.BlockSize >> partitionOrder) - order; } var riceParameter = reader.ReadBits(riceParameterLength); data.Content.Parameters[p] = (int)riceParameter; if (riceParameter >= escapeCode) { var raw = reader.ReadBits(5); //raw is always 5 bits (see ...(+5)) data.Content.RawBits[p] = (int)raw; for (var i = 0; i < samplesPerPartition; i++) { var sample = reader.ReadBitsSigned((int)raw); residualBuffer[i] = sample; } } else { ReadFlacRiceBlock(reader, samplesPerPartition, (int)riceParameter, residualBuffer); } residualBuffer = residualBuffer.Slice(samplesPerPartition); } }
private unsafe List <FlacFrameInformation> ScanThisShit(FlacMetadataStreamInfo streamInfo) { var stream = _stream; //if (!(stream is BufferedStream)) // stream = new BufferedStream(stream); var buffer = new byte[BufferSize]; stream.Position = 4; //fLaC //skip the metadata FlacMetadata.SkipMetadata(stream); var frames = new List <FlacFrameInformation>(); var frameInfo = new FlacFrameInformation { IsFirstFrame = true }; FlacFrameHeader baseHeader = null; while (true) { var read = stream.Read(buffer, 0, buffer.Length); if (read <= FlacConstant.FrameHeaderSize) break; fixed(byte *bufferPtr = buffer) { var ptr = bufferPtr; //for (int i = 0; i < read - FlacConstant.FrameHeaderSize; i++) while ((bufferPtr + read - FlacConstant.FrameHeaderSize) > ptr) { if (*ptr++ == 0xFF && (*ptr & 0xF8) == 0xF8) //check sync { var ptrSafe = ptr; ptr--; if (IsFrame(ref ptr, streamInfo, out var tmp)) { var header = tmp; if (frameInfo.IsFirstFrame) { baseHeader = header; frameInfo.IsFirstFrame = false; } if (baseHeader != null && baseHeader.IsFormatEqualTo(header)) { frameInfo.StreamOffset = stream.Position - read + ((ptrSafe - 1) - bufferPtr); frameInfo.Header = header; frames.Add(frameInfo); frameInfo.SampleOffset += header.BlockSize; } else { ptr = ptrSafe; } } else { ptr = ptrSafe; } } } } stream.Position -= FlacConstant.FrameHeaderSize; }