Browse Source

Implement triggers in all formats; Allow VST to use param outputs

pull/61/head
falkTX 6 years ago
parent
commit
5f65434e57
6 changed files with 135 additions and 45 deletions
  1. +5
    -2
      distrho/DistrhoPlugin.hpp
  2. +19
    -0
      distrho/src/DistrhoPluginJack.cpp
  3. +24
    -8
      distrho/src/DistrhoPluginLADSPA+DSSI.cpp
  4. +14
    -10
      distrho/src/DistrhoPluginLV2.cpp
  5. +4
    -0
      distrho/src/DistrhoPluginLV2export.cpp
  6. +69
    -25
      distrho/src/DistrhoPluginVST.cpp

+ 5
- 2
distrho/DistrhoPlugin.hpp View File

@@ -90,8 +90,11 @@ static const uint32_t kParameterIsLogarithmic = 0x08;
static const uint32_t kParameterIsOutput = 0x10; static const uint32_t kParameterIsOutput = 0x10;


/** /**
Parameter value is a trigger.
@note Cannot be used for output parameters
Parameter value is a trigger.@n
This means the value resets back to its default after each process/run call.@n
Cannot be used for output parameters.

@note Only officially supported under LV2. For other formats DPF simulates the behaviour.
*/ */
static const uint32_t kParameterIsTrigger = 0x20 | kParameterIsBoolean; static const uint32_t kParameterIsTrigger = 0x20 | kParameterIsBoolean;




+ 19
- 0
distrho/src/DistrhoPluginJack.cpp View File

@@ -430,6 +430,8 @@ protected:
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fPortMidiOutBuffer = nullptr; fPortMidiOutBuffer = nullptr;
#endif #endif

updateParameterTriggers();
} }


void jackShutdown() void jackShutdown()
@@ -474,6 +476,23 @@ protected:
} }
#endif #endif


// NOTE: no trigger support for JACK, simulate it here
void updateParameterTriggers()
{
float defValue;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) != kParameterIsTrigger)
continue;

defValue = fPlugin.getParameterRanges(i).def;

if (d_isNotEqual(defValue, fPlugin.getParameterValue(i)))
fPlugin.setParameterValue(i, defValue);
}
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------


private: private:


+ 24
- 8
distrho/src/DistrhoPluginLADSPA+DSSI.cpp View File

@@ -175,7 +175,7 @@ public:
{ {
// pre-roll // pre-roll
if (sampleCount == 0) if (sampleCount == 0)
return updateParameterOutputs();
return updateParameterOutputsAndTriggers();


// Check for updated parameters // Check for updated parameters
float curValue; float curValue;
@@ -272,7 +272,7 @@ public:
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount);
#endif #endif


updateParameterOutputs();
updateParameterOutputsAndTriggers();


#if defined(DISTRHO_PLUGIN_TARGET_DSSI) && ! DISTRHO_PLUGIN_WANT_MIDI_INPUT #if defined(DISTRHO_PLUGIN_TARGET_DSSI) && ! DISTRHO_PLUGIN_WANT_MIDI_INPUT
return; // unused return; // unused
@@ -375,17 +375,33 @@ private:


// ------------------------------------------------------------------- // -------------------------------------------------------------------


void updateParameterOutputs()
void updateParameterOutputsAndTriggers()
{ {
float value;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i) for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{ {
if (! fPlugin.isParameterOutput(i))
continue;
if (fPlugin.isParameterOutput(i))
{
value = fLastControlValues[i] = fPlugin.getParameterValue(i);


fLastControlValues[i] = fPlugin.getParameterValue(i);
if (fPortControls[i] != nullptr)
*fPortControls[i] = value;
}
else if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) == kParameterIsTrigger)
{
// NOTE: no trigger support in LADSPA control ports, simulate it here
const float value = fPlugin.getParameterRanges(i).def;


if (fPortControls[i] != nullptr)
*fPortControls[i] = fLastControlValues[i];
if (d_isEqual(value, fPlugin.getParameterValue(i)))
continue;

fLastControlValues[i] = value;
fPlugin.setParameterValue(i, value);

if (fPortControls[i] != nullptr)
*fPortControls[i] = value;
}
} }


#if DISTRHO_PLUGIN_WANT_LATENCY #if DISTRHO_PLUGIN_WANT_LATENCY


