Browse Source

Added VST3->VST2 backwards compatibility, with a flag JUCE_VST3_CAN_REPLACE_VST2 to disable this if you want your VST2 + 3 versions to use different IDs and not be interchangable.

tags/2021-05-28
jules 11 years ago
parent
commit
bf72ff0851
1 changed files with 138 additions and 15 deletions
  1. +138
    -15
      modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp

+ 138
- 15
modules/juce_audio_plugin_client/VST3/juce_VST3_Wrapper.cpp View File

@@ -34,6 +34,23 @@
#include "../utility/juce_IncludeModuleHeaders.h"
#include "../../juce_audio_processors/format_types/juce_VST3Common.h"
#ifndef JUCE_VST3_CAN_REPLACE_VST2
#define JUCE_VST3_CAN_REPLACE_VST2 1
#endif
#if JUCE_VST3_CAN_REPLACE_VST2
#if JUCE_MSVC
#pragma warning (push)
#pragma warning (disable: 4514 4996)
#endif
#include <pluginterfaces/vst2.x/vstfxstore.h>
#if JUCE_MSVC
#pragma warning (pop)
#endif
#endif
#undef Point
#undef Component
@@ -750,10 +767,30 @@ public:
return kResultOk;
}
tresult PLUGIN_API setIoMode (Vst::IoMode) override { return kNotImplemented; }
tresult PLUGIN_API getRoutingInfo (Vst::RoutingInfo&, Vst::RoutingInfo&) override { return kNotImplemented; }
tresult PLUGIN_API setIoMode (Vst::IoMode) override { return kNotImplemented; }
tresult PLUGIN_API getRoutingInfo (Vst::RoutingInfo&, Vst::RoutingInfo&) override { return kNotImplemented; }
#if JUCE_VST3_CAN_REPLACE_VST2
void loadVST2CompatibleState (const char* data, int size)
{
const int headerLen = htonl (*(juce::int32*) (data + 4));
const struct fxBank* bank = (const struct fxBank*) (data + (8 + headerLen));
const int version = htonl (bank->version);
jassert ('VstW' == htonl (*(juce::int32*) data));
jassert (1 == htonl (*(juce::int32*) (data + 8))); // version should be 1 according to Steinberg's docs
jassert (cMagic == htonl (bank->chunkMagic));
jassert (chunkBankMagic == htonl (bank->fxMagic));
jassert (version == 1 || version == 2);
jassert (JucePlugin_VSTUniqueID == htonl (bank->fxID));
pluginInstance->setStateInformation (bank->content.data.chunk,
jmin ((int) (size - (bank->content.data.chunk - data)),
(int) htonl (bank->content.data.size)));
}
#endif
bool readFromMemoryStream (IBStream* state) const
bool readFromMemoryStream (IBStream* state)
{
FUnknownPtr<MemoryStream> s (state);
@@ -767,14 +804,19 @@ public:
if (s->getSize() >= 5 && memcmp (s->getData(), "VC2!E", 5) == 0)
return false;
#if JUCE_VST3_CAN_REPLACE_VST2
loadVST2CompatibleState (s->getData(), (int) s->getSize());
#else
pluginInstance->setStateInformation (s->getData(), (int) s->getSize());
#endif
return true;
}
return false;
}
bool readFromUnknownStream (IBStream* state) const
bool readFromUnknownStream (IBStream* state)
{
MemoryOutputStream allData;
@@ -821,16 +863,58 @@ public:
return kResultFalse;
}
#if JUCE_VST3_CAN_REPLACE_VST2
static tresult writeVST2Int (IBStream* state, int n)
{
juce::int32 t = (juce::int32) htonl (n);
return state->write (&t, 4);
}
static tresult writeVST2Header (IBStream* state)
{
tresult status = writeVST2Int (state, 'VstW');
if (status == kResultOk) status = writeVST2Int (state, 8); // header size
if (status == kResultOk) status = writeVST2Int (state, 1); // version
if (status == kResultOk) status = writeVST2Int (state, 0); // bypass
return status;
}
#endif
tresult PLUGIN_API getState (IBStream* state) override
{
if (state != nullptr)
{
juce::MemoryBlock mem;
pluginInstance->getStateInformation (mem);
return state->write (mem.getData(), (Steinberg::int32) mem.getSize());
}
if (state == nullptr)
return kInvalidArgument;
return kInvalidArgument;
juce::MemoryBlock mem;
pluginInstance->getStateInformation (mem);
#if JUCE_VST3_CAN_REPLACE_VST2
tresult status = writeVST2Header (state);
if (status != kResultOk)
return status;
const int bankBlockSize = 160;
struct fxBank bank;
zerostruct (bank);
bank.chunkMagic = htonl (cMagic);
bank.byteSize = htonl (bankBlockSize - 8 + mem.getSize());
bank.fxMagic = htonl (chunkBankMagic);
bank.version = htonl (2);
bank.fxID = htonl (JucePlugin_VSTUniqueID);
bank.fxVersion = htonl (JucePlugin_VersionCode);
bank.content.data.size = htonl (mem.getSize());
status = state->write (&bank, bankBlockSize);
if (status != kResultOk)
return status;
#endif
return state->write (mem.getData(), (Steinberg::int32) mem.getSize());
}
//==============================================================================
@@ -1241,11 +1325,50 @@ private:
DECLARE_CLASS_IID (JuceAudioProcessor, 0x0101ABAB, 0xABCDEF01, JucePlugin_ManufacturerCode, JucePlugin_PluginCode)
DEF_CLASS_IID (JuceAudioProcessor)
DECLARE_CLASS_IID (JuceVST3Component, 0xABCDEF01, 0x9182FAEB, JucePlugin_ManufacturerCode, JucePlugin_PluginCode)
DEF_CLASS_IID (JuceVST3Component)
#if JUCE_VST3_CAN_REPLACE_VST2
// NB: Nasty old-fashioned code in here because it's copied from the Steinberg example code.
static FUID getFUIDForVST2ID (bool forControllerUID)
{
char uidString[33];
const int vstfxid = (('V' << 16) | ('S' << 8) | (forControllerUID ? 'E' : 'T'));
char vstfxidStr[7] = { 0 };
sprintf (vstfxidStr, "%06X", vstfxid);
strcpy (uidString, vstfxidStr);
char uidStr[9] = { 0 };
sprintf (uidStr, "%08X", JucePlugin_VSTUniqueID);
strcat (uidString, uidStr);
char nameidStr[3] = { 0 };
const size_t len = strlen (JucePlugin_Name);
for (size_t i = 0; i <= 8; ++i)
{
juce::uint8 c = i < len ? JucePlugin_Name[i] : 0;
if (c >= 'A' && c <= 'Z')
c += 'a' - 'A';
DECLARE_CLASS_IID (JuceVST3EditController, 0xABCDEF01, 0x1234ABCD, JucePlugin_ManufacturerCode, JucePlugin_PluginCode)
DEF_CLASS_IID (JuceVST3EditController)
sprintf (nameidStr, "%02X", c);
strcat (uidString, nameidStr);
}
FUID newOne;
newOne.fromString (uidString);
return newOne;
}
const Steinberg::FUID JuceVST3Component ::iid (getFUIDForVST2ID (false));
const Steinberg::FUID JuceVST3EditController::iid (getFUIDForVST2ID (true));
#else
DECLARE_CLASS_IID (JuceVST3EditController, 0xABCDEF01, 0x1234ABCD, JucePlugin_ManufacturerCode, JucePlugin_PluginCode)
DEF_CLASS_IID (JuceVST3EditController)
DECLARE_CLASS_IID (JuceVST3Component, 0xABCDEF01, 0x9182FAEB, JucePlugin_ManufacturerCode, JucePlugin_PluginCode)
DEF_CLASS_IID (JuceVST3Component)
#endif
#if JUCE_MSVC
#pragma warning (pop)


Loading…
Cancel
Save