From 090ee032746321c5557d4559d2d44d3899720a41 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 25 Sep 2021 11:29:36 +0100 Subject: [PATCH] VST3: implement parameter outputs and triggers, UI focus Signed-off-by: falkTX --- dgl/src/Window.cpp | 16 ------ distrho/src/DistrhoPluginInternal.hpp | 8 +++ distrho/src/DistrhoPluginVST2.cpp | 2 +- distrho/src/DistrhoPluginVST3.cpp | 79 +++++++++++++++++++++++++-- distrho/src/DistrhoUIInternal.hpp | 11 +++- distrho/src/DistrhoUIVST3.cpp | 30 ++++++---- 6 files changed, 110 insertions(+), 36 deletions(-) diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index 79538e07..6f2a7dad 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -407,22 +407,6 @@ void Window::setTransientWinId(const uintptr_t winId) { puglSetTransientFor(pData->view, winId); } - -// ----------------------------------------------------------------------- - -bool Window::handlePluginKeyboard(const bool press, const uint key) -{ - // TODO - return false; - // return pData->handlePluginKeyboard(press, key); -} - -bool Window::handlePluginSpecial(const bool press, const Key key) -{ - // TODO - return false; - // return pData->handlePluginSpecial(press, key); -} #endif // ----------------------------------------------------------------------- diff --git a/distrho/src/DistrhoPluginInternal.hpp b/distrho/src/DistrhoPluginInternal.hpp index 7d2a89d8..202887ce 100644 --- a/distrho/src/DistrhoPluginInternal.hpp +++ b/distrho/src/DistrhoPluginInternal.hpp @@ -610,6 +610,14 @@ public: return fData->parameters[index].groupId; } + float getParameterDefault(const uint32_t index) const + { + DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f); + DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, 0.0f); + + return fData->parameters[index].ranges.def; + } + float getParameterValue(const uint32_t index) const { DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr, 0.0f); diff --git a/distrho/src/DistrhoPluginVST2.cpp b/distrho/src/DistrhoPluginVST2.cpp index 824327a9..841dab42 100644 --- a/distrho/src/DistrhoPluginVST2.cpp +++ b/distrho/src/DistrhoPluginVST2.cpp @@ -370,7 +370,7 @@ public: } } - fUI.handlePluginKeyboard(down, static_cast(index), fKeyboardModifiers); + fUI.handlePluginKeyboardVST2(down, static_cast(index), fKeyboardModifiers); if (needsShiftRevert) fKeyboardModifiers &= ~kModifierShift; diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp index fff9fe40..a4cffbb2 100644 --- a/distrho/src/DistrhoPluginVST3.cpp +++ b/distrho/src/DistrhoPluginVST3.cpp @@ -219,7 +219,8 @@ public: PluginVst3() : fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback), fComponentHandler(nullptr), - fComponentHandlerArg(nullptr) + fComponentHandlerArg(nullptr), + fParameterValues(nullptr) #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT , fHostEventOutputHandle(nullptr) #endif @@ -288,6 +289,23 @@ public: port.busId = 0; } #endif + + if (const uint32_t parameterCount = fPlugin.getParameterCount()) + { + fParameterValues = new float[parameterCount]; + + for (uint32_t i=0; i < parameterCount; ++i) + fParameterValues[i] = fPlugin.getParameterDefault(i); + } + } + + ~PluginVst3() + { + if (fParameterValues != nullptr) + { + delete[] fParameterValues; + fParameterValues = nullptr; + } } // ---------------------------------------------------------------------------------------------------------------- @@ -842,6 +860,12 @@ public: } #endif + if (data->nframes <= 0) + { + updateParameterOutputsAndTriggers(); + return V3_OK; + } + const float* inputs[DISTRHO_PLUGIN_NUM_INPUTS != 0 ? DISTRHO_PLUGIN_NUM_INPUTS : 1]; /* */ float* outputs[DISTRHO_PLUGIN_NUM_OUTPUTS != 0 ? DISTRHO_PLUGIN_NUM_OUTPUTS : 1]; @@ -962,8 +986,7 @@ public: fHostEventOutputHandle = nullptr; #endif - // TODO updateParameterOutputsAndTriggers() - + updateParameterOutputsAndTriggers(); return V3_OK; } @@ -1130,6 +1153,7 @@ private: void* fComponentHandlerArg; // Temporary data + float* fParameterValues; #if DISTRHO_PLUGIN_WANT_MIDI_INPUT MidiEvent fMidiEvents[kMaxMidiEvents]; #endif @@ -1140,7 +1164,47 @@ private: TimePosition fTimePosition; #endif -#if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST + // ---------------------------------------------------------------------------------------------------------------- + // 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 VST3, simulate it here + curValue = fPlugin.getParameterValue(i); + + if (d_isEqual(curValue, fParameterValues[i])) + continue; + + fParameterValues[i] = curValue; + } + 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.getParameterDefault(i))) + continue; + + fPlugin.setParameterValue(i, curValue); + } + else + { + continue; + } + + requestParameterValueChange(i, curValue); + } + } + + // ---------------------------------------------------------------------------------------------------------------- + // DPF callbacks + bool requestParameterValueChange(const uint32_t index, const float value) { DISTRHO_SAFE_ASSERT_RETURN(fComponentHandler != nullptr, false); @@ -1156,6 +1220,7 @@ private: return ret; } +#if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST static bool requestParameterValueChangeCallback(void* const ptr, const uint32_t index, const float value) { return ((PluginVst3*)ptr)->requestParameterValueChange(index, value); @@ -1418,7 +1483,8 @@ struct dpf_edit_controller : v3_edit_controller_cpp { controller.get_parameter_string_for_value = []V3_API(void* self, v3_param_id index, double normalised, v3_str_128 output) -> v3_result { - d_stdout("dpf_edit_controller::get_parameter_string_for_value => %p %u %f %p", self, index, normalised, output); + // NOTE very noisy, called many times + // d_stdout("dpf_edit_controller::get_parameter_string_for_value => %p %u %f %p", self, index, normalised, output); dpf_edit_controller* const controller = *(dpf_edit_controller**)self; DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_NOT_INITIALISED); @@ -1466,7 +1532,8 @@ struct dpf_edit_controller : v3_edit_controller_cpp { controller.get_parameter_normalised = []V3_API(void* self, v3_param_id index) -> double { - d_stdout("dpf_edit_controller::get_parameter_normalised => %p", self); + // NOTE very noisy, called many times + // d_stdout("dpf_edit_controller::get_parameter_normalised => %p", self); dpf_edit_controller* const controller = *(dpf_edit_controller**)self; DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, 0.0); diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp index 232fdb66..46de9858 100644 --- a/distrho/src/DistrhoUIInternal.hpp +++ b/distrho/src/DistrhoUIInternal.hpp @@ -258,7 +258,7 @@ public: } #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI - bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) + bool handlePluginKeyboardVST2(const bool press, const uint key, const uint16_t mods) { DGL_NAMESPACE::Widget::KeyboardEvent ev; ev.mod = mods; @@ -289,6 +289,15 @@ public: ui->uiScaleFactorChanged(scaleFactor); } +#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI + void notifyFocusChanged(const bool focus) + { + DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); + + ui->uiFocus(focus, DGL_NAMESPACE::kCrossingNormal); + } +#endif + void setSampleRate(const double sampleRate, const bool doCallback = false) { DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); diff --git a/distrho/src/DistrhoUIVST3.cpp b/distrho/src/DistrhoUIVST3.cpp index c80fe154..3d9d484c 100644 --- a/distrho/src/DistrhoUIVST3.cpp +++ b/distrho/src/DistrhoUIVST3.cpp @@ -16,12 +16,6 @@ #include "DistrhoUIInternal.hpp" -#include "travesty/audio_processor.h" -#include "travesty/component.h" -#include "travesty/edit_controller.h" -#include "travesty/factory.h" -#include "travesty/view.h" - #include // TESTING awful idea dont reuse @@ -44,6 +38,12 @@ # include "DistrhoUIInternal.hpp" // #endif +#include "travesty/audio_processor.h" +#include "travesty/component.h" +#include "travesty/edit_controller.h" +#include "travesty/factory.h" +#include "travesty/view.h" + // -------------------------------------------------------------------------------------------------------------------- START_NAMESPACE_DISTRHO @@ -209,10 +209,16 @@ public: return V3_NOT_IMPLEMENTED; } - v3_result onFocus(const bool /*state*/) + v3_result onFocus(const bool state) { - // TODO +#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI + fUI.notifyFocusChanged(state); + return V3_OK; +#else return V3_NOT_IMPLEMENTED; + // unused + (void)state; +#endif } v3_result setFrame(v3_plugin_frame* const frame, void* const arg) noexcept @@ -692,11 +698,11 @@ struct dpf_plugin_view : v3_plugin_view_cpp { view.can_resize = []V3_API(void* self) -> v3_result { d_stdout("dpf_plugin_view::can_resize => %p", self); -#if DISTRHO_UI_USER_RESIZABLE - return V3_OK; -#else +// #if DISTRHO_UI_USER_RESIZABLE +// return V3_OK; +// #else return V3_NOT_IMPLEMENTED; -#endif +// #endif }; view.check_size_constraint = []V3_API(void* self, v3_view_rect* rect) -> v3_result