private void WriteFrame(Frame frame, FrameHeader header, long start, long end) { frame.ReadData(stream_); frame.ReadFooter(stream_); long startSample = frame.Header.StartingSampleNumber; int count = (int)(end - start); header.StartingSampleNumber = sampleCount_; header.BlockingStrategy = FrameHeader.BLOCKING_STRATEGY_VARIABLE; if (count == header.BlockSize) { frame.Write(outStream_); } else { header.BlockSize = count; frame.Write(outStream_, (int)(start - startSample), count); } trackFrameCount_++; sampleCount_ += header.BlockSize; }
private void WriteFrame(Frame frame, VirtualTrack track, long start, long end, int frameSize, long imageStartSample, long offset) { TrackFrame trackFrame = new TrackFrame(offset, frameSize, imageStartSample); trackFrame.imageBlockSize = frame.Header.BlockSize; trackFrame.startSample = sampleCount_; trackFrame.virtualOffset = track.Size; int count = (int)(end - start); int virtualSize; int sizeDifference = 0; if (frame.Header.BlockSize == count) { sizeDifference = flac.Io.UTF8Encoder.GetUtf8ULong(sampleCount_).Length - frame.Header.SampleIdSize; virtualSize = frameSize + sizeDifference; #if DEBUG frame.Header.StartingSampleNumber = sampleCount_; frame.Header.BlockingStrategy = FrameHeader.BLOCKING_STRATEGY_VARIABLE; outStream_.Writer.Truncate(0); frame.Write(outStream_); Debug.Assert(virtualSize == outStream_.Writer.Debug_BytesWritten); #endif } else { frame.Header.StartingSampleNumber = sampleCount_; frame.Header.BlockingStrategy = FrameHeader.BLOCKING_STRATEGY_VARIABLE; frame.Header.BlockSize = count; outStream_.Writer.Truncate(0); frame.Write(outStream_, (int)(start - imageStartSample), count); virtualSize = Convert.ToInt32(outStream_.Writer.Debug_BytesWritten); sizeDifference = virtualSize - frameSize; } trackFrame.sizeDifference = sizeDifference; track.Frames.Add(trackFrame.virtualOffset, trackFrame); track.Size += virtualSize; track.MinBlockSize = Math.Min(track.MinBlockSize, frame.Header.BlockSize); track.MaxBlockSize = Math.Max(track.MaxBlockSize, frame.Header.BlockSize); track.MinFrameSize = (int)Math.Min(track.MinFrameSize, virtualSize); track.MaxFrameSize = (int)Math.Max(track.MaxFrameSize, virtualSize); sampleCount_ += frame.Header.BlockSize; }
// read n bytes of virtual track starting at x offset into provided buffer public int Read(byte[] bytes, long offset, int count) { count = Math.Min((int)(track_.Size - offset), count); int bytesToRead = count; long currentOffset = offset; long endOffset = Math.Max(currentOffset, offset + bytesToRead - 1); // if header, copy it from memory long max = Math.Min(endOffset + 1, header_.Length); while (currentOffset < max) { bytes[currentOffset - offset] = header_[currentOffset]; currentOffset++; bytesToRead--; } if (bytesToRead <= 0) { goto exit; } List<TrackFrame> pairs; int currentIndex = GetOffsetPairs(bytesToRead, currentOffset, out pairs); foreach (TrackFrame op in pairs) { inStream_.Reader.Seek(op.imageOffset); Frame f = new Frame(); f.ReadHeader(inStream_); f.ReadData(inStream_); f.ReadFooter(inStream_); f.Header.BlockingStrategy = FrameHeader.BLOCKING_STRATEGY_VARIABLE; f.Header.StartingSampleNumber = op.startSample; f.Header.BlockSize = op.virtualBlockSize; outStream_.Writer.Truncate(0); bool countFunction = false; if ((currentIndex == 0 && op.imageStartSample != track_.StartSample) || (currentIndex == track_.Frames.Count -1 && op.imageEndSample != track_.EndSample)) { // partial frame long start = Math.Max(track_.StartSample, op.imageStartSample); long end = Math.Min(track_.EndSample, op.imageEndSample); f.Write(outStream_, (int)(start - op.imageStartSample), (int)(end - start)); countFunction = true; } else { f.Write(outStream_); } byte[] data = ReadAllBytes(); max = Math.Min(endOffset + 1, op.virtualOffset + op.virtualSize); if (!countFunction) { Debug.Assert(data.Length == op.virtualSize); } int i = Convert.ToInt32(currentOffset - op.virtualOffset); while (currentOffset < max) { bytes[currentOffset - offset] = data[i]; i++; currentOffset++; bytesToRead--; } if (bytesToRead <= 0) { break; } currentIndex++; } exit: return count; }