DPF

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

commit d6fdcbd34edde956a2a9d4afe88badbb8efa73ce
parent 5ab80c5d2dc799ed54c07f3aeae180f5f274850b
Author: falkTX <falktx@falktx.com>
Date:   Wed, 22 Sep 2021 23:10:52 +0100

Continue battling vst3, can show parameters now

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

Diffstat:
Mdistrho/src/DistrhoPluginVST3.cpp | 306+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mdistrho/src/travesty/README.txt | 6+++---
Mdistrho/src/travesty/align_pop.h | 2+-
Mdistrho/src/travesty/align_push.h | 2+-
Mdistrho/src/travesty/audio_processor.h | 2+-
Mdistrho/src/travesty/base.h | 102++++++++++++++++++++++++++++++++++++++++----------------------------------------
Mdistrho/src/travesty/bstream.h | 2+-
Mdistrho/src/travesty/component.h | 2+-
Mdistrho/src/travesty/edit_controller.h | 2+-
Mdistrho/src/travesty/events.h | 2+-
Mdistrho/src/travesty/factory.h | 2+-
Mdistrho/src/travesty/view.h | 10+++++-----
12 files changed, 306 insertions(+), 134 deletions(-)

diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp @@ -22,8 +22,12 @@ #include "travesty/edit_controller.h" #include "travesty/factory.h" +#include <list> + START_NAMESPACE_DISTRHO +// -------------------------------------------------------------------------------------------------------------------- + #if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT static const writeMidiFunc writeMidiCallback = nullptr; #endif @@ -31,11 +35,15 @@ static const writeMidiFunc writeMidiCallback = nullptr; static const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr; #endif +// -------------------------------------------------------------------------------------------------------------------- // custom v3_tuid compatible type + typedef uint32_t dpf_tuid[4]; static_assert(sizeof(v3_tuid) == sizeof(dpf_tuid), "uid size mismatch"); -// custom uids, fully created during module init +// -------------------------------------------------------------------------------------------------------------------- +// custom, constant uids related to DPF + static constexpr const uint32_t dpf_id_entry = d_cconst('D', 'P', 'F', ' '); static constexpr const uint32_t dpf_id_clas = d_cconst('c', 'l', 'a', 's'); static constexpr const uint32_t dpf_id_comp = d_cconst('c', 'o', 'm', 'p'); @@ -43,14 +51,75 @@ static constexpr const uint32_t dpf_id_ctrl = d_cconst('c', 't', 'r', 'l'); static constexpr const uint32_t dpf_id_proc = d_cconst('p', 'r', 'o', 'c'); static constexpr const uint32_t dpf_id_view = d_cconst('v', 'i', 'e', 'w'); -// plugin uids, values are filled in during plugin init +// -------------------------------------------------------------------------------------------------------------------- +// plugin specific uids (values are filled in during plugin init) + static dpf_tuid dpf_tuid_class = { dpf_id_entry, dpf_id_clas, 0, 0 }; static dpf_tuid dpf_tuid_component = { dpf_id_entry, dpf_id_comp, 0, 0 }; static dpf_tuid dpf_tuid_controller = { dpf_id_entry, dpf_id_ctrl, 0, 0 }; static dpf_tuid dpf_tuid_processor = { dpf_id_entry, dpf_id_proc, 0, 0 }; static dpf_tuid dpf_tuid_view = { dpf_id_entry, dpf_id_view, 0, 0 }; -// ----------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- +// Utility functions + +const char* tuid2str(const v3_tuid iid) +{ + if (v3_tuid_match(iid, v3_funknown_iid)) + return "{v3_funknown}"; + if (v3_tuid_match(iid, v3_plugin_base_iid)) + return "{v3_plugin_base}"; + if (v3_tuid_match(iid, v3_plugin_factory_iid)) + return "{v3_plugin_factory}"; + if (v3_tuid_match(iid, v3_plugin_factory_2_iid)) + return "{v3_plugin_factory_2}"; + if (v3_tuid_match(iid, v3_plugin_factory_3_iid)) + return "{v3_plugin_factory_3}"; + if (v3_tuid_match(iid, v3_component_iid)) + return "{v3_component}"; + if (v3_tuid_match(iid, v3_bstream_iid)) + return "{v3_bstream}"; + if (v3_tuid_match(iid, v3_event_list_iid)) + return "{v3_event_list}"; + if (v3_tuid_match(iid, v3_param_value_queue_iid)) + return "{v3_param_value_queue}"; + if (v3_tuid_match(iid, v3_param_changes_iid)) + return "{v3_param_changes}"; + if (v3_tuid_match(iid, v3_process_context_requirements_iid)) + return "{v3_process_context_requirements}"; + if (v3_tuid_match(iid, v3_audio_processor_iid)) + return "{v3_audio_processor}"; + if (v3_tuid_match(iid, v3_component_handler_iid)) + return "{v3_component_handler}"; + if (v3_tuid_match(iid, v3_edit_controller_iid)) + return "{v3_edit_controller}"; + if (v3_tuid_match(iid, v3_plugin_view_iid)) + return "{v3_plugin_view}"; + if (v3_tuid_match(iid, v3_plugin_frame_iid)) + return "{v3_plugin_frame}"; + if (v3_tuid_match(iid, v3_plugin_view_content_scale_steinberg_iid)) + return "{v3_plugin_view_content_scale_steinberg}"; + if (v3_tuid_match(iid, v3_plugin_view_parameter_finder_iid)) + return "{v3_plugin_view_parameter_finder}"; + if (std::memcmp(iid, dpf_tuid_class, sizeof(dpf_tuid)) == 0) + return "{dpf_tuid_class}"; + if (std::memcmp(iid, dpf_tuid_component, sizeof(dpf_tuid)) == 0) + return "{dpf_tuid_component}"; + if (std::memcmp(iid, dpf_tuid_controller, sizeof(dpf_tuid)) == 0) + return "{dpf_tuid_controller}"; + if (std::memcmp(iid, dpf_tuid_processor, sizeof(dpf_tuid)) == 0) + return "{dpf_tuid_processor}"; + if (std::memcmp(iid, dpf_tuid_view, sizeof(dpf_tuid)) == 0) + return "{dpf_tuid_view}"; + + static char buf[46]; + std::snprintf(buf, sizeof(buf), "{0x%08X,0x%08X,0x%08X,0x%08X}", + (uint32_t)d_cconst(iid[ 0], iid[ 1], iid[ 2], iid[ 3]), + (uint32_t)d_cconst(iid[ 4], iid[ 5], iid[ 6], iid[ 7]), + (uint32_t)d_cconst(iid[ 8], iid[ 9], iid[10], iid[11]), + (uint32_t)d_cconst(iid[12], iid[13], iid[14], iid[15])); + return buf; +} void strncpy(char* const dst, const char* const src, const size_t size) { @@ -67,11 +136,29 @@ void strncpy(char* const dst, const char* const src, const size_t size) } } -// ----------------------------------------------------------------------- +void strncpy_16from8(int16_t* const dst, const char* const src, const size_t size) +{ + DISTRHO_SAFE_ASSERT_RETURN(size > 0,); + + if (const size_t len = std::min(std::strlen(src), size-1U)) + { + for (size_t i=0; i<len; ++i) + { + // skip non-ascii chars + if ((uint8_t)src[i] >= 0x80) + continue; -// v3_funknown, v3_plugin_base, v3_component + dst[i] = src[i]; + } + dst[len] = 0; + } + else + { + dst[0] = 0; + } +} -// audio_processor +// ----------------------------------------------------------------------- class PluginVst3 { @@ -141,7 +228,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result { - d_stdout("dpf_plugin_view::query_interface => %s | %p %p %p", __PRETTY_FUNCTION__ + 41, self, iid, iface); + d_stdout("dpf_plugin_view::query_interface => %s | %p %s %p", __PRETTY_FUNCTION__ + 41, self, tuid2str(iid), iface); *iface = NULL; DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); @@ -171,7 +258,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { }; // ------------------------------------------------------------------------------------------------------------ - // v3_plugin_base + // v3_plugin_view view.is_platform_type_supported = []V3_API(void* self, const char* platform_type) -> v3_result { @@ -227,7 +314,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { return V3_OK; }; - view.set_frame = []V3_API(void* self, v3_plug_frame*) -> v3_result + view.set_frame = []V3_API(void* self, v3_plugin_frame*) -> v3_result { d_stdout("dpf_plugin_view::set_frame => %s | %p", __PRETTY_FUNCTION__ + 41, self); return V3_OK; @@ -251,6 +338,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { // dpf_edit_controller struct v3_edit_controller_cpp : v3_funknown { + v3_plugin_base base; v3_edit_controller controller; }; @@ -267,7 +355,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp { query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result { - d_stdout("dpf_edit_controller::query_interface => %s | %p %p %p", __PRETTY_FUNCTION__ + 41, self, iid, iface); + d_stdout("dpf_edit_controller::query_interface => %s | %p %s %p", __PRETTY_FUNCTION__ + 53, self, tuid2str(iid), iface); *iface = NULL; DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); @@ -286,94 +374,163 @@ struct dpf_edit_controller : v3_edit_controller_cpp { // we only support 1 plugin per binary, so don't have to care here ref = []V3_API(void* self) -> uint32_t { - d_stdout("dpf_edit_controller::ref => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_edit_controller::ref => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 1; }; unref = []V3_API(void* self) -> uint32_t { - d_stdout("dpf_edit_controller::unref => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_edit_controller::unref => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 0; }; // ------------------------------------------------------------------------------------------------------------ // v3_plugin_base + base.initialise = []V3_API(void* self, struct v3_plugin_base::v3_funknown *context) -> v3_result + { + d_stdout("dpf_edit_controller::initialise => %s | %p %p", __PRETTY_FUNCTION__ + 53, self, context); + return V3_OK; + }; + + base.terminate = []V3_API(void* self) -> v3_result + { + d_stdout("dpf_edit_controller::terminate => %s | %p", __PRETTY_FUNCTION__ + 53, self); + return V3_OK; + }; + + // ------------------------------------------------------------------------------------------------------------ + // v3_edit_controller + controller.set_component_state = []V3_API(void* self, v3_bstream*) -> v3_result { - d_stdout("dpf_edit_controller::set_component_state => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_edit_controller::set_component_state => %s | %p", __PRETTY_FUNCTION__ + 53, self); return V3_OK; }; controller.set_state = []V3_API(void* self, v3_bstream*) -> v3_result { - d_stdout("dpf_edit_controller::set_state => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_edit_controller::set_state => %s | %p", __PRETTY_FUNCTION__ + 53, self); return V3_OK; }; controller.get_state = []V3_API(void* self, v3_bstream*) -> v3_result { - d_stdout("dpf_edit_controller::get_state => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_edit_controller::get_state => %s | %p", __PRETTY_FUNCTION__ + 53, self); return V3_OK; }; controller.get_parameter_count = []V3_API(void* self) -> int32_t { - d_stdout("dpf_edit_controller::get_parameter_count => %s | %p", __PRETTY_FUNCTION__ + 41, self); - return 0; + d_stdout("dpf_edit_controller::get_parameter_count => %s | %p", __PRETTY_FUNCTION__ + 53, self); + return gPluginInfo->getParameterCount(); }; - controller.get_parameter_info = []V3_API(void* self, int32_t param_idx, v3_param_info*) -> v3_result + 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__ + 41, self, param_idx); + d_stdout("dpf_edit_controller::get_parameter_info => %s | %p %i", __PRETTY_FUNCTION__ + 53, self, param_idx); + + // 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); + + /* + v3_str_128 title; + v3_str_128 short_title; + v3_str_128 units; + */ + return V3_OK; }; - controller.get_param_string_for_value = []V3_API(void* self, v3_param_id, double normalised, v3_str_128 /*output*/) -> v3_result + controller.get_param_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__ + 41, self, normalised); + d_stdout("dpf_edit_controller::get_param_string_for_value => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + + const ParameterRanges& ranges(gPluginInfo->getParameterRanges(index)); + const float realvalue = ranges.getUnnormalizedValue(normalised); + char buf[24]; + sprintf(buf, "%f", realvalue); + strncpy_16from8(output, buf, 128); return V3_OK; }; controller.get_param_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__ + 41, self, input, output); - return V3_OK; + d_stdout("dpf_edit_controller::get_param_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 { - d_stdout("dpf_edit_controller::normalised_param_to_plain => %s | %p %f", __PRETTY_FUNCTION__ + 41, self, normalised); - return 0.0; + d_stdout("dpf_edit_controller::normalised_param_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 { - d_stdout("dpf_edit_controller::plain_param_to_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 41, self, normalised); - return 0.0; + d_stdout("dpf_edit_controller::plain_param_to_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, normalised); + return normalised; }; controller.get_param_normalised = []V3_API(void* self, v3_param_id) -> double { - d_stdout("dpf_edit_controller::get_param_normalised => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_edit_controller::get_param_normalised => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 0.0; }; controller.set_param_normalised = []V3_API(void* self, v3_param_id, double normalised) -> v3_result { - d_stdout("dpf_edit_controller::set_param_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 41, self, normalised); + d_stdout("dpf_edit_controller::set_param_normalised => %s | %p %f", __PRETTY_FUNCTION__ + 53, self, 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__ + 41, self); + d_stdout("dpf_edit_controller::set_component_handler => %s | %p", __PRETTY_FUNCTION__ + 53, self); return V3_OK; }; controller.create_view = []V3_API(void* self, const char* name) -> v3_plug_view** { - d_stdout("dpf_edit_controller::create_view => %s | %p %s", __PRETTY_FUNCTION__ + 41, self, name); + d_stdout("dpf_edit_controller::create_view => %s | %p %s", __PRETTY_FUNCTION__ + 53, self, name); return nullptr; }; } @@ -399,7 +556,7 @@ struct dpf_audio_processor : v3_audio_processor_cpp { query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result { - d_stdout("dpf_audio_processor::query_interface => %s | %p %p %p", __PRETTY_FUNCTION__ + 41, self, iid, iface); + d_stdout("dpf_audio_processor::query_interface => %s | %p %s %p", __PRETTY_FUNCTION__ + 53, self, tuid2str(iid), iface); *iface = NULL; DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); @@ -418,67 +575,67 @@ struct dpf_audio_processor : v3_audio_processor_cpp { // we only support 1 plugin per binary, so don't have to care here ref = []V3_API(void* self) -> uint32_t { - d_stdout("dpf_audio_processor::ref => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_audio_processor::ref => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 1; }; unref = []V3_API(void* self) -> uint32_t { - d_stdout("dpf_audio_processor::unref => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_audio_processor::unref => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 0; }; // ------------------------------------------------------------------------------------------------------------ - // v3_plugin_base + // v3_audio_processor processor.set_bus_arrangements = []V3_API(void* self, v3_speaker_arrangement* inputs, int32_t num_inputs, v3_speaker_arrangement* outputs, int32_t num_outputs) -> v3_result { - d_stdout("dpf_audio_processor::set_bus_arrangements => %s | %p %p %i %p %i", __PRETTY_FUNCTION__ + 41, self, inputs, num_inputs, outputs, num_outputs); + d_stdout("dpf_audio_processor::set_bus_arrangements => %s | %p %p %i %p %i", __PRETTY_FUNCTION__ + 53, self, inputs, num_inputs, outputs, num_outputs); return V3_OK; }; processor.get_bus_arrangement = []V3_API(void* self, int32_t bus_direction, int32_t idx, v3_speaker_arrangement*) -> v3_result { - d_stdout("dpf_audio_processor::get_bus_arrangement => %s | %p %i %i", __PRETTY_FUNCTION__ + 41, self, bus_direction, idx); + d_stdout("dpf_audio_processor::get_bus_arrangement => %s | %p %i %i", __PRETTY_FUNCTION__ + 53, self, bus_direction, idx); return V3_OK; }; processor.can_process_sample_size = []V3_API(void* self, int32_t symbolic_sample_size) -> v3_result { - d_stdout("dpf_audio_processor::can_process_sample_size => %s | %p %i", __PRETTY_FUNCTION__ + 41, self, symbolic_sample_size); + d_stdout("dpf_audio_processor::can_process_sample_size => %s | %p %i", __PRETTY_FUNCTION__ + 53, self, symbolic_sample_size); return V3_OK; }; processor.get_latency_samples = []V3_API(void* self) -> uint32_t { - d_stdout("dpf_audio_processor::get_latency_samples => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_audio_processor::get_latency_samples => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 0; }; processor.setup_processing = []V3_API(void* self, v3_process_setup*) -> v3_result { - d_stdout("dpf_audio_processor::setup_processing => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_audio_processor::setup_processing => %s | %p", __PRETTY_FUNCTION__ + 53, self); return V3_OK; }; processor.set_processing = []V3_API(void* self, v3_bool state) -> v3_result { - d_stdout("dpf_audio_processor::set_processing => %s | %p %u", __PRETTY_FUNCTION__ + 41, self, state); + d_stdout("dpf_audio_processor::set_processing => %s | %p %u", __PRETTY_FUNCTION__ + 53, self, state); return V3_OK; }; processor.process = []V3_API(void* self, v3_process_data*) -> v3_result { - d_stdout("dpf_audio_processor::process => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_audio_processor::process => %s | %p", __PRETTY_FUNCTION__ + 53, self); return V3_OK; }; processor.get_tail_samples = []V3_API(void* self) -> uint32_t { - d_stdout("dpf_audio_processor::get_tail_samples => %s | %p", __PRETTY_FUNCTION__ + 41, self); + d_stdout("dpf_audio_processor::get_tail_samples => %s | %p", __PRETTY_FUNCTION__ + 53, self); return 0; }; } @@ -493,9 +650,12 @@ struct v3_component_cpp : v3_funknown { }; struct dpf_component : v3_component_cpp { + dpf_audio_processor* processor = nullptr; + dpf_edit_controller* controller = nullptr; + dpf_component() { - static const uint8_t* kSupportedFactories[] = { + static const uint8_t* kSupportedBaseFactories[] = { v3_funknown_iid, v3_plugin_base_iid, v3_component_iid @@ -506,11 +666,11 @@ struct dpf_component : v3_component_cpp { query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result { - d_stdout("dpf_component::query_interface => %s | %p %p %p", __PRETTY_FUNCTION__ + 41, self, iid, iface); + d_stdout("dpf_component::query_interface => %s | %p %s %p", __PRETTY_FUNCTION__ + 41, self, tuid2str(iid), iface); *iface = NULL; DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); - for (const uint8_t* factory_iid : kSupportedFactories) + for (const uint8_t* factory_iid : kSupportedBaseFactories) { if (v3_tuid_match(factory_iid, iid)) { @@ -519,6 +679,24 @@ struct dpf_component : v3_component_cpp { } } + if (v3_tuid_match(v3_audio_processor_iid, iid)) + { + dpf_component* const component = *(dpf_component**)self; + if (component->processor == nullptr) + component->processor = new dpf_audio_processor(); + *iface = (v3_funknown*)&component->processor; + return V3_OK; + } + + if (v3_tuid_match(v3_edit_controller_iid, iid)) + { + dpf_component* const component = *(dpf_component**)self; + if (component->controller == nullptr) + component->controller = new dpf_edit_controller(); + *iface = (v3_funknown*)&component->controller; + return V3_OK; + } + return V3_NO_INTERFACE; }; @@ -555,7 +733,7 @@ struct dpf_component : v3_component_cpp { comp.get_controller_class_id = []V3_API(void* self, v3_tuid class_id) -> v3_result { - d_stdout("dpf_component::get_controller_class_id => %s | %p %p", __PRETTY_FUNCTION__ + 41, self, class_id); + d_stdout("dpf_component::get_controller_class_id => %s | %p %s", __PRETTY_FUNCTION__ + 41, self, tuid2str(class_id)); return V3_NOT_IMPLEMENTED; }; @@ -620,6 +798,8 @@ struct v3_plugin_factory_cpp : v3_funknown { v3_plugin_factory_3 v3; }; +std::list<dpf_component*> components; + struct dpf_factory : v3_plugin_factory_cpp { dpf_factory() { @@ -635,7 +815,7 @@ struct dpf_factory : v3_plugin_factory_cpp { query_interface = []V3_API(void* self, const v3_tuid iid, void** iface) -> v3_result { - d_stdout("dpf_factory::query_interface => %s | %p %p %p", __PRETTY_FUNCTION__ + 37, self, iid, iface); + d_stdout("dpf_factory::query_interface => %s | %p %s %p", __PRETTY_FUNCTION__ + 37, self, tuid2str(iid), iface); *iface = NULL; DISTRHO_SAFE_ASSERT_RETURN(self != nullptr, V3_NO_INTERFACE); @@ -685,6 +865,8 @@ struct dpf_factory : v3_plugin_factory_cpp { v1.get_class_info = []V3_API(void* self, int32_t idx, struct v3_class_info* const info) -> v3_result { d_stdout("dpf_factory::get_class_info => %s | %p %i %p", __PRETTY_FUNCTION__ + 37, self, idx, info); + DISTRHO_SAFE_ASSERT_RETURN(idx == 0, V3_NO_INTERFACE); + memcpy(info->class_id, dpf_tuid_class, sizeof(v3_tuid)); info->cardinality = 0x7FFFFFFF; DISTRHO_NAMESPACE::strncpy(info->category, "Audio Module Class", sizeof(info->category)); @@ -694,21 +876,14 @@ struct dpf_factory : v3_plugin_factory_cpp { v1.create_instance = []V3_API(void* self, const v3_tuid class_id, const v3_tuid iid, void** instance) -> v3_result { - d_stdout("dpf_factory::create_instance => %s | %p %p %p %p", __PRETTY_FUNCTION__ + 37, self, class_id, iid, instance); + d_stdout("dpf_factory::create_instance => %s | %p %s %s %p", __PRETTY_FUNCTION__ + 37, self, tuid2str(class_id), tuid2str(iid), instance); DISTRHO_SAFE_ASSERT_RETURN(v3_tuid_match(class_id, *(v3_tuid*)&dpf_tuid_class) && v3_tuid_match(iid, v3_component_iid), V3_NO_INTERFACE); - static dpf_component* component = nullptr; - - if (component == nullptr) - { - component = new dpf_component(); - *instance = &component; - return V3_OK; - } - - *instance = nullptr; - return V3_NO_INTERFACE; + dpf_component* const component = new dpf_component(); + components.push_back(component); + *instance = &components.back(); + return V3_OK; }; // ------------------------------------------------------------------------------------------------------------ @@ -760,11 +935,8 @@ const void* GetPluginFactory(void) { USE_NAMESPACE_DISTRHO; static const dpf_factory factory; - static const struct v3_plugin_factory_2* factories[] = { - (const v3_plugin_factory_2*)&factory, - nullptr - }; - return factories; + static const v3_funknown* const factoryptr = &factory; + return &factoryptr; } // -------------------------------------------------------------------------------------------------------------------- @@ -796,8 +968,8 @@ bool ENTRYFNNAME(void*) d_lastBufferSize = 0; d_lastSampleRate = 0.0; - dpf_tuid_class[3] = dpf_tuid_component[3] = dpf_tuid_controller[3] - = dpf_tuid_processor[3] = dpf_tuid_view[3] = gPluginInfo->getUniqueId(); + dpf_tuid_class[2] = dpf_tuid_component[2] = dpf_tuid_controller[2] + = dpf_tuid_processor[2] = dpf_tuid_view[2] = gPluginInfo->getUniqueId(); } return true; diff --git a/distrho/src/travesty/README.txt b/distrho/src/travesty/README.txt @@ -1,9 +1,9 @@ -This folder contains a pure C interface to Steinberg VST3 SDK, codenamed "travesty". +This folder contains a pure C VST3-compatible interface, codenamed "travesty". Name is a play on words from morphing "vestige" (the good old free VST2 reverse-engineered header file) and "three". The main target is to be able to create VST3-compatible plugins without a bloated SDK. -Everything that is required for plugins fits in a few small header files. -Also, being able to build VST3-compatible plugins in pure C code, something not possible with the original SDK. +Everything that is required for plugins fits in a few small header files as presented here. +Also being able to build VST3-compatible plugins in pure C code, something not possible with the original SDK. Please note this project is still a work in progress. Use at your own risk, and please report any issues to https://github.com/DISTRHO/DPF/. diff --git a/distrho/src/travesty/align_pop.h b/distrho/src/travesty/align_pop.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/align_push.h b/distrho/src/travesty/align_push.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/audio_processor.h b/distrho/src/travesty/audio_processor.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/base.h b/distrho/src/travesty/base.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with @@ -54,42 +54,42 @@ v3_tuid_match(const v3_tuid a, const v3_tuid b) #if V3_COM_COMPAT enum { - V3_NO_INTERFACE = 0x80004002L, - V3_OK = 0, - V3_TRUE = 0, - V3_FALSE = 1, - V3_INVALID_ARG = 0x80070057L, - V3_NOT_IMPLEMENTED = 0x80004001L, - V3_INTERNAL_ERR = 0x80004005L, - V3_NOT_INITIALISED = 0x8000FFFFL, - V3_NOMEM = 0x8007000EL + V3_NO_INTERFACE = 0x80004002L, + V3_OK = 0, + V3_TRUE = 0, + V3_FALSE = 1, + V3_INVALID_ARG = 0x80070057L, + V3_NOT_IMPLEMENTED = 0x80004001L, + V3_INTERNAL_ERR = 0x80004005L, + V3_NOT_INITIALISED = 0x8000FFFFL, + V3_NOMEM = 0x8007000EL }; -# define V3_ID(a, b, c, d) { \ - ((a) & 0x000000FF), \ - ((a) & 0x0000FF00) >> 8, \ - ((a) & 0x00FF0000) >> 16, \ - ((a) & 0xFF000000) >> 24, \ - \ - ((b) & 0x00FF0000) >> 16, \ - ((b) & 0xFF000000) >> 24, \ - ((b) & 0x000000FF), \ - ((b) & 0x0000FF00) >> 8, \ - \ - ((c) & 0xFF000000) >> 24, \ - ((c) & 0x00FF0000) >> 16, \ - ((c) & 0x0000FF00) >> 8, \ - ((c) & 0x000000FF), \ - \ - ((d) & 0xFF000000) >> 24, \ - ((d) & 0x00FF0000) >> 16, \ - ((d) & 0x0000FF00) >> 8, \ - ((d) & 0x000000FF), \ +# define V3_ID(a, b, c, d) { \ + ((a) & 0x000000FF), \ + ((a) & 0x0000FF00) >> 8, \ + ((a) & 0x00FF0000) >> 16, \ + ((a) & 0xFF000000) >> 24, \ + \ + ((b) & 0x00FF0000) >> 16, \ + ((b) & 0xFF000000) >> 24, \ + ((b) & 0x000000FF), \ + ((b) & 0x0000FF00) >> 8, \ + \ + ((c) & 0xFF000000) >> 24, \ + ((c) & 0x00FF0000) >> 16, \ + ((c) & 0x0000FF00) >> 8, \ + ((c) & 0x000000FF), \ + \ + ((d) & 0xFF000000) >> 24, \ + ((d) & 0x00FF0000) >> 16, \ + ((d) & 0x0000FF00) >> 8, \ + ((d) & 0x000000FF), \ } #else // V3_COM_COMPAT enum { - V3_NO_INTERFACE = -1, + V3_NO_INTERFACE = -1, V3_OK, V3_TRUE = V3_OK, V3_FALSE, @@ -100,26 +100,26 @@ enum { V3_NOMEM }; -# define V3_ID(a, b, c, d) { \ - ((a) & 0xFF000000) >> 24, \ - ((a) & 0x00FF0000) >> 16, \ - ((a) & 0x0000FF00) >> 8, \ - ((a) & 0x000000FF), \ - \ - ((b) & 0xFF000000) >> 24, \ - ((b) & 0x00FF0000) >> 16, \ - ((b) & 0x0000FF00) >> 8, \ - ((b) & 0x000000FF), \ - \ - ((c) & 0xFF000000) >> 24, \ - ((c) & 0x00FF0000) >> 16, \ - ((c) & 0x0000FF00) >> 8, \ - ((c) & 0x000000FF), \ - \ - ((d) & 0xFF000000) >> 24, \ - ((d) & 0x00FF0000) >> 16, \ - ((d) & 0x0000FF00) >> 8, \ - ((d) & 0x000000FF), \ +# define V3_ID(a, b, c, d) { \ + ((a) & 0xFF000000) >> 24, \ + ((a) & 0x00FF0000) >> 16, \ + ((a) & 0x0000FF00) >> 8, \ + ((a) & 0x000000FF), \ + \ + ((b) & 0xFF000000) >> 24, \ + ((b) & 0x00FF0000) >> 16, \ + ((b) & 0x0000FF00) >> 8, \ + ((b) & 0x000000FF), \ + \ + ((c) & 0xFF000000) >> 24, \ + ((c) & 0x00FF0000) >> 16, \ + ((c) & 0x0000FF00) >> 8, \ + ((c) & 0x000000FF), \ + \ + ((d) & 0xFF000000) >> 24, \ + ((d) & 0x00FF0000) >> 16, \ + ((d) & 0x0000FF00) >> 8, \ + ((d) & 0x000000FF), \ } #endif // V3_COM_COMPAT diff --git a/distrho/src/travesty/bstream.h b/distrho/src/travesty/bstream.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/component.h b/distrho/src/travesty/component.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/edit_controller.h b/distrho/src/travesty/edit_controller.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/events.h b/distrho/src/travesty/events.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/factory.h b/distrho/src/travesty/factory.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with diff --git a/distrho/src/travesty/view.h b/distrho/src/travesty/view.h @@ -1,5 +1,5 @@ /* - * travesty, pure C interface to steinberg VST3 SDK + * travesty, pure C VST3-compatible interface * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> * * Permission to use, copy, modify, and/or distribute this software for any purpose with @@ -68,7 +68,7 @@ struct v3_plugin_view { (void *self, v3_bool state); V3_API v3_result (*set_frame) - (void *self, struct v3_plug_frame *); + (void *self, struct v3_plugin_frame *); V3_API v3_result (*can_resize)(void *self); V3_API v3_result (*check_size_constraint) (void *self, struct v3_view_rect *); @@ -81,7 +81,7 @@ struct v3_plugin_frame { struct v3_funknown; V3_API v3_result (*resize_view) - (void *self, struct v3_plug_view *, struct v3_view_rect *); + (void *self, struct v3_plugin_view *, struct v3_view_rect *); }; static const v3_tuid v3_plugin_frame_iid = @@ -106,12 +106,12 @@ static const v3_tuid v3_plugin_view_content_scale_steinberg_iid = * support for querying the view to find what control is underneath the mouse */ -struct v3_plugin_view_param_finder { +struct v3_plugin_view_parameter_finder { struct v3_funknown; V3_API v3_result (*find_parameter) (void *self, int32_t x, int32_t y, v3_param_id *); }; -static const v3_tuid v3_plugin_view_param_finder_iid = +static const v3_tuid v3_plugin_view_parameter_finder_iid = V3_ID(0x0F618302, 0x215D4587, 0xA512073C, 0x77B9D383);