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.
This commit is contained in:
Stefano Pigozzi 2014-10-12 12:11:32 +02:00
parent 240266d12c
commit 7c07da57e3
4 changed files with 28 additions and 54 deletions

View File

@ -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}
},
};

View File

@ -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}
},
};

View File

@ -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:

View File

@ -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,