Beispiel #1
0
        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;
        }