Skip to content

Commit 8f64444

Browse files
committed
Add optional delegate to AUv3 IPC implementation that allows the host to inject code into the main thread when waiting for messages
1 parent 214c93a commit 8f64444

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

IPC/ARAIPCAudioUnit_v3.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,18 @@ extern "C" {
4545

4646
API_AVAILABLE_BEGIN(macos(13.0), ios(16.0))
4747

48+
//! optional delegate that can be provided in ARAIPCAUProxyPlugInInitialize()
49+
typedef void (*ARAMainThreadWaitForMessageDelegate) (void);
50+
4851
//! host side: initialize proxy plug-in component and its internal the message channels
4952
//! will return nullptr if the Audio Unit does not implement [AUAudioUnit messageChannelFor:]
5053
//! for the required ARA message channels
5154
//! the provided audioUnit is only used to establish the channels, it can be closed again
5255
//! after the call if not needed otherwise
5356
//! must be balanced with ARAIPCAUProxyPlugInUninitialize()
54-
ARAIPCConnectionRef _Nullable ARA_CALL ARAIPCAUProxyPlugInInitialize(AUAudioUnit * _Nonnull audioUnit);
57+
//! the optional delegate will be called periodically when the IPC needs to block the main thread
58+
ARAIPCConnectionRef _Nullable ARA_CALL ARAIPCAUProxyPlugInInitialize(AUAudioUnit * _Nonnull audioUnit,
59+
ARAMainThreadWaitForMessageDelegate _Nullable delegate);
5560

5661
//! allows the host to let the plug-in perform ARA IPC on the main thread when otherwise
5762
//! blocking it for an extended period of time

IPC/ARAIPCAudioUnit_v3.mm

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,13 @@ bool waitForMessage (ARATimeDuration timeout) override
183183
class ProxyPlugInMessageChannel : public AudioUnitMessageChannel
184184
{
185185
public:
186-
ProxyPlugInMessageChannel (NSObject<AUMessageChannel> * _Nonnull audioUnitChannel, bool isMainThreadChannel)
187-
: AudioUnitMessageChannel { audioUnitChannel, isMainThreadChannel }
186+
ProxyPlugInMessageChannel (NSObject<AUMessageChannel> * _Nonnull audioUnitChannel, bool isMainThreadChannel,
187+
ARAMainThreadWaitForMessageDelegate waitForMessageDelegate)
188+
: AudioUnitMessageChannel { audioUnitChannel, isMainThreadChannel },
189+
_waitForMessageDelegate { waitForMessageDelegate }
188190
{
191+
ARA_INTERNAL_ASSERT (isMainThreadChannel || !waitForMessageDelegate);
192+
189193
_audioUnitChannel.callHostBlock =
190194
^NSDictionary * _Nullable (NSDictionary * _Nonnull message)
191195
{
@@ -206,12 +210,26 @@ bool waitForMessage (ARATimeDuration timeout) override
206210
_audioUnitChannel.callHostBlock = nil;
207211
}
208212

213+
bool waitForMessage (ARATimeDuration timeout) override
214+
{
215+
if (AudioUnitMessageChannel::waitForMessage (timeout))
216+
return true;
217+
218+
if (_waitForMessageDelegate)
219+
_waitForMessageDelegate ();
220+
221+
return false;
222+
}
223+
209224
protected:
210225
NSDictionary * _sendMessage (NSDictionary * message) override
211226
{
212227
const auto reply { [_audioUnitChannel callAudioUnit:message] };
213228
return reply;
214229
}
230+
231+
private:
232+
const ARAMainThreadWaitForMessageDelegate _waitForMessageDelegate;
215233
};
216234
#endif // !ARA_AUDIOUNITV3_IPC_PROXY_HOST_ONLY
217235

@@ -220,7 +238,8 @@ bool waitForMessage (ARATimeDuration timeout) override
220238
class AUProxyPlugIn : public ProxyPlugIn, public AUConnection
221239
{
222240
public:
223-
static AUProxyPlugIn* createWithAudioUnit (AUAudioUnit * _Nonnull audioUnit)
241+
static AUProxyPlugIn* createWithAudioUnit (AUAudioUnit * _Nonnull audioUnit,
242+
ARAMainThreadWaitForMessageDelegate _Nullable waitForMessageDelegate)
224243
{
225244
// AUAudioUnits created before macOS 13 will not know about this API yet
226245
if (![audioUnit respondsToSelector:@selector(messageChannelFor:)])
@@ -234,7 +253,9 @@ bool waitForMessage (ARATimeDuration timeout) override
234253
if (!otherChannel)
235254
return nullptr;
236255

237-
return new AUProxyPlugIn { static_cast<NSObject<AUMessageChannel>*> (mainChannel), static_cast<NSObject<AUMessageChannel>*> (otherChannel), audioUnit };
256+
return new AUProxyPlugIn { static_cast<NSObject<AUMessageChannel>*> (mainChannel),
257+
static_cast<NSObject<AUMessageChannel>*> (otherChannel),
258+
audioUnit, waitForMessageDelegate };
238259
}
239260

240261
~AUProxyPlugIn () override
@@ -245,12 +266,15 @@ bool waitForMessage (ARATimeDuration timeout) override
245266
}
246267

247268
private:
248-
AUProxyPlugIn (NSObject<AUMessageChannel> * _Nonnull mainChannel, NSObject<AUMessageChannel> * _Nonnull otherChannel, AUAudioUnit * _Nonnull initAU)
269+
AUProxyPlugIn (NSObject<AUMessageChannel> * _Nonnull mainChannel,
270+
NSObject<AUMessageChannel> * _Nonnull otherChannel,
271+
AUAudioUnit * _Nonnull initAU,
272+
ARAMainThreadWaitForMessageDelegate _Nullable waitForMessageDelegate)
249273
: ProxyPlugIn { this },
250274
_initAU { initAU }
251275
{
252-
setMainThreadChannel (new ProxyPlugInMessageChannel { mainChannel, true });
253-
setOtherThreadsChannel (new ProxyPlugInMessageChannel { otherChannel, false });
276+
setMainThreadChannel (new ProxyPlugInMessageChannel { mainChannel, true, waitForMessageDelegate });
277+
setOtherThreadsChannel (new ProxyPlugInMessageChannel { otherChannel, false, nullptr });
254278
setMessageHandler (this);
255279
#if !__has_feature(objc_arc)
256280
[_initAU retain];
@@ -283,9 +307,10 @@ bool waitForMessage (ARATimeDuration timeout) override
283307
// host side: proxy plug-in C adapter
284308
#if !ARA_AUDIOUNITV3_IPC_PROXY_HOST_ONLY
285309

286-
ARAIPCConnectionRef ARA_CALL ARAIPCAUProxyPlugInInitialize (AUAudioUnit * _Nonnull audioUnit)
310+
ARAIPCConnectionRef ARA_CALL ARAIPCAUProxyPlugInInitialize (AUAudioUnit * _Nonnull audioUnit,
311+
ARAMainThreadWaitForMessageDelegate _Nullable waitForMessageDelegate)
287312
{
288-
return toIPCRef (AUProxyPlugIn::createWithAudioUnit (audioUnit));
313+
return toIPCRef (AUProxyPlugIn::createWithAudioUnit (audioUnit, waitForMessageDelegate));
289314
}
290315

291316
void ARA_CALL ARAIPCAUProxyPlugInPerformPendingMainThreadTasks (ARAIPCConnectionRef _Nonnull proxyRef)

0 commit comments

Comments
 (0)