Browse Source

resampler dmo stream working in WASAPI without need for MTAThread

pull/1/head
markheath 17 years ago
parent
commit
6f4c7f85b8
  1. 3
      NAudio/Changes.xml
  2. 1
      NAudio/CoreAudioApi/AudioClient.cs
  3. 4
      NAudio/Properties/AssemblyInfo.cs
  4. 86
      NAudio/Wave/WaveOutputs/WasapiOut.cs
  5. 8
      NAudio/Wave/WaveStreams/ResamplerDmoStream.cs

3
NAudio/Changes.xml

@ -823,6 +823,7 @@
<change>
<version>1.2.134.0</version>
<author>Mark Heath</author>
<desc>Fix to get WASAPI out working with DMO resampler again (still needs MTA)</desc>
<desc>Fix to get WASAPI out working with DMO resampler again</desc>
<desc>Fix to get WASAPI working with DMO resampler without needing MTA Thread (woohoo!)</desc>
</change>
</changes>

1
NAudio/CoreAudioApi/AudioClient.cs

@ -170,6 +170,7 @@ namespace NAudio.CoreAudioApi
WaveFormat desiredFormat, out WaveFormatExtensible closestMatchFormat )
{
int hresult = audioClientInterface.IsFormatSupported(shareMode, desiredFormat, out closestMatchFormat);
// S_OK is 0, S_FALSE = 1
if (hresult == 0)
{

4
NAudio/Properties/AssemblyInfo.cs

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.2.128.0")]
[assembly: AssemblyFileVersion("1.2.128.0")]
[assembly: AssemblyVersion("1.2.134.0")]
[assembly: AssemblyFileVersion("1.2.134.0")]

86
NAudio/Wave/WaveOutputs/WasapiOut.cs

@ -22,6 +22,10 @@ namespace NAudio.Wave
byte[] readBuffer;
PlaybackState playbackState;
Thread playThread;
WaveFormat outputFormat;
bool dmoResamplerNeeded;
/// <summary>
/// WASAPI Out using default audio endpoint
@ -54,34 +58,53 @@ namespace NAudio.Wave
private void PlayThread()
{
// fill a whole buffer
bufferFrameCount = audioClient.BufferSize;
bytesPerFrame = audioClient.MixFormat.Channels * audioClient.MixFormat.BitsPerSample / 8;
readBuffer = new byte[bufferFrameCount * bytesPerFrame];
FillBuffer(bufferFrameCount);
audioClient.Start();
while(playbackState != PlaybackState.Stopped)
{
// Sleep for half the buffer duration.
Thread.Sleep(latencyMilliseconds/2);
if (playbackState == PlaybackState.Playing)
ResamplerDmoStream resamplerDmoStream = null;
try
{
if (this.dmoResamplerNeeded)
{
// See how much buffer space is available.
int numFramesPadding = audioClient.CurrentPadding;
int numFramesAvailable = bufferFrameCount - numFramesPadding;
if (numFramesAvailable > 0)
resamplerDmoStream = new ResamplerDmoStream(sourceStream, outputFormat);
this.sourceStream = resamplerDmoStream;
}
// fill a whole buffer
bufferFrameCount = audioClient.BufferSize;
bytesPerFrame = audioClient.MixFormat.Channels * audioClient.MixFormat.BitsPerSample / 8;
readBuffer = new byte[bufferFrameCount * bytesPerFrame];
FillBuffer(bufferFrameCount);
audioClient.Start();
while (playbackState != PlaybackState.Stopped)
{
// Sleep for half the buffer duration.
Thread.Sleep(latencyMilliseconds / 2);
if (playbackState == PlaybackState.Playing)
{
FillBuffer(numFramesAvailable);
}
// See how much buffer space is available.
int numFramesPadding = audioClient.CurrentPadding;
int numFramesAvailable = bufferFrameCount - numFramesPadding;
if (numFramesAvailable > 0)
{
FillBuffer(numFramesAvailable);
}
}
}
Thread.Sleep(latencyMilliseconds / 2);
audioClient.Stop();
if (playbackState == PlaybackState.Stopped)
{
audioClient.Reset();
}
}
Thread.Sleep(latencyMilliseconds / 2);
audioClient.Stop();
if (playbackState == PlaybackState.Stopped)
finally
{
audioClient.Reset();
if (resamplerDmoStream != null)
{
sourceStream = resamplerDmoStream.InputStream;
resamplerDmoStream.Dispose();
}
}
}
@ -149,11 +172,10 @@ namespace NAudio.Wave
public void Init(WaveStream waveStream)
{
long latencyRefTimes = latencyMilliseconds * 10000;
outputFormat = waveStream.WaveFormat;
// first attempt uses the WaveFormat from the WaveStream
WaveFormat outputFormat;
WaveFormatExtensible closestSampleRateFormat;
if (!audioClient.IsFormatSupported(shareMode, waveStream.WaveFormat, out closestSampleRateFormat))
if (!audioClient.IsFormatSupported(shareMode, outputFormat, out closestSampleRateFormat))
{
// Use closesSampleRateFormat (in sharedMode, it equals usualy to the audioClient.MixFormat)
// See documentation : http://msdn.microsoft.com/en-us/library/ms678737(VS.85).aspx
@ -175,15 +197,21 @@ namespace NAudio.Wave
{
outputFormat = closestSampleRateFormat;
}
this.sourceStream = new ResamplerDmoStream(waveStream, outputFormat);
// just check that we can make it.
using (new ResamplerDmoStream(waveStream, outputFormat))
{
}
this.dmoResamplerNeeded = true;
}
else
{
this.sourceStream = waveStream;
dmoResamplerNeeded = false;
}
this.sourceStream = waveStream;
audioClient.Initialize(shareMode, AudioClientStreamFlags.None, latencyRefTimes, latencyRefTimes,
sourceStream.WaveFormat, Guid.Empty);
outputFormat, Guid.Empty);
renderClient = audioClient.AudioRenderClient;
}

8
NAudio/Wave/WaveStreams/ResamplerDmoStream.cs

@ -54,6 +54,14 @@ namespace NAudio.Wave
get { return outputFormat; }
}
/// <summary>
/// Input Stream
/// </summary>
public WaveStream InputStream
{
get { return inputStream; }
}
private long InputToOutputPosition(long inputPosition)
{
double ratio = (double)outputFormat.AverageBytesPerSecond

Loading…
Cancel
Save