]> Repos - portaudio/commitdiff
factored out InitPaDeviceInfoFromAsioDriver function. skip device rather than failing...
authorrbencina <rbencina@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 2 May 2013 01:06:01 +0000 (01:06 +0000)
committerrbencina <rbencina@0f58301d-fd10-0410-b4af-bbb618454e57>
Thu, 2 May 2013 01:06:01 +0000 (01:06 +0000)
src/hostapi/asio/pa_asio.cpp

index 9263c86dfc4823d26d75b3dd0b877cfc375bcab2..f230d8788d404c395497093d8b9e2503b906a75d 100644 (file)
@@ -1019,6 +1019,149 @@ static ASIOSampleRate defaultSampleRateSearchOrder_[]
         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;
@@ -1142,14 +1285,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
 
         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,
@@ -1177,13 +1312,12 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
                 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;
@@ -1192,119 +1326,17 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
                 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;
             }
         }
     }
@@ -1338,9 +1370,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
 
     return result;
 
-error_unload:
-       UnloadAsioDriver();
-
 error:
     if( asioHostApi )
     {