Browse Source

VST3: Add a new PluginDescription::uniqueId field

v6.1.6
reuk 4 years ago
parent
commit
041da08474
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
12 changed files with 106 additions and 55 deletions
  1. +28
    -0
      BREAKING-CHANGES.txt
  2. +12
    -11
      extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp
  3. +1
    -2
      extras/Build/CMake/JUCEUtils.cmake
  4. +0
    -1
      extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp
  5. +4
    -4
      modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  6. +4
    -4
      modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp
  7. +13
    -10
      modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp
  8. +6
    -5
      modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  9. +0
    -9
      modules/juce_audio_processors/juce_audio_processors.h
  10. +2
    -1
      modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  11. +13
    -5
      modules/juce_audio_processors/processors/juce_PluginDescription.cpp
  12. +23
    -3
      modules/juce_audio_processors/processors/juce_PluginDescription.h

+ 28
- 0
BREAKING-CHANGES.txt View File

@@ -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
=============



+ 12
- 11
extras/AudioPluginHost/Source/Plugins/InternalPlugins.cpp View File

@@ -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;
}


+ 1
- 2
extras/Build/CMake/JUCEUtils.cmake View File

@@ -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)



+ 0
- 1
extras/Projucer/Source/Application/StartPage/jucer_NewProjectWizard.cpp View File

@@ -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;


+ 4
- 4
modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -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))


+ 4
- 4
modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp View File

@@ -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));


+ 13
- 10
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -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;


+ 6
- 5
modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -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));


+ 0
- 9
modules/juce_audio_processors/juce_audio_processors.h View File

@@ -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


+ 2
- 1
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp View File

@@ -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)


+ 13
- 5
modules/juce_audio_processors/processors/juce_PluginDescription.cpp View File

@@ -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;
}


+ 23
- 3
modules/juce_audio_processors/processors/juce_PluginDescription.h View File

@@ -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;
/** 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 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 uid = 0;
int uniqueId = 0;
/** True if the plug-in identifies itself as a synthesiser. */
bool isInstrument = false;


Loading…
Cancel
Save