/// <summary>
        /// Internally append this slice (which must be allocated from our free buffer); this does the work
        /// of coalescing, updating _data and other fields, etc.
        /// </summary>
        Slice <TTime, TValue> InternalAppend(Slice <TTime, TValue> dest)
        {
            // dest must be from our free buffer
            HoloDebug.Assert(dest.Buffer.Data == _remainingFreeBuffer.Buffer.Data);

            if (_data.Count == 0)
            {
                _data.Add(new TimedSlice <TTime, TValue>(InitialTime, dest));
            }
            else
            {
                TimedSlice <TTime, TValue> last = _data[_data.Count - 1];
                if (last.Slice.Precedes(dest))
                {
                    _data[_data.Count - 1] = new TimedSlice <TTime, TValue>(last.InitialTime, last.Slice.UnionWith(dest));
                }
                else
                {
                    Spam.Audio.WriteLine("BufferedSliceStream.InternalAppend: last did not precede; last slice is " + last.Slice + ", last slice time " + last.InitialTime + ", dest is " + dest);
                    _data.Add(new TimedSlice <TTime, TValue>(last.InitialTime + last.Slice.Duration, dest));
                }
            }

            _discreteDuration   += dest.Duration;
            _remainingFreeBuffer = _remainingFreeBuffer.SubsliceStartingAt(dest.Duration);

            return(dest);
        }
Ejemplo n.º 2
0
 public int Compare(TimedSlice <TTime, TValue> x, TimedSlice <TTime, TValue> y)
 {
     if (x.InitialTime < y.InitialTime)
     {
         return(-1);
     }
     else if (x.InitialTime > y.InitialTime)
     {
         return(1);
     }
     else
     {
         return(0);
     }
 }
        /// <summary>
        /// Trim off any content beyond the maximum allowed to be buffered.
        /// </summary>
        /// <remarks>
        /// Internal because wrapper streams want to delegate to this when they are themselves Trimmed.</remarks>
        void Trim()
        {
            if (_maxBufferedDuration == 0 || _discreteDuration <= _maxBufferedDuration)
            {
                return;
            }

            while (DiscreteDuration > _maxBufferedDuration)
            {
                Duration <TTime> toTrim = DiscreteDuration - _maxBufferedDuration;
                // get the first slice
                TimedSlice <TTime, TValue> firstSlice = _data[0];
                if (firstSlice.Slice.Duration <= toTrim)
                {
                    _data.RemoveAt(0);
#if DEBUG
                    // check to make sure our later stream data doesn't reference this one we're about to free
                    foreach (TimedSlice <TTime, TValue> slice in _data)
                    {
                        HoloDebug.Assert(slice.Slice.Buffer.Data != firstSlice.Slice.Buffer.Data);
                    }
#endif
                    _allocator.Free(firstSlice.Slice.Buffer);
                    _discreteDuration -= firstSlice.Slice.Duration;
                    _initialTime      += firstSlice.Slice.Duration;
                }
                else
                {
                    TimedSlice <TTime, TValue> newFirstSlice = new TimedSlice <TTime, TValue>(
                        firstSlice.InitialTime + toTrim,
                        new Slice <TTime, TValue>(
                            firstSlice.Slice.Buffer,
                            firstSlice.Slice.Offset + toTrim,
                            firstSlice.Slice.Duration - toTrim,
                            SliverSize));
                    _data[0]           = newFirstSlice;
                    _discreteDuration -= toTrim;
                    _initialTime      += toTrim;
                }
            }
        }
        /// <summary>
        /// Map the interval time to stream local time, and get the next slice of it.
        /// </summary>
        /// <param name="interval"></param>
        /// <returns></returns>
        public override Slice <TTime, TValue> GetNextSliceAt(Interval <TTime> interval)
        {
            Interval <TTime> firstMappedInterval = _intervalMapper.MapNextSubInterval(interval);

            if (firstMappedInterval.IsEmpty)
            {
                return(Slice <TTime, TValue> .Empty);
            }

            HoloDebug.Assert(firstMappedInterval.InitialTime >= InitialTime);
            HoloDebug.Assert(firstMappedInterval.InitialTime + firstMappedInterval.Duration <= InitialTime + DiscreteDuration);

            TimedSlice <TTime, TValue> foundTimedSlice = GetInitialTimedSlice(firstMappedInterval);
            Interval <TTime>           intersection    = foundTimedSlice.Interval.Intersect(firstMappedInterval);

            HoloDebug.Assert(!intersection.IsEmpty);
            Slice <TTime, TValue> ret = foundTimedSlice.Slice.Subslice(
                intersection.InitialTime - foundTimedSlice.InitialTime,
                intersection.Duration);

            return(ret);
        }
        TimedSlice <TTime, TValue> GetInitialTimedSlice(Interval <TTime> firstMappedInterval)
        {
            // we must overlap somewhere
            HoloDebug.Assert(!firstMappedInterval.Intersect(new Interval <TTime>(InitialTime, DiscreteDuration)).IsEmpty);

            // Get the biggest available slice at firstMappedInterval.InitialTime.
            // First, get the index of the slice just after the one we want.
            TimedSlice <TTime, TValue> target = new TimedSlice <TTime, TValue>(firstMappedInterval.InitialTime, Slice <TTime, TValue> .Empty);
            int originalIndex = _data.BinarySearch(target, TimedSlice <TTime, TValue> .Comparer.Instance);
            int index         = originalIndex;

            if (index < 0)
            {
                // index is then the index of the next larger element
                // -- we know there is a smaller element because we know firstMappedInterval fits inside stream interval
                index = (~index) - 1;
                HoloDebug.Assert(index >= 0);
            }

            TimedSlice <TTime, TValue> foundTimedSlice = _data[index];

            return(foundTimedSlice);
        }