Changeset 1316

Show
Ignore:
Timestamp:
01/23/08 15:40:38 (7 months ago)
Author:
bjornroche
Message:

applied patch to fix ticket 64 -- added list of listeners for xruns in CoreAudio?.

Location:
portaudio/branches/v19-devel/src/hostapi/coreaudio
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core.c

    r1315 r1316  
    283283 
    284284/* 
    285  * Callback for setting over/underrun flags. 
    286  * 
    287  */ 
    288 static OSStatus xrunCallback( 
    289     AudioDeviceID inDevice,  
    290     UInt32 inChannel,  
    291     Boolean isInput,  
    292     AudioDevicePropertyID inPropertyID,  
    293     void* inClientData) 
    294 { 
    295    PaMacCoreStream *stream = (PaMacCoreStream *) inClientData; 
    296    if( stream->state != ACTIVE ) 
    297       return 0; //if the stream isn't active, we don't care if the device is dropping 
    298    if( isInput ) 
    299       OSAtomicOr32( paInputOverflow, (uint32_t *)&(stream->xrunFlags) ); 
    300    else 
    301       OSAtomicOr32( paOutputUnderflow, (uint32_t *)&(stream->xrunFlags) ); 
    302  
    303    return 0; 
    304 } 
    305  
    306 /* 
    307285 * Callback called when starting or stopping a stream. 
    308286 */ 
     
    558536    VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex)); 
    559537 
     538    initializeXRunListenerList(); 
     539 
    560540    auhalHostApi = (PaMacAUHAL*)PaUtil_AllocateMemory( sizeof(PaMacAUHAL) ); 
    561541    if( !auhalHostApi ) 
     
    680660    VVDBUG(("Terminate()\n")); 
    681661 
     662    destroyXRunListenerList(); 
     663 
    682664    /* 
    683665        IMPLEMENT ME: 
     
    951933    } 
    952934    /* -- add listener for dropouts -- */ 
    953     ERR_WRAP( AudioDeviceAddPropertyListener( *audioDevice, 
    954                                               0, 
    955                                               outStreamParams ? false : true, 
    956                                               kAudioDeviceProcessorOverload, 
    957                                               xrunCallback, 
    958                                               (void *)stream) ); 
    959  
     935    result = AudioDeviceAddPropertyListener( *audioDevice, 
     936                                             0, 
     937                                             outStreamParams ? false : true, 
     938                                             kAudioDeviceProcessorOverload, 
     939                                             xrunCallback, 
     940                                             addToXRunListenerList( (void *)stream, *audioDevice ) ) ; 
     941    if( result == kAudioHardwareIllegalOperationError ) { 
     942       // -- already registered, we're good 
     943    } else { 
     944       // -- not already registered, just check for errors 
     945       ERR_WRAP( result ); 
     946    } 
    960947    /* -- listen for stream start and stop -- */ 
    961948    ERR_WRAP( AudioUnitAddPropertyListener( *audioUnit, 
     
    21402127 
    21412128    if( stream ) { 
    2142        if( stream->outputUnit ) 
    2143           AudioDeviceRemovePropertyListener( stream->outputDevice, 
    2144                                              0, 
    2145                                              false, 
    2146                                              kAudioDeviceProcessorOverload, 
    2147                                              xrunCallback ); 
    2148        if( stream->inputUnit && stream->outputUnit != stream->inputUnit ) 
    2149           AudioDeviceRemovePropertyListener( stream->inputDevice, 
    2150                                              0, 
    2151                                              true, 
    2152                                              kAudioDeviceProcessorOverload, 
    2153                                              xrunCallback ); 
     2129       if( stream->outputUnit ) { 
     2130          int count = removeFromXRunListenerList( stream, stream->outputDevice ); 
     2131          if( count == 0 ) 
     2132             AudioDeviceRemovePropertyListener( stream->outputDevice, 
     2133                                                0, 
     2134                                                false, 
     2135                                                kAudioDeviceProcessorOverload, 
     2136                                                xrunCallback ); 
     2137       } 
     2138       if( stream->inputUnit && stream->outputUnit != stream->inputUnit ) { 
     2139          int count = removeFromXRunListenerList( stream, stream->inputDevice ); 
     2140          if( count == 0 ) 
     2141             AudioDeviceRemovePropertyListener( stream->inputDevice, 
     2142                                                0, 
     2143                                                true, 
     2144                                                kAudioDeviceProcessorOverload, 
     2145                                                xrunCallback ); 
     2146       } 
    21542147       if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { 
    21552148          AudioUnitUninitialize( stream->outputUnit ); 
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core_utilities.c

    r1304 r1316  
    5858 
    5959#include "pa_mac_core_utilities.h" 
     60#include "pa_mac_core_internal.h" 
     61#include <strings.h> 
    6062 
    6163PaError PaMacCore_SetUnixError( int err, int line ) 
     
    619621   return paNoError; 
    620622} 
     623 
     624/********************** 
     625 * 
     626 * XRun stuff 
     627 * 
     628 **********************/ 
     629 
     630struct PaMacXRunListNode_s { 
     631   PaMacCoreStream *stream; 
     632   AudioDeviceID audioDevice; 
     633   struct PaMacXRunListNode_s *next; 
     634} ; 
     635 
     636typedef struct PaMacXRunListNode_s PaMacXRunListNode; 
     637 
     638OSStatus xrunCallback( 
     639    AudioDeviceID inDevice,  
     640    UInt32 inChannel,  
     641    Boolean isInput,  
     642    AudioDevicePropertyID inPropertyID,  
     643    void* inClientData) 
     644{ 
     645   PaMacXRunListNode *node = (PaMacXRunListNode *) inClientData; 
     646 
     647   node = node->next ; //skip the first node 
     648 
     649   for( ; node; node=node->next ) { 
     650      if( node->audioDevice != inDevice ) 
     651         continue; //not the same device. continue. 
     652 
     653      PaMacCoreStream *stream = node->stream; 
     654 
     655      if( stream->state != ACTIVE ) 
     656         continue; //if the stream isn't active, we don't care if the device is dropping 
     657 
     658      if( isInput ) 
     659         OSAtomicOr32( paInputOverflow, (uint32_t *)&(stream->xrunFlags) ); 
     660      else 
     661         OSAtomicOr32( paOutputUnderflow, (uint32_t *)&(stream->xrunFlags) ); 
     662   } 
     663 
     664   return 0; 
     665} 
     666 
     667/** Always empty, so that it can always be the one returned by 
     668    addToXRunListenerList. note that it's not a pointer. */ 
     669static PaMacXRunListNode firstXRunListNode; 
     670static int xRunListSize; 
     671 
     672void initializeXRunListenerList() 
     673{ 
     674   xRunListSize = 0; 
     675   bzero( (void *) &firstXRunListNode, sizeof(firstXRunListNode) ); 
     676} 
     677void destroyXRunListenerList() 
     678{ 
     679   PaMacXRunListNode *node; 
     680   node = firstXRunListNode.next; 
     681   while( node ) { 
     682      PaMacXRunListNode *tmp = node; 
     683      node = node->next; 
     684      free( tmp ); 
     685   } 
     686   xRunListSize = 0; 
     687} 
     688 
     689void *addToXRunListenerList( void *stream, AudioDeviceID audioDevice ) 
     690{ 
     691   PaMacXRunListNode *newNode; 
     692   // setup new node: 
     693   newNode = (PaMacXRunListNode *) malloc( sizeof( PaMacXRunListNode ) ); 
     694   newNode->stream = (PaMacCoreStream *) stream; 
     695   newNode->audioDevice = audioDevice; 
     696   newNode->next = firstXRunListNode.next; 
     697   // insert: 
     698   firstXRunListNode.next = newNode; 
     699 
     700   return &firstXRunListNode; 
     701} 
     702 
     703int removeFromXRunListenerList( void *stream, AudioDeviceID audioDevice ) 
     704{ 
     705   PaMacXRunListNode *node, *prev; 
     706   prev = &firstXRunListNode; 
     707   node = firstXRunListNode.next; 
     708   while( node ) { 
     709      if( node->stream == stream && node->audioDevice == audioDevice ) { 
     710         //found it: 
     711         --xRunListSize; 
     712         prev->next = node->next; 
     713         free( node ); 
     714         return xRunListSize; 
     715      } 
     716      prev = prev->next; 
     717      node = node->next; 
     718   } 
     719 
     720   // failure 
     721   return xRunListSize; 
     722} 
     723 
  • portaudio/branches/v19-devel/src/hostapi/coreaudio/pa_mac_core_utilities.h

    r1304 r1316  
    203203                                UInt32 requestedFramesPerBuffer,  
    204204                                UInt32 *actualFramesPerBuffer ); 
     205 
     206 
     207/********************* 
     208 * 
     209 *  xrun handling 
     210 * 
     211 *********************/ 
     212 
     213OSStatus xrunCallback( 
     214    AudioDeviceID inDevice,  
     215    UInt32 inChannel,  
     216    Boolean isInput,  
     217    AudioDevicePropertyID inPropertyID,  
     218    void* inClientData ) ; 
     219 
     220void initializeXRunListenerList(); 
     221void destroyXRunListenerList(); 
     222 
     223/**Returns the list, so that it can be passed to CorAudio.*/ 
     224void *addToXRunListenerList( void *stream, AudioDeviceID audioDevice ); 
     225/**Returns the number of Listeners in the list remaining.*/ 
     226int removeFromXRunListenerList( void *stream, AudioDeviceID audioDevice ); 
     227 
    205228#endif /* PA_MAC_CORE_UTILITIES_H__*/