Signed-off-by: falkTX <falktx@falktx.com>pull/351/head
| @@ -96,7 +96,7 @@ enum Vst3InternalParameters { | |||||
| # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | ||||
| kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | ||||
| kVst3InternalParameterCount | |||||
| kVst3InternalParameterCount = kVst3InternalParameterMidiCC_end | |||||
| # else | # else | ||||
| kVst3InternalParameterCount = kVst3InternalParameterBaseCount | kVst3InternalParameterCount = kVst3InternalParameterBaseCount | ||||
| # endif | # endif | ||||
| @@ -28,10 +28,6 @@ | |||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
| #endif | #endif | ||||
| // #undef DISTRHO_PLUGIN_HAS_UI | |||||
| // #define DISTRHO_PLUGIN_HAS_UI 1 | |||||
| // #define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0 | |||||
| #if DISTRHO_PLUGIN_HAS_UI == 1 && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS == 0 | #if DISTRHO_PLUGIN_HAS_UI == 1 && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS == 0 | ||||
| # define DPF_VST3_USES_SEPARATE_CONTROLLER | # define DPF_VST3_USES_SEPARATE_CONTROLLER | ||||
| #endif | #endif | ||||
| @@ -71,14 +67,17 @@ namespace std { | |||||
| /* TODO items: | /* TODO items: | ||||
| * == parameters | * == parameters | ||||
| * - parameter enumeration as lists | |||||
| * - implement getParameterValueForString (use names from enumeration if available, fallback to std::atof) | |||||
| * - implement getParameterNormalized for MIDI CC params | |||||
| * - hide parameter outputs? | |||||
| * - hide program parameter? | |||||
| * - deal with parameter triggers | |||||
| * - test parameter triggers | |||||
| * - have parameter outputs host-provided UI working in at least 1 host | |||||
| * - parameter groups via unit ids | * - parameter groups via unit ids | ||||
| * - test parameter changes from DSP (aka requestParameterValueChange) | |||||
| * - how to hide parameter outputs? | |||||
| * - how to hide program parameter? | |||||
| * - test receiving midi CC | |||||
| * - implement getParameterNormalized/setParameterNormalized for MIDI CC params ? | |||||
| * - fully implemented parameter stuff and verify | |||||
| * - float to int safe casting | * - float to int safe casting | ||||
| * - verify that latency changes works (with and without DPF_VST3_USES_SEPARATE_CONTROLLER) | |||||
| * == MIDI | * == MIDI | ||||
| * - MIDI CC changes (need to store value to give to the host?) | * - MIDI CC changes (need to store value to give to the host?) | ||||
| * - MIDI program changes | * - MIDI program changes | ||||
| @@ -89,11 +88,12 @@ namespace std { | |||||
| * - optional audio buses, create dummy buffer of max_block_size length for them | * - optional audio buses, create dummy buffer of max_block_size length for them | ||||
| * - routing info, do we care? | * - routing info, do we care? | ||||
| * - set sidechain bus name from port group | * - set sidechain bus name from port group | ||||
| * == CV | |||||
| * - cv scaling to -1/+1 | |||||
| * - test in at least 1 host | |||||
| * == INFO | * == INFO | ||||
| * - set factory email (needs new DPF API, useful for LV2 as well) | * - set factory email (needs new DPF API, useful for LV2 as well) | ||||
| * - do something with get_controller_class_id and set_io_mode? | |||||
| * == UI | |||||
| * - proper way to create ui, from factory | |||||
| * - do something with set_io_mode? | |||||
| */ | */ | ||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| @@ -1631,7 +1631,7 @@ public: | |||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | #if DISTRHO_PLUGIN_WANT_PROGRAMS | ||||
| case kVst3InternalParameterProgram: | case kVst3InternalParameterProgram: | ||||
| info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_LIST | V3_PARAM_PROGRAM_CHANGE; | |||||
| info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_LIST | V3_PARAM_PROGRAM_CHANGE | V3_PARAM_IS_HIDDEN; | |||||
| info->step_count = fProgramCountMinusOne; | info->step_count = fProgramCountMinusOne; | ||||
| strncpy_utf16(info->title, "Current Program", 128); | strncpy_utf16(info->title, "Current Program", 128); | ||||
| strncpy_utf16(info->short_title, "Program", 128); | strncpy_utf16(info->short_title, "Program", 128); | ||||
| @@ -1643,7 +1643,7 @@ public: | |||||
| if (rindex < kVst3InternalParameterCount) | if (rindex < kVst3InternalParameterCount) | ||||
| { | { | ||||
| const uint32_t index = static_cast<uint32_t>(rindex - kVst3InternalParameterMidiCC_start); | const uint32_t index = static_cast<uint32_t>(rindex - kVst3InternalParameterMidiCC_start); | ||||
| info->flags = V3_PARAM_CAN_AUTOMATE /*| V3_PARAM_IS_HIDDEN*/; | |||||
| info->flags = V3_PARAM_CAN_AUTOMATE | V3_PARAM_IS_HIDDEN; | |||||
| info->step_count = 127; | info->step_count = 127; | ||||
| char ccstr[24]; | char ccstr[24]; | ||||
| snprintf(ccstr, sizeof(ccstr)-1, "MIDI Ch. %d CC %d", index / 130 + 1, index % 130); | snprintf(ccstr, sizeof(ccstr)-1, "MIDI Ch. %d CC %d", index / 130 + 1, index % 130); | ||||
| @@ -2077,8 +2077,13 @@ public: | |||||
| void ctrl2view_disconnect() | void ctrl2view_disconnect() | ||||
| { | { | ||||
| fConnectionFromCtrlToView = nullptr; | |||||
| fConnectedToUI = false; | fConnectedToUI = false; | ||||
| if (fConnectionFromCtrlToView != nullptr) | |||||
| { | |||||
| v3_cpp_obj_unref(fConnectionFromCtrlToView); | |||||
| fConnectionFromCtrlToView = nullptr; | |||||
| } | |||||
| } | } | ||||
| v3_result ctrl2view_notify(v3_message** const message) | v3_result ctrl2view_notify(v3_message** const message) | ||||
| @@ -2170,9 +2175,7 @@ public: | |||||
| if (std::strcmp(msgid, "close") == 0) | if (std::strcmp(msgid, "close") == 0) | ||||
| { | { | ||||
| fConnectedToUI = false; | |||||
| v3_cpp_obj_unref(fConnectionFromCtrlToView); | |||||
| fConnectionFromCtrlToView = nullptr; | |||||
| ctrl2view_disconnect(); | |||||
| return V3_OK; | return V3_OK; | ||||
| } | } | ||||
| @@ -2844,10 +2847,6 @@ struct dpf_ctrl2view_connection_point : v3_connection_point_cpp { | |||||
| if (PluginVst3* const vst3 = point->vst3) | if (PluginVst3* const vst3 = point->vst3) | ||||
| vst3->ctrl2view_disconnect(); | vst3->ctrl2view_disconnect(); | ||||
| /* TODO | |||||
| v3_cpp_obj_unref(point->other); | |||||
| */ | |||||
| point->other = nullptr; | point->other = nullptr; | ||||
| return V3_OK; | return V3_OK; | ||||
| @@ -2929,13 +2928,7 @@ struct dpf_midi_mapping : v3_midi_mapping_cpp { | |||||
| DISTRHO_SAFE_ASSERT_INT_RETURN(channel >= 0 && channel < 16, channel, V3_FALSE); | DISTRHO_SAFE_ASSERT_INT_RETURN(channel >= 0 && channel < 16, channel, V3_FALSE); | ||||
| DISTRHO_SAFE_ASSERT_INT_RETURN(cc >= 0 && cc < 130, cc, V3_FALSE); | DISTRHO_SAFE_ASSERT_INT_RETURN(cc >= 0 && cc < 130, cc, V3_FALSE); | ||||
| # if DISTRHO_PLUGIN_WANT_PROGRAMS | |||||
| static constexpr const v3_param_id offset = 1; | |||||
| # else | |||||
| static constexpr const v3_param_id offset = 0; | |||||
| # endif | |||||
| *id = offset + channel * 130 + cc; | |||||
| *id = kVst3InternalParameterMidiCC_start + channel * 130 + cc; | |||||
| return V3_TRUE; | return V3_TRUE; | ||||
| } | } | ||||
| @@ -302,7 +302,7 @@ enum Vst3InternalParameters { | |||||
| # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | ||||
| kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | ||||
| kVst3InternalParameterCount | |||||
| kVst3InternalParameterCount = kVst3InternalParameterMidiCC_end | |||||
| # else | # else | ||||
| kVst3InternalParameterCount = kVst3InternalParameterBaseCount | kVst3InternalParameterCount = kVst3InternalParameterBaseCount | ||||
| # endif | # endif | ||||
| @@ -39,6 +39,8 @@ namespace std { | |||||
| /* TODO items: | /* TODO items: | ||||
| * - mousewheel event | * - mousewheel event | ||||
| * - key down/up events | * - key down/up events | ||||
| * - host-side resizing | |||||
| * - file request? | |||||
| */ | */ | ||||
| #if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS)) | #if !(defined(DISTRHO_OS_MAC) || defined(DISTRHO_OS_WINDOWS)) | ||||
| @@ -889,7 +891,7 @@ struct dpf_timer_handler : v3_timer_handler_cpp { | |||||
| unref = dpf_single_instance_unref<dpf_timer_handler>; | unref = dpf_single_instance_unref<dpf_timer_handler>; | ||||
| // v3_timer_handler | // v3_timer_handler | ||||
| handler.on_timer = on_timer; | |||||
| timer.on_timer = on_timer; | |||||
| } | } | ||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| @@ -954,6 +956,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| void* const instancePointer; | void* const instancePointer; | ||||
| double sampleRate; | double sampleRate; | ||||
| v3_plugin_frame** frame; | v3_plugin_frame** frame; | ||||
| v3_run_loop** runloop; | |||||
| int32_t nextWidth, nextHeight; | int32_t nextWidth, nextHeight; | ||||
| dpf_plugin_view(v3_host_application** const host, void* const instance, const double sr) | dpf_plugin_view(v3_host_application** const host, void* const instance, const double sr) | ||||
| @@ -962,6 +965,7 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| instancePointer(instance), | instancePointer(instance), | ||||
| sampleRate(sr), | sampleRate(sr), | ||||
| frame(nullptr), | frame(nullptr), | ||||
| runloop(nullptr), | |||||
| nextWidth(0), | nextWidth(0), | ||||
| nextHeight(0) | nextHeight(0) | ||||
| { | { | ||||
| @@ -995,6 +999,11 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| { | { | ||||
| d_stdout("~dpf_plugin_view()"); | d_stdout("~dpf_plugin_view()"); | ||||
| connection = nullptr; | |||||
| scale = nullptr; | |||||
| #ifdef DPF_VST3_USING_HOST_RUN_LOOP | |||||
| timer = nullptr; | |||||
| #endif | |||||
| uivst3 = nullptr; | uivst3 = nullptr; | ||||
| if (hostApplication != nullptr) | if (hostApplication != nullptr) | ||||
| @@ -1074,23 +1083,19 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| v3_cpp_obj(view->connection->other)->disconnect(view->connection->other, | v3_cpp_obj(view->connection->other)->disconnect(view->connection->other, | ||||
| (v3_connection_point**)&view->connection); | (v3_connection_point**)&view->connection); | ||||
| /* | |||||
| if (dpf_ui_connection_point* const conn = view->connection) | if (dpf_ui_connection_point* const conn = view->connection) | ||||
| { | { | ||||
| if (const int refcount = conn->refcounter) | if (const int refcount = conn->refcounter) | ||||
| { | { | ||||
| d_stderr("DPF warning: asked to delete view while connection point still active (refcount %d)", refcount); | d_stderr("DPF warning: asked to delete view while connection point still active (refcount %d)", refcount); | ||||
| return V3_INVALID_ARG; | |||||
| } | } | ||||
| } | } | ||||
| */ | |||||
| if (dpf_plugin_view_content_scale* const scale = view->scale) | if (dpf_plugin_view_content_scale* const scale = view->scale) | ||||
| { | { | ||||
| if (const int refcount = scale->refcounter) | if (const int refcount = scale->refcounter) | ||||
| { | { | ||||
| d_stderr("DPF warning: asked to delete view while content scale still active (refcount %d)", refcount); | d_stderr("DPF warning: asked to delete view while content scale still active (refcount %d)", refcount); | ||||
| return 0; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1132,6 +1137,8 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| v3_run_loop** runloop = nullptr; | v3_run_loop** runloop = nullptr; | ||||
| v3_cpp_obj_query_interface(view->frame, v3_run_loop_iid, &runloop); | v3_cpp_obj_query_interface(view->frame, v3_run_loop_iid, &runloop); | ||||
| DISTRHO_SAFE_ASSERT_RETURN(runloop != nullptr, V3_INVALID_ARG); | DISTRHO_SAFE_ASSERT_RETURN(runloop != nullptr, V3_INVALID_ARG); | ||||
| view->runloop = runloop; | |||||
| #endif | #endif | ||||
| const float scaleFactor = view->scale != nullptr ? view->scale->scaleFactor : 0.0f; | const float scaleFactor = view->scale != nullptr ? view->scale->scaleFactor : 0.0f; | ||||
| @@ -1172,21 +1179,12 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| #ifdef DPF_VST3_USING_HOST_RUN_LOOP | #ifdef DPF_VST3_USING_HOST_RUN_LOOP | ||||
| // unregister our timer as needed | // unregister our timer as needed | ||||
| if (view->timer != nullptr) | |||||
| if (v3_run_loop** const runloop = view->runloop) | |||||
| { | { | ||||
| v3_run_loop** runloop = nullptr; | |||||
| if (view->frame != nullptr) | |||||
| v3_cpp_obj_query_interface(view->frame, v3_run_loop_iid, &runloop); | |||||
| if (runloop != nullptr) | |||||
| if (view->timer != nullptr && view->timer->valid) | |||||
| { | { | ||||
| v3_cpp_obj(runloop)->unregister_timer(runloop, (v3_timer_handler**)&view->timer); | v3_cpp_obj(runloop)->unregister_timer(runloop, (v3_timer_handler**)&view->timer); | ||||
| // we query it 2 times in total, so lets unref 2 times as well | |||||
| v3_cpp_obj_unref(runloop); | |||||
| v3_cpp_obj_unref(runloop); | |||||
| if (const int refcount = --view->timer->refcounter) | if (const int refcount = --view->timer->refcounter) | ||||
| { | { | ||||
| view->timer->valid = false; | view->timer->valid = false; | ||||
| @@ -1197,11 +1195,9 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||||
| view->timer = nullptr; | view->timer = nullptr; | ||||
| } | } | ||||
| } | } | ||||
| else | |||||
| { | |||||
| view->timer->valid = false; | |||||
| d_stderr("VST3 warning: Host run loop not available during dpf_plugin_view::removed"); | |||||
| } | |||||
| v3_cpp_obj_unref(runloop); | |||||
| view->runloop = nullptr; | |||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -176,7 +176,7 @@ struct v3_event_handler_cpp : v3_funknown { | |||||
| }; | }; | ||||
| struct v3_timer_handler_cpp : v3_funknown { | struct v3_timer_handler_cpp : v3_funknown { | ||||
| v3_timer_handler handler; | |||||
| v3_timer_handler timer; | |||||
| }; | }; | ||||
| struct v3_run_loop_cpp : v3_funknown { | struct v3_run_loop_cpp : v3_funknown { | ||||