|
|
|
@@ -3578,6 +3578,12 @@ static const char* getAsioErrorString( ASIOError result ) |
|
|
|
|
|
|
|
#if defined(__WINDOWS_WASAPI__) // Windows WASAPI API
|
|
|
|
|
|
|
|
// Authored by Marcus Tomlinson <themarcustomlinson@gmail.com>, April 2014
|
|
|
|
// - Introduces support for the Windows WASAPI API
|
|
|
|
// - Aims to deliver bit streams to and from hardware at the lowest possible latency, via the absolute minimum buffer sizes required
|
|
|
|
// - Provides flexible stream configuration to an otherwise strict and inflexible WASAPI interface
|
|
|
|
// - Includes automatic internal conversion of sample rate, buffer size and channel count
|
|
|
|
|
|
|
|
#ifndef INITGUID
|
|
|
|
#define INITGUID
|
|
|
|
#endif
|
|
|
|
@@ -3762,8 +3768,7 @@ private: |
|
|
|
// channel counts between HW and the user. The convertBufferWasapi function is used to perform
|
|
|
|
// these conversions between HwIn->UserIn and UserOut->HwOut during the stream callback loop.
|
|
|
|
// This sample rate converter favors speed over quality, and works best with conversions between
|
|
|
|
// one rate and its multiple. RtApiWasapi will not populate a device's sample rate list with rates
|
|
|
|
// that may cause artifacts via this conversion.
|
|
|
|
// one rate and its multiple.
|
|
|
|
void convertBufferWasapi( char* outBuffer,
|
|
|
|
const char* inBuffer,
|
|
|
|
const unsigned int& inChannelCount,
|
|
|
|
@@ -4090,18 +4095,9 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) |
|
|
|
// sample rates
|
|
|
|
info.sampleRates.clear();
|
|
|
|
|
|
|
|
// allow support for sample rates that are multiples of the base rate
|
|
|
|
// allow support for all sample rates as we have a built-in sample rate converter
|
|
|
|
for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
|
|
|
|
if ( SAMPLE_RATES[i] < deviceFormat->nSamplesPerSec ) {
|
|
|
|
if ( deviceFormat->nSamplesPerSec % SAMPLE_RATES[i] == 0 ) {
|
|
|
|
info.sampleRates.push_back( SAMPLE_RATES[i] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( SAMPLE_RATES[i] % deviceFormat->nSamplesPerSec == 0 ) {
|
|
|
|
info.sampleRates.push_back( SAMPLE_RATES[i] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
info.sampleRates.push_back( SAMPLE_RATES[i] );
|
|
|
|
}
|
|
|
|
|
|
|
|
// native format
|
|
|
|
@@ -4620,7 +4616,8 @@ void RtApiWasapi::wasapiThread() |
|
|
|
|
|
|
|
// convBuffer is used to store converted buffers between WASAPI and the user
|
|
|
|
char* convBuffer = NULL;
|
|
|
|
unsigned int deviceBufferSize = 0;
|
|
|
|
unsigned int convBuffSize = 0;
|
|
|
|
unsigned int deviceBuffSize = 0;
|
|
|
|
|
|
|
|
errorText_.clear();
|
|
|
|
RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR;
|
|
|
|
@@ -4795,18 +4792,22 @@ void RtApiWasapi::wasapiThread() |
|
|
|
}
|
|
|
|
|
|
|
|
if ( stream_.mode == INPUT ) {
|
|
|
|
deviceBufferSize = ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
|
|
|
|
convBuffSize = ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
|
|
|
|
deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] );
|
|
|
|
}
|
|
|
|
else if ( stream_.mode == OUTPUT ) {
|
|
|
|
deviceBufferSize = ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
|
|
|
|
convBuffSize = ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
|
|
|
|
deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] );
|
|
|
|
}
|
|
|
|
else if ( stream_.mode == DUPLEX ) {
|
|
|
|
deviceBufferSize = std::max( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
|
|
|
|
( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
|
|
|
|
convBuffSize = std::max( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
|
|
|
|
( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
|
|
|
|
deviceBuffSize = std::max( stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ),
|
|
|
|
stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
convBuffer = ( char* ) malloc( deviceBufferSize );
|
|
|
|
stream_.deviceBuffer = ( char* ) malloc( deviceBufferSize );
|
|
|
|
convBuffer = ( char* ) malloc( convBuffSize );
|
|
|
|
stream_.deviceBuffer = ( char* ) malloc( deviceBuffSize );
|
|
|
|
if ( !convBuffer || !stream_.deviceBuffer ) {
|
|
|
|
errorType = RtAudioError::MEMORY_ERROR;
|
|
|
|
errorText_ = "RtApiWasapi::wasapiThread: Error allocating device buffer memory.";
|
|
|
|
|