Skip to content

Commit

Permalink
BufferedWaveProvider configurable Read behaviour
Browse files Browse the repository at this point in the history
ReadFully defaults to true and ensures bytes requested from count is always returned
  • Loading branch information
markheath committed Sep 20, 2015
1 parent 762ee66 commit 6cfd03d
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
19 changes: 14 additions & 5 deletions NAudio/Wave/WaveProviders/BufferedWaveProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using NAudio.Utils;

// ReSharper disable once CheckNamespace
namespace NAudio.Wave
{
/// <summary>
Expand All @@ -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;
}

/// <summary>
/// If true, always read the amount of data requested, padding with zeroes if necessary
/// By default is set to true
/// </summary>
public bool ReadFully { get; set; }

/// <summary>
/// Buffer length in bytes
/// </summary>
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

/// <summary>
Expand Down
49 changes: 46 additions & 3 deletions NAudioTests/WaveStreams/BufferedWaveProviderTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Linq;
using NAudio.Wave;
using NUnit.Framework;

Expand Down Expand Up @@ -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);
}

}
}
4 changes: 4 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 6cfd03d

Please sign in to comment.