tracktion_engine icon indicating copy to clipboard operation
tracktion_engine copied to clipboard

Added support for asynchronous instantiation of ExternalPlugins.

Open mathieugarcia opened this issue 1 year ago • 6 comments

Support for asynchronous plugin instantiation in ExternalPlugin. This allow proper hosting of AUv3 plugins on iOS and possibly other platforms and/or plugin formats that require asynchronous instantiation.

What changed:

  • Added a static helper method ExternalPlugin::requiresAsyncInstantiation().
  • Moved post-initialisation code in a method called completePluginInitialisation(), to avoid code redundancy and minimize differences between the sync and async versions. This method is called once the plugin instance is available.
  • createPluginInstance will check if the plugin requires asynchronous instantiation, if so, JUCE's PluginFormatManager::createPluginInstanceAsync() is called, with a callback that will perform all the necessary tasks after the plugin instance has been returned. Note that baseClassInitialise() and initialise() have to be called manually so the ExternalPlugin state is fully initialised.
  • createPluginInstance method signature will not return the error String anymore.

For more information and discussion about this pull request see https://github.com/Tracktion/tracktion_engine/issues/105

mathieugarcia avatar Feb 25 '23 09:02 mathieugarcia

FYI here's that Selectable helper class I mentioned: https://github.com/Tracktion/tracktion_engine/commit/c9b328c89f807dfa356778442a98bd6d8ce354c0

drowaudio avatar Mar 01 '23 13:03 drowaudio

Unit Test Results

       3 files  ±0         3 suites  ±0   0s :stopwatch: ±0s    158 tests +1     158 :heavy_check_mark: +1  0 :zzz: ±0  0 :x: ±0  6 153 runs  +3  6 153 :heavy_check_mark: +3  0 :zzz: ±0  0 :x: ±0 

Results for commit c9b328c8. ± Comparison against base commit c679bc74.

github-actions[bot] avatar Mar 01 '23 13:03 github-actions[bot]

Performance Test Results

0 files  ±0  0 suites  ±0   0s :stopwatch: ±0s 0 tests ±0  0 :heavy_check_mark: ±0  0 :zzz: ±0  0 :x: ±0 

Results for commit c9b328c8. ± Comparison against base commit c679bc74.

github-actions[bot] avatar Mar 01 '23 13:03 github-actions[bot]

Unfortunatelly calling edit.restartPlayback() instead of baseClassInitialise() and initialise() resulted in various asserts being triggered:

In ExternalPlugin.cpp :

jassert (isInstancePrepared); 

In AudioUnitPluginFormat.mm :

// If these are hit, we might allocate in the process block!
jassert (buffer.getNumChannels() <= preparedChannels);
jassert (buffer.getNumSamples()  <= preparedSamples);

mathieugarcia avatar Mar 01 '23 14:03 mathieugarcia

Any update on this ? Thank you !

mathieugarcia avatar Sep 11 '23 09:09 mathieugarcia

Sorry, it's been a while since I looked at this and have forgotten most of the details. Plugin hosting with all the external formats is precarious at best which is why I'm hesitant to make changes without fully understanding all the ramifications.

I think the main outstanding issue was that you had to call:

    safeThis->baseClassInitialise (info);
    safeThis->initialise (info);

I couldn't understand why the audio graph isn't rebuilt automatically and then the PluginNode handle calling baseClassInitialise? Any update on that front?

drowaudio avatar Sep 18 '23 10:09 drowaudio