1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

VST3PluginFormat: Extract headless plugin format type

This commit is contained in:
reuk 2025-08-20 15:28:56 +01:00
parent 6fa7b21435
commit 9c88358e46
No known key found for this signature in database
14 changed files with 4022 additions and 3812 deletions

View file

@ -115,7 +115,7 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#include "JucePluginDefines.h"
#endif
#include <juce_audio_processors/format_types/juce_VST3Utilities.h>
#include <juce_audio_processors_headless/format_types/juce_VST3Utilities.h>
#include <juce_audio_processors_headless/utilities/juce_VST3Interface.h>
#include <juce_audio_plugin_client/juce_audio_plugin_client.h>
#include "juce_VST3ModuleInfo.h"

View file

@ -48,7 +48,7 @@ JUCE_BEGIN_NO_SANITIZE ("vptr")
#define JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY 1
#endif
#include <juce_audio_processors/format_types/juce_VST3Headers.h>
#include <juce_audio_processors_headless/format_types/juce_VST3Headers.h>
#undef JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
@ -63,8 +63,8 @@ JUCE_BEGIN_NO_SANITIZE ("vptr")
//==============================================================================
#include <juce_audio_processors_headless/format_types/juce_LegacyAudioParameter.h>
#include <juce_audio_processors_headless/utilities/juce_FlagCache.h>
#include <juce_audio_processors/format_types/juce_VST3Utilities.h>
#include <juce_audio_processors/format_types/juce_VST3Common.h>
#include <juce_audio_processors_headless/format_types/juce_VST3Utilities.h>
#include <juce_audio_processors_headless/format_types/juce_VST3Common.h>
#include <juce_audio_plugin_client/VST3/juce_VST3ModuleInfo.h>
#if JUCE_VST3_CAN_REPLACE_VST2 && ! JUCE_FORCE_USE_LEGACY_PARAM_IDS && ! JUCE_IGNORE_VST3_MISMATCHED_PARAMETER_ID_WARNING

View file

@ -42,52 +42,9 @@ namespace juce
@tags{Audio}
*/
class JUCE_API VST3PluginFormat : public AudioPluginFormat
class JUCE_API VST3PluginFormat : public VST3PluginFormatHeadless
{
public:
/** Constructor */
VST3PluginFormat();
/** Destructor */
~VST3PluginFormat() override;
//==============================================================================
/** @cond */
/** Attempts to reload a VST3 plugin's state from some preset file data.
@see VSTPluginFormat::loadFromFXBFile
*/
[[deprecated ("Instead of using this function, use AudioPluginInstance::getExtensions() "
"to visit the ExtensionsVisitor::VST3 struct for the instance, if it exists. "
"Then, call ExtensionsVisitor::VST3::setPreset() to set the state using the "
"contents of a vstpreset file.")]]
static bool setStateFromVSTPresetFile (AudioPluginInstance*, const MemoryBlock&);
/** @endcond */
//==============================================================================
static String getFormatName() { return "VST3"; }
String getName() const override { return getFormatName(); }
bool canScanForPlugins() const override { return true; }
bool isTrivialToScan() const override { return false; }
void findAllTypesForFile (OwnedArray<PluginDescription>&, const String& fileOrIdentifier) override;
bool fileMightContainThisPluginType (const String& fileOrIdentifier) override;
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override;
bool pluginNeedsRescanning (const PluginDescription&) override;
StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive, bool) override;
bool doesPluginStillExist (const PluginDescription&) override;
FileSearchPath getDefaultLocationsToSearch() override;
void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) override;
private:
//==============================================================================
void createPluginInstance (const PluginDescription&, double initialSampleRate,
int initialBufferSize, PluginCreationCallback) override;
bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const override;
void recursiveFileSearch (StringArray&, const File&, bool recursive);
StringArray getLibraryPaths (const String&);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginFormat)
void createPluginInstance (const PluginDescription&, double, int, PluginCreationCallback) override;
};
#endif // JUCE_PLUGINHOST_VST3

View file

