Skip to content

Commit bf2bf12

Browse files
committed
Host side of AUv3 IPC forwards incoming transactions to dedicated dispatch queues
because AUMessageChannel does not allow to call back from the receiving thread...
1 parent 5cd5586 commit bf2bf12

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

IPC/ARAIPCAudioUnit_v3.mm

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ void _sendMessage (MessageID messageID, MessageEncoder * encoder) override
166166
: AudioUnitMessageChannel { this },
167167
_audioUnitChannel { audioUnitChannel }
168168
{
169+
// \todo there's also QOS_CLASS_USER_INTERACTIVE which seems more appropriate but is undocumented...
170+
if (_instanceCount == 0)
171+
_readAudioQueue = dispatch_queue_create ("ARA read audio samples", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, -1));
172+
++_instanceCount;
173+
169174
#if !__has_feature(objc_arc)
170175
[_audioUnitChannel retain];
171176
#endif
@@ -180,6 +185,27 @@ void _sendMessage (MessageID messageID, MessageEncoder * encoder) override
180185
~ProxyPlugInMessageChannel () override
181186
{
182187
_audioUnitChannel.callHostBlock = nil;
188+
189+
--_instanceCount;
190+
if (_instanceCount == 0)
191+
dispatch_release (_readAudioQueue);
192+
}
193+
194+
DispatchTarget getDispatchTargetForIncomingTransaction (MessageID messageID) override
195+
{
196+
// AUMessageChannel cannot be called back from the same thread it receives the message,
197+
// so we dispatch to the main queue for playback requests and to a dedicated read samples queue for audio requests
198+
// \todo maybe we should make this configurable, so hosts can set these queues if they already have appropriate ones?
199+
if (messageID == ARA_IPC_HOST_METHOD_ID (ARAAudioAccessControllerInterface, readAudioSamples).getMessageID ())
200+
{
201+
return _readAudioQueue;
202+
}
203+
else
204+
{
205+
ARA_INTERNAL_ASSERT ((ARA_IPC_HOST_METHOD_ID (ARAPlaybackControllerInterface, requestStartPlayback).getMessageID () <= messageID) &&
206+
(messageID <= ARA_IPC_HOST_METHOD_ID (ARAPlaybackControllerInterface, requestEnableCycle).getMessageID ()));
207+
return dispatch_get_main_queue ();
208+
}
183209
}
184210

185211
protected:
@@ -191,8 +217,13 @@ void _sendMessage (MessageID messageID, MessageEncoder * encoder) override
191217

192218
private:
193219
NSObject<AUMessageChannel> * __strong _Nonnull _audioUnitChannel;
220+
static dispatch_queue_t _readAudioQueue;
221+
static int _instanceCount;
194222
};
195223

224+
dispatch_queue_t ProxyPlugInMessageChannel::_readAudioQueue { nullptr };
225+
int ProxyPlugInMessageChannel::_instanceCount { 0 };
226+
196227

197228
// host side: proxy plug-in message channel further specialization for plug-in extension messages
198229
class ProxyPlugInExtensionMessageChannel : public ProxyPlugInMessageChannel

0 commit comments

Comments
 (0)