migrating to the latest JUCE version
This commit is contained in:
@ -1,98 +1,98 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioPluginFormat::AudioPluginFormat() {}
|
||||
AudioPluginFormat::~AudioPluginFormat() {}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize)
|
||||
{
|
||||
String errorMessage;
|
||||
return createInstanceFromDescription (desc, initialSampleRate, initialBufferSize, errorMessage);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
String& errorMessage)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread()
|
||||
&& requiresUnblockedMessageThreadDuringCreation (desc))
|
||||
{
|
||||
errorMessage = NEEDS_TRANS ("This plug-in cannot be instantiated synchronously");
|
||||
return {};
|
||||
}
|
||||
|
||||
WaitableEvent finishedSignal;
|
||||
std::unique_ptr<AudioPluginInstance> instance;
|
||||
|
||||
auto callback = [&] (std::unique_ptr<AudioPluginInstance> p, const String& error)
|
||||
{
|
||||
errorMessage = error;
|
||||
instance = std::move (p);
|
||||
finishedSignal.signal();
|
||||
};
|
||||
|
||||
if (! MessageManager::getInstance()->isThisTheMessageThread())
|
||||
createPluginInstanceAsync (desc, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
else
|
||||
createPluginInstance (desc, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
|
||||
finishedSignal.wait();
|
||||
return instance;
|
||||
}
|
||||
|
||||
struct AudioPluginFormat::AsyncCreateMessage : public Message
|
||||
{
|
||||
AsyncCreateMessage (const PluginDescription& d, double sr, int size, PluginCreationCallback call)
|
||||
: desc (d), sampleRate (sr), bufferSize (size), callbackToUse (std::move (call))
|
||||
{
|
||||
}
|
||||
|
||||
PluginDescription desc;
|
||||
double sampleRate;
|
||||
int bufferSize;
|
||||
PluginCreationCallback callbackToUse;
|
||||
};
|
||||
|
||||
void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
PluginCreationCallback callback)
|
||||
{
|
||||
jassert (callback != nullptr);
|
||||
postMessage (new AsyncCreateMessage (description, initialSampleRate, initialBufferSize, std::move (callback)));
|
||||
}
|
||||
|
||||
void AudioPluginFormat::handleMessage (const Message& message)
|
||||
{
|
||||
if (auto m = dynamic_cast<const AsyncCreateMessage*> (&message))
|
||||
createPluginInstance (m->desc, m->sampleRate, m->bufferSize, std::move (m->callbackToUse));
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioPluginFormat::AudioPluginFormat() {}
|
||||
AudioPluginFormat::~AudioPluginFormat() {}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize)
|
||||
{
|
||||
String errorMessage;
|
||||
return createInstanceFromDescription (desc, initialSampleRate, initialBufferSize, errorMessage);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormat::createInstanceFromDescription (const PluginDescription& desc,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
String& errorMessage)
|
||||
{
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread()
|
||||
&& requiresUnblockedMessageThreadDuringCreation (desc))
|
||||
{
|
||||
errorMessage = NEEDS_TRANS ("This plug-in cannot be instantiated synchronously");
|
||||
return {};
|
||||
}
|
||||
|
||||
WaitableEvent finishedSignal;
|
||||
std::unique_ptr<AudioPluginInstance> instance;
|
||||
|
||||
auto callback = [&] (std::unique_ptr<AudioPluginInstance> p, const String& error)
|
||||
{
|
||||
errorMessage = error;
|
||||
instance = std::move (p);
|
||||
finishedSignal.signal();
|
||||
};
|
||||
|
||||
if (! MessageManager::getInstance()->isThisTheMessageThread())
|
||||
createPluginInstanceAsync (desc, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
else
|
||||
createPluginInstance (desc, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
|
||||
finishedSignal.wait();
|
||||
return instance;
|
||||
}
|
||||
|
||||
struct AudioPluginFormat::AsyncCreateMessage : public Message
|
||||
{
|
||||
AsyncCreateMessage (const PluginDescription& d, double sr, int size, PluginCreationCallback call)
|
||||
: desc (d), sampleRate (sr), bufferSize (size), callbackToUse (std::move (call))
|
||||
{
|
||||
}
|
||||
|
||||
PluginDescription desc;
|
||||
double sampleRate;
|
||||
int bufferSize;
|
||||
PluginCreationCallback callbackToUse;
|
||||
};
|
||||
|
||||
void AudioPluginFormat::createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
PluginCreationCallback callback)
|
||||
{
|
||||
jassert (callback != nullptr);
|
||||
postMessage (new AsyncCreateMessage (description, initialSampleRate, initialBufferSize, std::move (callback)));
|
||||
}
|
||||
|
||||
void AudioPluginFormat::handleMessage (const Message& message)
|
||||
{
|
||||
if (auto m = dynamic_cast<const AsyncCreateMessage*> (&message))
|
||||
createPluginInstance (m->desc, m->sampleRate, m->bufferSize, std::move (m->callbackToUse));
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,162 +1,174 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.
|
||||
|
||||
@see AudioPluginFormatManager
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioPluginFormat : private MessageListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
~AudioPluginFormat() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the format name.
|
||||
E.g. "VST", "AudioUnit", etc.
|
||||
*/
|
||||
virtual String getName() const = 0;
|
||||
|
||||
/** This tries to create descriptions for all the plugin types available in
|
||||
a binary module file.
|
||||
|
||||
The file will be some kind of DLL or bundle.
|
||||
|
||||
Normally there will only be one type returned, but some plugins
|
||||
(e.g. VST shells) can use a single DLL to create a set of different plugin
|
||||
subtypes, so in that case, each subtype is returned as a separate object.
|
||||
*/
|
||||
virtual void findAllTypesForFile (OwnedArray<PluginDescription>& results,
|
||||
const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Tries to recreate a type from a previously generated PluginDescription.
|
||||
@see AudioPluginFormatManager::createInstance
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize);
|
||||
|
||||
/** Same as above but with the possibility of returning an error message.
|
||||
@see AudioPluginFormatManager::createInstance
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
String& errorMessage);
|
||||
|
||||
/** A callback lambda that is passed to createPluginInstanceAsync() */
|
||||
using PluginCreationCallback = std::function<void (std::unique_ptr<AudioPluginInstance>, const String&)>;
|
||||
|
||||
/** Tries to recreate a type from a previously generated PluginDescription.
|
||||
When the plugin has been created, it will be passed to the caller via an
|
||||
asynchronous call to the PluginCreationCallback lambda that was provided.
|
||||
@see AudioPluginFormatManager::createPluginInstanceAsync
|
||||
*/
|
||||
void createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
PluginCreationCallback);
|
||||
|
||||
/** Should do a quick check to see if this file or directory might be a plugin of
|
||||
this format.
|
||||
|
||||
This is for searching for potential files, so it shouldn't actually try to
|
||||
load the plugin or do anything time-consuming.
|
||||
*/
|
||||
virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Returns a readable version of the name of the plugin that this identifier refers to. */
|
||||
virtual String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Returns true if this plugin's version or date has changed and it should be re-checked. */
|
||||
virtual bool pluginNeedsRescanning (const PluginDescription&) = 0;
|
||||
|
||||
/** Checks whether this plugin could possibly be loaded.
|
||||
It doesn't actually need to load it, just to check whether the file or component
|
||||
still exists.
|
||||
*/
|
||||
virtual bool doesPluginStillExist (const PluginDescription&) = 0;
|
||||
|
||||
/** Returns true if this format needs to run a scan to find its list of plugins. */
|
||||
virtual bool canScanForPlugins() const = 0;
|
||||
|
||||
/** Should return true if this format is both safe and quick to scan - i.e. if a file
|
||||
can be scanned within a few milliseconds on a background thread, without actually
|
||||
needing to load an executable.
|
||||
*/
|
||||
virtual bool isTrivialToScan() const = 0;
|
||||
|
||||
/** Searches a suggested set of directories for any plugins in this format.
|
||||
The path might be ignored, e.g. by AUs, which are found by the OS rather
|
||||
than manually.
|
||||
|
||||
@param directoriesToSearch This specifies which directories shall be
|
||||
searched for plug-ins.
|
||||
@param recursive Should the search recursively traverse folders.
|
||||
@param allowPluginsWhichRequireAsynchronousInstantiation
|
||||
If this is false then plug-ins which require
|
||||
asynchronous creation will be excluded.
|
||||
*/
|
||||
virtual StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
|
||||
bool recursive,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false) = 0;
|
||||
|
||||
/** Returns the typical places to look for this kind of plugin.
|
||||
|
||||
Note that if this returns no paths, it means that the format doesn't search in
|
||||
files or folders, e.g. AudioUnits.
|
||||
*/
|
||||
virtual FileSearchPath getDefaultLocationsToSearch() = 0;
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
friend class AudioPluginFormatManager;
|
||||
|
||||
AudioPluginFormat();
|
||||
|
||||
/** Implementors must override this function. This is guaranteed to be called on
|
||||
the message thread. You may call the callback on any thread.
|
||||
*/
|
||||
virtual void createPluginInstance (const PluginDescription&, double initialSampleRate,
|
||||
int initialBufferSize, PluginCreationCallback) = 0;
|
||||
|
||||
/** Returns true if instantiation of this plugin type must be done from a non-message thread. */
|
||||
virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0;
|
||||
|
||||
private:
|
||||
struct AsyncCreateMessage;
|
||||
void handleMessage (const Message&) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.
|
||||
|
||||
@see AudioPluginFormatManager
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioPluginFormat : private MessageListener
|
||||
{
|
||||
public:
|
||||
/** Destructor. */
|
||||
~AudioPluginFormat() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the format name.
|
||||
E.g. "VST", "AudioUnit", etc.
|
||||
*/
|
||||
virtual String getName() const = 0;
|
||||
|
||||
/** This tries to create descriptions for all the plugin types available in
|
||||
a binary module file.
|
||||
|
||||
The file will be some kind of DLL or bundle.
|
||||
|
||||
Normally there will only be one type returned, but some plugins
|
||||
(e.g. VST shells) can use a single DLL to create a set of different plugin
|
||||
subtypes, so in that case, each subtype is returned as a separate object.
|
||||
*/
|
||||
virtual void findAllTypesForFile (OwnedArray<PluginDescription>& results,
|
||||
const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Tries to recreate a type from a previously generated PluginDescription.
|
||||
@see AudioPluginFormatManager::createInstance
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize);
|
||||
|
||||
/** Same as above but with the possibility of returning an error message.
|
||||
@see AudioPluginFormatManager::createInstance
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createInstanceFromDescription (const PluginDescription&,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
String& errorMessage);
|
||||
|
||||
/** A callback lambda that is passed to createPluginInstanceAsync() */
|
||||
using PluginCreationCallback = std::function<void (std::unique_ptr<AudioPluginInstance>, const String&)>;
|
||||
|
||||
/** Tries to recreate a type from a previously generated PluginDescription.
|
||||
When the plugin has been created, it will be passed to the caller via an
|
||||
asynchronous call to the PluginCreationCallback lambda that was provided.
|
||||
@see AudioPluginFormatManager::createPluginInstanceAsync
|
||||
*/
|
||||
void createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate,
|
||||
int initialBufferSize,
|
||||
PluginCreationCallback);
|
||||
|
||||
/** Should do a quick check to see if this file or directory might be a plugin of
|
||||
this format.
|
||||
|
||||
This is for searching for potential files, so it shouldn't actually try to
|
||||
load the plugin or do anything time-consuming.
|
||||
*/
|
||||
virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Returns a readable version of the name of the plugin that this identifier refers to. */
|
||||
virtual String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Returns true if this plugin's version or date has changed and it should be re-checked. */
|
||||
virtual bool pluginNeedsRescanning (const PluginDescription&) = 0;
|
||||
|
||||
/** Checks whether this plugin could possibly be loaded.
|
||||
It doesn't actually need to load it, just to check whether the file or component
|
||||
still exists.
|
||||
*/
|
||||
virtual bool doesPluginStillExist (const PluginDescription&) = 0;
|
||||
|
||||
/** Returns true if this format needs to run a scan to find its list of plugins. */
|
||||
virtual bool canScanForPlugins() const = 0;
|
||||
|
||||
/** Should return true if this format is both safe and quick to scan - i.e. if a file
|
||||
can be scanned within a few milliseconds on a background thread, without actually
|
||||
needing to load an executable.
|
||||
*/
|
||||
virtual bool isTrivialToScan() const = 0;
|
||||
|
||||
/** Searches a suggested set of directories for any plugins in this format.
|
||||
The path might be ignored, e.g. by AUs, which are found by the OS rather
|
||||
than manually.
|
||||
|
||||
@param directoriesToSearch This specifies which directories shall be
|
||||
searched for plug-ins.
|
||||
@param recursive Should the search recursively traverse folders.
|
||||
@param allowPluginsWhichRequireAsynchronousInstantiation
|
||||
If this is false then plug-ins which require
|
||||
asynchronous creation will be excluded.
|
||||
*/
|
||||
virtual StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
|
||||
bool recursive,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false) = 0;
|
||||
|
||||
/** Returns the typical places to look for this kind of plugin.
|
||||
|
||||
Note that if this returns no paths, it means that the format doesn't search in
|
||||
files or folders, e.g. AudioUnits.
|
||||
*/
|
||||
virtual FileSearchPath getDefaultLocationsToSearch() = 0;
|
||||
|
||||
/** Returns true if instantiation of this plugin type must be done from a non-message thread. */
|
||||
virtual bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const = 0;
|
||||
|
||||
/** A callback lambda that is passed to getARAFactory() */
|
||||
using ARAFactoryCreationCallback = std::function<void (ARAFactoryResult)>;
|
||||
|
||||
/** Tries to create an ::ARAFactoryWrapper for this description.
|
||||
|
||||
The result of the operation will be wrapped into an ARAFactoryResult,
|
||||
which will be passed to a callback object supplied by the caller.
|
||||
|
||||
@see AudioPluginFormatManager::createARAFactoryAsync
|
||||
*/
|
||||
virtual void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) { callback ({}); }
|
||||
|
||||
protected:
|
||||
//==============================================================================
|
||||
friend class AudioPluginFormatManager;
|
||||
|
||||
AudioPluginFormat();
|
||||
|
||||
/** Implementors must override this function. This is guaranteed to be called on
|
||||
the message thread. You may call the callback on any thread.
|
||||
*/
|
||||
virtual void createPluginInstance (const PluginDescription&, double initialSampleRate,
|
||||
int initialBufferSize, PluginCreationCallback) = 0;
|
||||
|
||||
private:
|
||||
struct AsyncCreateMessage;
|
||||
void handleMessage (const Message&) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormat)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,151 +1,205 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioPluginFormatManager::AudioPluginFormatManager() {}
|
||||
AudioPluginFormatManager::~AudioPluginFormatManager() {}
|
||||
|
||||
//==============================================================================
|
||||
void AudioPluginFormatManager::addDefaultFormats()
|
||||
{
|
||||
#if JUCE_DEBUG
|
||||
// you should only call this method once!
|
||||
for (auto* format : formats)
|
||||
{
|
||||
ignoreUnused (format);
|
||||
|
||||
#if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD || JUCE_IOS)
|
||||
jassert (dynamic_cast<VSTPluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD)
|
||||
jassert (dynamic_cast<VST3PluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_AU && (JUCE_MAC || JUCE_IOS)
|
||||
jassert (dynamic_cast<AudioUnitPluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_LADSPA && (JUCE_LINUX || JUCE_BSD)
|
||||
jassert (dynamic_cast<LADSPAPluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_AU && (JUCE_MAC || JUCE_IOS)
|
||||
formats.add (new AudioUnitPluginFormat());
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD || JUCE_IOS)
|
||||
formats.add (new VSTPluginFormat());
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD)
|
||||
formats.add (new VST3PluginFormat());
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_LADSPA && (JUCE_LINUX || JUCE_BSD)
|
||||
formats.add (new LADSPAPluginFormat());
|
||||
#endif
|
||||
}
|
||||
|
||||
int AudioPluginFormatManager::getNumFormats() const { return formats.size(); }
|
||||
AudioPluginFormat* AudioPluginFormatManager::getFormat (int index) const { return formats[index]; }
|
||||
|
||||
Array<AudioPluginFormat*> AudioPluginFormatManager::getFormats() const
|
||||
{
|
||||
Array<AudioPluginFormat*> a;
|
||||
a.addArray (formats);
|
||||
return a;
|
||||
}
|
||||
|
||||
void AudioPluginFormatManager::addFormat (AudioPluginFormat* format)
|
||||
{
|
||||
formats.add (format);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormatManager::createPluginInstance (const PluginDescription& description,
|
||||
double rate, int blockSize,
|
||||
String& errorMessage) const
|
||||
{
|
||||
if (auto* format = findFormatForDescription (description, errorMessage))
|
||||
return format->createInstanceFromDescription (description, rate, blockSize, errorMessage);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
AudioPluginFormat::PluginCreationCallback callback)
|
||||
{
|
||||
String error;
|
||||
|
||||
if (auto* format = findFormatForDescription (description, error))
|
||||
return format->createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
|
||||
struct DeliverError : public CallbackMessage
|
||||
{
|
||||
DeliverError (AudioPluginFormat::PluginCreationCallback c, const String& e)
|
||||
: call (std::move (c)), error (e)
|
||||
{
|
||||
post();
|
||||
}
|
||||
|
||||
void messageCallback() override { call (nullptr, error); }
|
||||
|
||||
AudioPluginFormat::PluginCreationCallback call;
|
||||
String error;
|
||||
};
|
||||
|
||||
new DeliverError (std::move (callback), error);
|
||||
}
|
||||
|
||||
AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const PluginDescription& description,
|
||||
String& errorMessage) const
|
||||
{
|
||||
errorMessage = {};
|
||||
|
||||
for (auto* format : formats)
|
||||
if (format->getName() == description.pluginFormatName
|
||||
&& format->fileMightContainThisPluginType (description.fileOrIdentifier))
|
||||
return format;
|
||||
|
||||
errorMessage = NEEDS_TRANS ("No compatible plug-in format exists for this plug-in");
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const
|
||||
{
|
||||
for (auto* format : formats)
|
||||
if (format->getName() == description.pluginFormatName)
|
||||
return format->doesPluginStillExist (description);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
AudioPluginFormatManager::AudioPluginFormatManager() {}
|
||||
AudioPluginFormatManager::~AudioPluginFormatManager() {}
|
||||
|
||||
//==============================================================================
|
||||
void AudioPluginFormatManager::addDefaultFormats()
|
||||
{
|
||||
#if JUCE_PLUGINHOST_VST && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD || JUCE_IOS)
|
||||
#define HAS_VST 1
|
||||
#else
|
||||
#define HAS_VST 0
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD)
|
||||
#define HAS_VST3 1
|
||||
#else
|
||||
#define HAS_VST3 0
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_AU && (JUCE_MAC || JUCE_IOS)
|
||||
#define HAS_AU 1
|
||||
#else
|
||||
#define HAS_AU 0
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_LADSPA && (JUCE_LINUX || JUCE_BSD)
|
||||
#define HAS_LADSPA 1
|
||||
#else
|
||||
#define HAS_LADSPA 0
|
||||
#endif
|
||||
|
||||
#if JUCE_PLUGINHOST_LV2 && (JUCE_MAC || JUCE_LINUX || JUCE_BSD || JUCE_WINDOWS)
|
||||
#define HAS_LV2 1
|
||||
#else
|
||||
#define HAS_LV2 0
|
||||
#endif
|
||||
|
||||
#if JUCE_DEBUG
|
||||
// you should only call this method once!
|
||||
for (auto* format : formats)
|
||||
{
|
||||
ignoreUnused (format);
|
||||
|
||||
#if HAS_VST
|
||||
jassert (dynamic_cast<VSTPluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if HAS_VST3
|
||||
jassert (dynamic_cast<VST3PluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if HAS_AU
|
||||
jassert (dynamic_cast<AudioUnitPluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if HAS_LADSPA
|
||||
jassert (dynamic_cast<LADSPAPluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
|
||||
#if HAS_LV2
|
||||
jassert (dynamic_cast<LV2PluginFormat*> (format) == nullptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_AU
|
||||
formats.add (new AudioUnitPluginFormat());
|
||||
#endif
|
||||
|
||||
#if HAS_VST
|
||||
formats.add (new VSTPluginFormat());
|
||||
#endif
|
||||
|
||||
#if HAS_VST3
|
||||
formats.add (new VST3PluginFormat());
|
||||
#endif
|
||||
|
||||
#if HAS_LADSPA
|
||||
formats.add (new LADSPAPluginFormat());
|
||||
#endif
|
||||
|
||||
#if HAS_LV2
|
||||
formats.add (new LV2PluginFormat());
|
||||
#endif
|
||||
}
|
||||
|
||||
int AudioPluginFormatManager::getNumFormats() const { return formats.size(); }
|
||||
AudioPluginFormat* AudioPluginFormatManager::getFormat (int index) const { return formats[index]; }
|
||||
|
||||
Array<AudioPluginFormat*> AudioPluginFormatManager::getFormats() const
|
||||
{
|
||||
Array<AudioPluginFormat*> a;
|
||||
a.addArray (formats);
|
||||
return a;
|
||||
}
|
||||
|
||||
void AudioPluginFormatManager::addFormat (AudioPluginFormat* format)
|
||||
{
|
||||
formats.add (format);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioPluginInstance> AudioPluginFormatManager::createPluginInstance (const PluginDescription& description,
|
||||
double rate, int blockSize,
|
||||
String& errorMessage) const
|
||||
{
|
||||
if (auto* format = findFormatForDescription (description, errorMessage))
|
||||
return format->createInstanceFromDescription (description, rate, blockSize, errorMessage);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void AudioPluginFormatManager::createARAFactoryAsync (const PluginDescription& description,
|
||||
AudioPluginFormat::ARAFactoryCreationCallback callback) const
|
||||
{
|
||||
String errorMessage;
|
||||
|
||||
if (auto* format = findFormatForDescription (description, errorMessage))
|
||||
{
|
||||
format->createARAFactoryAsync (description, callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = NEEDS_TRANS ("Couldn't find format for the provided description");
|
||||
callback ({ {}, std::move (errorMessage) });
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPluginFormatManager::createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
AudioPluginFormat::PluginCreationCallback callback)
|
||||
{
|
||||
String error;
|
||||
|
||||
if (auto* format = findFormatForDescription (description, error))
|
||||
return format->createPluginInstanceAsync (description, initialSampleRate, initialBufferSize, std::move (callback));
|
||||
|
||||
struct DeliverError : public CallbackMessage
|
||||
{
|
||||
DeliverError (AudioPluginFormat::PluginCreationCallback c, const String& e)
|
||||
: call (std::move (c)), error (e)
|
||||
{
|
||||
post();
|
||||
}
|
||||
|
||||
void messageCallback() override { call (nullptr, error); }
|
||||
|
||||
AudioPluginFormat::PluginCreationCallback call;
|
||||
String error;
|
||||
};
|
||||
|
||||
new DeliverError (std::move (callback), error);
|
||||
}
|
||||
|
||||
AudioPluginFormat* AudioPluginFormatManager::findFormatForDescription (const PluginDescription& description,
|
||||
String& errorMessage) const
|
||||
{
|
||||
errorMessage = {};
|
||||
|
||||
for (auto* format : formats)
|
||||
if (format->getName() == description.pluginFormatName
|
||||
&& format->fileMightContainThisPluginType (description.fileOrIdentifier))
|
||||
return format;
|
||||
|
||||
errorMessage = NEEDS_TRANS ("No compatible plug-in format exists for this plug-in");
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool AudioPluginFormatManager::doesPluginStillExist (const PluginDescription& description) const
|
||||
{
|
||||
for (auto* format : formats)
|
||||
if (format->getName() == description.pluginFormatName)
|
||||
return format->doesPluginStillExist (description);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,126 +1,142 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This maintains a list of known AudioPluginFormats.
|
||||
|
||||
@see AudioPluginFormat
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioPluginFormatManager
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
AudioPluginFormatManager();
|
||||
|
||||
/** Destructor. */
|
||||
~AudioPluginFormatManager();
|
||||
|
||||
//==============================================================================
|
||||
/** Adds the set of available standard formats, e.g. VST. */
|
||||
void addDefaultFormats();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of types of format that are available.
|
||||
Use getFormat() to get one of them.
|
||||
*/
|
||||
int getNumFormats() const;
|
||||
|
||||
/** Returns one of the available formats.
|
||||
@see getNumFormats
|
||||
*/
|
||||
AudioPluginFormat* getFormat (int index) const;
|
||||
|
||||
/** Returns a list of all the registered formats. */
|
||||
Array<AudioPluginFormat*> getFormats() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a format to the list.
|
||||
The object passed in will be owned and deleted by the manager.
|
||||
*/
|
||||
void addFormat (AudioPluginFormat*);
|
||||
|
||||
//==============================================================================
|
||||
/** Tries to load the type for this description, by trying all the formats
|
||||
that this manager knows about.
|
||||
|
||||
If it can't load the plugin, it returns nullptr and leaves a message in the
|
||||
errorMessage string.
|
||||
|
||||
If you intend to instantiate a AudioUnit v3 plug-in then you must either
|
||||
use the non-blocking asynchronous version below - or call this method from a
|
||||
thread other than the message thread and without blocking the message
|
||||
thread.
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createPluginInstance (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
String& errorMessage) const;
|
||||
|
||||
/** Tries to asynchronously load the type for this description, by trying
|
||||
all the formats that this manager knows about.
|
||||
|
||||
The caller must supply a callback object which will be called when
|
||||
the instantiation has completed.
|
||||
|
||||
If it can't load the plugin then the callback function will be called
|
||||
passing a nullptr as the instance argument along with an error message.
|
||||
|
||||
The callback function will be called on the message thread so the caller
|
||||
must not block the message thread.
|
||||
|
||||
The callback object will be deleted automatically after it has been
|
||||
invoked.
|
||||
|
||||
The caller is responsible for deleting the instance that is passed to
|
||||
the callback function.
|
||||
|
||||
If you intend to instantiate a AudioUnit v3 plug-in then you must use
|
||||
this non-blocking asynchronous version - or call the synchronous method
|
||||
from an auxiliary thread.
|
||||
*/
|
||||
void createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
AudioPluginFormat::PluginCreationCallback callback);
|
||||
|
||||
/** Checks that the file or component for this plugin actually still exists.
|
||||
(This won't try to load the plugin)
|
||||
*/
|
||||
bool doesPluginStillExist (const PluginDescription&) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioPluginFormat* findFormatForDescription (const PluginDescription&, String& errorMessage) const;
|
||||
|
||||
OwnedArray<AudioPluginFormat> formats;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormatManager)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
This maintains a list of known AudioPluginFormats.
|
||||
|
||||
@see AudioPluginFormat
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API AudioPluginFormatManager
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
AudioPluginFormatManager();
|
||||
|
||||
/** Destructor. */
|
||||
~AudioPluginFormatManager();
|
||||
|
||||
//==============================================================================
|
||||
/** Adds the set of available standard formats, e.g. VST. */
|
||||
void addDefaultFormats();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of types of format that are available.
|
||||
Use getFormat() to get one of them.
|
||||
*/
|
||||
int getNumFormats() const;
|
||||
|
||||
/** Returns one of the available formats.
|
||||
@see getNumFormats
|
||||
*/
|
||||
AudioPluginFormat* getFormat (int index) const;
|
||||
|
||||
/** Returns a list of all the registered formats. */
|
||||
Array<AudioPluginFormat*> getFormats() const;
|
||||
|
||||
//==============================================================================
|
||||
/** Adds a format to the list.
|
||||
The object passed in will be owned and deleted by the manager.
|
||||
*/
|
||||
void addFormat (AudioPluginFormat*);
|
||||
|
||||
//==============================================================================
|
||||
/** Tries to load the type for this description, by trying all the formats
|
||||
that this manager knows about.
|
||||
|
||||
If it can't load the plugin, it returns nullptr and leaves a message in the
|
||||
errorMessage string.
|
||||
|
||||
If you intend to instantiate a AudioUnit v3 plug-in then you must either
|
||||
use the non-blocking asynchronous version below - or call this method from a
|
||||
thread other than the message thread and without blocking the message
|
||||
thread.
|
||||
*/
|
||||
std::unique_ptr<AudioPluginInstance> createPluginInstance (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
String& errorMessage) const;
|
||||
|
||||
/** Tries to asynchronously load the type for this description, by trying
|
||||
all the formats that this manager knows about.
|
||||
|
||||
The caller must supply a callback object which will be called when
|
||||
the instantiation has completed.
|
||||
|
||||
If it can't load the plugin then the callback function will be called
|
||||
passing a nullptr as the instance argument along with an error message.
|
||||
|
||||
The callback function will be called on the message thread so the caller
|
||||
must not block the message thread.
|
||||
|
||||
The callback object will be deleted automatically after it has been
|
||||
invoked.
|
||||
|
||||
The caller is responsible for deleting the instance that is passed to
|
||||
the callback function.
|
||||
|
||||
If you intend to instantiate a AudioUnit v3 plug-in then you must use
|
||||
this non-blocking asynchronous version - or call the synchronous method
|
||||
from an auxiliary thread.
|
||||
*/
|
||||
void createPluginInstanceAsync (const PluginDescription& description,
|
||||
double initialSampleRate, int initialBufferSize,
|
||||
AudioPluginFormat::PluginCreationCallback callback);
|
||||
|
||||
/** Tries to create an ::ARAFactoryWrapper for this description.
|
||||
|
||||
The result of the operation will be wrapped into an ARAFactoryResult,
|
||||
which will be passed to a callback object supplied by the caller.
|
||||
|
||||
The operation may fail, in which case the callback will be called with
|
||||
with a result object where ARAFactoryResult::araFactory.get() will return
|
||||
a nullptr.
|
||||
|
||||
In case of success the returned ::ARAFactoryWrapper will ensure that
|
||||
modules required for the correct functioning of the ARAFactory will remain
|
||||
loaded for the lifetime of the object.
|
||||
*/
|
||||
void createARAFactoryAsync (const PluginDescription& description,
|
||||
AudioPluginFormat::ARAFactoryCreationCallback callback) const;
|
||||
|
||||
/** Checks that the file or component for this plugin actually still exists.
|
||||
(This won't try to load the plugin)
|
||||
*/
|
||||
bool doesPluginStillExist (const PluginDescription&) const;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioPluginFormat* findFormatForDescription (const PluginDescription&, String& errorMessage) const;
|
||||
|
||||
OwnedArray<AudioPluginFormat> formats;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioPluginFormatManager)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
Reference in New Issue
Block a user