Skip to content

Commit

Permalink
Refactor AUv3 out-of-process binding, removing the need for a dedicat…
Browse files Browse the repository at this point in the history
…ed AUMessageChannel for it

messages for the plug-in extension will be sent through the regular document controller channels now
  • Loading branch information
sgretscher committed Feb 11, 2024
1 parent a275d26 commit c03de16
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 44 deletions.
21 changes: 10 additions & 11 deletions ExamplesCommon/PlugInHosting/AudioUnitLoader.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@
AURenderBlock v3RenderBlock; // only for AUv3: cache of render block outside ObjC runtime
#if ARA_AUDIOUNITV3_IPC_IS_AVAILABLE
BOOL isOutOfProcess; // loaded in- or out-of-process
BOOL isBoundViaIPC; // YES if extensionIPCChannelRef has been initialized via ARA binding
ARAIPCMessageChannelRef extensionIPCChannelRef; // only valid when isBoundViaIPC is YES
const ARAPlugInExtensionInstance * ipcInstance; // != NULL when bound to ARA via IPC
#endif
};

Expand Down Expand Up @@ -135,12 +134,12 @@ AudioUnitInstance AudioUnitOpenInstance(AudioUnitComponent audioUnitComponent, b
result->audioUnitComponent = audioUnitComponent;
#if ARA_AUDIOUNITV3_IPC_IS_AVAILABLE
result->isOutOfProcess = useIPC;
result->isBoundViaIPC = NO;
result->ipcInstance = NULL;
#endif

AudioComponentDescription desc;
AudioComponentGetDescription(audioUnitComponent->component, &desc);
result->isAUv2 = AudioUnitIsV2 (audioUnitComponent);
result->isAUv2 = AudioUnitIsV2(audioUnitComponent);

if (result->isAUv2)
{
Expand Down Expand Up @@ -309,14 +308,14 @@ AudioUnitInstance AudioUnitOpenInstance(AudioUnitComponent audioUnitComponent, b
{
if (@available(macOS 13.0, *))
{
instance = ARAIPCAUProxyPlugInBindToDocumentController (audioUnitInstance->v3AudioUnit, controllerRef, knownRoles, assignedRoles, &audioUnitInstance->extensionIPCChannelRef);
audioUnitInstance->isBoundViaIPC = (instance != NULL);
instance = ARAIPCAUProxyPlugInBindToDocumentController(audioUnitInstance->v3AudioUnit, controllerRef, knownRoles, assignedRoles);
audioUnitInstance->ipcInstance = instance;
}
}
else
#endif
{
ARA_INTERNAL_ASSERT ([audioUnitInstance->v3AudioUnit conformsToProtocol:@protocol(ARAAudioUnit)]);
ARA_INTERNAL_ASSERT([audioUnitInstance->v3AudioUnit conformsToProtocol:@protocol(ARAAudioUnit)]);
instance = [(AUAudioUnit<ARAAudioUnit> *)audioUnitInstance->v3AudioUnit bindToDocumentController:controllerRef withRoles:assignedRoles knownRoles:knownRoles];
}
ARA_VALIDATE_API_CONDITION(instance != NULL);
Expand Down Expand Up @@ -510,7 +509,7 @@ OSStatus ARA_MAYBE_UNUSED_VAR(status) = audioUnitInstance->v3RenderBlock(&flags,
^AUAudioUnitStatus (AudioUnitRenderActionFlags *actionFlags, const AudioTimeStamp *timestamp,
AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList *inputData)
{
return RenderCallback (NULL, actionFlags, timestamp, (UInt32)inputBusNumber, frameCount, inputData);
return RenderCallback(NULL, actionFlags, timestamp, (UInt32)inputBusNumber, frameCount, inputData);
});
ARA_INTERNAL_ASSERT(status == noErr);
}
Expand Down Expand Up @@ -542,8 +541,8 @@ void AudioUnitCloseInstance(AudioUnitInstance audioUnitInstance)
#if ARA_AUDIOUNITV3_IPC_IS_AVAILABLE
if (@available(macOS 13.0, *))
{
if (audioUnitInstance->isBoundViaIPC)
ARAIPCAUProxyPlugInCleanupBinding(audioUnitInstance->extensionIPCChannelRef);
if (audioUnitInstance->ipcInstance)
ARAIPCAUProxyPlugInCleanupBinding(audioUnitInstance->ipcInstance);
}
#endif
[audioUnitInstance->v3AudioUnit release];
Expand All @@ -561,6 +560,6 @@ void AudioUnitCleanupComponent(AudioUnitComponent audioUnitComponent)
}
#endif

free (audioUnitComponent);
free(audioUnitComponent);
// Explicit unloading is not supported by the Audio Unit API.
}
8 changes: 3 additions & 5 deletions TestHost/CompanionAPIs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,7 @@ class AUPlugInEntry : public PlugInEntry
const ARA::ARADocumentProperties* properties) override
{
if (usesIPC ())
return ARA::IPC::ARAIPCProxyPlugInCreateDocumentControllerWithDocument (_messageChannelRef,
ARA::IPC::ARAIPCProxyPlugInGetFactoryAtIndex (_messageChannelRef, 0)->factoryID,
hostInstance, properties);
return ARA::IPC::ARAIPCProxyPlugInCreateDocumentControllerWithDocument (_messageChannelRef, getARAFactory ()->factoryID, hostInstance, properties);
else
return PlugInEntry::createDocumentControllerWithDocument (hostInstance, properties);
}
Expand Down Expand Up @@ -472,7 +470,7 @@ class IPCPlugInInstance : public PlugInInstance, protected ARA::IPC::RemoteCalle
{
// \todo these are the roles that our Companion API Loaders implicitly assume - they should be published properly
const ARA::ARAPlugInInstanceRoleFlags knownRoles { ARA::kARAPlaybackRendererRole | ARA::kARAEditorRendererRole | ARA::kARAEditorViewRole };
auto plugInExtension { ARA::IPC::ARAIPCProxyPlugInBindToDocumentController (_remoteRef, toIPCRef (getMessageChannel ()), documentControllerRef, knownRoles, assignedRoles) };
auto plugInExtension { ARA::IPC::ARAIPCProxyPlugInBindToDocumentController (_remoteRef, documentControllerRef, knownRoles, assignedRoles) };
validateAndSetPlugInExtensionInstance (plugInExtension, assignedRoles);
}

