From 74ee7ee091958683725aa1bc9ef0cb027b49718b Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 3 Jun 2022 04:56:28 +0200 Subject: [PATCH] Add parallel realtime threads to CoreAudio workgroup This API is only available since BigSur (11.0), see also https://developer.apple.com/documentation/audiotoolbox/workgroup_management/adding_parallel_real-time_threads_to_audio_workgroups?language=objc --- libs/backends/coreaudio/coreaudio_backend.cc | 41 +++++++++++++++++++- libs/backends/coreaudio/coreaudio_backend.h | 6 +++ libs/backends/coreaudio/coreaudio_pcmio.cc | 9 +++++ libs/backends/coreaudio/coreaudio_pcmio.h | 8 ++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/libs/backends/coreaudio/coreaudio_backend.cc b/libs/backends/coreaudio/coreaudio_backend.cc index 78d1730d3d..72ec0d277d 100644 --- a/libs/backends/coreaudio/coreaudio_backend.cc +++ b/libs/backends/coreaudio/coreaudio_backend.cc @@ -830,9 +830,40 @@ void * CoreAudioBackend::coreaudio_process_thread (void *arg) { ThreadData* td = reinterpret_cast (arg); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 + if (td->_joined_workgroup) { + /* have WG */ + int res = os_workgroup_join (td->_workgroup, &td->_join_token); + switch (res) { + case 0: + PBD::info << _("AudioEngine: process thread joined AUHAL workgroup.") << endmsg; + break; + case EALREADY: + PBD::warning << _("AudioEngine: process thread is already in a workgroup.") << endmsg; + td->_joined_workgroup = false; + break; + case EINVAL: + PBD::warning << _("AudioEngine: invalid workgroup for process thread.") << endmsg; + td->_joined_workgroup = false; + break; + default: + td->_joined_workgroup = false; + PBD::warning << _("AudioEngine: process thread failed to join AUHAL workgroup.") << endmsg; + break; + + } + } +#endif + boost::function f = td->f; - delete td; f (); + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 + if (td->_joined_workgroup) { + os_workgroup_leave (td->_workgroup, &td->_join_token); + } +#endif + delete td; return 0; } @@ -842,6 +873,14 @@ CoreAudioBackend::create_process_thread (boost::function func) pthread_t thread_id; ThreadData* td = new ThreadData (this, func, PBD_RT_STACKSIZE_PROC); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 + if (_pcmio->workgroup (td->_workgroup)) { + td->_joined_workgroup = true; + } else { + td->_joined_workgroup = false; + } +#endif + if (pbd_realtime_pthread_create (PBD_SCHED_FIFO, PBD_RT_PRI_PROC, PBD_RT_STACKSIZE_PROC, &thread_id, coreaudio_process_thread, td)) { if (pbd_pthread_create (PBD_RT_STACKSIZE_PROC, &thread_id, coreaudio_process_thread, td)) { diff --git a/libs/backends/coreaudio/coreaudio_backend.h b/libs/backends/coreaudio/coreaudio_backend.h index b3839f68a2..34c17590b8 100644 --- a/libs/backends/coreaudio/coreaudio_backend.h +++ b/libs/backends/coreaudio/coreaudio_backend.h @@ -389,6 +389,12 @@ class CoreAudioBackend : public AudioBackend, public PortEngineSharedImpl { boost::function f; size_t stacksize; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 + bool _joined_workgroup; + os_workgroup_t _workgroup; + os_workgroup_join_token_s _join_token; +#endif + ThreadData (CoreAudioBackend* e, boost::function fp, size_t stacksz) : engine (e) , f (fp) , stacksize (stacksz) {} }; diff --git a/libs/backends/coreaudio/coreaudio_pcmio.cc b/libs/backends/coreaudio/coreaudio_pcmio.cc index 3619064f64..a38a3f5afd 100644 --- a/libs/backends/coreaudio/coreaudio_pcmio.cc +++ b/libs/backends/coreaudio/coreaudio_pcmio.cc @@ -1209,6 +1209,15 @@ CoreAudioPCM::set_playback_channel (uint32_t chn, const float *output, uint32_t return 0; } +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 +bool +CoreAudioPCM::workgroup (os_workgroup_t& workgroup) +{ + assert (_auhal); + UInt32 size = sizeof (os_workgroup_t); + return noErr == AudioUnitGetProperty (_auhal, kAudioOutputUnitProperty_OSWorkgroup, kAudioUnitScope_Output, 0, &workgroup, &size); +} +#endif void CoreAudioPCM::launch_control_app (uint32_t device_id) diff --git a/libs/backends/coreaudio/coreaudio_pcmio.h b/libs/backends/coreaudio/coreaudio_pcmio.h index e53cf29670..765b42ddc9 100644 --- a/libs/backends/coreaudio/coreaudio_pcmio.h +++ b/libs/backends/coreaudio/coreaudio_pcmio.h @@ -23,6 +23,10 @@ #include #include +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 +# include +#endif + #include #include @@ -74,6 +78,10 @@ public: void launch_control_app (uint32_t device_id); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 110000 + bool workgroup (os_workgroup_t&); +#endif + void pcm_stop (void); int pcm_start ( uint32_t input_device,