From f5d2ea76b4d1687e755ca075591eecfc45c8979e Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 26 Jul 2023 00:21:18 +1000 Subject: [PATCH] osxaudio: Attempt to configure the segment size in CoreAudio Set the BufferFrame size in CoreAudio so it will deliver data in ringbuffer segment units when recording. Otherwise, CoreAudio will provide data in whatever granularity it wants, with no relationship to the requested latency-time. Part-of: --- .../sys/osxaudio/gstosxaudioringbuffer.c | 7 +++++-- .../sys/osxaudio/gstosxcoreaudio.c | 14 +++++++++----- .../sys/osxaudio/gstosxcoreaudio.h | 1 + .../sys/osxaudio/gstosxcoreaudiohal.c | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c index 32eb120fd5..5a8e58214d 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c @@ -174,7 +174,8 @@ gst_osx_audio_ring_buffer_acquire (GstAudioRingBuffer * buf, { gboolean ret = FALSE, is_passthrough = FALSE; GstOsxAudioRingBuffer *osxbuf; - AudioStreamBasicDescription format; + AudioStreamBasicDescription format = { 0 }; + guint32 frames_per_packet = 0; osxbuf = GST_OSX_AUDIO_RING_BUFFER (buf); @@ -225,6 +226,8 @@ gst_osx_audio_ring_buffer_acquire (GstAudioRingBuffer * buf, (spec->latency_time * GST_AUDIO_INFO_RATE (&spec->info) / G_USEC_PER_SEC) * GST_AUDIO_INFO_BPF (&spec->info); spec->segtotal = spec->buffer_time / spec->latency_time; + frames_per_packet = spec->segsize / GST_AUDIO_INFO_BPF (&spec->info); + is_passthrough = FALSE; } @@ -239,7 +242,7 @@ gst_osx_audio_ring_buffer_acquire (GstAudioRingBuffer * buf, buf->memory = g_malloc0 (buf->size); ret = gst_core_audio_initialize (osxbuf->core_audio, format, spec->caps, - is_passthrough); + frames_per_packet, is_passthrough); if (!ret) { g_free (buf->memory); diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c index 08a52e4f33..036245c7cf 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c @@ -208,22 +208,26 @@ gst_core_audio_get_samples_and_latency (GstCoreAudio * core_audio, gboolean gst_core_audio_initialize (GstCoreAudio * core_audio, - AudioStreamBasicDescription format, GstCaps * caps, gboolean is_passthrough) + AudioStreamBasicDescription format, GstCaps * caps, + guint32 frames_per_packet, gboolean is_passthrough) { - guint32 frame_size; - GST_DEBUG_OBJECT (core_audio, "Initializing: passthrough:%d caps:%" GST_PTR_FORMAT, is_passthrough, caps); if (!gst_core_audio_initialize_impl (core_audio, format, caps, - is_passthrough, &frame_size)) { + is_passthrough, &frames_per_packet)) { return FALSE; } if (core_audio->is_src) { /* create AudioBufferList needed for recording */ - core_audio->recBufferSize = frame_size * format.mBytesPerFrame; + core_audio->recBufferSize = frames_per_packet * format.mBytesPerFrame; + + GST_DEBUG_OBJECT (core_audio, + "Allocating record buffers %u bytes %u frames", + core_audio->recBufferSize, frames_per_packet); + core_audio->recBufferList = buffer_list_alloc (format.mChannelsPerFrame, core_audio->recBufferSize, /* Currently always TRUE (i.e. interleaved) */ diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h index 4319434d49..3416db6539 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h @@ -127,6 +127,7 @@ gboolean gst_core_audio_close (GstCoreAudio *core gboolean gst_core_audio_initialize (GstCoreAudio *core_audio, AudioStreamBasicDescription format, GstCaps *caps, + guint32 frames_per_packet, gboolean is_passthrough); void gst_core_audio_uninitialize (GstCoreAudio *core_audio); diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiohal.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiohal.c index 7e41f59aac..31ebe60709 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiohal.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiohal.c @@ -1174,6 +1174,24 @@ gst_core_audio_initialize_impl (GstCoreAudio * core_audio, if (core_audio->is_src) { propertySize = sizeof (*frame_size); + + // Attempt to configure the requested frame size if smaller than the device's + // This will apparently modify the size for all audio devices in the current process so should + // be done conservatively + if (frame_size != 0) { + guint32 cur_frame_size; + status = AudioUnitGetProperty (core_audio->audiounit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0, /* N/A for global */ + &cur_frame_size, &propertySize); + if (!status && *frame_size < cur_frame_size) { + status = AudioUnitSetProperty (core_audio->audiounit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0, /* N/A for global */ + frame_size, propertySize); + if (status) { + GST_WARNING_OBJECT (core_audio->osxbuf, + "Failed to set desired frame size of %u: %d", *frame_size, + (int) status); + } + } + } status = AudioUnitGetProperty (core_audio->audiounit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, 0, /* N/A for global */ frame_size, &propertySize);