26#if (JUCE_PLUGINHOST_ARA && (JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_AU) && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX))
30#include <ARA_Library/Dispatch/ARAHostDispatch.cpp>
38 bool add (ARA::Host::DocumentController& dc)
45 bool remove (ARA::Host::DocumentController& dc)
58ARAEditGuard::ARAEditGuard (ARA::Host::DocumentController&
dcIn) : dc (
dcIn)
60 if (editGuardState.add (dc))
64ARAEditGuard::~ARAEditGuard()
66 if (editGuardState.remove (dc))
75AudioSource::AudioSource (ARA::ARAAudioSourceHostRef hostRef,
76 ARA::Host::DocumentController& dc,
77 const ARA::ARAAudioSourceProperties& props)
78 : ManagedARAHandle (dc, [&]
80 const ARAEditGuard guard (dc);
81 return dc.createAudioSource (hostRef, &props);
86void AudioSource::update (
const ARA::ARAAudioSourceProperties& props)
88 const ARAEditGuard guard (getDocumentController());
89 getDocumentController().updateAudioSourceProperties (getPluginRef(), &props);
92void AudioSource::enableAudioSourceSamplesAccess (
bool x)
94 const ARAEditGuard guard (getDocumentController());
95 getDocumentController().enableAudioSourceSamplesAccess (getPluginRef(), x);
98void AudioSource::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
100 dc.destroyAudioSource (ptr);
104AudioModification::AudioModification (ARA::ARAAudioModificationHostRef hostRef,
105 ARA::Host::DocumentController& dc,
107 const ARA::ARAAudioModificationProperties& props)
108 : ManagedARAHandle (dc, [&]
110 const ARAEditGuard guard (dc);
111 return dc.createAudioModification (s.getPluginRef(), hostRef, &props);
117void AudioModification::update (
const ARA::ARAAudioModificationProperties& props)
119 const ARAEditGuard guard (getDocumentController());
120 getDocumentController().updateAudioModificationProperties (getPluginRef(), &props);
123void AudioModification::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
125 dc.destroyAudioModification (ptr);
129class PlaybackRegion::Impl :
public ManagedARAHandle<Impl, ARA::ARAPlaybackRegionRef>,
130 public DeletionListener
133 Impl (ARA::ARAPlaybackRegionHostRef hostRef,
134 ARA::Host::DocumentController& dc,
135 AudioModification& m,
136 const ARA::ARAPlaybackRegionProperties& props);
140 for (
const auto& l : listeners)
141 l->removeListener (*this);
151 void update (
const ARA::ARAPlaybackRegionProperties& props);
153 auto& getAudioModification()
const {
return modification; }
155 static void destroy (ARA::Host::DocumentController&, Ptr);
157 void addListener (DeletionListener& l) { listeners.insert (&l); }
158 void removeListener (DeletionListener& l)
noexcept override { listeners.erase (&l); }
161 AudioModification* modification =
nullptr;
165PlaybackRegion::Impl::Impl (ARA::ARAPlaybackRegionHostRef hostRef,
166 ARA::Host::DocumentController& dc,
167 AudioModification& m,
168 const ARA::ARAPlaybackRegionProperties& props)
169 : ManagedARAHandle (dc, [&]
171 const ARAEditGuard guard (dc);
172 return dc.createPlaybackRegion (m.getPluginRef(), hostRef, &props);
178PlaybackRegion::~PlaybackRegion() =
default;
180void PlaybackRegion::Impl::update (
const ARA::ARAPlaybackRegionProperties& props)
182 const ARAEditGuard guard (getDocumentController());
183 getDocumentController().updatePlaybackRegionProperties (getPluginRef(), &props);
186void PlaybackRegion::Impl::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
188 dc.destroyPlaybackRegion (ptr);
191PlaybackRegion::PlaybackRegion (ARA::ARAPlaybackRegionHostRef hostRef,
192 ARA::Host::DocumentController& dc,
193 AudioModification& m,
194 const ARA::ARAPlaybackRegionProperties& props)
199void PlaybackRegion::update (
const ARA::ARAPlaybackRegionProperties& props) { impl->update (props); }
201void PlaybackRegion::addListener (DeletionListener& x) { impl->addListener (x); }
203auto& PlaybackRegion::getAudioModification()
const {
return impl->getAudioModification(); }
205ARA::ARAPlaybackRegionRef PlaybackRegion::getPluginRef() const noexcept {
return impl->getPluginRef(); }
207DeletionListener& PlaybackRegion::getDeletionListener() const noexcept {
return *impl.get(); }
210MusicalContext::MusicalContext (ARA::ARAMusicalContextHostRef hostRef,
211 ARA::Host::DocumentController& dc,
212 const ARA::ARAMusicalContextProperties& props)
213 : ManagedARAHandle (dc, [&]
215 const ARAEditGuard guard (dc);
216 return dc.createMusicalContext (hostRef, &props);
221void MusicalContext::update (
const ARA::ARAMusicalContextProperties& props)
223 const ARAEditGuard guard (getDocumentController());
224 return getDocumentController().updateMusicalContextProperties (getPluginRef(), &props);
227void MusicalContext::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
229 dc.destroyMusicalContext (ptr);
233RegionSequence::RegionSequence (ARA::ARARegionSequenceHostRef hostRef,
234 ARA::Host::DocumentController& dc,
235 const ARA::ARARegionSequenceProperties& props)
236 : ManagedARAHandle (dc, [&]
238 const ARAEditGuard guard (dc);
239 return dc.createRegionSequence (hostRef, &props);
244void RegionSequence::update (
const ARA::ARARegionSequenceProperties& props)
246 const ARAEditGuard guard (getDocumentController());
247 return getDocumentController().updateRegionSequenceProperties (getPluginRef(), &props);
250void RegionSequence::destroy (ARA::Host::DocumentController& dc, Ptr ptr)
252 dc.destroyRegionSequence (ptr);
256PlaybackRendererInterface PlugInExtensionInstance::getPlaybackRendererInterface()
const
258 if (instance !=
nullptr)
259 return PlaybackRendererInterface (instance->playbackRendererRef, instance->playbackRendererInterface);
264EditorRendererInterface PlugInExtensionInstance::getEditorRendererInterface()
const
266 if (instance !=
nullptr)
267 return EditorRendererInterface (instance->editorRendererRef, instance->editorRendererInterface);
275class ARAHostDocumentController::Impl
278 Impl (ARAFactoryWrapper araFactoryIn,
280 const ARA::ARADocumentControllerInstance* documentControllerInstance,
286 : araFactory (
std::
move (araFactoryIn)),
287 audioAccessController (
std::
move (audioAccessControllerIn)),
288 archivingController (
std::
move (archivingControllerIn)),
289 contentAccessController (
std::
move (contentAccessControllerIn)),
290 modelUpdateController (
std::
move (modelUpdateControllerIn)),
291 playbackController (
std::
move (playbackControllerIn)),
292 dcHostInstance (
std::
move (dcHostInstanceIn)),
293 documentController (documentControllerInstance)
299 documentController.destroyDocumentController();
303 createImpl (ARAFactoryWrapper araFactory,
304 const String& documentName,
312 std::make_unique<ARA::Host::DocumentControllerHostInstance> (audioAccessController.get(),
313 archivingController.get(),
314 contentAccessController.get(),
315 modelUpdateController.get(),
316 playbackController.get());
318 const auto documentProperties = makeARASizedStruct (&ARA::ARADocumentProperties::name, documentName.toRawUTF8());
320 if (
auto* dci = araFactory.get()->createDocumentControllerWithDocument (dcHostInstance.
get(), &documentProperties))
321 return std::make_unique<Impl> (std::move (araFactory),
322 std::move (dcHostInstance),
324 std::move (audioAccessController),
325 std::move (archivingController),
326 std::move (contentAccessController),
327 std::move (modelUpdateController),
328 std::move (playbackController));
333 ARAHostModel::PlugInExtensionInstance bindDocumentToPluginInstance (AudioPluginInstance& instance,
334 ARA::ARAPlugInInstanceRoleFlags knownRoles,
335 ARA::ARAPlugInInstanceRoleFlags assignedRoles)
338 const auto makeVisitor = [] (
auto vst3Fn,
auto auFn)
340 using Vst3Fn =
decltype (vst3Fn);
341 using AuFn =
decltype (auFn);
343 struct Visitor final :
public ExtensionsVisitor, Vst3Fn, AuFn
345 explicit Visitor (Vst3Fn vst3Fn, AuFn auFn) : Vst3Fn (
std::
move (vst3Fn)), AuFn (
std::
move (auFn)) {}
346 void visitVST3Client (
const VST3Client& x)
override { Vst3Fn::operator() (x); }
347 void visitAudioUnitClient (
const AudioUnitClient& x)
override { AuFn::operator() (x); }
350 return Visitor { std::move (vst3Fn), std::move (auFn) };
353 const ARA::ARAPlugInExtensionInstance* pei =
nullptr;
354 auto visitor = makeVisitor ([
this, &pei, knownRoles, assignedRoles] (
const ExtensionsVisitor::VST3Client& vst3Client)
356 auto* iComponentPtr = vst3Client.getIComponentPtr();
357 VSTComSmartPtr<ARA::IPlugInEntryPoint2> araEntryPoint;
359 if (araEntryPoint.loadFrom (iComponentPtr))
360 pei = araEntryPoint->bindToDocumentControllerWithRoles (documentController.getRef(), knownRoles, assignedRoles);
362 #if JUCE_PLUGINHOST_AU && JUCE_MAC
363 [
this, &pei, knownRoles, assignedRoles] (
const ExtensionsVisitor::AudioUnitClient& auClient)
365 auto audioUnit = auClient.getAudioUnitHandle();
366 auto propertySize = (UInt32)
sizeof (ARA::ARAAudioUnitPlugInExtensionBinding);
367 const auto expectedPropertySize = propertySize;
368 ARA::ARAAudioUnitPlugInExtensionBinding audioUnitBinding { ARA::kARAAudioUnitMagic,
369 documentController.getRef(),
374 auto status = AudioUnitGetProperty (audioUnit,
375 ARA::kAudioUnitProperty_ARAPlugInExtensionBindingWithRoles,
376 kAudioUnitScope_Global,
382 && propertySize == expectedPropertySize
383 && audioUnitBinding.inOutMagicNumber == ARA::kARAAudioUnitMagic
384 && audioUnitBinding.inDocumentControllerRef == documentController.getRef()
385 && audioUnitBinding.outPlugInExtension !=
nullptr)
387 pei = audioUnitBinding.outPlugInExtension;
397 instance.getExtensions (visitor);
398 return ARAHostModel::PlugInExtensionInstance { pei };
401 auto& getDocumentController() {
return documentController; }
404 ARAFactoryWrapper araFactory;
413 ARA::Host::DocumentController documentController;
421 const String& documentName,
428 if (
auto impl = Impl::createImpl (std::move (factory),
430 std::move (audioAccessController),
431 std::move (archivingController),
432 std::move (contentAccessController),
433 std::move (modelUpdateController),
434 std::move (playbackController)))
436 return rawToUniquePtr (
new ARAHostDocumentController (std::move (impl)));
442ARAHostDocumentController::~ARAHostDocumentController() =
default;
444ARA::Host::DocumentController& ARAHostDocumentController::getDocumentController()
const
446 return impl->getDocumentController();
449ARAHostModel::PlugInExtensionInstance ARAHostDocumentController::bindDocumentToPluginInstance (AudioPluginInstance& instance,
450 ARA::ARAPlugInInstanceRoleFlags knownRoles,
451 ARA::ARAPlugInInstanceRoleFlags assignedRoles)
453 return impl->bindDocumentToPluginInstance (instance, knownRoles, assignedRoles);
458 if (! instance.getPluginDescription().hasARAExtension)
459 cb (ARAFactoryWrapper{});
461 struct Extensions final :
public ExtensionsVisitor
463 Extensions (
std::function<
void (ARAFactoryWrapper)> callbackIn)
464 : callback (
std::
move (callbackIn))
467 void visitARAClient (
const ARAClient& araClient)
override
469 araClient.createARAFactoryAsync (std::move (callback));
475 Extensions extensions { std::move (cb) };
476 instance.getExtensions (extensions);
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
void createARAFactoryAsync(AudioPluginInstance &instance, std::function< void(ARAFactoryWrapper)> cb)
Calls the provided callback with an ARAFactoryWrapper object obtained from the provided AudioPluginIn...
std::unique_ptr< T > rawToUniquePtr(T *ptr)
Converts an owning raw pointer into a unique_ptr, deriving the type of the unique_ptr automatically.