From c347629c8d7dc30dc2dd22c37c3b712a36250cce Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 3 Aug 2015 15:14:41 -0700 Subject: [PATCH] CoreAudio: obtain device buffer duration --- soundio/soundio.h | 4 ++-- src/coreaudio.cpp | 36 +++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/soundio/soundio.h b/soundio/soundio.h index cdfcac7..bdfe3be 100644 --- a/soundio/soundio.h +++ b/soundio/soundio.h @@ -353,8 +353,8 @@ struct SoundIoDevice { // Period duration in seconds. After this much time passes, write_callback // is called. If values are unknown, they are set to 0.0. These values are - // meaningless for PulseAudio. For JACK, buffer duration and period duration - // are the same. + // meaningless for PulseAudio and CoreAudio. For JACK, buffer duration and + // period duration are the same. double period_duration_min; double period_duration_max; double period_duration_current; diff --git a/src/coreaudio.cpp b/src/coreaudio.cpp index a31f1ef..52b4b94 100644 --- a/src/coreaudio.cpp +++ b/src/coreaudio.cpp @@ -112,13 +112,6 @@ static int aim_to_scope(SoundIoDeviceAim aim) { clients should re-evaluate everything they need to know about the device, particularly the layout and values of the controls. */ -/* - @constant kAudioDevicePropertyBufferFrameSize - A UInt32 whose value indicates the number of frames in the IO buffers. - @constant kAudioDevicePropertyBufferFrameSizeRange - An AudioValueRange indicating the minimum and maximum values, inclusive, for - kAudioDevicePropertyBufferFrameSize. -*/ /* @constant kAudioDevicePropertyLatency A UInt32 containing the number of frames of latency in the AudioDevice. Note @@ -577,6 +570,35 @@ static int refresh_devices(struct SoundIoPrivate *si) { rd.device->sample_rate_min = avr.mMinimum; rd.device->sample_rate_max = avr.mMaximum; + prop_address.mSelector = kAudioDevicePropertyBufferFrameSize; + prop_address.mScope = aim_to_scope(aim); + prop_address.mElement = kAudioObjectPropertyElementMaster; + io_size = sizeof(UInt32); + UInt32 buffer_frame_size; + if ((os_err = AudioObjectGetPropertyData(deviceID, &prop_address, 0, nullptr, + &io_size, &buffer_frame_size))) + { + deinit_refresh_devices(&rd); + return SoundIoErrorOpeningDevice; + } + double use_sample_rate = clamp(rd.device->sample_rate_min, rd.device->sample_rate_current, + rd.device->sample_rate_max); + rd.device->buffer_duration_current = buffer_frame_size / use_sample_rate; + + prop_address.mSelector = kAudioDevicePropertyBufferFrameSizeRange; + prop_address.mScope = aim_to_scope(aim); + prop_address.mElement = kAudioObjectPropertyElementMaster; + io_size = sizeof(AudioValueRange); + if ((os_err = AudioObjectGetPropertyData(deviceID, &prop_address, 0, nullptr, + &io_size, &avr))) + { + deinit_refresh_devices(&rd); + return SoundIoErrorOpeningDevice; + } + rd.device->buffer_duration_min = avr.mMinimum / use_sample_rate; + rd.device->buffer_duration_max = avr.mMaximum / use_sample_rate; + + SoundIoList *device_list; if (rd.device->aim == SoundIoDeviceAimOutput) {