void ca_get_device_list(struct ao *ao, struct ao_device_list *list) { 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++) { if (!ca_is_output_device(ao, devs[i])) continue; void *ta_ctx = talloc_new(NULL); char *name; char *desc; err = CA_GET_STR(devs[i], kAudioDevicePropertyDeviceUID, &name); if (err != noErr) { MP_VERBOSE(ao, "skipping device %d, which has no UID\n", i); talloc_free(ta_ctx); continue; } talloc_steal(ta_ctx, name); err = CA_GET_STR(devs[i], kAudioObjectPropertyName, &desc); if (err != noErr) desc = talloc_strdup(NULL, "Unknown"); talloc_steal(ta_ctx, desc); ao_device_list_add(list, ao, &(struct ao_device_desc){name, desc}); talloc_free(ta_ctx); }
static void init_physical_format(struct ao *ao) { struct priv *p = ao->priv; OSErr err; AudioStreamBasicDescription asbd; ca_fill_asbd(ao, &asbd); AudioStreamID *streams; size_t n_streams; err = CA_GET_ARY_O(p->device, kAudioDevicePropertyStreams, &streams, &n_streams); CHECK_CA_ERROR("could not get number of streams"); for (int i = 0; i < n_streams; i++) { AudioStreamRangedDescription *formats; size_t n_formats; err = CA_GET_ARY(streams[i], kAudioStreamPropertyAvailablePhysicalFormats, &formats, &n_formats); if (!CHECK_CA_WARN("could not get number of stream formats")) continue; // try next one MP_VERBOSE(ao, "Looking at formats in substream %d...\n", i); AudioStreamBasicDescription best_asbd = {0}; for (int j = 0; j < n_formats; j++) { AudioStreamBasicDescription *stream_asbd = &formats[j].mFormat; ca_print_asbd(ao, "- ", stream_asbd); if (!best_asbd.mFormatID || ca_asbd_is_better(&asbd, &best_asbd, stream_asbd)) best_asbd = *stream_asbd; } if (best_asbd.mFormatID) { p->original_asbd_stream = streams[i]; err = CA_GET(p->original_asbd_stream, kAudioStreamPropertyPhysicalFormat, &p->original_asbd); CHECK_CA_WARN("could not get current physical stream format"); ca_change_physical_format_sync(ao, streams[i], best_asbd); break; } } coreaudio_error: return; }
void ca_get_device_list(struct ao *ao, struct ao_device_list *list) { 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[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}); }
bool ca_stream_supports_digital(struct ao *ao, AudioStreamID stream) { AudioStreamRangedDescription *formats = NULL; size_t n_formats; OSStatus err = CA_GET_ARY(stream, kAudioStreamPropertyAvailablePhysicalFormats, &formats, &n_formats); CHECK_CA_ERROR("Could not get number of stream formats."); for (int i = 0; i < n_formats; i++) { AudioStreamBasicDescription asbd = formats[i].mFormat; ca_print_asbd(ao, "supported format:", &(asbd)); if (ca_format_is_digital(asbd)) { talloc_free(formats); return true; } } talloc_free(formats); coreaudio_error: return false; }