Expand Down Expand Up @@ -733,7 +731,7 @@ int main (std::unique_ptr<PlugInEntry> plugInEntry, const std::string& channelID
auto plugInCallbacksChannel { IPCMessageChannel::createPublishingID (channelID, &handler) };

ARA::IPC::ARAIPCProxyHostAddFactory (_plugInEntry->getARAFactory ());
ARA::IPC::ARAIPCProxyHostSetBindingHandler ([] (ARA::IPC::ARAIPCMessageChannelRef /*messageChannel*/, ARA::IPC::ARAIPCPlugInInstanceRef plugInInstanceRef,
ARA::IPC::ARAIPCProxyHostSetBindingHandler ([] (ARA::IPC::ARAIPCPlugInInstanceRef plugInInstanceRef,
ARA::ARADocumentControllerRef controllerRef,
ARA::ARAPlugInInstanceRoleFlags knownRoles, ARA::ARAPlugInInstanceRoleFlags assignedRoles)
-> const ARA::ARAPlugInExtensionInstance*
Expand Down
46 changes: 18 additions & 28 deletions TestPlugIn/AudioUnit_v3/Framework/TestAUv3AudioUnit.mm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
// The IPC-related additions to TestAUv3AudioUnit could also be moved to a reusable base class
// from which TestAUv3AudioUnit and others could derive.
// A workaround might be a set of macros that can be used to provide the code with adjusted
// class names for client projects, but since the some methods may be implemented in the client
// class names for client projects, but since some methods may be implemented in the client
// this is somewhat messy.

API_AVAILABLE(macos(13.0))
Expand All @@ -48,13 +48,13 @@ @implementation TestAUv3ARAIPCMessageChannel {

@synthesize callHostBlock = _callHostBlock;

- (instancetype)initWithAudioUnit:(AUAudioUnit * _Nullable)audioUnit {
- (instancetype)init {
self = [super init];

if (self == nil) { return nil; }

_callHostBlock = nil;
_messageChannelRef = ARA::IPC::ARAIPCAUProxyHostInitializeMessageChannel(audioUnit, self);
_messageChannelRef = ARA::IPC::ARAIPCAUProxyHostInitializeMessageChannel(self);

return self;
}
Expand All @@ -77,11 +77,6 @@ @interface TestAUv3AudioUnit ()
@property AUAudioUnitBusArray *inputBusArray;
@property AUAudioUnitBusArray *outputBusArray;
@property (nonatomic, readonly) AUAudioUnitBus *outputBus;
@property (nonatomic, readonly, nonnull) const ARA::ARAFactory * araFactory;

#if ARA_AUDIOUNITV3_IPC_IS_AVAILABLE
@property (nonatomic, nullable, retain) NSObject<AUMessageChannel> * araIPCPlugInExtensionMessageChannel API_AVAILABLE(macos(13.0));
#endif

@end

Expand All @@ -93,6 +88,11 @@ @implementation TestAUv3AudioUnit {
ARA::PlugIn::PlugInExtension * _araPlugInExtension;
}

@synthesize araFactory = _araFactory;
#if ARA_AUDIOUNITV3_IPC_IS_AVAILABLE
@synthesize araRemoteInstanceRef = _araRemoteInstanceRef;
#endif

// MARK: - AUAudioUnit Overrides

- (instancetype)initWithComponentDescription:(AudioComponentDescription)componentDescription options:(AudioComponentInstantiationOptions)options error:(NSError **)outError {
Expand Down Expand Up @@ -125,7 +125,8 @@ - (instancetype)initWithComponentDescription:(AudioComponentDescription)componen
_araPlugInExtension = nullptr;

#if ARA_AUDIOUNITV3_IPC_IS_AVAILABLE
_araIPCPlugInExtensionMessageChannel = nil;
static_assert(sizeof(self) == sizeof(NSUInteger), "opaque ref type size mismatch");
_araRemoteInstanceRef = (NSUInteger)self;
#endif

return self;
Expand Down Expand Up @@ -273,31 +274,20 @@ void destroy_sharedFactoryMessageChannel() {
}
}

+ (void)initialize {
if (self != [TestAUv3AudioUnit class]) { return; }

if (@available(macOS 13.0, *))
{
ARA::IPC::ARAIPCAUProxyHostAddFactory(ARATestDocumentController::getARAFactory());

_sharedFactoryMessageChannel = [[TestAUv3ARAIPCMessageChannel alloc] initWithAudioUnit:nil];

ARA::IPC::ARAIPCAUProxyHostInitialize(_sharedFactoryMessageChannel);
}
}

// \todo the return value should be _Nullable!
- (id<AUMessageChannel> _Nonnull)messageChannelFor:(NSString * _Nonnull)channelName {
if (@available(macOS 13.0, *))
{
if ([channelName isEqualTo:ARA_AUDIOUNIT_FACTORY_CUSTOM_MESSAGES_UTI])
return _sharedFactoryMessageChannel;

if ([channelName isEqualTo:ARA_AUDIOUNIT_PLUGINEXTENSION_CUSTOM_MESSAGES_UTI])
{
if (!self.araIPCPlugInExtensionMessageChannel)
self.araIPCPlugInExtensionMessageChannel = [[TestAUv3ARAIPCMessageChannel alloc] initWithAudioUnit:self];
return self.araIPCPlugInExtensionMessageChannel;
if (!_sharedFactoryMessageChannel)
{
ARA::IPC::ARAIPCAUProxyHostAddFactory(ARATestDocumentController::getARAFactory());
_sharedFactoryMessageChannel = [TestAUv3ARAIPCMessageChannel new];
ARA::IPC::ARAIPCAUProxyHostInitialize(_sharedFactoryMessageChannel);
}

return _sharedFactoryMessageChannel;
}
}
return nil;
Expand Down

0 comments on commit c03de16

Please sign in to comment.