diff options
-rw-r--r-- | audio/out/ao_coreaudio.c | 5 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_properties.c | 7 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.c | 50 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.h | 3 |
4 files changed, 46 insertions, 19 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 590549bd1a..0eab220421 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -156,7 +156,10 @@ static int init(struct ao *ao) OSStatus err = ca_select_device(ao, ao->device, &p->device); CHECK_CA_ERROR("failed to select device"); - ao->detected_device = talloc_asprintf(ao, "%d", p->device); + char *uid; + err = CA_GET_STR(p->device, kAudioDevicePropertyDeviceUID, &uid); + CHECK_CA_ERROR("failed to get device UID"); + ao->detected_device = talloc_steal(ao, uid); if (!init_chmap(ao)) goto coreaudio_error; diff --git a/audio/out/ao_coreaudio_properties.c b/audio/out/ao_coreaudio_properties.c index 181d338cbd..cf2b4d14a1 100644 --- a/audio/out/ao_coreaudio_properties.c +++ b/audio/out/ao_coreaudio_properties.c @@ -83,12 +83,7 @@ OSStatus ca_get_str(AudioObjectID id, ca_scope scope, ca_sel selector, ca_get(id, scope, selector, sizeof(CFStringRef), (void **)&string); CHECK_CA_ERROR_SILENT_L(coreaudio_error); - CFIndex size = - CFStringGetMaximumSizeForEncoding( - CFStringGetLength(string), CA_CFSTR_ENCODING) + 1; - - *data = talloc_zero_size(NULL, size); - CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING); + *data = cfstr_get_cstr(string); CFRelease(string); coreaudio_error: return err; diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index fe8354939a..50c866d86c 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -28,6 +28,21 @@ #include "osdep/endian.h" #include "audio/format.h" +CFStringRef cfstr_from_cstr(char *str) +{ + return CFStringCreateWithCString(NULL, str, CA_CFSTR_ENCODING); +} + +char *cfstr_get_cstr(CFStringRef cfstr) +{ + CFIndex size = + CFStringGetMaximumSizeForEncoding( + CFStringGetLength(cfstr), CA_CFSTR_ENCODING) + 1; + char *buffer = talloc_zero_size(NULL, size); + CFStringGetCString(cfstr, buffer, size, CA_CFSTR_ENCODING); + return buffer; +} + static bool ca_is_output_device(struct ao *ao, AudioDeviceID dev) { size_t n_buffers; @@ -49,9 +64,9 @@ void ca_get_device_list(struct ao *ao, struct ao_device_list *list) for (int i = 0; i < n_devs; i++) { if (!ca_is_output_device(ao, devs[i])) continue; - char name[32]; + char *name; char *desc; - sprintf(name, "%d", devs[i]); + err = CA_GET_STR(devs[i], kAudioDevicePropertyDeviceUID, &name); err = CA_GET_STR(devs[i], kAudioObjectPropertyName, &desc); if (err != noErr) desc = "Unknown"; @@ -65,21 +80,32 @@ coreaudio_error: OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device) { OSStatus err = noErr; - errno = 0; - int selection = name && name[0] ? strtol(name, (char **)NULL, 10) : -1; - if (errno == EINVAL || errno == ERANGE) { - selection = -1; - MP_WARN(ao, "device identifier '%s' is invalid\n", name); - } - *device = 0; - if (selection < 0) { + *device = kAudioObjectUnknown; + + if (name) { + CFStringRef uid = cfstr_from_cstr(name); + AudioValueTranslation v = (AudioValueTranslation) { + .mInputData = &uid, + .mInputDataSize = sizeof(CFStringRef), + .mOutputData = device, + .mOutputDataSize = sizeof(*device), + }; + uint32_t size = sizeof(AudioValueTranslation); + AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) { + .mSelector = kAudioHardwarePropertyDeviceForUID, + .mScope = kAudioObjectPropertyScopeGlobal, + .mElement = kAudioObjectPropertyElementMaster, + }; + err = AudioObjectGetPropertyData( + kAudioObjectSystemObject, &p_addr, 0, 0, &size, &v); + CFRelease(uid); + CHECK_CA_ERROR("unable to query for device UID"); + } else { // device not set by user, get the default one err = CA_GET(kAudioObjectSystemObject, kAudioHardwarePropertyDefaultOutputDevice, device); CHECK_CA_ERROR("could not get default audio device"); - } else { - *device = selection; } if (mp_msg_test(ao->log, MSGL_V)) { diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h index 0ef84c3afa..17c60b93be 100644 --- a/audio/out/ao_coreaudio_utils.h +++ b/audio/out/ao_coreaudio_utils.h @@ -28,6 +28,9 @@ #define CA_CFSTR_ENCODING kCFStringEncodingASCII +CFStringRef cfstr_from_cstr(char *str); +char *cfstr_get_cstr(CFStringRef cfstr); + char *fourcc_repr(void *talloc_ctx, uint32_t code); bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message); |