From 91f3e583468d20bf0c18583b23ff307cb4061f2d Mon Sep 17 00:00:00 2001 From: Marcus Tomlinson Date: Sat, 23 Dec 2017 11:22:43 +0200 Subject: [PATCH] Replace convertBufferWasapi() calls with renderResampler->Convert() --- RtAudio.cpp | 88 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/RtAudio.cpp b/RtAudio.cpp index 7fb2798..7b2f907 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -3700,6 +3700,7 @@ static const char* getAsioErrorString( ASIOError result ) #include #pragma comment( lib, "mfplat.lib" ) +#pragma comment( lib, "mfuuid.lib" ) #pragma comment( lib, "wmcodecdspuuid" ) //============================================================================= @@ -5071,23 +5072,43 @@ void RtApiWasapi::wasapiThread() // 2. If 1. was successful: Convert callback buffer to user sample rate and channel count // Convert callback buffer to user format - if ( captureAudioClient ) { - // Pull callback buffer from inputBuffer - callbackPulled = captureBuffer.pullBuffer( convBuffer, - ( unsigned int ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT], - stream_.deviceFormat[INPUT] ); + if ( captureAudioClient ) + { + int samplesToPull = ( unsigned int ) floorf( stream_.bufferSize * captureSrRatio ); + if ( captureSrRatio != 1 ) + { + // account for remainders + samplesToPull--; + } + + convBufferSize = 0; + while ( convBufferSize < stream_.bufferSize ) + { + // Pull callback buffer from inputBuffer + callbackPulled = captureBuffer.pullBuffer( convBuffer, + samplesToPull * stream_.nDeviceChannels[INPUT], + stream_.deviceFormat[INPUT] ); + + if ( !callbackPulled ) + { + break; + } - if ( callbackPulled ) { // Convert callback buffer to user sample rate - convertBufferWasapi( stream_.deviceBuffer, - convBuffer, - stream_.nDeviceChannels[INPUT], - captureFormat->nSamplesPerSec, - stream_.sampleRate, - ( unsigned int ) ( stream_.bufferSize * captureSrRatio ), - convBufferSize, - stream_.deviceFormat[INPUT] ); + unsigned int deviceBufferOffset = convBufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.userFormat ); + unsigned int convSamples = 0; + captureResampler->Convert( stream_.deviceBuffer + deviceBufferOffset, + convBuffer, + samplesToPull, + convSamples ); + + convBufferSize += convSamples; + samplesToPull = 1; // now pull one sample at a time until we have stream_.bufferSize samples + } + + if ( callbackPulled ) + { if ( stream_.doConvertBuffer[INPUT] ) { // Convert callback buffer to user format convertBuffer( stream_.userBuffer[INPUT], @@ -5164,24 +5185,26 @@ void RtApiWasapi::wasapiThread() // 2. Convert callback buffer to stream sample rate and channel count // 3. Push callback buffer into outputBuffer - if ( renderAudioClient && callbackPulled ) { - if ( stream_.doConvertBuffer[OUTPUT] ) { - // Convert callback buffer to stream format - convertBuffer( stream_.deviceBuffer, - stream_.userBuffer[OUTPUT], - stream_.convertInfo[OUTPUT] ); + if ( renderAudioClient && callbackPulled ) + { + // if the last call to renderBuffer.PushBuffer() was successful + if ( callbackPushed || convBufferSize == 0 ) + { + if ( stream_.doConvertBuffer[OUTPUT] ) + { + // Convert callback buffer to stream format + convertBuffer( stream_.deviceBuffer, + stream_.userBuffer[OUTPUT], + stream_.convertInfo[OUTPUT] ); - } + } - // Convert callback buffer to stream sample rate - convertBufferWasapi( convBuffer, - stream_.deviceBuffer, - stream_.nDeviceChannels[OUTPUT], - stream_.sampleRate, - renderFormat->nSamplesPerSec, - stream_.bufferSize, - convBufferSize, - stream_.deviceFormat[OUTPUT] ); + // Convert callback buffer to stream sample rate + renderResampler->Convert( convBuffer, + stream_.deviceBuffer, + stream_.bufferSize, + convBufferSize ); + } // Push callback buffer into outputBuffer callbackPushed = renderBuffer.pushBuffer( convBuffer, @@ -5319,7 +5342,10 @@ void RtApiWasapi::wasapiThread() // if the callback buffer was pushed renderBuffer reset callbackPulled flag if ( callbackPushed ) { + // unsetting the callbackPulled flag lets the stream know that + // the audio device is ready for another callback output buffer. callbackPulled = false; + // tick stream time RtApi::tickStreamTime(); } @@ -5332,6 +5358,8 @@ Exit: CoTaskMemFree( renderFormat ); free ( convBuffer ); + delete renderResampler; + delete captureResampler; CoUninitialize(); -- 2.30.2