/// <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); }
/// <summary> /// Append this slice's data, by copying it into this stream's private buffers. /// </summary> public override void Append(Slice <TTime, TValue> source) { HoloDebug.Assert(!IsShut); // Try to keep copying source into _remainingFreeBuffer while (!source.IsEmpty()) { EnsureFreeBuffer(); // if source is larger than available free buffer, then we'll iterate Slice <TTime, TValue> originalSource = source; if (source.Duration > _remainingFreeBuffer.Duration) { source = source.Subslice(0, _remainingFreeBuffer.Duration); } // now we know source can fit Slice <TTime, TValue> dest = _remainingFreeBuffer.SubsliceOfDuration(source.Duration); source.CopyTo(dest); // dest may well be adjacent to the previous slice, if there is one, since we may // be appending onto an open chunk. So here is where we coalesce this, if so. dest = InternalAppend(dest); // and update our loop variables source = originalSource.SubsliceStartingAt(source.Duration); Trim(); } }