diff --git a/NAudio/Wave/WaveProviders/BufferedWaveProvider.cs b/NAudio/Wave/WaveProviders/BufferedWaveProvider.cs index 87085a21..752c7d16 100644 --- a/NAudio/Wave/WaveProviders/BufferedWaveProvider.cs +++ b/NAudio/Wave/WaveProviders/BufferedWaveProvider.cs @@ -1,6 +1,7 @@ using System; using NAudio.Utils; +// ReSharper disable once CheckNamespace namespace NAudio.Wave { /// @@ -20,9 +21,16 @@ public class BufferedWaveProvider : IWaveProvider public BufferedWaveProvider(WaveFormat waveFormat) { this.waveFormat = waveFormat; - this.BufferLength = waveFormat.AverageBytesPerSecond * 5; + BufferLength = waveFormat.AverageBytesPerSecond * 5; + ReadFully = true; } + /// + /// If true, always read the amount of data requested, padding with zeroes if necessary + /// By default is set to true + /// + public bool ReadFully { get; set; } + /// /// Buffer length in bytes /// @@ -84,7 +92,7 @@ public void AddSamples(byte[] buffer, int offset, int count) // create buffer here to allow user to customise buffer length if (circularBuffer == null) { - circularBuffer = new CircularBuffer(this.BufferLength); + circularBuffer = new CircularBuffer(BufferLength); } var written = circularBuffer.Write(buffer, offset, count); @@ -103,14 +111,15 @@ public int Read(byte[] buffer, int offset, int count) int read = 0; if (circularBuffer != null) // not yet created { - read = this.circularBuffer.Read(buffer, offset, count); + read = circularBuffer.Read(buffer, offset, count); } - if (read < count) + if (ReadFully && read < count) { // zero the end of the buffer Array.Clear(buffer, offset + read, count - read); + read = count; } - return count; + return read; } /// diff --git a/NAudioTests/WaveStreams/BufferedWaveProviderTests.cs b/NAudioTests/WaveStreams/BufferedWaveProviderTests.cs index a660943c..d8d586b7 100644 --- a/NAudioTests/WaveStreams/BufferedWaveProviderTests.cs +++ b/NAudioTests/WaveStreams/BufferedWaveProviderTests.cs @@ -1,6 +1,4 @@ -using System; -using System.ComponentModel; -using System.Linq; +using System.Linq; using NAudio.Wave; using NUnit.Framework; @@ -31,5 +29,50 @@ public void BufferedBytesAreReturned() Assert.AreEqual(readBuffer,data); Assert.AreEqual(0, bwp.BufferedBytes); } + + [Test] + public void EmptyBufferCanReturnZeroFromRead() + { + var bwp = new BufferedWaveProvider(new WaveFormat()); + bwp.ReadFully = false; + var buffer = new byte[44100]; + var read = bwp.Read(buffer, 0, buffer.Length); + Assert.AreEqual(0, read); + } + + [Test] + public void PartialReadsPossibleWithReadFullyFalse() + { + var bwp = new BufferedWaveProvider(new WaveFormat()); + bwp.ReadFully = false; + var buffer = new byte[44100]; + bwp.AddSamples(buffer, 0, 2000); + var read = bwp.Read(buffer, 0, buffer.Length); + Assert.AreEqual(2000, read); + Assert.AreEqual(0, bwp.BufferedBytes); + } + + [Test] + public void FullReadsByDefault() + { + var bwp = new BufferedWaveProvider(new WaveFormat()); + var buffer = new byte[44100]; + bwp.AddSamples(buffer, 0, 2000); + var read = bwp.Read(buffer, 0, buffer.Length); + Assert.AreEqual(buffer.Length, read); + Assert.AreEqual(0, bwp.BufferedBytes); + } + + [Test] + public void WhenBufferHasMoreThanNeededReadFully() + { + var bwp = new BufferedWaveProvider(new WaveFormat()); + var buffer = new byte[44100]; + bwp.AddSamples(buffer, 0, 5000); + var read = bwp.Read(buffer, 0, 2000); + Assert.AreEqual(2000, read); + Assert.AreEqual(3000, bwp.BufferedBytes); + } + } } diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f8eaa76d..1b638d9c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -20,6 +20,10 @@ * RawSourceStream handles end of stream better * PropVariant supports VT_BOOL * Better handling of exceptions in WaveFileReader constructor + * WasapiOut default constructor (uses default device, shared mode) + * WasapiCapture and WasapiLoopbackCapture can report capture state + * BufferedWaveProvider can be configured to not fully read if no data is available + * WasapiOut can report the default mix format for shared mode #### 1.7.3 5 Mar 2015