mirror of https://github.com/mpv-player/mpv
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:
parent
240266d12c
commit
7c07da57e3
|
@ -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}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue