From bec8a09bd96fff81c0f2e20be99c988987fd4c8e Mon Sep 17 00:00:00 2001 From: jp9000 Date: Tue, 4 Mar 2014 07:10:33 -0700 Subject: [PATCH] CoreAudio: Separate enumeration code The enumeration code being up at the top was making things quite messy, so I split that code out to a separate set of files. --- plugins/mac-capture/CMakeLists.txt | 8 +- plugins/mac-capture/audio-device-enum.c | 103 +++++++++++++++++++ plugins/mac-capture/audio-device-enum.h | 35 +++++++ plugins/mac-capture/mac-audio.c | 130 +----------------------- plugins/mac-capture/mac-helpers.h | 2 + 5 files changed, 148 insertions(+), 130 deletions(-) create mode 100644 plugins/mac-capture/audio-device-enum.c create mode 100644 plugins/mac-capture/audio-device-enum.h diff --git a/plugins/mac-capture/CMakeLists.txt b/plugins/mac-capture/CMakeLists.txt index 4e9697c65..4c9f796b2 100644 --- a/plugins/mac-capture/CMakeLists.txt +++ b/plugins/mac-capture/CMakeLists.txt @@ -8,12 +8,18 @@ include_directories(${COREAUDIO} ${AUDIOUNIT} ${COREFOUNDATION}) +set(mac-capture_HEADERS + audio-device-enum.h + mac-helpers.h) + set(mac-capture_SOURCES plugin-main.c + audio-device-enum.c mac-audio.c) add_library(mac-capture MODULE - ${mac-capture_SOURCES}) + ${mac-capture_SOURCES} + ${mac-capture_HEADERS}) target_link_libraries(mac-capture libobs ${COREAUDIO} diff --git a/plugins/mac-capture/audio-device-enum.c b/plugins/mac-capture/audio-device-enum.c new file mode 100644 index 000000000..8da14a7d6 --- /dev/null +++ b/plugins/mac-capture/audio-device-enum.c @@ -0,0 +1,103 @@ +#include +#include + +#include "mac-helpers.h" +#include "audio-device-enum.h" + +/* ugh, because mac has no means of capturing output, we have to basically + * mark soundflower and wavtap as output devices. */ +static inline bool device_is_input(char *device) +{ + return astrstri(device, "soundflower") == NULL && + astrstri(device, "wavtap") == NULL; +} + +static inline bool enum_success(OSStatus stat, const char *msg) +{ + if (stat != noErr) { + blog(LOG_WARNING, "[coreaudio_enum_devices] %s failed: %d", + msg, (int)stat); + return false; + } + + return true; +} + +static void coreaudio_enum_add_device(struct device_list *list, + AudioDeviceID id, bool input) +{ + OSStatus stat; + UInt32 size = 0; + CFStringRef cf_name = NULL; + CFStringRef cf_value = NULL; + struct device_item item; + + AudioObjectPropertyAddress addr = { + kAudioDevicePropertyStreams, + kAudioDevicePropertyScopeInput, + kAudioObjectPropertyElementMaster + }; + + memset(&item, 0, sizeof(item)); + + /* 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_value); + if (!enum_success(stat, "get audio device UID")) + return; + + addr.mSelector = kAudioDevicePropertyDeviceNameCFString; + stat = AudioObjectGetPropertyData(id, &addr, 0, NULL, &size, &cf_name); + if (!enum_success(stat, "get audio device name")) + goto fail; + + if (!cf_to_dstr(cf_name, &item.name)) + goto fail; + if (!cf_to_dstr(cf_value, &item.value)) + goto fail; + + if (input || !device_is_input(item.value.array)) + device_list_add(list, &item); + +fail: + device_item_free(&item); + CFRelease(cf_name); + CFRelease(cf_value); +} + +void coreaudio_enum_devices(struct device_list *list, bool input) +{ + AudioObjectPropertyAddress addr = { + kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + + UInt32 size = 0; + UInt32 count; + OSStatus stat; + AudioDeviceID *ids; + + stat = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, + 0, NULL, &size); + if (!enum_success(stat, "get kAudioObjectSystemObject data size")) + return; + + ids = bmalloc(size); + count = size / sizeof(AudioDeviceID); + + stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, + 0, NULL, &size, ids); + + if (enum_success(stat, "get kAudioObjectSystemObject data")) + for (UInt32 i = 0; i < count; i++) + coreaudio_enum_add_device(list, ids[i], input); + + bfree(ids); +} diff --git a/plugins/mac-capture/audio-device-enum.h b/plugins/mac-capture/audio-device-enum.h new file mode 100644 index 000000000..14fa0968c --- /dev/null +++ b/plugins/mac-capture/audio-device-enum.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +struct device_item { + struct dstr name, value; +}; + +static inline void device_item_free(struct device_item *item) +{ + dstr_free(&item->name); + dstr_free(&item->value); +} + +struct device_list { + DARRAY(struct device_item) items; +}; + +static inline void device_list_free(struct device_list *list) +{ + for (size_t i = 0; i < list->items.num; i++) + device_item_free(list->items.array+i); + + da_free(list->items); +} + +static inline void device_list_add(struct device_list *list, + struct device_item *item) +{ + da_push_back(list->items, item); + memset(item, 0, sizeof(struct device_item)); +} + +extern void coreaudio_enum_devices(struct device_list *list, bool input); diff --git a/plugins/mac-capture/mac-audio.c b/plugins/mac-capture/mac-audio.c index 1512226a0..9693433d1 100644 --- a/plugins/mac-capture/mac-audio.c +++ b/plugins/mac-capture/mac-audio.c @@ -7,10 +7,9 @@ #include #include #include -#include -#include #include "mac-helpers.h" +#include "audio-device-enum.h" #define PROPERTY_DEFAULT_DEVICE kAudioHardwarePropertyDefaultInputDevice #define PROPERTY_FORMATS kAudioStreamPropertyAvailablePhysicalFormats @@ -51,133 +50,6 @@ struct coreaudio_data { obs_source_t source; }; -struct device_item { - struct dstr name, value; -}; - -static inline void device_item_free(struct device_item *item) -{ - dstr_free(&item->name); - dstr_free(&item->value); -} - -struct device_list { - DARRAY(struct device_item) items; -}; - -static inline void device_list_add(struct device_list *list, - struct device_item *item) -{ - da_push_back(list->items, item); - memset(item, 0, sizeof(struct device_item)); -} - -static inline void device_list_free(struct device_list *list) -{ - for (size_t i = 0; i < list->items.num; i++) - device_item_free(list->items.array+i); - - da_free(list->items); -} - -/* ugh, because mac has no means of capturing output, we have to basically - * mark soundflower and wavtap as output devices. */ -static inline bool device_is_input(char *device) -{ - return astrstri(device, "soundflower") == NULL && - astrstri(device, "wavtap") == NULL; -} - -static inline bool enum_success(OSStatus stat, const char *msg) -{ - if (stat != noErr) { - blog(LOG_WARNING, "[coreaudio_enum_devices] %s failed: %d", - msg, (int)stat); - return false; - } - - return true; -} - -static void coreaudio_enum_add_device(struct device_list *list, - AudioDeviceID id, bool input) -{ - OSStatus stat; - UInt32 size = 0; - CFStringRef cf_name = NULL; - CFStringRef cf_value = NULL; - struct device_item item; - - AudioObjectPropertyAddress addr = { - kAudioDevicePropertyStreams, - kAudioDevicePropertyScopeInput, - kAudioObjectPropertyElementMaster - }; - - memset(&item, 0, sizeof(item)); - - /* 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_value); - if (!enum_success(stat, "get audio device UID")) - return; - - addr.mSelector = kAudioDevicePropertyDeviceNameCFString; - stat = AudioObjectGetPropertyData(id, &addr, 0, NULL, &size, &cf_name); - if (!enum_success(stat, "get audio device name")) - goto fail; - - if (!cf_to_dstr(cf_name, &item.name)) - goto fail; - if (!cf_to_dstr(cf_value, &item.value)) - goto fail; - - if (input || !device_is_input(item.value.array)) - device_list_add(list, &item); - -fail: - device_item_free(&item); - CFRelease(cf_name); - CFRelease(cf_value); -} - -static void coreaudio_enum_devices(struct device_list *list, bool input) -{ - AudioObjectPropertyAddress addr = { - kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - - UInt32 size = 0; - UInt32 count; - OSStatus stat; - AudioDeviceID *ids; - - stat = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr, - 0, NULL, &size); - if (!enum_success(stat, "get kAudioObjectSystemObject data size")) - return; - - ids = bmalloc(size); - count = size / sizeof(AudioDeviceID); - - stat = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, - 0, NULL, &size, ids); - - if (enum_success(stat, "get kAudioObjectSystemObject data")) - for (UInt32 i = 0; i < count; i++) - coreaudio_enum_add_device(list, ids[i], input); - - bfree(ids); -} - static bool get_default_output_device(struct coreaudio_data *ca) { struct device_list list; diff --git a/plugins/mac-capture/mac-helpers.h b/plugins/mac-capture/mac-helpers.h index 0f8904fc4..077e9828c 100644 --- a/plugins/mac-capture/mac-helpers.h +++ b/plugins/mac-capture/mac-helpers.h @@ -1,5 +1,7 @@ #pragma once +#include + static inline bool mac_success(OSStatus stat, const char *action) { if (stat != noErr) {