@ -32,9 +32,9 @@
==============================================================================
*/
#include "juce_VST3Headers.h"
#include "juce_VST3Utilities.h"
#include "juce_VST3Common.h"
#include <juce_audio_processors_headless/format_types/juce_VST3Headers.h>
#include <juce_audio_processors_headless/format_types/juce_VST3Utilities.h>
#include <juce_audio_processors_headless/format_types/juce_VST3Common.h>
namespace juce
{

View file

@ -46,17 +46,17 @@
#define JUCE_GUI_BASICS_INCLUDE_XHEADERS 1
#define JUCE_GUI_BASICS_INCLUDE_SCOPED_THREAD_DPI_AWARENESS_SETTER 1
#define JUCE_GRAPHICS_INCLUDE_COREGRAPHICS_HELPERS 1
#define JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY 1
#include "juce_audio_processors.h"
#include <juce_gui_extra/juce_gui_extra.h>
//==============================================================================
#if (JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3) && (JUCE_LINUX || JUCE_BSD)
#if JUCE_PLUGINHOST_VST && (JUCE_LINUX || JUCE_BSD)
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wvariadic-macros")
#include <X11/Xlib.h>
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#include <X11/Xutil.h>
#include <sys/utsname.h>
#undef KeyPress
#endif

View file

@ -137,6 +137,7 @@ JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-W#warnings",
#include <public.sdk/source/vst/utility/vst2persistence.h>
#include <public.sdk/source/vst/vsteditcontroller.h>
#include <public.sdk/source/vst/vstpresetfile.h>
#include <public.sdk/source/vst/moduleinfo/moduleinfoparser.h>
#include <juce_audio_processors_headless/format_types/pslextensions/ipslviewembedding.h>
#else

View file

@ -0,0 +1,173 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
#if JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD)
#include <juce_audio_processors_headless/format_types/juce_VST3PluginFormatImpl.h>
namespace juce
{
// UB Sanitizer doesn't necessarily have instrumentation for loaded plugins, so
// it won't recognize the dynamic types of pointers to the plugin's interfaces.
JUCE_BEGIN_NO_SANITIZE ("vptr")
bool VST3PluginFormatHeadless::setStateFromVSTPresetFile (AudioPluginInstance* api, const MemoryBlock& rawData)
{
if (auto vst3 = dynamic_cast<VST3PluginInstanceHeadless*> (api))
return vst3->setStateFromPresetFile (rawData);
return false;
}
void VST3PluginFormatHeadless::findAllTypesForFile (OwnedArray<PluginDescription>& results, const String& fileOrIdentifier)
{
if (! fileMightContainThisPluginType (fileOrIdentifier))
return;
if (const auto fast = DescriptionLister::findDescriptionsFast (File (fileOrIdentifier)); ! fast.empty())
{
for (const auto& d : fast)
results.add (new PluginDescription (d));
return;
}
for (const auto& file : getLibraryPaths (*this, fileOrIdentifier))
{
/**
Since there is no apparent indication if a VST3 plugin is a shell or not,
we're stuck iterating through a VST3's factory, creating a description
for every housed plugin.
*/
auto handle = RefCountedDllHandle::getHandle (file);
if (handle == nullptr)
continue;
auto pluginFactory = handle->getPluginFactory();
if (pluginFactory == nullptr)
continue;
auto host = addVSTComSmartPtrOwner (new VST3HostContextHeadless());
for (const auto& d : DescriptionLister::findDescriptionsSlow (*host, *pluginFactory, File (file)))
results.add (new PluginDescription (d));
}
}
void VST3PluginFormatHeadless::createARAFactoryAsync (const PluginDescription& description, ARAFactoryCreationCallback callback)
{
if (! description.hasARAExtension)
{
jassertfalse;
callback ({ {}, "The provided plugin does not support ARA features" });
}
const File file (description.fileOrIdentifier);
auto handle = RefCountedDllHandle::getHandle (file.getFullPathName());
auto pluginFactory = handle->getPluginFactory();
const auto* pluginName = description.name.toRawUTF8();
callback ({ ARAFactoryWrapper { ::juce::getARAFactory (pluginFactory.get(), pluginName) }, {} });
}
void VST3PluginFormatHeadless::createPluginInstance (const PluginDescription& description,
double,
int,
PluginCreationCallback callback)
{
createVst3InstanceImpl<VST3PluginInstanceHeadless> (*this,
becomeVSTComSmartPtrOwner (new VST3HostContextHeadless),
description,
callback);
}
bool VST3PluginFormatHeadless::requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const
{
return false;
}
bool VST3PluginFormatHeadless::fileMightContainThisPluginType (const String& fileOrIdentifier)
{
auto f = File::createFileWithoutCheckingPath (fileOrIdentifier);
return f.hasFileExtension (".vst3") && f.exists();
}
String VST3PluginFormatHeadless::getNameOfPluginFromIdentifier (const String& fileOrIdentifier)
{
return fileOrIdentifier; //Impossible to tell because every VST3 is a type of shell...
}
bool VST3PluginFormatHeadless::pluginNeedsRescanning (const PluginDescription& description)
{
return File (description.fileOrIdentifier).getLastModificationTime() != description.lastFileModTime;
}
bool VST3PluginFormatHeadless::doesPluginStillExist (const PluginDescription& description)
{
return File (description.fileOrIdentifier).exists();
}
StringArray VST3PluginFormatHeadless::searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive, bool)
{
StringArray results;
for (int i = 0; i < directoriesToSearch.getNumPaths(); ++i)
recursiveFileSearch (*this, results, directoriesToSearch[i], recursive);
return results;
}
FileSearchPath VST3PluginFormatHeadless::getDefaultLocationsToSearch()
{
#if JUCE_WINDOWS
const auto localAppData = File::getSpecialLocation (File::windowsLocalAppData) .getFullPathName();
const auto programFiles = File::getSpecialLocation (File::globalApplicationsDirectory).getFullPathName();
return FileSearchPath (localAppData + "\\Programs\\Common\\VST3;" + programFiles + "\\Common Files\\VST3");
#elif JUCE_MAC
return FileSearchPath ("~/Library/Audio/Plug-Ins/VST3;/Library/Audio/Plug-Ins/VST3");
#else
return FileSearchPath ("~/.vst3/;/usr/lib/vst3/;/usr/local/lib/vst3/");
#endif
}
JUCE_END_NO_SANITIZE
} // namespace juce
#endif // JUCE_PLUGINHOST_VST3

