commit 4645f65e9610262aff8ed8db0537ec7743bf6658
parent 80824ae66632dddbbfa7484ddd6e9afe934c28d2
Author: falkTX <falktx@falktx.com>
Date: Sat, 25 Sep 2021 18:35:55 +0100
VST3: Implement UI->DSP parameter changes
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
6 files changed, 112 insertions(+), 68 deletions(-)
diff --git a/distrho/src/DistrhoPluginInternal.hpp b/distrho/src/DistrhoPluginInternal.hpp
@@ -171,6 +171,12 @@ struct Plugin::PrivateData {
parameterOffset += 1;
# endif
#endif
+
+#ifdef DISTRHO_PLUGIN_TARGET_VST3
+# if DISTRHO_PLUGIN_WANT_PROGRAMS
+ parameterOffset += 1;
+# endif
+#endif
}
~PrivateData() noexcept
diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp
@@ -1048,15 +1048,15 @@ public:
return fPlugin.getParameterCount() + fParameterOffset;
}
- v3_result getParameterInfo(const int32_t index, v3_param_info* const info) const noexcept
+ v3_result getParameterInfo(const int32_t rindex, v3_param_info* const info) const noexcept
{
- DISTRHO_SAFE_ASSERT_RETURN(index >= 0, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_RETURN(rindex >= 0, V3_INVALID_ARG);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
{
std::memset(info, 0, sizeof(v3_param_info));
- info->param_id = index;
+ info->param_id = rindex;
info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_LIST | V3_PARAM_PROGRAM_CHANGE;
info->step_count = fProgramCountMinusOne;
strncpy_utf16(info->title, "Current Program", 128);
@@ -1065,8 +1065,8 @@ public:
}
#endif
- const uint32_t uindex = static_cast<uint32_t>(index) - fParameterOffset;
- DISTRHO_SAFE_ASSERT_RETURN(uindex < fPlugin.getParameterCount(), V3_INVALID_ARG);
+ const uint32_t index = static_cast<uint32_t>(rindex) - fParameterOffset;
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(index < fPlugin.getParameterCount(), index, V3_INVALID_ARG);
// set up flags
int32_t flags = 0;
@@ -1100,7 +1100,7 @@ public:
step_count = ranges.max - ranges.min - 1;
std::memset(info, 0, sizeof(v3_param_info));
- info->param_id = index;
+ info->param_id = rindex;
info->flags = flags;
info->step_count = step_count;
info->default_normalised_value = ranges.getNormalizedValue(ranges.def);
@@ -1111,12 +1111,12 @@ public:
return V3_OK;
}
- v3_result getParameterStringForValue(const v3_param_id index, const double normalised, v3_str_128 output)
+ v3_result getParameterStringForValue(const v3_param_id rindex, const double normalised, v3_str_128 output)
{
- DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(rindex < fPlugin.getParameterCount() + fParameterOffset, rindex, V3_INVALID_ARG);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
{
DISTRHO_SAFE_ASSERT_RETURN(normalised >= 0.0 && normalised <= 1.0, V3_INVALID_ARG);
@@ -1126,17 +1126,17 @@ public:
}
#endif
- const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
+ const ParameterRanges& ranges(fPlugin.getParameterRanges(rindex - fParameterOffset));
snprintf_f32_utf16(output, ranges.getUnnormalizedValue(normalised), 128);
return V3_OK;
}
- v3_result getParameterValueForString(const v3_param_id index, int16_t*, double*)
+ v3_result getParameterValueForString(const v3_param_id rindex, int16_t*, double*)
{
- DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(rindex < fPlugin.getParameterCount() + fParameterOffset, rindex, V3_INVALID_ARG);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
{
// TODO find program index based on name
return V3_NOT_IMPLEMENTED;
@@ -1147,53 +1147,53 @@ public:
return V3_NOT_IMPLEMENTED;
};
- double normalisedParameterToPlain(const v3_param_id index, const double normalised)
+ double normalisedParameterToPlain(const v3_param_id rindex, const double normalised)
{
- DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(rindex < fPlugin.getParameterCount() + fParameterOffset, rindex, 0.0);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
return std::round(normalised * fProgramCountMinusOne);
#endif
- const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
+ const ParameterRanges& ranges(fPlugin.getParameterRanges(rindex - fParameterOffset));
return ranges.getUnnormalizedValue(normalised);
};
- double plainParameterToNormalised(const v3_param_id index, const double plain)
+ double plainParameterToNormalised(const v3_param_id rindex, const double plain)
{
- DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(rindex < fPlugin.getParameterCount() + fParameterOffset, rindex, 0.0);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
return std::max(0.0, std::min(1.0, plain / fProgramCountMinusOne));
#endif
- const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
+ const ParameterRanges& ranges(fPlugin.getParameterRanges(rindex - fParameterOffset));
return ranges.getNormalizedValue(plain);
};
- double getParameterNormalized(const v3_param_id index)
+ double getParameterNormalized(const v3_param_id rindex)
{
- DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, 0.0);
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(rindex < fPlugin.getParameterCount() + fParameterOffset, rindex, 0.0);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
return std::max(0.0, std::min(1.0, (double)fCurrentProgram / fProgramCountMinusOne));
#endif
- const float value = fPlugin.getParameterValue(index);
- const ParameterRanges& ranges(fPlugin.getParameterRanges(index - fParameterOffset));
+ const float value = fPlugin.getParameterValue(rindex - fParameterOffset);
+ const ParameterRanges& ranges(fPlugin.getParameterRanges(rindex - fParameterOffset));
return ranges.getNormalizedValue(value);
}
- v3_result setParameterNormalized(const v3_param_id index, const double value)
+ v3_result setParameterNormalized(const v3_param_id rindex, const double value)
{
- DISTRHO_SAFE_ASSERT_RETURN(index < fPlugin.getParameterCount() + fParameterOffset, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_UINT_RETURN(rindex < fPlugin.getParameterCount() + fParameterOffset, rindex, V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(value >= 0.0 && value <= 1.0, V3_INVALID_ARG);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
- if (index == 0)
+ if (rindex == 0)
{
fCurrentProgram = std::round(value * fProgramCountMinusOne);
fPlugin.loadProgram(fCurrentProgram);
@@ -1201,6 +1201,7 @@ public:
}
#endif
+ const uint32_t index = rindex - fParameterOffset;
const uint32_t hints = fPlugin.getParameterHints(index);
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
@@ -1378,7 +1379,8 @@ private:
// --------------------------------------------------------------------------------------------------------------------
// dpf_plugin_view_create (called from DSP side)
-v3_funknown** dpf_plugin_view_create(void* instancePointer, double sampleRate);
+v3_funknown** dpf_plugin_view_create(v3_edit_controller** controller, v3_component_handler** handler,
+ void* instancePointer, double sampleRate);
#endif
// --------------------------------------------------------------------------------------------------------------------
@@ -1570,7 +1572,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
controller.plain_parameter_to_normalised = []V3_API(void* self, v3_param_id index, double plain) -> double
{
- d_stdout("dpf_edit_controller::plain_parameter_to_normalised => %p %f", self, plain);
+ d_stdout("dpf_edit_controller::plain_parameter_to_normalised => %p %u %f", self, index, plain);
dpf_edit_controller* const controller = *(dpf_edit_controller**)self;
DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_NOT_INITIALISED);
@@ -1583,7 +1585,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
controller.get_parameter_normalised = []V3_API(void* self, v3_param_id index) -> double
{
// NOTE very noisy, called many times
- // d_stdout("dpf_edit_controller::get_parameter_normalised => %p", self);
+ // d_stdout("dpf_edit_controller::get_parameter_normalised => %p %u", self, index);
dpf_edit_controller* const controller = *(dpf_edit_controller**)self;
DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, 0.0);
@@ -1595,7 +1597,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
controller.set_parameter_normalised = []V3_API(void* self, v3_param_id index, double normalised) -> v3_result
{
- d_stdout("dpf_edit_controller::set_parameter_normalised => %p %f", self, normalised);
+ d_stdout("dpf_edit_controller::set_parameter_normalised => %p %u %f", self, index, normalised);
dpf_edit_controller* const controller = *(dpf_edit_controller**)self;
DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_NOT_INITIALISED);
@@ -1637,7 +1639,10 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, nullptr);
#if DISTRHO_PLUGIN_HAS_UI
- return (v3_plugin_view**)dpf_plugin_view_create(vst3->getInstancePointer(), vst3->getSampleRate());
+ return (v3_plugin_view**)dpf_plugin_view_create((v3_edit_controller**)self,
+ controller->handler,
+ vst3->getInstancePointer(),
+ vst3->getSampleRate());
#else
return nullptr;
#endif
diff --git a/distrho/src/DistrhoUIPrivateData.hpp b/distrho/src/DistrhoUIPrivateData.hpp
@@ -332,6 +332,7 @@ struct UI::PrivateData {
parameterOffset += 1;
# endif
#endif
+
#ifdef DISTRHO_PLUGIN_TARGET_VST3
# if DISTRHO_PLUGIN_WANT_PROGRAMS
parameterOffset += 1;
diff --git a/distrho/src/DistrhoUIVST3.cpp b/distrho/src/DistrhoUIVST3.cpp
@@ -74,8 +74,13 @@ const char* tuid2str(const v3_tuid iid);
class UIVst3 : public Thread
{
public:
- UIVst3(const intptr_t winId, const float scaleFactor, const double sampleRate,
- void* const instancePointer, v3_plugin_view** const view)
+ UIVst3(v3_plugin_view** const view,
+ v3_edit_controller** const controller,
+ v3_component_handler** const handler,
+ const intptr_t winId,
+ const float scaleFactor,
+ const double sampleRate,
+ void* const instancePointer)
: fUI(this, winId, sampleRate,
editParameterCallback,
setParameterCallback,
@@ -87,6 +92,8 @@ public:
instancePointer,
scaleFactor),
fView(view),
+ fController(controller),
+ fHandler(handler),
fFrame(nullptr),
fScaleFactor(scaleFactor)
{
@@ -196,41 +203,35 @@ private:
// VST3 stuff
v3_plugin_view** const fView;
+ v3_edit_controller** const fController;
+ v3_component_handler** const fHandler;
v3_plugin_frame** fFrame;
- // v3_component_handler_cpp** handler = nullptr;
// Temporary data
float fScaleFactor;
- void editParameter(const uint32_t /*index*/, const bool /*started*/) const
+ void editParameter(const uint32_t rindex, const bool started) const
{
-// DISTRHO_SAFE_ASSERT_RETURN(handler != nullptr,);
-//
-// v3_component_handler_cpp* const chandler = *handler;
-// DISTRHO_SAFE_ASSERT_RETURN(chandler != nullptr,);
-//
-// if (started)
-// chandler->handler.begin_edit(handler, index);
-// else
-// chandler->handler.end_edit(handler, index);
+ DISTRHO_SAFE_ASSERT_RETURN(fHandler != nullptr,);
+
+ if (started)
+ v3_cpp_obj(fHandler)->begin_edit(fHandler, rindex);
+ else
+ v3_cpp_obj(fHandler)->end_edit(fHandler, rindex);
}
- static void editParameterCallback(void* ptr, uint32_t index, bool started)
+ static void editParameterCallback(void* ptr, uint32_t rindex, bool started)
{
- ((UIVst3*)ptr)->editParameter(index, started);
+ ((UIVst3*)ptr)->editParameter(rindex, started);
}
- void setParameterValue(const uint32_t /*index*/, const float /*realValue*/)
+ void setParameterValue(const uint32_t rindex, const float realValue)
{
-// DISTRHO_SAFE_ASSERT_RETURN(handler != nullptr,);
-//
-// v3_component_handler_cpp* const chandler = *handler;
-// DISTRHO_SAFE_ASSERT_RETURN(chandler != nullptr,);
-
-// const double value = vst3->plainParameterToNormalised(index, realValue);
-// chandler->handler.perform_edit(handler, index, value);
+ DISTRHO_SAFE_ASSERT_RETURN(fController != nullptr,);
+ DISTRHO_SAFE_ASSERT_RETURN(fHandler != nullptr,);
- // TODO send change to DSP side?
+ const double value = v3_cpp_obj(fController)->plain_parameter_to_normalised(fController, rindex, realValue);
+ v3_cpp_obj(fHandler)->perform_edit(fHandler, rindex, value);
}
static void setParameterCallback(void* ptr, uint32_t rindex, float value)
@@ -370,14 +371,22 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
ScopedPointer<dpf_plugin_view_scale> scale;
ScopedPointer<UIVst3> uivst3;
// cached values
+ v3_edit_controller** const controller;
+ v3_component_handler** const handler;
void* const instancePointer;
double sampleRate;
// v3_component_handler_cpp** handler = nullptr;
v3_plugin_frame** frame = nullptr;
- dpf_plugin_view(ScopedPointer<dpf_plugin_view>* s, void* const instance, const double sr)
+ dpf_plugin_view(ScopedPointer<dpf_plugin_view>* selfptr,
+ v3_edit_controller** const controllerptr,
+ v3_component_handler** const handlerptr,
+ void* const instance,
+ const double sr)
: refcounter(1),
- self(s),
+ self(selfptr),
+ controller(controllerptr),
+ handler(handlerptr),
instancePointer(instance),
sampleRate(sr)
{
@@ -481,10 +490,14 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
if (std::strcmp(kSupportedPlatforms[i], platform_type) == 0)
{
const float scaleFactor = view->scale != nullptr ? view->scale->scaleFactor : 0.0f;
- view->uivst3 = new UIVst3((uintptr_t)parent, scaleFactor, view->sampleRate,
- view->instancePointer, (v3_plugin_view**)self);
+ view->uivst3 = new UIVst3((v3_plugin_view**)self,
+ view->controller,
+ view->handler,
+ (uintptr_t)parent,
+ scaleFactor,
+ view->sampleRate,
+ view->instancePointer);
view->uivst3->setFrame(view->frame);
- // view->uivst3->setHandler(view->handler);
return V3_OK;
}
}
@@ -623,12 +636,14 @@ struct dpf_plugin_view : v3_plugin_view_cpp {
// --------------------------------------------------------------------------------------------------------------------
// dpf_plugin_view_create (called from plugin side)
-v3_funknown** dpf_plugin_view_create(void* instancePointer, double sampleRate);
+v3_funknown** dpf_plugin_view_create(v3_edit_controller** controller, v3_component_handler** handler,
+ void* instancePointer, double sampleRate);
-v3_funknown** dpf_plugin_view_create(void* const instancePointer, const double sampleRate)
+v3_funknown** dpf_plugin_view_create(v3_edit_controller** const controller, v3_component_handler** const handler,
+ void* const instancePointer, const double sampleRate)
{
ScopedPointer<dpf_plugin_view>* const viewptr = new ScopedPointer<dpf_plugin_view>;
- *viewptr = new dpf_plugin_view(viewptr, instancePointer, sampleRate);
+ *viewptr = new dpf_plugin_view(viewptr, controller, handler, instancePointer, sampleRate);
return (v3_funknown**)viewptr;
}
diff --git a/distrho/src/travesty/base.h b/distrho/src/travesty/base.h
@@ -28,7 +28,11 @@
template<class T> static inline
constexpr T* v3_cpp_obj(T** obj)
{
- return (T*)((uint8_t*)*obj + sizeof(void*)*3);
+ /**
+ * this ugly piece of code is required due to C++ assuming `reinterpret_cast` by default,
+ * but we need everything to be `static_cast` for it to be `constexpr` compatible.
+ */
+ return static_cast<T*>(static_cast<void*>(static_cast<uint8_t*>(static_cast<void*>(*obj)) + sizeof(void*)*3));
}
#else
# ifndef constexpr
diff --git a/distrho/src/travesty/edit_controller.h b/distrho/src/travesty/edit_controller.h
@@ -84,4 +84,17 @@ struct v3_edit_controller {
static constexpr const v3_tuid v3_edit_controller_iid =
V3_ID(0xDCD7BBE3, 0x7742448D, 0xA874AACC, 0x979C759E);
+#ifdef __cplusplus
+template<> inline
+constexpr v3_edit_controller* v3_cpp_obj(v3_edit_controller** obj)
+{
+ /**
+ * this ugly piece of code is required due to C++ assuming `reinterpret_cast` by default,
+ * but we need everything to be `static_cast` for it to be `constexpr` compatible.
+ */
+ return static_cast<v3_edit_controller*>(
+ static_cast<void*>(static_cast<uint8_t*>(static_cast<void*>(*obj)) + sizeof(void*)*5));
+}
+#endif
+
#include "align_pop.h"