+ 14
- 10
distrho/src/DistrhoPluginLV2.cpp View File

@@ -524,9 +524,7 @@ public:
fLastControlValues[i] = curValue; fLastControlValues[i] = curValue;


if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass) if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass)
{
curValue = 1.0f - curValue; curValue = 1.0f - curValue;
}


fPlugin.setParameterValue(i, curValue); fPlugin.setParameterValue(i, curValue);
} }
@@ -609,7 +607,7 @@ public:
#endif #endif
} }


updateParameterOutputs();
updateParameterOutputsAndTriggers();


#if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI
fEventsOutData.initIfNeeded(fURIDs.atomSequence); fEventsOutData.initIfNeeded(fURIDs.atomSequence);
@@ -1032,17 +1030,23 @@ private:
} }
#endif #endif


void updateParameterOutputs()
void updateParameterOutputsAndTriggers()
{ {
float curValue;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i) for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{ {
if (! fPlugin.isParameterOutput(i))
continue;

fLastControlValues[i] = fPlugin.getParameterValue(i);
if (fPlugin.isParameterOutput(i))
{
curValue = fLastControlValues[i] = fPlugin.getParameterValue(i);


if (fPortControls[i] != nullptr)
*fPortControls[i] = fLastControlValues[i];
if (fPortControls[i] != nullptr)
*fPortControls[i] = curValue;
}
else if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) == kParameterIsTrigger)
{
// NOTE: host is responsible for auto-updating control port buffers
}
} }


#if DISTRHO_PLUGIN_WANT_LATENCY #if DISTRHO_PLUGIN_WANT_LATENCY


+ 4
- 0
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -522,7 +522,11 @@ void lv2_generate_ttl(const char* const basename)
const uint32_t hints(plugin.getParameterHints(i)); const uint32_t hints(plugin.getParameterHints(i));


if (hints & kParameterIsBoolean) if (hints & kParameterIsBoolean)
{
if ((hints & kParameterIsTrigger) == kParameterIsTrigger)
pluginString += " lv2:portProperty <" LV2_PORT_PROPS__trigger "> ;\n";
pluginString += " lv2:portProperty lv2:toggled ;\n"; pluginString += " lv2:portProperty lv2:toggled ;\n";
}
if (hints & kParameterIsInteger) if (hints & kParameterIsInteger)
pluginString += " lv2:portProperty lv2:integer ;\n"; pluginString += " lv2:portProperty lv2:integer ;\n";
if (hints & kParameterIsLogarithmic) if (hints & kParameterIsLogarithmic)


+ 69
- 25
distrho/src/DistrhoPluginVST.cpp View File

@@ -94,17 +94,16 @@ void snprintf_iparam(char* const dst, const int32_t value, const size_t size)
dst[size-1] = '\0'; dst[size-1] = '\0';
} }