View file

@ -0,0 +1,90 @@
/*
==============================================================================
This file is part of the JUCE framework.
Copyright (c) Raw Material Software Limited
JUCE is an open source framework subject to commercial or open source
licensing.
By downloading, installing, or using the JUCE framework, or combining the
JUCE framework with any other source code, object code, content or any other
copyrightable work, you agree to the terms of the JUCE End User Licence
Agreement, and all incorporated terms including the JUCE Privacy Policy and
the JUCE Website Terms of Service, as applicable, which will bind you. If you
do not agree to the terms of these agreements, we will not license the JUCE
framework to you, and you must discontinue the installation or download
process and cease use of the JUCE framework.
JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/
JUCE Privacy Policy: https://juce.com/juce-privacy-policy
JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/
Or:
You may also use this code under the terms of the AGPLv3:
https://www.gnu.org/licenses/agpl-3.0.en.html
THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL
WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
namespace juce
{
#if (JUCE_PLUGINHOST_VST3 && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX || JUCE_BSD)) || DOXYGEN
/**
Implements a plugin format for VST3s.
@tags{Audio}
*/
class JUCE_API VST3PluginFormatHeadless : public AudioPluginFormat
{
public:
/** Constructor */
VST3PluginFormatHeadless() = default;
//==============================================================================
/** @cond */
/** Attempts to reload a VST3 plugin's state from some preset file data.
@see VSTPluginFormat::loadFromFXBFile
*/
[[deprecated ("Instead of using this function, use AudioPluginInstance::getExtensions() "
"to visit the ExtensionsVisitor::VST3 struct for the instance, if it exists. "
"Then, call ExtensionsVisitor::VST3::setPreset() to set the state using the "
"contents of a vstpreset file.")]]
static bool setStateFromVSTPresetFile (AudioPluginInstance*, const MemoryBlock&);
/** @endcond */
//==============================================================================
static String getFormatName() { return "VST3"; }
String getName() const override { return getFormatName(); }
bool canScanForPlugins() const override { return true; }
bool isTrivialToScan() const override { return false; }
void findAllTypesForFile (OwnedArray<PluginDescription>&, const String& fileOrIdentifier) override;
bool fileMightContainThisPluginType (const String& fileOrIdentifier) override;
String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) override;
bool pluginNeedsRescanning (const PluginDescription&) override;
StringArray searchPathsForPlugins (const FileSearchPath&, bool recursive, bool) override;
bool doesPluginStillExist (const PluginDescription&) override;
FileSearchPath getDefaultLocationsToSearch() override;
void createARAFactoryAsync (const PluginDescription&, ARAFactoryCreationCallback callback) override;
private:
//==============================================================================
void createPluginInstance (const PluginDescription&, double initialSampleRate,
int initialBufferSize, PluginCreationCallback) override;
bool requiresUnblockedMessageThreadDuringCreation (const PluginDescription&) const override;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VST3PluginFormatHeadless)
};
#endif // JUCE_PLUGINHOST_VST3
} // namespace juce

File diff suppressed because it is too large Load diff

View file

@ -67,3 +67,4 @@
#include <juce_audio_processors_headless/format_types/juce_AudioUnitPluginFormatHeadless.mm>
#include <juce_audio_processors_headless/format_types/juce_LADSPAPluginFormatHeadless.cpp>
#include <juce_audio_processors_headless/format_types/juce_LV2PluginFormatHeadless.cpp>
#include <juce_audio_processors_headless/format_types/juce_VST3PluginFormatHeadless.cpp>

View file

@ -92,3 +92,4 @@
#include <juce_audio_processors_headless/format_types/juce_AudioUnitPluginFormatHeadless.h>
#include <juce_audio_processors_headless/format_types/juce_LADSPAPluginFormatHeadless.h>
#include <juce_audio_processors_headless/format_types/juce_LV2PluginFormatHeadless.h>
#include <juce_audio_processors_headless/format_types/juce_VST3PluginFormatHeadless.h>