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;
        }
        void LoadFromXml(string dir, XmlNode track)
        {
            FileName = track.Attributes["name"].Value;
            StartSample = Convert.ToInt64(track.Attributes["startSample"].Value);
            EndSample = Convert.ToInt64(track.Attributes["endSample"].Value);

            Metadata = LoadMetadata(dir, FileName);
            long metadataBlockSize = Metadata.block.Length + 4; // 4 is size of metadatablockheader
            Size = Convert.ToInt64(track.Attributes["size"].Value) + metadataBlockSize;

            MinBlockSize  = Convert.ToInt32(track.Attributes["minBlockSize"].Value);
            MaxBlockSize = Convert.ToInt32(track.Attributes["maxBlockSize"].Value);
            MinFrameSize = Convert.ToInt32(track.Attributes["minFrameSize"].Value);
            MaxFrameSize = Convert.ToInt32(track.Attributes["maxFrameSize"].Value);
            TotalSamples = Convert.ToInt64(track.Attributes["totalSamples"].Value);

            XmlNode frames = track.SelectSingleNode("frames");
            MemoryStream ms = new MemoryStream(Convert.FromBase64String(frames.InnerText));
            BinaryReader br = new BinaryReader(ms);

            while (ms.Position < ms.Length)
            {
                TrackFrame trackFrame = new TrackFrame(br, metadataBlockSize);
                frames_.Add(trackFrame.virtualOffset, trackFrame);
            }
            frames_.Values[0].CalculateVirtualBlockSizeDifference(StartSample, true);
            frames_.Values[frames_.Count - 1].CalculateVirtualBlockSizeDifference(EndSample, false);
        }