#if DISTRHO_PLUGIN_HAS_UI
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class UiHelper
class ParameterCheckHelper
{ {
public: public:
UiHelper()
ParameterCheckHelper()
: parameterChecks(nullptr), : parameterChecks(nullptr),
parameterValues(nullptr) {} parameterValues(nullptr) {}


virtual ~UiHelper()
virtual ~ParameterCheckHelper()
{ {
if (parameterChecks != nullptr) if (parameterChecks != nullptr)
{ {
@@ -121,17 +120,18 @@ public:
bool* parameterChecks; bool* parameterChecks;
float* parameterValues; float* parameterValues;


# if DISTRHO_PLUGIN_WANT_STATE
#if DISTRHO_PLUGIN_WANT_STATE
virtual void setStateFromUI(const char* const newKey, const char* const newValue) = 0; virtual void setStateFromUI(const char* const newKey, const char* const newValue) = 0;
# endif
#endif
}; };


#if DISTRHO_PLUGIN_HAS_UI
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class UIVst class UIVst
{ {
public: public:
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, UiHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId)
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, ParameterCheckHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId)
: fAudioMaster(audioMaster), : fAudioMaster(audioMaster),
fEffect(effect), fEffect(effect),
fUiHelper(uiHelper), fUiHelper(uiHelper),
@@ -306,7 +306,7 @@ private:
// Vst stuff // Vst stuff
const audioMasterCallback fAudioMaster; const audioMasterCallback fAudioMaster;
AEffect* const fEffect; AEffect* const fEffect;
UiHelper* const fUiHelper;
ParameterCheckHelper* const fUiHelper;
PluginExporter* const fPlugin; PluginExporter* const fPlugin;


// Plugin UI // Plugin UI
@@ -349,11 +349,7 @@ private:


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


#if DISTRHO_PLUGIN_HAS_UI
class PluginVst : public UiHelper
#else
class PluginVst
#endif
class PluginVst : public ParameterCheckHelper
{ {
public: public:
PluginVst(const audioMasterCallback audioMaster, AEffect* const effect) PluginVst(const audioMasterCallback audioMaster, AEffect* const effect)
@@ -383,7 +379,7 @@ public:
for (uint32_t i=0; i < paramCount; ++i) for (uint32_t i=0; i < paramCount; ++i)
{ {
parameterChecks[i] = false; parameterChecks[i] = false;
parameterValues[i] = 0.0f;
parameterValues[i] = NAN;
} }
} }
# if DISTRHO_OS_MAC # if DISTRHO_OS_MAC
@@ -823,7 +819,10 @@ public:
void vst_processReplacing(const float** const inputs, float** const outputs, const int32_t sampleFrames) void vst_processReplacing(const float** const inputs, float** const outputs, const int32_t sampleFrames)
{ {
if (sampleFrames <= 0) if (sampleFrames <= 0)
{
updateParameterOutputsAndTriggers();
return; return;
}


if (! fPlugin.isActive()) if (! fPlugin.isActive())
{ {
@@ -882,16 +881,7 @@ public:
fPlugin.run(inputs, outputs, sampleFrames); fPlugin.run(inputs, outputs, sampleFrames);
#endif #endif


#if DISTRHO_PLUGIN_HAS_UI
if (fVstUI == nullptr)
return;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (fPlugin.isParameterOutput(i))
setParameterValueFromPlugin(i, fPlugin.getParameterValue(i));
}
#endif
updateParameterOutputsAndTriggers();
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -947,6 +937,56 @@ private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// functions called from the plugin side, RT no block // functions called from the plugin side, RT no block


void updateParameterOutputsAndTriggers()
{
float curValue;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (fPlugin.isParameterOutput(i))
{
// NOTE: no output parameter support in VST, simulate it here
curValue = fPlugin.getParameterValue(i);

if (d_isEqual(curValue, parameterValues[i]))
continue;

#if DISTRHO_PLUGIN_HAS_UI
if (fVstUI != nullptr)
setParameterValueFromPlugin(i, curValue);
else
#endif
parameterValues[i] = curValue;

#ifndef DPF_VST_SHOW_PARAMETER_OUTPUTS
// skip automating parameter outputs from plugin if we disable them on VST
continue;
#endif
}
else if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) == kParameterIsTrigger)
{
// NOTE: no trigger support in VST parameters, simulate it here
curValue = fPlugin.getParameterValue(i);

if (d_isEqual(curValue, fPlugin.getParameterRanges(i).def))
continue;

#if DISTRHO_PLUGIN_HAS_UI
if (fVstUI != nullptr)
setParameterValueFromPlugin(i, curValue);
#endif
fPlugin.setParameterValue(i, curValue);
}
else
{
continue;
}

const ParameterRanges& ranges(fPlugin.getParameterRanges(i));
hostCallback(audioMasterAutomate, i, 0, nullptr, ranges.getNormalizedValue(curValue));
}
}

#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
void setParameterValueFromPlugin(const uint32_t index, const float realValue) void setParameterValueFromPlugin(const uint32_t index, const float realValue)
{ {
@@ -1282,7 +1322,10 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
effect->version = plugin->getVersion(); effect->version = plugin->getVersion();
#endif #endif


// VST doesn't support parameter outputs, hide them
// VST doesn't support parameter outputs. we can fake them, but it is a hack. Disabled by default.
#ifdef DPF_VST_SHOW_PARAMETER_OUTPUTS
const int numParams = plugin->getParameterCount();
#else
int numParams = 0; int numParams = 0;
bool outputsReached = false; bool outputsReached = false;


@@ -1297,6 +1340,7 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
} }
outputsReached = true; outputsReached = true;
} }
#endif


// plugin fields // plugin fields
effect->numParams = numParams; effect->numParams = numParams;


Loading…
Cancel
Save