Advertisement
sbooth

CreateOutputDeviceArray

Jul 30th, 2011
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.76 KB | None | 0 0
  1. CFArrayRef CreateOutputDeviceArray()
  2. {
  3.     AudioObjectPropertyAddress propertyAddress = {
  4.         kAudioHardwarePropertyDevices,
  5.         kAudioObjectPropertyScopeGlobal,
  6.         kAudioObjectPropertyElementMaster
  7.     };
  8.  
  9.     UInt32 dataSize = 0;
  10.     OSStatus status = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize);
  11.     if(kAudioHardwareNoError != status) {
  12.         fprintf(stderr, "AudioObjectGetPropertyDataSize (kAudioHardwarePropertyDevices) failed: %i\n", status);
  13.         return NULL;
  14.     }
  15.  
  16.     UInt32 deviceCount = (UInt32)(dataSize / sizeof(AudioDeviceID));
  17.  
  18.     AudioDeviceID *audioDevices = (AudioDeviceID *)malloc(dataSize);
  19.     if(NULL == audioDevices) {
  20.         fputs("Unable to allocate memory", stderr);
  21.         return NULL;
  22.     }
  23.  
  24.     status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize, audioDevices);
  25.     if(kAudioHardwareNoError != status) {
  26.         fprintf(stderr, "AudioObjectGetPropertyData (kAudioHardwarePropertyDevices) failed: %i\n", status);
  27.         free(audioDevices), audioDevices = NULL;
  28.         return NULL;
  29.     }
  30.  
  31.     CFMutableArrayRef outputDeviceArray = CFArrayCreateMutable(kCFAllocatorDefault, deviceCount, &kCFTypeArrayCallBacks);
  32.     if(NULL == outputDeviceArray) {
  33.         fputs("CFArrayCreateMutable failed", stderr);
  34.         free(audioDevices), audioDevices = NULL;
  35.         return NULL;
  36.     }
  37.  
  38.     // Iterate through all the devices and determine which are output-capable
  39.     propertyAddress.mScope = kAudioDevicePropertyScopeOutput;
  40.     for(UInt32 i = 0; i < deviceCount; ++i) {
  41.         // Query device UID
  42.         CFStringRef deviceUID = NULL;
  43.         dataSize = sizeof(deviceUID);
  44.         propertyAddress.mSelector = kAudioDevicePropertyDeviceUID;
  45.         status = AudioObjectGetPropertyData(audioDevices[i], &propertyAddress, 0, NULL, &dataSize, &deviceUID);
  46.         if(kAudioHardwareNoError != status) {
  47.             fprintf(stderr, "AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID) failed: %i\n", status);
  48.             continue;
  49.         }
  50.  
  51.         // Query device name
  52.         CFStringRef deviceName = NULL;
  53.         dataSize = sizeof(deviceName);
  54.         propertyAddress.mSelector = kAudioDevicePropertyDeviceNameCFString;
  55.         status = AudioObjectGetPropertyData(audioDevices[i], &propertyAddress, 0, NULL, &dataSize, &deviceName);
  56.         if(kAudioHardwareNoError != status) {
  57.             fprintf(stderr, "AudioObjectGetPropertyData (kAudioDevicePropertyDeviceNameCFString) failed: %i\n", status);
  58.             continue;
  59.         }
  60.  
  61.         // Query device manufacturer
  62.         CFStringRef deviceManufacturer = NULL;
  63.         dataSize = sizeof(deviceManufacturer);
  64.         propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturerCFString;
  65.         status = AudioObjectGetPropertyData(audioDevices[i], &propertyAddress, 0, NULL, &dataSize, &deviceManufacturer);
  66.         if(kAudioHardwareNoError != status) {
  67.             fprintf(stderr, "AudioObjectGetPropertyData (kAudioDevicePropertyDeviceManufacturerCFString) failed: %i\n", status);
  68.             continue;
  69.         }
  70.  
  71.         // Determine if the device is an output device (it is an output device if it has output channels)
  72.         dataSize = 0;
  73.         propertyAddress.mSelector = kAudioDevicePropertyStreamConfiguration;
  74.         status = AudioObjectGetPropertyDataSize(audioDevices[i], &propertyAddress, 0, NULL, &dataSize);
  75.         if(kAudioHardwareNoError != status) {
  76.             fprintf(stderr, "AudioObjectGetPropertyDataSize (kAudioDevicePropertyStreamConfiguration) failed: %i\n", status);
  77.             continue;
  78.         }
  79.  
  80.         AudioBufferList *bufferList = (AudioBufferList *)malloc(dataSize);
  81.         if(NULL == bufferList) {
  82.             fputs("Unable to allocate memory", stderr);
  83.             break;
  84.         }
  85.  
  86.         status = AudioObjectGetPropertyData(audioDevices[i], &propertyAddress, 0, NULL, &dataSize, bufferList);
  87.         if(kAudioHardwareNoError != status || 0 == bufferList->mNumberBuffers) {
  88.             if(kAudioHardwareNoError != status)
  89.                 fprintf(stderr, "AudioObjectGetPropertyData (kAudioDevicePropertyStreamConfiguration) failed: %i\n", status);
  90.             free(bufferList), bufferList = NULL;
  91.             continue;          
  92.         }
  93.  
  94.         free(bufferList), bufferList = NULL;
  95.  
  96.         // Add a dictionary for this device to the array of output devices
  97.         CFStringRef keys    []  = { CFSTR("deviceUID"),     CFSTR("deviceName"),    CFSTR("deviceManufacturer") };
  98.         CFStringRef values  []  = { deviceUID,              deviceName,             deviceManufacturer };
  99.  
  100.         CFDictionaryRef deviceDictionary = CFDictionaryCreate(kCFAllocatorDefault,
  101.                                                               (const void **)keys,
  102.                                                               (const void **)values,
  103.                                                               3,
  104.                                                               &kCFTypeDictionaryKeyCallBacks,
  105.                                                               &kCFTypeDictionaryValueCallBacks);
  106.  
  107.  
  108.         CFArrayAppendValue(outputDeviceArray, deviceDictionary);
  109.  
  110.         CFRelease(deviceDictionary), deviceDictionary = NULL;
  111.     }
  112.  
  113.     free(audioDevices), audioDevices = NULL;
  114.  
  115.     // Return a non-mutable copy of the array
  116.     CFArrayRef copy = CFArrayCreateCopy(kCFAllocatorDefault, outputDeviceArray);
  117.     CFRelease(outputDeviceArray), outputDeviceArray = NULL;
  118.  
  119.     return copy;
  120. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement