From 7c07da57e3797b26c6e896bd27afc2ed7d639a18 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 12 Oct 2014 12:11:32 +0200 Subject: coreaudio: use the new device selection API The CoreAudio API is built around device IDs so we store the integer as string and read it back. --- audio/out/ao_coreaudio.c | 20 +++++-------------- audio/out/ao_coreaudio_device.c | 14 ++----------- audio/out/ao_coreaudio_utils.c | 44 ++++++++++++++++++----------------------- audio/out/ao_coreaudio_utils.h | 4 ++-- 4 files changed, 28 insertions(+), 54 deletions(-) diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index 9335877208..8a8a73f5ce 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -33,10 +33,6 @@ struct priv { AudioUnit audio_unit; uint64_t hw_latency_us; - - // options - int opt_device_id; - int opt_list; }; bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, @@ -151,9 +147,7 @@ static int init(struct ao *ao) { struct priv *p = ao->priv; - if (p->opt_list) ca_print_device_list(ao); - - OSStatus err = ca_select_device(ao, p->opt_device_id, &p->device); + OSStatus err = ca_select_device(ao, ao->device, &p->device); CHECK_CA_ERROR("failed to select device"); if (!init_chmap(ao)) @@ -221,9 +215,9 @@ static bool init_audiounit(struct ao *ao, AudioStreamBasicDescription asbd) AudioComponentDescription desc = (AudioComponentDescription) { .componentType = kAudioUnitType_Output, - .componentSubType = (p->opt_device_id < 0) ? - kAudioUnitSubType_DefaultOutput : - kAudioUnitSubType_HALOutput, + .componentSubType = (ao->device) ? + kAudioUnitSubType_HALOutput : + kAudioUnitSubType_DefaultOutput, .componentManufacturer = kAudioUnitManufacturer_Apple, .componentFlags = 0, .componentFlagsMask = 0, @@ -440,10 +434,6 @@ const struct ao_driver audio_out_coreaudio = { .control = control, .pause = stop, .resume = start, + .list_devs = ca_get_device_list, .priv_size = sizeof(struct priv), - .options = (const struct m_option[]) { - OPT_INT("device_id", opt_device_id, 0, OPTDEF_INT(-1)), - OPT_FLAG("list", opt_list, 0), - {0} - }, }; diff --git a/audio/out/ao_coreaudio_device.c b/audio/out/ao_coreaudio_device.c index 0c908d52ef..49560a2e80 100644 --- a/audio/out/ao_coreaudio_device.c +++ b/audio/out/ao_coreaudio_device.c @@ -333,10 +333,6 @@ struct priv { bool changed_mixing; int stream_asbd_changed; bool muted; - - // options - int opt_device_id; - int opt_list; }; static int get_ring_size(struct ao *ao) @@ -402,9 +398,7 @@ static int init(struct ao *ao) { struct priv *p = ao->priv; - if (p->opt_list) ca_print_device_list(ao); - - OSStatus err = ca_select_device(ao, p->opt_device_id, &p->device); + OSStatus err = ca_select_device(ao, ao->device, &p->device); CHECK_CA_ERROR("failed to select device"); ao->format = af_fmt_from_planar(ao->format); @@ -660,6 +654,7 @@ const struct ao_driver audio_out_coreaudio_exclusive = { .reset = reset, .pause = audio_pause, .resume = audio_resume, + .list_devs = ca_get_device_list, .priv_size = sizeof(struct priv), .priv_defaults = &(const struct priv){ .muted = false, @@ -669,9 +664,4 @@ const struct ao_driver audio_out_coreaudio_exclusive = { .stream_idx = -1, .changed_mixing = false, }, - .options = (const struct m_option[]) { - OPT_INT("device_id", opt_device_id, 0, OPTDEF_INT(-1)), - OPT_FLAG("list", opt_list, 0), - {0} - }, }; diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index 08214ef387..cc08f4c6ab 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -28,42 +28,36 @@ #include "osdep/endian.h" #include "audio/format.h" -void ca_print_device_list(struct ao *ao) +void ca_get_device_list(struct ao *ao, struct ao_device_list *list) { - char *help = talloc_strdup(NULL, "Available output devices:\n"); - AudioDeviceID *devs; size_t n_devs; - OSStatus err = CA_GET_ARY(kAudioObjectSystemObject, kAudioHardwarePropertyDevices, &devs, &n_devs); - CHECK_CA_ERROR("Failed to get list of output devices."); - for (int i = 0; i < n_devs; i++) { - char *name; - err = CA_GET_STR(devs[i], kAudioObjectPropertyName, &name); - - if (err == noErr) - talloc_steal(devs, name); - else - name = "Unknown"; - - help = talloc_asprintf_append( - help, " * %s (id: %" PRIu32 ")\n", name, devs[i]); + char name[32]; + char *desc; + sprintf(name, "%d", devs[i]); + err = CA_GET_STR(devs[i], kAudioObjectPropertyName, &desc); + if (err != noErr) + desc = "Unknown"; + ao_device_list_add(list, ao, &(struct ao_device_desc){name, desc}); } - talloc_free(devs); - coreaudio_error: - MP_INFO(ao, "%s", help); - talloc_free(help); + return; } -OSStatus ca_select_device(struct ao *ao, int selection, AudioDeviceID *device) +OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device) { OSStatus err = noErr; + int selection = name ? strtol(name, (char **)NULL, 10) : -1; + if (errno == EINVAL || errno == ERANGE) { + selection = -1; + MP_ERR(ao, "device identifier '%s' is invalid\n", name); + } *device = 0; if (selection < 0) { // device not set by user, get the default one @@ -76,14 +70,14 @@ OSStatus ca_select_device(struct ao *ao, int selection, AudioDeviceID *device) } if (mp_msg_test(ao->log, MSGL_V)) { - char *name; - err = CA_GET_STR(*device, kAudioObjectPropertyName, &name); + char *desc; + err = CA_GET_STR(*device, kAudioObjectPropertyName, &desc); CHECK_CA_ERROR("could not get selected audio device name"); MP_VERBOSE(ao, "selected audio output device: %s (%" PRIu32 ")\n", - name, *device); + desc, *device); - talloc_free(name); + talloc_free(desc); } coreaudio_error: diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h index 2c746195fc..0ef84c3afa 100644 --- a/audio/out/ao_coreaudio_utils.h +++ b/audio/out/ao_coreaudio_utils.h @@ -46,8 +46,8 @@ bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message); if (err != noErr) goto label; \ } while (0) -void ca_print_device_list(struct ao *ao); -OSStatus ca_select_device(struct ao *ao, int selection, AudioDeviceID *device); +void ca_get_device_list(struct ao *ao, struct ao_device_list *list); +OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device); void ca_fill_asbd(struct ao *ao, AudioStreamBasicDescription *asbd); void ca_print_asbd(struct ao *ao, const char *description, -- cgit v1.2.3