#include #include #include "../../obs-internal.h" #include "../../util/dstr.h" #include "mac-helpers.h" static inline bool cf_to_cstr(CFStringRef ref, char *buf, size_t size) { if (!ref) return false; return (bool)CFStringGetCString(ref, buf, size, kCFStringEncodingUTF8); } static void obs_enum_audio_monitoring_device(obs_enum_audio_device_cb cb, void *data, AudioDeviceID id) { UInt32 size = 0; CFStringRef cf_name = NULL; CFStringRef cf_uid = NULL; char name[1024]; char uid[1024]; OSStatus stat; AudioObjectPropertyAddress addr = { kAudioDevicePropertyStreams, kAudioDevicePropertyScopeInput, kAudioObjectPropertyElementMaster }; /* check to see if it's a mac input device */ AudioObjectGetPropertyDataSize(id, &addr, 0, NULL, &size); if (!size) return; size = sizeof(CFStringRef); addr.mSelector = kAudioDevicePropertyDeviceUID; stat = AudioObjectGetPropertyData(id, &addr, 0, NULL, &size, &cf_uid); if (!success(stat, "get audio device UID")) return; addr.mSelector = kAudioDevicePropertyDeviceNameCFString; stat = AudioObjectGetPropertyData(id, &addr, 0, NULL, &size, &cf_name); if (!success(stat, "get audio device name")) goto fail; if (!cf_to_cstr(cf_name, name, sizeof(name))) { blog(LOG_WARNING, "%s: failed to convert name", __FUNCTION__); goto fail; } if (!cf_to_cstr(cf_uid, uid, sizeof(uid))) { blog(LOG_WARNING, "%s: failed to convert uid", __FUNCTION__); goto fail; } cb(data, name, uid); fail: if (cf_name) CFRelease(cf_name); if (cf_uid) CFRelease(cf_uid); } void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data) { AudioObjectPropertyAddress addr = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; UInt32 size = 0; UInt32 count; OSStatus stat; AudioDeviceID *ids; stat = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, 0, NULL, &size); if (!success(stat, "get data size")) return; ids = malloc(size); count = size / sizeof(AudioDeviceID); stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, 0, NULL, &size, ids); if (success(stat, "get data")) { for (UInt32 i = 0; i < count; i++) obs_enum_audio_monitoring_device(cb, data, ids[i]); } free(ids); }