mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
VST3: Add a new PluginDescription::uniqueId field
This commit is contained in:
parent
a533e86044
commit
041da08474
12 changed files with 107 additions and 56 deletions
|
|
@ -1,6 +1,34 @@
|
|||
JUCE breaking changes
|
||||
=====================
|
||||
|
||||
Develop
|
||||
=======
|
||||
|
||||
Change
|
||||
------
|
||||
PluginDescription::uid has been deprecated and replaced with a new 'uniqueId'
|
||||
data member.
|
||||
|
||||
Possible Issues
|
||||
---------------
|
||||
Code using the old data member will need to be updated in order to compile.
|
||||
|
||||
Workaround
|
||||
----------
|
||||
Code that used to use 'uid' to identify plugins should switch to using
|
||||
'uniqueId', with some caveats - see "Rationale" for details.
|
||||
|
||||
Rationale
|
||||
---------
|
||||
The 'uniqueId' member has the benefit of being consistent for
|
||||
a given VST3 across Windows, macOS, and Linux. However, the value of the
|
||||
uniqueId may differ from the value of the old uid on some platforms. The value
|
||||
of the old 'uid' member can now be found in the 'deprecatedUid' member, which
|
||||
should allow clients to implement logic such as checking a saved uid against
|
||||
the new uniqueId, and falling back to the deprecatedUid. This should allow
|
||||
hosts to gracefully upgrade from the old uid values to the new values.
|
||||
|
||||
|
||||
Version 6.0.8
|
||||
=============
|
||||
|
||||
|
|
|
|||
|
|
@ -113,17 +113,18 @@ private:
|
|||
|
||||
PluginDescription descr;
|
||||
|
||||
descr.name = identifier;
|
||||
descr.descriptiveName = identifier;
|
||||
descr.pluginFormatName = InternalPluginFormat::getIdentifier();
|
||||
descr.category = (registerAsGenerator ? (acceptsMidi ? "Synth" : "Generator") : "Effect");
|
||||
descr.manufacturerName = "JUCE";
|
||||
descr.version = ProjectInfo::versionString;
|
||||
descr.fileOrIdentifier = identifier;
|
||||
descr.uid = identifier.hashCode();
|
||||
descr.isInstrument = (acceptsMidi && registerAsGenerator);
|
||||
descr.numInputChannels = ins;
|
||||
descr.numOutputChannels = outs;
|
||||
descr.name = identifier;
|
||||
descr.descriptiveName = identifier;
|
||||
descr.pluginFormatName = InternalPluginFormat::getIdentifier();
|
||||
descr.category = (registerAsGenerator ? (acceptsMidi ? "Synth" : "Generator") : "Effect");
|
||||
descr.manufacturerName = "JUCE";
|
||||
descr.version = ProjectInfo::versionString;
|
||||
descr.fileOrIdentifier = identifier;
|
||||
descr.isInstrument = (acceptsMidi && registerAsGenerator);
|
||||
descr.numInputChannels = ins;
|
||||
descr.numOutputChannels = outs;
|
||||
|
||||
descr.uniqueId = descr.deprecatedUid = identifier.hashCode();
|
||||
|
||||
return descr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2274,8 +2274,7 @@ function(juce_add_pip header)
|
|||
target_compile_definitions(${JUCE_PIP_NAME}
|
||||
PRIVATE ${pip_moduleflags}
|
||||
PUBLIC
|
||||
JUCE_VST3_CAN_REPLACE_VST2=0
|
||||
JUCE_VST3_HOST_CROSS_PLATFORM_UID=1)
|
||||
JUCE_VST3_CAN_REPLACE_VST2=0)
|
||||
|
||||
_juce_get_pip_targets(${JUCE_PIP_NAME} pip_targets)
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ static void doBasicProjectSetup (Project& project, const NewProjectTemplates::Pr
|
|||
project.getMainGroup().addNewSubGroup ("Source", 0);
|
||||
|
||||
project.getConfigFlag ("JUCE_STRICT_REFCOUNTEDPOINTER") = true;
|
||||
project.getConfigFlag ("JUCE_VST3_HOST_CROSS_PLATFORM_UID") = true;
|
||||
project.getProjectValue (Ids::useAppConfig) = false;
|
||||
project.getProjectValue (Ids::addUsingNamespaceToJuceHeader) = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -846,9 +846,9 @@ public:
|
|||
desc.name = pluginName;
|
||||
desc.descriptiveName = pluginName;
|
||||
desc.fileOrIdentifier = AudioUnitFormatHelpers::createPluginIdentifier (componentDesc);
|
||||
desc.uid = ((int) componentDesc.componentType)
|
||||
^ ((int) componentDesc.componentSubType)
|
||||
^ ((int) componentDesc.componentManufacturer);
|
||||
desc.uniqueId = desc.deprecatedUid = ((int) componentDesc.componentType)
|
||||
^ ((int) componentDesc.componentSubType)
|
||||
^ ((int) componentDesc.componentManufacturer);
|
||||
desc.lastFileModTime = Time();
|
||||
desc.lastInfoUpdateTime = Time::getCurrentTime();
|
||||
desc.pluginFormatName = "AudioUnit";
|
||||
|
|
@ -2634,7 +2634,7 @@ void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>&
|
|||
|
||||
PluginDescription desc;
|
||||
desc.fileOrIdentifier = fileOrIdentifier;
|
||||
desc.uid = 0;
|
||||
desc.uniqueId = desc.deprecatedUid = 0;
|
||||
|
||||
if (MessageManager::getInstance()->isThisTheMessageThread()
|
||||
&& requiresUnblockedMessageThreadDuringCreation (desc))
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ public:
|
|||
{
|
||||
desc.name = getName();
|
||||
desc.fileOrIdentifier = module->file.getFullPathName();
|
||||
desc.uid = getUID();
|
||||
desc.uniqueId = desc.deprecatedUid = getUID();
|
||||
desc.lastFileModTime = module->file.getLastModificationTime();
|
||||
desc.lastInfoUpdateTime = Time::getCurrentTime();
|
||||
desc.pluginFormatName = "LADSPA";
|
||||
|
|
@ -583,7 +583,7 @@ void LADSPAPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& res
|
|||
|
||||
PluginDescription desc;
|
||||
desc.fileOrIdentifier = fileOrIdentifier;
|
||||
desc.uid = 0;
|
||||
desc.uniqueId = desc.deprecatedUid = 0;
|
||||
|
||||
auto createdInstance = createInstanceFromDescription (desc, 44100.0, 512);
|
||||
auto instance = dynamic_cast<LADSPAPluginInstance*> (createdInstance.get());
|
||||
|
|
@ -600,7 +600,7 @@ void LADSPAPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& res
|
|||
{
|
||||
if (auto* plugin = instance->module->moduleMain ((size_t) uid))
|
||||
{
|
||||
desc.uid = uid;
|
||||
desc.uniqueId = desc.deprecatedUid = uid;
|
||||
desc.name = plugin->Name != nullptr ? plugin->Name : "Unknown";
|
||||
|
||||
if (! arrayContainsPlugin (results, desc))
|
||||
|
|
@ -631,7 +631,7 @@ void LADSPAPluginFormat::createPluginInstance (const PluginDescription& desc,
|
|||
|
||||
if (module != nullptr)
|
||||
{
|
||||
shellLADSPAUIDToCreate = desc.uid;
|
||||
shellLADSPAUIDToCreate = desc.uniqueId;
|
||||
|
||||
result.reset (new LADSPAPluginInstance (module));
|
||||
|
||||
|
|
|
|||
|
|
@ -79,18 +79,18 @@ static int warnOnFailureIfImplemented (int result) noexcept
|
|||
#endif
|
||||
|
||||
//==============================================================================
|
||||
static int getHashForTUID (const TUID& tuid) noexcept
|
||||
std::array<uint32, 4> getNormalisedTUID (const TUID& tuid) noexcept
|
||||
{
|
||||
#if JUCE_VST3_HOST_CROSS_PLATFORM_UID
|
||||
const FUID fuid { tuid };
|
||||
const uint32 inputArray[] { fuid.getLong1(), fuid.getLong2(), fuid.getLong3(), fuid.getLong4() };
|
||||
#else
|
||||
const auto& inputArray = tuid;
|
||||
#endif
|
||||
return { { fuid.getLong1(), fuid.getLong2(), fuid.getLong3(), fuid.getLong4() } };
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
static int getHashForRange (Range&& range) noexcept
|
||||
{
|
||||
uint32 value = 0;
|
||||
|
||||
for (const auto& item : inputArray)
|
||||
for (const auto& item : range)
|
||||
value = (value * 31) + (uint32) item;
|
||||
|
||||
return (int) value;
|
||||
|
|
@ -120,7 +120,9 @@ static void createPluginDescription (PluginDescription& description,
|
|||
description.pluginFormatName = "VST3";
|
||||
description.numInputChannels = numInputs;
|
||||
description.numOutputChannels = numOutputs;
|
||||
description.uid = getHashForTUID (info.cid);
|
||||
|
||||
description.deprecatedUid = getHashForRange (info.cid);
|
||||
description.uniqueId = getHashForRange (getNormalisedTUID (info.cid));
|
||||
|
||||
if (infoW != nullptr) fillDescriptionWith (description, *infoW);
|
||||
else if (info2 != nullptr) fillDescriptionWith (description, *info2);
|
||||
|
|
@ -780,7 +782,7 @@ struct DescriptionFactory
|
|||
}
|
||||
}
|
||||
|
||||
if (desc.uid != 0)
|
||||
if (desc.uniqueId != 0)
|
||||
result = performOnDescription (desc);
|
||||
|
||||
if (result.failed())
|
||||
|
|
@ -1105,7 +1107,8 @@ private:
|
|||
continue;
|
||||
|
||||
if (toString (info.name).trim() == description.name
|
||||
&& getHashForTUID (info.cid) == description.uid)
|
||||
&& (getHashForRange (getNormalisedTUID (info.cid)) == description.uniqueId
|
||||
|| getHashForRange (info.cid) == description.deprecatedUid))
|
||||
{
|
||||
name = description.name;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -1170,7 +1170,7 @@ struct VSTPluginInstance : public AudioPluginInstance,
|
|||
}
|
||||
|
||||
desc.fileOrIdentifier = vstModule->file.getFullPathName();
|
||||
desc.uid = getUID();
|
||||
desc.uniqueId = desc.deprecatedUid = getUID();
|
||||
desc.lastFileModTime = vstModule->file.getLastModificationTime();
|
||||
desc.lastInfoUpdateTime = Time::getCurrentTime();
|
||||
desc.pluginFormatName = "VST";
|
||||
|
|
@ -3470,7 +3470,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& result
|
|||
|
||||
PluginDescription desc;
|
||||
desc.fileOrIdentifier = fileOrIdentifier;
|
||||
desc.uid = 0;
|
||||
desc.uniqueId = desc.deprecatedUid = 0;
|
||||
|
||||
auto instance = createAndUpdateDesc (*this, desc);
|
||||
|
||||
|
|
@ -3495,7 +3495,7 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& result
|
|||
if (uid == 0)
|
||||
break;
|
||||
|
||||
desc.uid = uid;
|
||||
desc.uniqueId = desc.deprecatedUid = uid;
|
||||
desc.name = shellEffectName;
|
||||
|
||||
aboutToScanVSTShellPlugin (desc);
|
||||
|
|
@ -3504,7 +3504,8 @@ void VSTPluginFormat::findAllTypesForFile (OwnedArray<PluginDescription>& result
|
|||
|
||||
if (shellInstance != nullptr)
|
||||
{
|
||||
jassert (desc.uid == uid);
|
||||
jassert (desc.deprecatedUid == uid);
|
||||
jassert (desc.uniqueId == uid);
|
||||
desc.hasSharedContainer = true;
|
||||
desc.name = shellEffectName;
|
||||
|
||||
|
|
@ -3530,7 +3531,7 @@ void VSTPluginFormat::createPluginInstance (const PluginDescription& desc,
|
|||
|
||||
if (auto module = ModuleHandle::findOrCreateModule (file))
|
||||
{
|
||||
shellUIDToCreate = desc.uid;
|
||||
shellUIDToCreate = desc.uniqueId;
|
||||
|
||||
result.reset (VSTPluginInstance::create (module, sampleRate, blockSize));
|
||||
|
||||
|
|
|
|||
|
|
@ -102,15 +102,6 @@
|
|||
#define JUCE_CUSTOM_VST3_SDK 0
|
||||
#endif
|
||||
|
||||
/** Config: JUCE_VST3_HOST_CROSS_PLATFORM_UID
|
||||
If enabled, ensures that PluginDescription::uid will produce consistent values for VST3 plugins on all platforms.
|
||||
It is recommended to enable this flag in all new projects.
|
||||
Projects which predate this flag should leave it disabled, in case they need to interact with uid values which they previously stored.
|
||||
*/
|
||||
#ifndef JUCE_VST3_HOST_CROSS_PLATFORM_UID
|
||||
#define JUCE_VST3_HOST_CROSS_PLATFORM_UID 0
|
||||
#endif
|
||||
|
||||
#if ! (JUCE_PLUGINHOST_AU || JUCE_PLUGINHOST_VST || JUCE_PLUGINHOST_VST3 || JUCE_PLUGINHOST_LADSPA)
|
||||
// #error "You need to set either the JUCE_PLUGINHOST_AU and/or JUCE_PLUGINHOST_VST and/or JUCE_PLUGINHOST_VST3 and/or JUCE_PLUGINHOST_LADSPA flags if you're using this module!"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1418,13 +1418,14 @@ const String AudioProcessorGraph::AudioGraphIOProcessor::getName() const
|
|||
void AudioProcessorGraph::AudioGraphIOProcessor::fillInPluginDescription (PluginDescription& d) const
|
||||
{
|
||||
d.name = getName();
|
||||
d.uid = d.name.hashCode();
|
||||
d.category = "I/O devices";
|
||||
d.pluginFormatName = "Internal";
|
||||
d.manufacturerName = "JUCE";
|
||||
d.version = "1.0";
|
||||
d.isInstrument = false;
|
||||
|
||||
d.deprecatedUid = d.uniqueId = d.name.hashCode();
|
||||
|
||||
d.numInputChannels = getTotalNumInputChannels();
|
||||
|
||||
if (type == audioOutputNode && graph != nullptr)
|
||||
|
|
|
|||
|
|
@ -28,14 +28,18 @@ namespace juce
|
|||
|
||||
bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept
|
||||
{
|
||||
return fileOrIdentifier == other.fileOrIdentifier
|
||||
&& uid == other.uid;
|
||||
const auto tie = [] (const PluginDescription& d)
|
||||
{
|
||||
return std::tie (d.fileOrIdentifier, d.deprecatedUid, d.uniqueId);
|
||||
};
|
||||
|
||||
return tie (*this) == tie (other);
|
||||
}
|
||||
|
||||
static String getPluginDescSuffix (const PluginDescription& d)
|
||||
{
|
||||
return "-" + String::toHexString (d.fileOrIdentifier.hashCode())
|
||||
+ "-" + String::toHexString (d.uid);
|
||||
+ "-" + String::toHexString (d.uniqueId);
|
||||
}
|
||||
|
||||
bool PluginDescription::matchesIdentifierString (const String& identifierString) const
|
||||
|
|
@ -62,7 +66,7 @@ std::unique_ptr<XmlElement> PluginDescription::createXml() const
|
|||
e->setAttribute ("manufacturer", manufacturerName);
|
||||
e->setAttribute ("version", version);
|
||||
e->setAttribute ("file", fileOrIdentifier);
|
||||
e->setAttribute ("uid", String::toHexString (uid));
|
||||
e->setAttribute ("uniqueId", String::toHexString (uniqueId));
|
||||
e->setAttribute ("isInstrument", isInstrument);
|
||||
e->setAttribute ("fileTime", String::toHexString (lastFileModTime.toMilliseconds()));
|
||||
e->setAttribute ("infoUpdateTime", String::toHexString (lastInfoUpdateTime.toMilliseconds()));
|
||||
|
|
@ -70,6 +74,8 @@ std::unique_ptr<XmlElement> PluginDescription::createXml() const
|
|||
e->setAttribute ("numOutputs", numOutputChannels);
|
||||
e->setAttribute ("isShell", hasSharedContainer);
|
||||
|
||||
e->setAttribute ("uid", String::toHexString (deprecatedUid));
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +90,6 @@ bool PluginDescription::loadFromXml (const XmlElement& xml)
|
|||
manufacturerName = xml.getStringAttribute ("manufacturer");
|
||||
version = xml.getStringAttribute ("version");
|
||||
fileOrIdentifier = xml.getStringAttribute ("file");
|
||||
uid = xml.getStringAttribute ("uid").getHexValue32();
|
||||
isInstrument = xml.getBoolAttribute ("isInstrument", false);
|
||||
lastFileModTime = Time (xml.getStringAttribute ("fileTime").getHexValue64());
|
||||
lastInfoUpdateTime = Time (xml.getStringAttribute ("infoUpdateTime").getHexValue64());
|
||||
|
|
@ -92,6 +97,9 @@ bool PluginDescription::loadFromXml (const XmlElement& xml)
|
|||
numOutputChannels = xml.getIntAttribute ("numOutputs");
|
||||
hasSharedContainer = xml.getBoolAttribute ("isShell", false);
|
||||
|
||||
deprecatedUid = xml.getStringAttribute ("uid").getHexValue32();
|
||||
uniqueId = xml.getStringAttribute ("uniqueId", "0").getHexValue32();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,9 +44,12 @@ class JUCE_API PluginDescription
|
|||
public:
|
||||
//==============================================================================
|
||||
PluginDescription() = default;
|
||||
PluginDescription (const PluginDescription& other) = default;
|
||||
|
||||
PluginDescription& operator= (const PluginDescription& other) = default;
|
||||
PluginDescription (const PluginDescription&) = default;
|
||||
PluginDescription (PluginDescription&&) = default;
|
||||
|
||||
PluginDescription& operator= (const PluginDescription&) = default;
|
||||
PluginDescription& operator= (PluginDescription&&) = default;
|
||||
|
||||
//==============================================================================
|
||||
/** The name of the plug-in. */
|
||||
|
|
@ -88,14 +91,31 @@ public:
|
|||
*/
|
||||
Time lastInfoUpdateTime;
|
||||
|
||||
/** A unique ID for the plug-in.
|
||||
/** Deprecated: New projects should use uniqueId instead.
|
||||
|
||||
A unique ID for the plug-in.
|
||||
|
||||
Note that this might not be unique between formats, e.g. a VST and some
|
||||
other format might actually have the same id.
|
||||
|
||||
@see createIdentifierString
|
||||
*/
|
||||
int uid = 0;
|
||||
int deprecatedUid = 0;
|
||||
|
||||
/** A unique ID for the plug-in.
|
||||
|
||||
Note that this might not be unique between formats, e.g. a VST and some
|
||||
other format might actually have the same id.
|
||||
|
||||
The uniqueId field replaces the deprecatedUid field, and fixes an issue
|
||||
where VST3 plugins with matching FUIDs would generate different uid
|
||||
values depending on the platform. The deprecatedUid field is kept for
|
||||
backwards compatibility, allowing existing hosts to migrate from the
|
||||
old uid to the new uniqueId.
|
||||
|
||||
@see createIdentifierString
|
||||
*/
|
||||
int uniqueId = 0;
|
||||
|
||||
/** True if the plug-in identifies itself as a synthesiser. */
|
||||
bool isInstrument = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue