/// <summary> /// Gets or sets the source stream. See remarks. /// </summary> /// <value>The source.</value> /// <remarks> /// The source must be set before calling <see cref="GetSamples()"/> /// </remarks> public void SetSourceStream(Stream value) { lock (sourceReaderLock) { // If the nextSourceReader is not null if (nextSourceReader != null) { nextSourceReader.Dispose(); } nextSourceReader = new SourceReader(value); Initialize(nextSourceReader); } }
/// <summary> /// Gets the decoded PCM samples. See remarks. /// </summary> /// <param name="startingPositionInSeconds">The starting position in seconds.</param> /// <returns>An enumerator of pointer to PCM decoded data with the same format as returned by <see cref="WaveFormat"/>.</returns> /// <remarks> /// This method is only working as a single enumerator at a time. /// The <see cref="SetSourceStream(System.IO.Stream)"/> must be set before calling <see cref="GetSamples()"/> /// </remarks> public IEnumerable <DataPointer> GetSamples(TimeSpan startingPositionInSeconds) { // A new reader is setup, so initialize it. lock (sourceReaderLock) { // If the reader was changed if (nextSourceReader != null) { if (sourceReader != null) { sourceReader.Dispose(); } sourceReader = nextSourceReader; nextSourceReader = null; } } // Make sure that any prior call CleanupAndDispose(); CheckIfDisposed(); // Set the position sourceReader.SetCurrentPosition((long)(startingPositionInSeconds.Ticks)); while (true) { int streamIndex; SourceReaderFlags flags; long time; CheckIfDisposed(); using (currentSample = sourceReader.ReadSample(SourceReaderIndex.FirstAudioStream, SourceReaderControlFlags.None, out streamIndex, out flags, out time)) { if ((flags & SourceReaderFlags.Endofstream) != 0) { break; } CheckIfDisposed(); using (currentBuffer = currentSample.ConvertToContiguousBuffer()) { int bufferMaxLength; int bufferCurrentLength; CheckIfDisposed(); var ptr = currentBuffer.Lock(out bufferMaxLength, out bufferCurrentLength); yield return(new DataPointer(ptr, bufferCurrentLength)); // Warning, because the yield could never return here, currentBuffer and currentSample should be disposed when disposing this object or when // calling it again on the GetSamples method. // In case a Dispose occurred while decoding if (currentBuffer == null) { break; } currentBuffer.Unlock(); } } } // They have been disposed, so we can just clear them currentBuffer = null; currentSample = null; }