Ticket #11: portaudio-deviceschanged.patch
| File portaudio-deviceschanged.patch, 44.7 KB (added by rossb, 9 months ago) |
|---|
-
test/patest2.c
1 /** @file patest2.c 2 @ingroup test_src 3 @brief Ring modulate the audio input with a sine wave for 20 seconds with 4 device change detection. 5 @author Ross Bencina <rossb@audiomulch.com>, 6 Phil Burk http://www.softsynth.com, 7 Erik Bunce <kde@bunce.us> 8 */ 9 /* 10 * $Id$ 11 * 12 * This program uses the PortAudio Portable Audio Library. 13 * For more information see: http://www.portaudio.com 14 * Copyright (c) 1999-2000 Ross Bencina and Phil Burk 15 * 16 * Permission is hereby granted, free of charge, to any person obtaining 17 * a copy of this software and associated documentation files 18 * (the "Software"), to deal in the Software without restriction, 19 * including without limitation the rights to use, copy, modify, merge, 20 * publish, distribute, sublicense, and/or sell copies of the Software, 21 * and to permit persons to whom the Software is furnished to do so, 22 * subject to the following conditions: 23 * 24 * The above copyright notice and this permission notice shall be 25 * included in all copies or substantial portions of the Software. 26 * 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 30 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 31 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 32 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 33 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 */ 35 36 /* 37 * The text above constitutes the entire PortAudio license; however, 38 * the PortAudio community also makes the following non-binding requests: 39 * 40 * Any person wishing to distribute modifications to the Software is 41 * requested to send the modifications to the original developer so that 42 * they can be incorporated into the canonical version. It is also 43 * requested that these non-binding requests be included along with the 44 * license above. 45 */ 46 47 #include <stdio.h> 48 #include <math.h> 49 #include "portaudio.h" 50 51 #ifndef M_PI 52 #define M_PI (3.14159265) 53 #endif 54 55 #define SAMPLE_RATE (44100) 56 57 typedef struct 58 { 59 float sine[100]; 60 int phase; 61 int sampsToGo; 62 } 63 patest1data; 64 65 static void patest1DevicesChangedCallback( PaDevicesChangedFlags flags, 66 void *userData ) 67 { 68 int i, numDevices, defaultDisplayed; 69 const PaDeviceInfo *deviceInfo; 70 printf( "========================================\n" ); 71 printf( "patest1DevicesChangedCallback(%04x, %p)\n", flags, userData ); 72 numDevices = Pa_GetDeviceCount(); 73 74 if( numDevices < 0 ) 75 { 76 printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices ); 77 return; 78 } 79 80 if ( ( flags & paDefaultInputDeviceChanged ) ) 81 { 82 i = Pa_GetDefaultInputDevice(); 83 84 deviceInfo = Pa_GetDeviceInfo( i ); 85 if ( deviceInfo != NULL) 86 printf( "Default input device changed to %d: %s (%s)\n", i, deviceInfo->name, Pa_GetHostApiInfo( deviceInfo->hostApi )->name ); 87 else 88 printf( "Default input device changed to %d\n", i ); 89 } 90 91 92 if ( ( flags & paDefaultOutputDeviceChanged ) ) 93 { 94 i = Pa_GetDefaultOutputDevice(); 95 96 deviceInfo = Pa_GetDeviceInfo( i ); 97 if ( deviceInfo ) 98 printf( "Default output device changed to %d: %s (%s)\n", i, deviceInfo->name, Pa_GetHostApiInfo( deviceInfo->hostApi )->name ); 99 else 100 printf( "Default output device changed to %d\n", i ); 101 } 102 103 /* only display the new list if the list has already changed */ 104 if ( ( flags & paDevicesListChanged ) == 0 ) 105 return; 106 107 printf( "Hardware device list changed\n" ); 108 109 printf( "Number of devices = %d\n", numDevices ); 110 for( i=0; i<numDevices; i++ ) 111 { 112 deviceInfo = Pa_GetDeviceInfo( i ); 113 printf( "--------------------------------------- device #%d\n", i ); 114 115 /* Mark global and API specific default devices */ 116 defaultDisplayed = 0; 117 if( i == Pa_GetDefaultInputDevice() ) 118 { 119 printf( "[ Default Input" ); 120 defaultDisplayed = 1; 121 } 122 else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice ) 123 { 124 const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi ); 125 printf( "[ Default %s Input", hostInfo->name ); 126 defaultDisplayed = 1; 127 } 128 129 if( i == Pa_GetDefaultOutputDevice() ) 130 { 131 printf( (defaultDisplayed ? "," : "[") ); 132 printf( " Default Output" ); 133 defaultDisplayed = 1; 134 } 135 else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice ) 136 { 137 const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi ); 138 printf( (defaultDisplayed ? "," : "[") ); 139 printf( " Default %s Output", hostInfo->name ); 140 defaultDisplayed = 1; 141 } 142 143 if( defaultDisplayed ) 144 printf( " ]\n" ); 145 146 /* print device info fields */ 147 printf( "Name = %s\n", deviceInfo->name ); 148 printf( "Host API = %s\n", Pa_GetHostApiInfo( deviceInfo->hostApi )->name ); 149 printf( "Max inputs = %d", deviceInfo->maxInputChannels ); 150 printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels ); 151 152 printf( "Default low input latency = %8.3f\n", deviceInfo->defaultLowInputLatency ); 153 printf( "Default low output latency = %8.3f\n", deviceInfo->defaultLowOutputLatency ); 154 printf( "Default high input latency = %8.3f\n", deviceInfo->defaultHighInputLatency ); 155 printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency ); 156 } 157 } 158 159 static int patest1Callback( const void *inputBuffer, void *outputBuffer, 160 unsigned long framesPerBuffer, 161 const PaStreamCallbackTimeInfo* timeInfo, 162 PaStreamCallbackFlags statusFlags, 163 void *userData ) 164 { 165 patest1data *data = (patest1data*)userData; 166 float *in = (float*)inputBuffer; 167 float *out = (float*)outputBuffer; 168 int framesToCalc = framesPerBuffer; 169 unsigned long i = 0; 170 int finished; 171 172 if( data->sampsToGo < framesPerBuffer ) 173 { 174 framesToCalc = data->sampsToGo; 175 finished = paComplete; 176 } 177 else 178 { 179 finished = paContinue; 180 } 181 182 for( ; i<framesToCalc; i++ ) 183 { 184 *out++ = *in++ * data->sine[data->phase]; /* left */ 185 *out++ = *in++ * data->sine[data->phase++]; /* right */ 186 if( data->phase >= 100 ) 187 data->phase = 0; 188 } 189 190 data->sampsToGo -= framesToCalc; 191 192 /* zero remainder of final buffer if not already done */ 193 for( ; i<framesPerBuffer; i++ ) 194 { 195 *out++ = 0; /* left */ 196 *out++ = 0; /* right */ 197 } 198 199 return finished; 200 } 201 202 int main(int argc, char* argv[]); 203 int main(int argc, char* argv[]) 204 { 205 PaStream *stream; 206 PaError err; 207 patest1data data; 208 int i; 209 PaStreamParameters inputParameters, outputParameters; 210 const PaHostErrorInfo* herr; 211 212 printf("patest1.c\n"); fflush(stdout); 213 printf("Ring modulate input for 20 seconds.\n"); fflush(stdout); 214 215 /* initialise sinusoidal wavetable */ 216 for( i=0; i<100; i++ ) 217 data.sine[i] = sin( ((double)i/100.) * M_PI * 2. ); 218 data.phase = 0; 219 data.sampsToGo = SAMPLE_RATE * 20; /* 20 seconds. */ 220 221 /* initialise portaudio subsytem */ 222 err = Pa_Initialize(); 223 224 err = Pa_AddDevicesChangedCallback(patest1DevicesChangedCallback, NULL); 225 226 inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */ 227 inputParameters.channelCount = 2; /* stereo input */ 228 inputParameters.sampleFormat = paFloat32; /* 32 bit floating point input */ 229 inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; 230 inputParameters.hostApiSpecificStreamInfo = NULL; 231 232 outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ 233 outputParameters.channelCount = 2; /* stereo output */ 234 outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */ 235 outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency; 236 outputParameters.hostApiSpecificStreamInfo = NULL; 237 238 err = Pa_OpenStream( 239 &stream, 240 &inputParameters, 241 &outputParameters, 242 (double)SAMPLE_RATE, /* Samplerate in Hertz. */ 243 512, /* Small buffers */ 244 paClipOff, /* We won't output out of range samples so don't bother clipping them. */ 245 patest1Callback, 246 &data ); 247 if( err != paNoError ) goto done; 248 249 err = Pa_StartStream( stream ); 250 if( err != paNoError ) goto done; 251 252 printf( "Press any key to end.\n" ); fflush(stdout); 253 254 getc( stdin ); /* wait for input before exiting */ 255 256 err = Pa_AbortStream( stream ); 257 if( err != paNoError ) goto done; 258 259 printf( "Waiting for stream to complete...\n" ); 260 261 /* sleep until playback has finished */ 262 while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000); 263 if( err < 0 ) goto done; 264 265 err = Pa_CloseStream( stream ); 266 if( err != paNoError ) goto done; 267 268 done: 269 err = Pa_RemoveDevicesChangedCallback(patest1DevicesChangedCallback, NULL); 270 271 Pa_Terminate(); 272 273 if( err != paNoError ) 274 { 275 fprintf( stderr, "An error occured while using portaudio\n" ); 276 if( err == paUnanticipatedHostError ) 277 { 278 fprintf( stderr, " unanticipated host error.\n"); 279 herr = Pa_GetLastHostErrorInfo(); 280 if (herr) 281 { 282 fprintf( stderr, " Error number: %ld\n", herr->errorCode ); 283 if (herr->errorText) 284 fprintf( stderr, " Error text: %s\n", herr->errorText ); 285 } 286 else 287 fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" ); 288 } 289 else 290 { 291 fprintf( stderr, " Error number: %d\n", err ); 292 fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) ); 293 } 294 295 err = 1; /* Always return 0 or 1, but no other return codes. */ 296 } 297 298 printf( "bye\n" ); 299 300 return err; 301 } -
Makefile.in
Property changes on: test/patest2.c ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + author id date revision Name: svn:eol-style + native
59 59 bin/paqa_devs \ 60 60 bin/paqa_errs \ 61 61 bin/patest1 \ 62 bin/patest2 \ 62 63 bin/patest_buffer \ 63 64 bin/patest_callbackstop \ 64 65 bin/patest_clip \ -
include/portaudio.h
356 356 */ 357 357 const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); 358 358 359 /* Device enumeration and capabilities */ 359 360 361 /** Flags used to indicate which device states have changed. 362 363 @see paDevicesListAboutToBeChanged, paDevicesListChanged, 364 paDefaultInputDeviceChanged, paDefaultOutputDeviceChanged 365 */ 366 typedef unsigned long PaDevicesChangedFlags; 360 367 361 /* Device enumeration and capabilities */368 /** Indicates that the list of devices is about to be changed. 362 369 370 This is sent before the list of devices is changed. All PaDeviceInfo 371 structures retrieved prior to this notification are about to be freed. 372 373 @see PaDevicesChangedFlags 374 */ 375 #define paDevicesListAboutToBeChanged ((PaDevicesChangedFlags) 0x00000001) 376 377 /** Indicates that the list of devices has changed. 378 379 This is sent after the PortAudio list of devices has changed. 380 All PaDeviceInfo structures retrieved prior to this notification are now 381 invalid. 382 383 @see PaDevicesChangedFlags 384 */ 385 #define paDevicesListChanged ((PaDevicesChangedFlags) 0x00000002) 386 387 /** Indicates that the systems default input device has changed. 388 389 @see PaDevicesChangedFlags 390 */ 391 #define paDefaultInputDeviceChanged ((PaDevicesChangedFlags) 0x00000004) 392 393 /** Indicates that the systems default output device has changed. 394 395 @see PaDevicesChangedFlags 396 */ 397 #define paDefaultOutputDeviceChanged ((PaDevicesChangedFlags) 0x00000008) 398 399 /** Functions of type PaDevicesChangedCallback are implemented by PortAudio 400 clients. They can be registered using the Pa_SetDevicesChangedCallback 401 function. Once registered they are called when the state of installed devices 402 changes. 403 404 @param flags The flags indicate what aspects of the known devices has 405 changed. 406 @param userData The userData parameter supplied t Pa_SetDevicesChangedCallback(). 407 408 @see Pa_AddDevicesChangedCallback, Pa_RemoveDevicesChangedCallback, 409 PaDevicesChangedFlags 410 */ 411 typedef void PaDevicesChangedCallback( PaDevicesChangedFlags flags, 412 void *userData ); 413 414 /** Add a devices changed callback function which will be called when the 415 the state of installed devices changes. 416 417 @note If no callback is registered the traditional behavior of ignoring devices 418 changes is maintained. However, if a callback is registered then PortAudio 419 will automatically rescan the set of available devices when a change is detected. 420 This is done in an attempt to maintain backwards compatibility for older 421 clients. 422 423 @param userData A client supplied pointer which is passed to the stream callback 424 function. It could for example, contain a pointer to instance data necessary for 425 processing device change notifications. 426 */ 427 PaError Pa_AddDevicesChangedCallback( PaDevicesChangedCallback* devicesCallback, 428 void *userData ); 429 430 /** Remove a devices changed callback function which will be called when the 431 the state of installed devices changes. 432 433 @param userData A client supplied pointer which is passed to the stream callback 434 function. It could for example, contain a pointer to instance data necessary for 435 processing device change notifications. 436 */ 437 PaError Pa_RemoveDevicesChangedCallback( PaDevicesChangedCallback* devicesCallback, 438 void *userData ); 439 440 /** Rescans the system in order to detect new devices. 441 442 It will call the registered PaDevicesChangedCallback with paDevicesListChanged 443 when it is done. 444 445 @note This will free all PaDeviceInfo structures that may have been returned 446 previously. 447 */ 448 PaError Pa_RescanDevices( void ); 449 363 450 /** Retrieve the number of available devices. The number of available devices 364 451 may be zero. 365 452 … … 470 557 471 558 @note PortAudio manages the memory referenced by the returned pointer, 472 559 the client must not manipulate or free the memory. The pointer is only 473 guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). 560 guaranteed to be valid between calls to Pa_Initialize(), Pa_RescanDevices(), 561 and Pa_Terminate(). 474 562 475 563 @see PaDeviceInfo, PaDeviceIndex 476 564 */ -
src/hostapi/alsa/pa_linux_alsa.c
254 254 (*hostApi)->info.name = "ALSA"; 255 255 256 256 (*hostApi)->Terminate = Terminate; 257 (*hostApi)->RescanDevices = NULL; 257 258 (*hostApi)->OpenStream = OpenStream; 258 259 (*hostApi)->IsFormatSupported = IsFormatSupported; 259 260 -
src/hostapi/oss/pa_unix_oss.c
250 250 (*hostApi)->info.type = paOSS; 251 251 (*hostApi)->info.name = "OSS"; 252 252 (*hostApi)->Terminate = Terminate; 253 (*hostApi)->RescanDevices = NULL; 253 254 (*hostApi)->OpenStream = OpenStream; 254 255 (*hostApi)->IsFormatSupported = IsFormatSupported; 255 256 -
src/hostapi/wasapi/pa_win_wasapi.cpp
635 635 spEndpoints->Release(); 636 636 637 637 (*hostApi)->Terminate = Terminate; 638 (*hostApi)->RescanDevices = NULL; 638 639 (*hostApi)->OpenStream = OpenStream; 639 640 (*hostApi)->IsFormatSupported = IsFormatSupported; 640 641 … … 1908 1909 stream->outVol->SetMute(FALSE, NULL); 1909 1910 bFirst = false; 1910 1911 } 1911 #endif 1912 No newline at end of file 1912 #endif -
src/hostapi/wdmks/pa_win_wdmks.c
1876 1876 (*hostApi)->info.deviceCount = deviceCount; 1877 1877 1878 1878 (*hostApi)->Terminate = Terminate; 1879 (*hostApi)->RescanDevices = NULL; 1879 1880 (*hostApi)->OpenStream = OpenStream; 1880 1881 (*hostApi)->IsFormatSupported = IsFormatSupported; 1881 1882 … … 3280 3281 /* IMPLEMENT ME, see portaudio.h for required behavior*/ 3281 3282 PA_LOGL_; 3282 3283 return 0; 3283 } 3284 No newline at end of file 3284 } -
src/hostapi/wmme/pa_win_wmme.c
1040 1040 InitializeDefaultDeviceIdsFromEnv( winMmeHostApi ); 1041 1041 1042 1042 (*hostApi)->Terminate = Terminate; 1043 (*hostApi)->RescanDevices = NULL; 1043 1044 (*hostApi)->OpenStream = OpenStream; 1044 1045 (*hostApi)->IsFormatSupported = IsFormatSupported; 1045 1046 -
src/hostapi/jack/pa_jack.c
746 746 /* Register functions */ 747 747 748 748 (*hostApi)->Terminate = Terminate; 749 (*hostApi)->RescanDevices = NULL; 749 750 (*hostApi)->OpenStream = OpenStream; 750 751 (*hostApi)->IsFormatSupported = IsFormatSupported; 751 752 -
src/hostapi/coreaudio/pa_mac_core.c
70 70 #include "pa_mac_core.h" 71 71 #include "pa_mac_core_utilities.h" 72 72 #include "pa_mac_core_blocking.h" 73 #include "pa_debugprint.h" 73 74 74 75 75 76 #ifdef __cplusplus … … 227 228 #define RING_BUFFER_ADVANCE_DENOMINATOR (4) 228 229 229 230 static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); 231 static PaError RescanDevices( struct PaUtilHostApiRepresentation *hostApi ); 230 232 static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, 231 233 const PaStreamParameters *inputParameters, 232 234 const PaStreamParameters *outputParameters, … … 324 326 sfc( stream->streamRepresentation.userData ); 325 327 } 326 328 327 328 /*currently, this is only used in initialization, but it might be modified 329 to be used when the list of devices changes.*/ 330 static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi) 329 /* This is used during initialization, rescan, and default device changes to 330 gather information about the current default input device. */ 331 static void gatherDefaultInputDevice(PaMacAUHAL *auhalHostApi) 331 332 { 332 UInt32 size; 333 UInt32 propsize; 334 VVDBUG(("gatherDeviceInfo()\n")); 335 /* -- free any previous allocations -- */ 336 if( auhalHostApi->devIds ) 337 PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds); 338 auhalHostApi->devIds = NULL; 339 340 /* -- figure out how many devices there are -- */ 341 AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, 342 &propsize, 343 NULL ); 344 auhalHostApi->devCount = propsize / sizeof( AudioDeviceID ); 345 346 VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) ); 347 348 /* -- copy the device IDs -- */ 349 auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory( 350 auhalHostApi->allocations, 351 propsize ); 352 if( !auhalHostApi->devIds ) 353 return paInsufficientMemory; 354 AudioHardwareGetProperty( kAudioHardwarePropertyDevices, 355 &propsize, 356 auhalHostApi->devIds ); 357 #ifdef MAC_CORE_VERBOSE_DEBUG 358 { 359 int i; 360 for( i=0; i<auhalHostApi->devCount; ++i ) 361 printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] ); 362 } 363 #endif 364 365 size = sizeof(AudioDeviceID); 333 UInt32 size = sizeof(AudioDeviceID); 334 VVDBUG(("gatherDefaultInputDevice()\n")); 366 335 auhalHostApi->defaultIn = kAudioDeviceUnknown; 367 auhalHostApi->defaultOut = kAudioDeviceUnknown;368 336 369 337 /* determine the default device. */ 370 338 /* I am not sure how these calls to AudioHardwareGetProperty() … … 385 353 auhalHostApi->defaultIn = auhalHostApi->devIds[i]; 386 354 break; 387 355 } 388 }356 } 389 357 } 358 VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) ); 359 } 360 361 /* This is used during initialization, rescan, and default device changes to 362 gather information about the current default output device. */ 363 static void gatherDefaultOutputDevice(PaMacAUHAL *auhalHostApi) 364 { 365 UInt32 size = sizeof(AudioDeviceID); 366 VVDBUG(("gatherDefaultOutputDevice()\n")); 367 auhalHostApi->defaultOut = kAudioDeviceUnknown; 368 390 369 if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, 391 370 &size, 392 371 &auhalHostApi->defaultOut) ) { … … 404 383 } 405 384 } 406 385 } 407 408 VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) );409 386 VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) ); 387 } 410 388 389 /* This is used during initialization and rescan to gather information about 390 devices. */ 391 static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi) 392 { 393 UInt32 size; 394 UInt32 propsize; 395 VVDBUG(("gatherDeviceInfo()\n")); 396 /* -- free any previous allocations -- */ 397 if( auhalHostApi->devIds ) 398 PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds); 399 auhalHostApi->devIds = NULL; 400 401 /* -- figure out how many devices there are -- */ 402 AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, 403 &propsize, 404 NULL ); 405 auhalHostApi->devCount = propsize / sizeof( AudioDeviceID ); 406 407 VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) ); 408 409 /* -- copy the device IDs -- */ 410 auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory( 411 auhalHostApi->allocations, 412 propsize ); 413 if( !auhalHostApi->devIds ) 414 return paInsufficientMemory; 415 AudioHardwareGetProperty( kAudioHardwarePropertyDevices, 416 &propsize, 417 auhalHostApi->devIds ); 418 #ifdef MAC_CORE_VERBOSE_DEBUG 419 { 420 int i; 421 for( i=0; i<auhalHostApi->devCount; ++i ) 422 printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] ); 423 } 424 #endif 425 426 gatherDefaultInputDevice(auhalHostApi); 427 gatherDefaultOutputDevice(auhalHostApi); 428 411 429 return paNoError; 412 430 } 413 431 432 /* Callback for audio hardware property changes. */ 433 static OSStatus audioPropertyCallback(AudioHardwarePropertyID inPropertyID, 434 void *refCon) 435 { 436 struct PaUtilHostApiRepresentation *hostApi = 437 (struct PaUtilHostApiRepresentation *)refCon; 438 PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; 439 int i; 440 switch (inPropertyID) 441 { 442 /* 443 * These are the other types of notifications we might receive, however, they are beyond 444 * the scope of this sample and we ignore them. 445 **/ 446 case kAudioHardwarePropertyDefaultInputDevice: 447 PA_DEBUG(("audioPropertyCallback: default input device changed\n")); 448 449 /* default to no device, in case we don't find it in the devIds. */ 450 hostApi->info.defaultInputDevice = paNoDevice; 451 452 gatherDefaultInputDevice(auhalHostApi); 453 454 /* attempt to find the device amongst the known devIds. */ 455 for( i=0; i < auhalHostApi->devCount; ++i ) 456 { 457 if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn) 458 hostApi->info.defaultInputDevice = i; 459 } 460 461 PaUtil_DevicesChanged( paDefaultInputDeviceChanged ); 462 break; 463 464 case kAudioHardwarePropertyDefaultOutputDevice: 465 PA_DEBUG(("audioPropertyCallback: default output device changed\n")); 466 467 /* default to no device, in case we don't find it in the devIds. */ 468 hostApi->info.defaultOutputDevice = paNoDevice; 469 470 gatherDefaultOutputDevice(auhalHostApi); 471 472 /* attempt to find the device amongst the known devIds. */ 473 for( i=0; i < auhalHostApi->devCount; ++i ) 474 { 475 if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut) 476 hostApi->info.defaultOutputDevice = i; 477 } 478 479 PaUtil_DevicesChanged( paDefaultOutputDeviceChanged ); 480 break; 481 482 case kAudioHardwarePropertyDefaultSystemOutputDevice: 483 PA_DEBUG(("audioPropertyCallback: default system output device changed\n")); 484 break; 485 486 case kAudioHardwarePropertyDevices: 487 PA_DEBUG(("audioPropertyCallback: device list changed\n")); 488 PaUtil_DevicesChanged( paUtilHardwareDevicesChanged ); 489 break; 490 491 default: 492 PA_DEBUG(("audioPropertyCallback: unknown message id=%08lx\n", inPropertyID)); 493 break; 494 } 495 496 return noErr; 497 } 498 414 499 static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi, 415 500 PaDeviceInfo *deviceInfo, 416 501 AudioDeviceID macCoreDeviceId, … … 626 711 } 627 712 628 713 (*hostApi)->Terminate = Terminate; 714 (*hostApi)->RescanDevices = RescanDevices; 629 715 (*hostApi)->OpenStream = OpenStream; 630 716 (*hostApi)->IsFormatSupported = IsFormatSupported; 631 717 … … 647 733 GetStreamReadAvailable, 648 734 GetStreamWriteAvailable ); 649 735 736 /* register the audio hardware change listener */ 737 AudioHardwareAddPropertyListener(kAudioHardwarePropertyDevices, 738 audioPropertyCallback, *hostApi); 739 AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultInputDevice, 740 audioPropertyCallback, *hostApi); 741 AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultOutputDevice, 742 audioPropertyCallback, *hostApi); 743 650 744 return result; 651 745 652 746 error: … … 676 770  
