DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit bea070111cd3809d2a6f7d25fbfae25408e1367f
parent f462f60dfeb5ba6df1bcd99588e4009dcb9599c7
Author: falkTX <falktx@falktx.com>
Date:   Thu, 23 Sep 2021 12:35:25 +0100

More VST3 tweaks

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdistrho/src/DistrhoPluginVST2.cpp | 2+-
Mdistrho/src/DistrhoPluginVST3.cpp | 234+++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mdistrho/src/travesty/edit_controller.h | 12++++++------
3 files changed, 169 insertions(+), 79 deletions(-)

diff --git a/distrho/src/DistrhoPluginVST2.cpp b/distrho/src/DistrhoPluginVST2.cpp @@ -1066,7 +1066,7 @@ public: void vst_setParameter(const int32_t index, const float value) { - const uint32_t hints(fPlugin.getParameterHints(index)); + const uint32_t hints = fPlugin.getParameterHints(index); const ParameterRanges& ranges(fPlugin.getParameterRanges(index)); // TODO figure out how to detect kVstParameterUsesIntegerMinMax host support, and skip normalization diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp @@ -22,7 +22,8 @@ #include "travesty/edit_controller.h" #include "travesty/factory.h" -#include <list> +#include <atomic> +#include <vector> START_NAMESPACE_DISTRHO @@ -158,7 +159,7 @@ void strncpy_16from8(int16_t* const dst, const char* const src, const size_t siz } } -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- class PluginVst3 { @@ -168,6 +169,85 @@ public: { } + // ---------------------------------------------------------------------------------------------------------------- + // stuff for vst3 interfaces + + uint32_t getParameterCount() const noexcept + { + return fPlugin.getParameterCount(); + } + + void getParameterInfo(const uint32_t index, v3_param_info* const info) const noexcept + { + // set up flags + int32_t flags = 0; + + const auto desig = fPlugin.getParameterDesignation(index); + const auto hints = fPlugin.getParameterHints(index); + + const ParameterRanges& ranges(fPlugin.getParameterRanges(index)); + + switch (desig) + { + case kParameterDesignationNull: + break; + case kParameterDesignationBypass: + flags |= V3_PARAM_IS_BYPASS; + break; + } + + if (hints & kParameterIsAutomable) + flags |= V3_PARAM_CAN_AUTOMATE; + if (hints & kParameterIsOutput) + flags |= V3_PARAM_READ_ONLY; + // TODO V3_PARAM_IS_LIST + + // set up step_count + int32_t step_count = 0; + + if (hints & kParameterIsBoolean) + step_count = 1; + if ((hints & kParameterIsInteger) && ranges.max - ranges.min > 1) + step_count = ranges.max - ranges.min - 1; + + std::memset(info, 0, sizeof(v3_param_info)); + info->param_id = index; + info->flags = flags; + info->step_count = step_count; + info->default_normalised_value = ranges.getNormalizedValue(ranges.def); + // int32_t unit_id; + strncpy_16from8(info->title, fPlugin.getParameterName(index), 128); + strncpy_16from8(info->short_title, fPlugin.getParameterShortName(index), 128); + strncpy_16from8(info->units, fPlugin.getParameterUnit(index), 128); + } + + double getNormalizedParameterValue(const uint32_t index) + { + const ParameterRanges& ranges(fPlugin.getParameterRanges(index)); + return ranges.getNormalizedValue(fPlugin.getParameterValue(index)); + } + + void setNormalizedParameterValue(const uint32_t index, const double value) + { + const uint32_t hints = fPlugin.getParameterHints(index); + const ParameterRanges& ranges(fPlugin.getParameterRanges(index)); + + float realValue = ranges.getUnnormalizedValue(value); + + if (hints & kParameterIsBoolean) + { + const float midRange = ranges.min + (ranges.max - ranges.min) / 2.0f; + realValue = realValue > midRange ? ranges.max : ranges.min; + } + + if (hints & kParameterIsInteger) + { + realValue = std::round(realValue); + } + + fPlugin.setParameterValue(index, realValue); + } + private: // Plugin PluginExporter fPlugin; @@ -343,7 +423,10 @@ struct v3_edit_controller_cpp : v3_funknown { }; struct dpf_edit_controller : v3_edit_controller_cpp { - dpf_edit_controller() + ScopedPointer<PluginVst3>& vst3; + + dpf_edit_controller(ScopedPointer<PluginVst3>& v) + : vst3(v) { static const uint8_t* kSupportedFactories[] = { v3_funknown_iid, @@ -423,66 +506,34 @@ struct dpf_edit_controller : v3_edit_controller_cpp { controller.get_parameter_count = []V3_API(void* self) -> int32_t { d_stdout("dpf_edit_controller::get_parameter_count => %s | %p", __PRETTY_FUNCTION__ + 53, self); - return gPluginInfo->getParameterCount(); + dpf_edit_controller* const controller = *(dpf_edit_controller**)self; + DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_INVALID_ARG); + + PluginVst3* const vst3 = controller->vst3.get(); + DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, V3_NOT_INITIALISED); + return vst3->getParameterCount(); }; controller.get_parameter_info = []V3_API(void* self, int32_t param_idx, v3_param_info* param_info) -> v3_result { d_stdout("dpf_edit_controller::get_parameter_info => %s | %p %i", __PRETTY_FUNCTION__ + 53, self, param_idx); + dpf_edit_controller* const controller = *(dpf_edit_controller**)self; + DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_INVALID_ARG); + DISTRHO_SAFE_ASSERT_RETURN(param_idx >= 0, V3_INVALID_ARG); - // set up flags - int32_t flags = 0; - - const auto desig = gPluginInfo->getParameterDesignation(param_idx); - const auto hints = gPluginInfo->getParameterHints(param_idx); - - const ParameterRanges& ranges(gPluginInfo->getParameterRanges(param_idx)); - - switch (desig) - { - case kParameterDesignationNull: - break; - case kParameterDesignationBypass: - flags |= V3_PARAM_IS_BYPASS; - break; - } - - if (hints & kParameterIsAutomable) - flags |= V3_PARAM_CAN_AUTOMATE; - if (hints & kParameterIsOutput) - flags |= V3_PARAM_READ_ONLY; - // TODO V3_PARAM_IS_LIST - - // set up step_count - int32_t step_count = 0; - - if (hints & kParameterIsBoolean) - step_count = 1; - if ((hints & kParameterIsInteger) && ranges.max - ranges.min > 1) - step_count = ranges.max - ranges.min - 1; - - std::memset(param_info, 0, sizeof(v3_param_info)); - param_info->param_id = param_idx; - param_info->flags = flags; - param_info->step_count = step_count; - param_info->default_normalised_value = ranges.getNormalizedValue(ranges.def); - // int32_t unit_id; - strncpy_16from8(param_info->title, gPluginInfo->getParameterName(param_idx), 128); - strncpy_16from8(param_info->short_title, gPluginInfo->getParameterShortName(param_idx), 128); - strncpy_16from8(param_info->units, gPluginInfo->getParameterUnit(param_idx), 128); + PluginVst3* const vst3 = controller->vst3.get(); + DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, V3_NOT_INITIALISED); - /* - v3_str_128 title; - v3_str_128 short_title; - v3_str_128 units; - */ + const uint32_t uidx = static_cast<uint32_t>(param_idx); + DISTRHO_SAFE_ASSERT_RETURN(uidx < vst3->getParameterCount(), V3_INVALID_ARG); + vst3->getParameterInfo(uidx, param_info); return V3_OK; }; - controller.get_param_string_for_value = []V3_API(void* self, v3_param_id index, double normalised, v3_str_128 output) -> v3_result + 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_param_string_for_value => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + d_stdout("dpf_edit_controller::get_parameter_string_for_value => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); const ParameterRanges& ranges(gPluginInfo->getParameterRanges(index)); const float realvalue = ranges.getUnnormalizedValue(normalised); @@ -492,40 +543,55 @@ struct dpf_edit_controller : v3_edit_controller_cpp { return V3_OK; }; - controller.get_param_value_for_string = []V3_API(void* self, v3_param_id, int16_t* input, double* output) -> v3_result + controller.get_parameter_value_for_string = []V3_API(void* self, v3_param_id, int16_t* input, double* output) -> v3_result { - d_stdout("dpf_edit_controller::get_param_value_for_string => %s | %p %p %p", __PRETTY_FUNCTION__ + 53, self, input, output); + d_stdout("dpf_edit_controller::get_parameter_value_for_string => %s | %p %p %p", __PRETTY_FUNCTION__ + 53, self, input, output); return V3_NOT_IMPLEMENTED; }; - controller.normalised_param_to_plain = []V3_API(void* self, v3_param_id, double normalised) -> double + controller.normalised_parameter_to_plain = []V3_API(void* self, v3_param_id, double normalised) -> double { - d_stdout("dpf_edit_controller::normalised_param_to_plain => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + d_stdout("dpf_edit_controller::normalised_parameter_to_plain => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); return normalised; }; - controller.plain_param_to_normalised = []V3_API(void* self, v3_param_id, double normalised) -> double + controller.plain_parameter_to_normalised = []V3_API(void* self, v3_param_id, double normalised) -> double { - d_stdout("dpf_edit_controller::plain_param_to_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + d_stdout("dpf_edit_controller::plain_parameter_to_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); return normalised; }; - controller.get_param_normalised = []V3_API(void* self, v3_param_id) -> double + controller.get_parameter_normalised = []V3_API(void* self, v3_param_id param_idx) -> double { - d_stdout("dpf_edit_controller::get_param_normalised => %s | %p", __PRETTY_FUNCTION__ + 53, self); - return 0.0; + d_stdout("dpf_edit_controller::get_parameter_normalised => %s | %p", __PRETTY_FUNCTION__ + 53, self); + dpf_edit_controller* const controller = *(dpf_edit_controller**)self; + DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, 0.0); + + PluginVst3* const vst3 = controller->vst3.get(); + DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, 0.0); + DISTRHO_SAFE_ASSERT_RETURN(param_idx < vst3->getParameterCount(), 0.0); + + return vst3->getNormalizedParameterValue(param_idx); }; - controller.set_param_normalised = []V3_API(void* self, v3_param_id, double normalised) -> v3_result + controller.set_parameter_normalised = []V3_API(void* self, v3_param_id param_idx, double normalised) -> v3_result { - d_stdout("dpf_edit_controller::set_param_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + d_stdout("dpf_edit_controller::set_parameter_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + dpf_edit_controller* const controller = *(dpf_edit_controller**)self; + DISTRHO_SAFE_ASSERT_RETURN(controller != nullptr, V3_INVALID_ARG); + + PluginVst3* const vst3 = controller->vst3.get(); + DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, V3_NOT_INITIALISED); + DISTRHO_SAFE_ASSERT_RETURN(param_idx < vst3->getParameterCount(), V3_INVALID_ARG); + + vst3->setNormalizedParameterValue(param_idx, normalised); return V3_OK; }; controller.set_component_handler = []V3_API(void* self, v3_component_handler**) -> v3_result { d_stdout("dpf_edit_controller::set_component_handler => %s | %p", __PRETTY_FUNCTION__ + 53, self); - return V3_OK; + return V3_NOT_IMPLEMENTED; }; controller.create_view = []V3_API(void* self, const char* name) -> v3_plug_view** @@ -615,9 +681,13 @@ struct dpf_audio_processor : v3_audio_processor_cpp { return 0; }; - processor.setup_processing = []V3_API(void* self, v3_process_setup*) -> v3_result + processor.setup_processing = []V3_API(void* self, v3_process_setup* setup) -> v3_result { d_stdout("dpf_audio_processor::setup_processing => %s | %p", __PRETTY_FUNCTION__ + 53, self); + + d_lastBufferSize = setup->max_block_size; + d_lastSampleRate = setup->sample_rate; + return V3_OK; }; @@ -650,10 +720,13 @@ struct v3_component_cpp : v3_funknown { }; struct dpf_component : v3_component_cpp { - dpf_audio_processor* processor = nullptr; - dpf_edit_controller* controller = nullptr; + std::atomic<int> refcounter; + ScopedPointer<dpf_audio_processor> processor; + ScopedPointer<dpf_edit_controller> controller; + ScopedPointer<PluginVst3> vst3; dpf_component() + : refcounter(1) { static const uint8_t* kSupportedBaseFactories[] = { v3_funknown_iid, @@ -684,7 +757,7 @@ struct dpf_component : v3_component_cpp { dpf_component* const component = *(dpf_component**)self; if (component->processor == nullptr) component->processor = new dpf_audio_processor(); - *iface = (v3_funknown*)&component->processor; + *iface = &component->processor; return V3_OK; } @@ -692,8 +765,8 @@ struct dpf_component : v3_component_cpp { { dpf_component* const component = *(dpf_component**)self; if (component->controller == nullptr) - component->controller = new dpf_edit_controller(); - *iface = (v3_funknown*)&component->controller; + component->controller = new dpf_edit_controller(component->vst3); + *iface = &component->controller; return V3_OK; } @@ -704,27 +777,44 @@ struct dpf_component : v3_component_cpp { ref = []V3_API(void* self) -> uint32_t { d_stdout("dpf_component::ref => %s | %p", __PRETTY_FUNCTION__ + 41, self); - return 1; + dpf_component* const component = *(dpf_component**)self; + return ++component->refcounter; }; unref = []V3_API(void* self) -> uint32_t { d_stdout("dpf_component::unref => %s | %p", __PRETTY_FUNCTION__ + 41, self); + dpf_component* const component = *(dpf_component**)self; + if (const int refcounter = --component->refcounter) + return refcounter; + // delete component; + *(dpf_component**)self = nullptr; return 0; }; // ------------------------------------------------------------------------------------------------------------ // v3_plugin_base - base.initialise = []V3_API(void* self, struct v3_plugin_base::v3_funknown *context) -> v3_result + base.initialise = []V3_API(void* self, struct v3_plugin_base::v3_funknown* context) -> v3_result { d_stdout("dpf_component::initialise => %s | %p %p", __PRETTY_FUNCTION__ + 41, self, context); + dpf_component* const component = *(dpf_component**)self; + + // default early values + if (d_lastBufferSize == 0) + d_lastBufferSize = 2048; + if (d_lastSampleRate <= 0.0) + d_lastSampleRate = 44100.0; + + component->vst3 = new PluginVst3(); return V3_OK; }; base.terminate = []V3_API(void* self) -> v3_result { d_stdout("dpf_component::terminate => %s | %p", __PRETTY_FUNCTION__ + 41, self); + dpf_component* const component = *(dpf_component**)self; + component->vst3 = nullptr; return V3_OK; }; @@ -799,7 +889,7 @@ struct v3_plugin_factory_cpp : v3_funknown { }; struct dpf_factory : v3_plugin_factory_cpp { - std::list<dpf_component*> components; + std::vector<dpf_component*> components; dpf_factory() { diff --git a/distrho/src/travesty/edit_controller.h b/distrho/src/travesty/edit_controller.h @@ -86,18 +86,18 @@ struct v3_edit_controller { V3_API v3_result (*get_parameter_info) (void *self, int32_t param_idx, struct v3_param_info *); - V3_API v3_result (*get_param_string_for_value) + V3_API v3_result (*get_parameter_string_for_value) (void *self, v3_param_id, double normalised, v3_str_128 output); - V3_API v3_result (*get_param_value_for_string) + V3_API v3_result (*get_parameter_value_for_string) (void *self, v3_param_id, int16_t *input, double *output); - V3_API double (*normalised_param_to_plain) + V3_API double (*normalised_parameter_to_plain) (void *self, v3_param_id, double normalised); - V3_API double (*plain_param_to_normalised) + V3_API double (*plain_parameter_to_normalised) (void *self, v3_param_id, double normalised); - V3_API double (*get_param_normalised)(void *self, v3_param_id); - V3_API v3_result (*set_param_normalised) + V3_API double (*get_parameter_normalised)(void *self, v3_param_id); + V3_API v3_result (*set_parameter_normalised) (void *self, v3_param_id, double normalised); V3_API v3_result (*set_component_handler)