mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Add program change parameter to VST-3 plug-ins
This commit is contained in:
parent
fc69dc00db
commit
8cd6f49ea0
1 changed files with 108 additions and 17 deletions
|
|
@ -81,12 +81,6 @@ using namespace Steinberg;
|
|||
extern JUCE_API void setNativeHostWindowSizeVST (void* window, Component*, int newWidth, int newHeight, bool isNSView);
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
kJuceVST3BypassParamID = 0x62797073, // 'byps'
|
||||
kMidiControllerMappingsStartID = 0x6d636d00 // 'mdm*'
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class JuceAudioProcessor : public FUnknown
|
||||
{
|
||||
|
|
@ -197,6 +191,13 @@ public:
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
enum InternalParameters
|
||||
{
|
||||
paramPreset = 0x70727374, // 'prst'
|
||||
paramBypass = 0x62797073, // 'byps'
|
||||
paramMidiControllerOffset = 0x6d636d00 // 'mdm*'
|
||||
};
|
||||
|
||||
struct Param : public Vst::Parameter
|
||||
{
|
||||
Param (AudioProcessor& p, int index, Vst::ParamID paramID) : owner (p), paramIndex (index)
|
||||
|
|
@ -350,6 +351,79 @@ public:
|
|||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BypassParam)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
struct ProgramChangeParameter : public Vst::Parameter
|
||||
{
|
||||
ProgramChangeParameter (AudioProcessor& p) : owner (p)
|
||||
{
|
||||
jassert (owner.getNumPrograms() > 1);
|
||||
|
||||
info.id = paramPreset;
|
||||
toString128 (info.title, "Program");
|
||||
toString128 (info.shortTitle, "Program");
|
||||
toString128 (info.units, "");
|
||||
info.stepCount = owner.getNumPrograms() - 1;
|
||||
info.defaultNormalizedValue = static_cast<Vst::ParamValue> (owner.getCurrentProgram()) / static_cast<Vst::ParamValue> (info.stepCount);
|
||||
info.unitId = Vst::kRootUnitId;
|
||||
info.flags = Vst::ParameterInfo::kIsProgramChange | Vst::ParameterInfo::kCanAutomate;
|
||||
}
|
||||
|
||||
virtual ~ProgramChangeParameter() {}
|
||||
|
||||
bool setNormalized (Vst::ParamValue v) override
|
||||
{
|
||||
Vst::ParamValue program = v * info.stepCount;
|
||||
|
||||
if (! isPositiveAndBelow ((int) program, owner.getNumPrograms()))
|
||||
return false;
|
||||
|
||||
if (valueNormalized != v)
|
||||
{
|
||||
valueNormalized = v;
|
||||
changed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void toString (Vst::ParamValue value, Vst::String128 result) const override
|
||||
{
|
||||
Vst::ParamValue program = value * info.stepCount;
|
||||
toString128 (result, owner.getProgramName ((int) program));
|
||||
}
|
||||
|
||||
bool fromString (const Vst::TChar* text, Vst::ParamValue& outValueNormalized) const override
|
||||
{
|
||||
const String paramValueString (getStringFromVstTChars (text));
|
||||
|
||||
const int n = owner.getNumPrograms();
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (paramValueString == owner.getProgramName (i))
|
||||
{
|
||||
outValueNormalized = static_cast<Vst::ParamValue> (i) / info.stepCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static String getStringFromVstTChars (const Vst::TChar* text)
|
||||
{
|
||||
return juce::String (juce::CharPointer_UTF16 (reinterpret_cast<const juce::CharPointer_UTF16::CharType*> (text)));
|
||||
}
|
||||
|
||||
Vst::ParamValue toPlain (Vst::ParamValue v) const override { return v * info.stepCount; }
|
||||
Vst::ParamValue toNormalized (Vst::ParamValue v) const override { return v / info.stepCount; }
|
||||
|
||||
private:
|
||||
AudioProcessor& owner;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramChangeParameter)
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
tresult PLUGIN_API setComponentState (IBStream* stream) override
|
||||
{
|
||||
|
|
@ -362,6 +436,10 @@ public:
|
|||
setParamNormalized (getVSTParamIDForIndex (i), (double) pluginInstance->getParameter (i));
|
||||
|
||||
setParamNormalized (bypassParamID, audioProcessor->isBypassed ? 1.0f : 0.0f);
|
||||
|
||||
const int numPrograms = pluginInstance->getNumPrograms();
|
||||
if (numPrograms > 1)
|
||||
setParamNormalized (paramPreset, static_cast<Vst::ParamValue> (pluginInstance->getCurrentProgram()) / static_cast<Vst::ParamValue> (numPrograms - 1));
|
||||
}
|
||||
|
||||
return Vst::EditController::setComponentState (stream);
|
||||
|
|
@ -459,6 +537,13 @@ public:
|
|||
|
||||
void audioProcessorChanged (AudioProcessor*) override
|
||||
{
|
||||
if (AudioProcessor* pluginInstance = getPluginInstance())
|
||||
{
|
||||
if (pluginInstance->getNumPrograms() > 1)
|
||||
EditController::setParamNormalized (paramPreset, static_cast<Vst::ParamValue> (pluginInstance->getCurrentProgram())
|
||||
/ static_cast<Vst::ParamValue> (pluginInstance->getNumPrograms() - 1));
|
||||
}
|
||||
|
||||
if (componentHandler != nullptr)
|
||||
componentHandler->restartComponent (Vst::kLatencyChanged | Vst::kParamValuesChanged);
|
||||
}
|
||||
|
|
@ -531,12 +616,15 @@ private:
|
|||
parameters.addParameter (new Param (*pluginInstance, i, vstParamID));
|
||||
}
|
||||
|
||||
bypassParamID = static_cast<Vst::ParamID> (usingManagedParameter ? kJuceVST3BypassParamID : numParameters);
|
||||
bypassParamID = static_cast<Vst::ParamID> (usingManagedParameter ? paramBypass : numParameters);
|
||||
parameters.addParameter (new BypassParam (*pluginInstance, bypassParamID));
|
||||
|
||||
if (pluginInstance->getNumPrograms() > 1)
|
||||
parameters.addParameter (new ProgramChangeParameter (*pluginInstance));
|
||||
}
|
||||
|
||||
#if JUCE_VST3_EMULATE_MIDI_CC_WITH_PARAMETERS
|
||||
parameterToMidiControllerOffset = static_cast<Vst::ParamID> (usingManagedParameter ? kMidiControllerMappingsStartID
|
||||
parameterToMidiControllerOffset = static_cast<Vst::ParamID> (usingManagedParameter ? paramMidiControllerOffset
|
||||
: parameters.getParameterCount());
|
||||
|
||||
initialiseMidiControllerMappings ();
|
||||
|
|
@ -1357,7 +1445,7 @@ public:
|
|||
{
|
||||
if (listIndex == 0)
|
||||
{
|
||||
info.id = paramPreset;
|
||||
info.id = JuceVST3EditController::paramPreset;
|
||||
info.programCount = (Steinberg::int32) getPluginInstance().getNumPrograms();
|
||||
|
||||
toString128 (info.name, TRANS("Factory Presets"));
|
||||
|
|
@ -1372,7 +1460,7 @@ public:
|
|||
|
||||
tresult PLUGIN_API getProgramName (Vst::ProgramListID listId, Steinberg::int32 programIndex, Vst::String128 name) override
|
||||
{
|
||||
if (listId == paramPreset
|
||||
if (listId == JuceVST3EditController::paramPreset
|
||||
&& isPositiveAndBelow ((int) programIndex, getPluginInstance().getNumPrograms()))
|
||||
{
|
||||
toString128 (name, getPluginInstance().getProgramName ((int) programIndex));
|
||||
|
|
@ -1722,6 +1810,15 @@ public:
|
|||
else if (juceVST3EditController->isMidiControllerParamID (vstParamID))
|
||||
addParameterChangeToMidiBuffer (offsetSamples, vstParamID, value);
|
||||
#endif
|
||||
else if (vstParamID == JuceVST3EditController::paramPreset)
|
||||
{
|
||||
const int numPrograms = pluginInstance->getNumPrograms();
|
||||
const int programValue = static_cast<int> (std::round (value * static_cast<Vst::ParamValue> (numPrograms)));
|
||||
|
||||
if (numPrograms > 1 && isPositiveAndBelow (programValue, numPrograms)
|
||||
&& programValue != pluginInstance->getCurrentProgram())
|
||||
pluginInstance->setCurrentProgram (programValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int index = getJuceIndexForVSTParamID (vstParamID);
|
||||
|
|
@ -1972,12 +2069,6 @@ private:
|
|||
return AudioBusPointerHelper<FloatType>::impl (data);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
enum InternalParameters
|
||||
{
|
||||
paramPreset = 'prst'
|
||||
};
|
||||
|
||||
void preparePlugin (double sampleRate, int bufferSize)
|
||||
{
|
||||
AudioProcessor& p = getPluginInstance();
|
||||
|
|
@ -1996,7 +2087,7 @@ private:
|
|||
const int numParameters = pluginInstance->getNumParameters();
|
||||
usingManagedParameter = (pluginInstance->getParameters().size() == numParameters);
|
||||
|
||||
vstBypassParameterId = static_cast<Vst::ParamID> (usingManagedParameter ? kJuceVST3BypassParamID : numParameters);
|
||||
vstBypassParameterId = static_cast<Vst::ParamID> (usingManagedParameter ? JuceVST3EditController::paramBypass : numParameters);
|
||||
|
||||
for (int i = 0; i < numParameters; ++i)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue