Show
Ignore:
Timestamp:
06/28/08 14:27:34 (5 months ago)
Author:
philburk
Message:

Supports multiple threads using ASIO by adding CoInitialize?(0) and CoUninitialize?() calls.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • portaudio/trunk/src/hostapi/asio/pa_asio.cpp

    r1363 r1386  
    966966} 
    967967 
    968  
     968/* Unload whatever we loaded in LoadAsioDriver(). 
     969   Also balance the call to CoInitialize(0). 
     970*/ 
     971static void UnloadAsioDriver( void ) 
     972{ 
     973        ASIOExit(); 
     974        CoUninitialize(); 
     975} 
    969976 
    970977/* 
    971978    load the asio driver named by <driverName> and return statistics about 
    972979    the driver in info. If no error occurred, the driver will remain open 
    973     and must be closed by the called by calling ASIOExit() - if an error 
    974     is returned the driver will already be closed. 
     980    and must be closed by the called by calling UnloadAsioDriver() - if an error 
     981    is returned the driver will already be unloaded. 
    975982*/ 
    976983static PaError LoadAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName, 
     
    981988    int asioIsInitialized = 0; 
    982989 
    983     /* @todo note that the V18 version always called CoInitialize() here to ensure  
    984         that COM was initialized before loading the driver.  
    985         probably the docs need to require clients to initialize COM in new threads? 
     990    /*  
     991        ASIO uses CoCreateInstance() to load a driver. That requires that 
     992        CoInitialize(0) be called for every thread that loads a driver. 
     993        It is OK to call CoInitialize(0) multiple times form one thread as long 
     994        as it is balanced by a call to CoUninitialize(). See UnloadAsioDriver(). 
     995 
     996        The V18 version called CoInitialize() starting on 2/19/02. 
     997        That was removed from PA V19 for unknown reasons. 
     998        Phil Burk added it back on 6/27/08 so that JSyn would work. 
    986999    */ 
     1000        CoInitialize( 0 ); 
     1001 
    9871002    if( !asioHostApi->asioDrivers->loadDriver( const_cast<char*>(driverName) ) ) 
    9881003    { 
     1004                /* If this returns an error then it might be because CoInitialize(0) was removed. 
     1005                  It should be called right before this. 
     1006            */ 
    9891007        result = paUnanticipatedHostError; 
    9901008        PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" ); 
     
    10321050error: 
    10331051    if( asioIsInitialized ) 
    1034         ASIOExit(); 
    1035  
     1052        { 
     1053                ASIOExit(); 
     1054        } 
     1055        CoUninitialize(); 
    10361056    return result; 
    10371057} 
     
    12761296                { 
    12771297                    result = paInsufficientMemory; 
    1278                     goto error; 
     1298                    goto error_unload; 
    12791299                } 
    12801300 
     
    12891309                        result = paUnanticipatedHostError; 
    12901310                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); 
    1291                         goto error; 
     1311                        goto error_unload; 
    12921312                    } 
    12931313                } 
     
    13021322                        result = paUnanticipatedHostError; 
    13031323                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); 
    1304                         goto error; 
     1324                        goto error_unload; 
    13051325                    } 
    13061326                } 
     
    13081328 
    13091329                /* unload the driver */ 
    1310                 ASIOExit(); 
     1330                UnloadAsioDriver(); 
    13111331 
    13121332                (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; 
     
    13441364 
    13451365    return result; 
     1366 
     1367error_unload: 
     1368        UnloadAsioDriver(); 
    13461369 
    13471370error: 
     
    15171540    if( asioHostApi->openAsioDeviceIndex == paNoDevice ) 
    15181541    { 
    1519         ASIOExit(); /* not sure if we should check for errors here */ 
     1542        UnloadAsioDriver(); /* not sure if we should check for errors here */ 
    15201543    } 
    15211544 
     
    18661889        asioIsInitialized = 1; 
    18671890    else{ 
    1868         PA_DEBUG(("OpenStream ERROR1\n")); 
     1891        PA_DEBUG(("OpenStream ERROR1 - LoadAsioDriver returned %d\n", result)); 
    18691892        goto error; 
    18701893    } 
     
    25782601 
    25792602    if( asioIsInitialized ) 
    2580         ASIOExit(); 
    2581  
     2603        { 
     2604                UnloadAsioDriver(); 
     2605        } 
    25822606    return result; 
    25832607} 
     
    26302654 
    26312655    ASIODisposeBuffers(); 
    2632     ASIOExit(); 
     2656    UnloadAsioDriver(); 
    26332657 
    26342658    return result; 
     
    33833407 
    33843408            /* If the available amount of data frames is insufficient. */ 
    3385             if( PaUtil_GetRingBufferReadAvailable(pRb) < lFramesPerBlock ) 
     3409            if( PaUtil_GetRingBufferReadAvailable(pRb) < (long) lFramesPerBlock ) 
    33863410            { 
    33873411                /* Make sure, the event isn't already set! */ 
     
    35583582 
    35593583            /* If the available amount of buffers is insufficient. */ 
    3560             if( PaUtil_GetRingBufferWriteAvailable(pRb) < lFramesPerBlock ) 
     3584            if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) lFramesPerBlock ) 
    35613585            { 
    35623586                /* Make sure, the event isn't already set! */ 
     
    37173741    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; 
    37183742 
    3719     /* @todo note that the V18 version always called CoInitialize() here to ensure  
    3720         that COM was initialized before loading the driver.  
    3721         probably the docs need to require clients to initialize COM in new threads? 
    3722     */ 
     3743    /* See notes about CoInitialize(0) in LoadAsioDriver(). */ 
     3744        CoInitialize(0); 
     3745 
    37233746    if( !asioHostApi->asioDrivers->loadDriver( const_cast<char*>(asioDeviceInfo->commonDeviceInfo.name) ) ) 
    37243747    { 
     
    37693792    } 
    37703793 
     3794        CoUninitialize(); 
    37713795PA_DEBUG(("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText(asioError) )); 
    37723796 
     
    37753799error: 
    37763800    if( asioIsInitialized ) 
    3777         ASIOExit(); 
     3801        { 
     3802                ASIOExit(); 
     3803        } 
     3804        CoUninitialize(); 
    37783805 
    37793806    return result; 
     
    38863913 
    38873914        /* If the blocking i/o buffer contains enough output data, */ 
    3888         if( PaUtil_GetRingBufferReadAvailable(pRb) >= framesPerBuffer ) 
     3915        if( PaUtil_GetRingBufferReadAvailable(pRb) >= (long) framesPerBuffer ) 
    38893916        { 
    38903917            /* Extract the requested data from the ring buffer. */ 
     
    39003927 
    39013928            /* If playback is to be stopped */ 
    3902             if( blockingState->stopFlag && PaUtil_GetRingBufferReadAvailable(pRb) < framesPerBuffer ) 
     3929            if( blockingState->stopFlag && PaUtil_GetRingBufferReadAvailable(pRb) < (long) framesPerBuffer ) 
    39033930            { 
    39043931                /* Extract all the remaining data from the ring buffer, 
     
    39093936 
    39103937        /* Set blocking i/o event? */ 
    3911         if( blockingState->writeBuffersRequestedFlag && PaUtil_GetRingBufferWriteAvailable(pRb) >= blockingState->writeBuffersRequested ) 
     3938        if( blockingState->writeBuffersRequestedFlag && PaUtil_GetRingBufferWriteAvailable(pRb) >= (long) blockingState->writeBuffersRequested ) 
    39123939        { 
    39133940            /* Reset buffer request. */ 
     
    39353962 
    39363963        /* If the blocking i/o buffer contains not enough input buffers */ 
    3937         if( PaUtil_GetRingBufferWriteAvailable(pRb) < framesPerBuffer ) 
     3964        if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) framesPerBuffer ) 
    39383965        { 
    39393966            /* Signalize a read-buffer overflow. */ 
     
    39483975 
    39493976        /* Set blocking i/o event? */ 
    3950         if( blockingState->readFramesRequestedFlag && PaUtil_GetRingBufferReadAvailable(pRb) >= blockingState->readFramesRequested ) 
     3977        if( blockingState->readFramesRequestedFlag && PaUtil_GetRingBufferReadAvailable(pRb) >= (long) blockingState->readFramesRequested ) 
    39513978        { 
    39523979            /* Reset buffer request. */