192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
+static PaError InitPaDeviceInfoFromAsioDriver( PaAsioHostApiRepresentation *asioHostApi,
+ const char *driverName, int driverIndex,
+ PaDeviceInfo *deviceInfo, PaAsioDeviceInfo *asioDeviceInfo )
+{
+ PaError result = paNoError;
+
+ /* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio
+ drivers f.i.). This is an attempt to overcome that. */
+ union _tag_local {
+ PaAsioDriverInfo info;
+ char _padding[4096];
+ } paAsioDriver;
+
+ asioDeviceInfo->asioChannelInfos = 0; /* we check this below to handle error cleanup */
+
+ result = LoadAsioDriver( asioHostApi, driverName, &paAsioDriver.info, asioHostApi->systemSpecific );
+ if( result == paNoError )
+ {
+ PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", driverIndex,deviceInfo->name));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", driverIndex, paAsioDriver.info.inputChannelCount));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", driverIndex, paAsioDriver.info.outputChannelCount));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", driverIndex, paAsioDriver.info.bufferMinSize));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", driverIndex, paAsioDriver.info.bufferMaxSize));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", driverIndex, paAsioDriver.info.bufferPreferredSize));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", driverIndex, paAsioDriver.info.bufferGranularity));
+
+ deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount;
+ deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
+
+ deviceInfo->defaultSampleRate = 0.;
+ bool foundDefaultSampleRate = false;
+ for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
+ {
+ ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
+ if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
+ {
+ deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
+ foundDefaultSampleRate = true;
+ break;
+ }
+ }
+
+ PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", driverIndex, deviceInfo->defaultSampleRate));
+
+ if( foundDefaultSampleRate ){
+
+ /* calculate default latency values from bufferPreferredSize
+ for default low latency, and bufferMaxSize
+ for default high latency.
+ use the default sample rate to convert from samples to
+ seconds. Without knowing what sample rate the user will
+ use this is the best we can do.
+ */
+
+ double defaultLowLatency =
+ paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate;
+
+ deviceInfo->defaultLowInputLatency = defaultLowLatency;
+ deviceInfo->defaultLowOutputLatency = defaultLowLatency;
+
+ double defaultHighLatency =
+ paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate;
+
+ if( defaultHighLatency < defaultLowLatency )
+ defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
+
+ deviceInfo->defaultHighInputLatency = defaultHighLatency;
+ deviceInfo->defaultHighOutputLatency = defaultHighLatency;
+
+ }else{
+
+ deviceInfo->defaultLowInputLatency = 0.;
+ deviceInfo->defaultLowOutputLatency = 0.;
+ deviceInfo->defaultHighInputLatency = 0.;
+ deviceInfo->defaultHighOutputLatency = 0.;
+ }
+
+ PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", driverIndex, deviceInfo->defaultLowInputLatency));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", driverIndex, deviceInfo->defaultLowOutputLatency));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", driverIndex, deviceInfo->defaultHighInputLatency));
+ PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", driverIndex, deviceInfo->defaultHighOutputLatency));
+
+ asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize;
+ asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize;
+ asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize;
+ asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity;
+
+
+ asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
+ asioHostApi->allocations,
+ sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
+ + deviceInfo->maxOutputChannels) );
+ if( !asioDeviceInfo->asioChannelInfos )
+ {
+ result = paInsufficientMemory;
+ goto error_unload;
+ }
+
+ int a;
+
+ for( a=0; a < deviceInfo->maxInputChannels; ++a ){
+ asioDeviceInfo->asioChannelInfos[a].channel = a;
+ asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
+ ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
+ if( asioError != ASE_OK )
+ {
+ result = paUnanticipatedHostError;
+ PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+ goto error_unload;
+ }
+ }
+
+ for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
+ int b = deviceInfo->maxInputChannels + a;
+ asioDeviceInfo->asioChannelInfos[b].channel = a;
+ asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
+ ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
+ if( asioError != ASE_OK )
+ {
+ result = paUnanticipatedHostError;
+ PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+ goto error_unload;
+ }
+ }
+
+ /* unload the driver */
+ UnloadAsioDriver();
+ }
+
+ return result;
+
+error_unload:
+ UnloadAsioDriver();
+
+ if( asioDeviceInfo->asioChannelInfos ){
+ PaUtil_GroupFreeMemory( asioHostApi->allocations, asioDeviceInfo->asioChannelInfos );
+ asioDeviceInfo->asioChannelInfos = 0;
+ }
+
+ return result;
+}
+
+
/* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */
typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID);
IsDebuggerPresentPtr IsDebuggerPresent_ = 0;
for( i=0; i < driverCount; ++i )
{
- /* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio
- drivers f.i.). This is an attempt to overcome that. */
- union _tag_local {
- PaAsioDriverInfo info;
- char _padding[4096];
- } paAsioDriver;
-
-
PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i]));
// Since portaudio opens ALL ASIO drivers, and no one else does that,
if( strcmp(names[i], "ASIO Digidesign Driver") == 0 )
{
PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n"));
- continue;
+ continue;
}
}
- /* Attempt to load the asio driver... */
- if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriver.info, asioHostApi->systemSpecific ) == paNoError )
+ /* Attempt to init device info from the asio driver... */
{
PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
deviceInfo->hostApi = hostApiIndex;
deviceInfo->name = names[i];
- PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", i,deviceInfo->name));
- PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", i, paAsioDriver.info.inputChannelCount));
- PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", i, paAsioDriver.info.outputChannelCount));
- PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", i, paAsioDriver.info.bufferMinSize));
- PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", i, paAsioDriver.info.bufferMaxSize));
- PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriver.info.bufferPreferredSize));
- PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", i, paAsioDriver.info.bufferGranularity));
-
- deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount;
- deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
-
- deviceInfo->defaultSampleRate = 0.;
- bool foundDefaultSampleRate = false;
- for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
- {
- ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
- if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
- {
- deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
- foundDefaultSampleRate = true;
- break;
- }
- }
-
- PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate));
-
- if( foundDefaultSampleRate ){
-
- /* calculate default latency values from bufferPreferredSize
- for default low latency, and bufferMaxSize
- for default high latency.
- use the default sample rate to convert from samples to
- seconds. Without knowing what sample rate the user will
- use this is the best we can do.
- */
-
- double defaultLowLatency =
- paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate;
- deviceInfo->defaultLowInputLatency = defaultLowLatency;
- deviceInfo->defaultLowOutputLatency = defaultLowLatency;
-
- double defaultHighLatency =
- paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate;
-
- if( defaultHighLatency < defaultLowLatency )
- defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
-
- deviceInfo->defaultHighInputLatency = defaultHighLatency;
- deviceInfo->defaultHighOutputLatency = defaultHighLatency;
-
- }else{
-
- deviceInfo->defaultLowInputLatency = 0.;
- deviceInfo->defaultLowOutputLatency = 0.;
- deviceInfo->defaultHighInputLatency = 0.;
- deviceInfo->defaultHighOutputLatency = 0.;
- }
-
- PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
- PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
- PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
- PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
-
- asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize;
- asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize;
- asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize;
- asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity;
-
-
- asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
- asioHostApi->allocations,
- sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
- + deviceInfo->maxOutputChannels) );
- if( !asioDeviceInfo->asioChannelInfos )
+ if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError )
{
- result = paInsufficientMemory;
- goto error_unload;
- }
-
- int a;
-
- for( a=0; a < deviceInfo->maxInputChannels; ++a ){
- asioDeviceInfo->asioChannelInfos[a].channel = a;
- asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
- ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
- if( asioError != ASE_OK )
- {
- result = paUnanticipatedHostError;
- PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
- goto error_unload;
- }
+ (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
+ ++(*hostApi)->info.deviceCount;
}
-
- for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
- int b = deviceInfo->maxInputChannels + a;
- asioDeviceInfo->asioChannelInfos[b].channel = a;
- asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
- ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
- if( asioError != ASE_OK )
- {
- result = paUnanticipatedHostError;
- PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
- goto error_unload;
- }
+ else
+ {
+ PA_DEBUG(("Skipping ASIO device:%s\n",names[i]));
+ continue;
}
-
-
- /* unload the driver */
- UnloadAsioDriver();
-
- (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
- ++(*hostApi)->info.deviceCount;
}
}
}
return result;
-error_unload:
- UnloadAsioDriver();
-
error:
if( asioHostApi )
{