Signed-off-by: falkTX <falktx@falktx.com>pull/351/head
| @@ -96,7 +96,7 @@ enum Vst3InternalParameters { | |||
| # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | |||
| kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | |||
| kVst3InternalParameterCount | |||
| kVst3InternalParameterCount = kVst3InternalParameterMidiCC_end | |||
| # else | |||
| kVst3InternalParameterCount = kVst3InternalParameterBaseCount | |||
| # endif | |||
| @@ -28,10 +28,6 @@ | |||
| # define DISTRHO_PLUGIN_HAS_UI 0 | |||
| #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 | |||
| # define DPF_VST3_USES_SEPARATE_CONTROLLER | |||
| #endif | |||
| @@ -71,14 +67,17 @@ namespace std { | |||
| /* TODO items: | |||
| * == 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 | |||
| * - 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 | |||
| * - verify that latency changes works (with and without DPF_VST3_USES_SEPARATE_CONTROLLER) | |||
| * == MIDI | |||
| * - MIDI CC changes (need to store value to give to the host?) | |||
| * - MIDI program changes | |||
| @@ -89,11 +88,12 @@ namespace std { | |||
| * - optional audio buses, create dummy buffer of max_block_size length for them | |||
| * - routing info, do we care? | |||
| * - set sidechain bus name from port group | |||
| * == CV | |||
| * - cv scaling to -1/+1 | |||
| * - test in at least 1 host | |||
| * == INFO | |||
| * - 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 | |||
| @@ -1631,7 +1631,7 @@ public: | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
| 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; | |||
| strncpy_utf16(info->title, "Current Program", 128); | |||
| strncpy_utf16(info->short_title, "Program", 128); | |||
| @@ -1643,7 +1643,7 @@ public: | |||
| if (rindex < kVst3InternalParameterCount) | |||
| { | |||
| 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; | |||
| char ccstr[24]; | |||
| snprintf(ccstr, sizeof(ccstr)-1, "MIDI Ch. %d CC %d", index / 130 + 1, index % 130); | |||
| @@ -2077,8 +2077,13 @@ public: | |||
| void ctrl2view_disconnect() | |||
| { | |||
| fConnectionFromCtrlToView = nullptr; | |||
| fConnectedToUI = false; | |||
| if (fConnectionFromCtrlToView != nullptr) | |||
| { | |||
| v3_cpp_obj_unref(fConnectionFromCtrlToView); | |||
| fConnectionFromCtrlToView = nullptr; | |||
| } | |||
| } | |||
| v3_result ctrl2view_notify(v3_message** const message) | |||
| @@ -2170,9 +2175,7 @@ public: | |||
| if (std::strcmp(msgid, "close") == 0) | |||
| { | |||
| fConnectedToUI = false; | |||
| v3_cpp_obj_unref(fConnectionFromCtrlToView); | |||
| fConnectionFromCtrlToView = nullptr; | |||
| ctrl2view_disconnect(); | |||
| return V3_OK; | |||
| } | |||
| @@ -2844,10 +2847,6 @@ struct dpf_ctrl2view_connection_point : v3_connection_point_cpp { | |||
| if (PluginVst3* const vst3 = point->vst3) | |||
| vst3->ctrl2view_disconnect(); | |||
| /* TODO | |||
| v3_cpp_obj_unref(point->other); | |||
| */ | |||
| point->other = nullptr; | |||
| 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(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; | |||
| } | |||
| @@ -302,7 +302,7 @@ enum Vst3InternalParameters { | |||
| # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||
| kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount, | |||
| kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16, | |||
| kVst3InternalParameterCount | |||
| kVst3InternalParameterCount = kVst3InternalParameterMidiCC_end | |||
| # else | |||
| kVst3InternalParameterCount = kVst3InternalParameterBaseCount | |||
| # endif | |||
| @@ -39,6 +39,8 @@ namespace std { | |||
| /* TODO items: | |||
| * - mousewheel event | |||
| * - key down/up events | |||
| * - host-side resizing | |||
| * - file request? | |||
| */ | |||
| #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>; | |||
| // 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; | |||
| double sampleRate; | |||
| v3_plugin_frame** frame; | |||
| v3_run_loop** runloop; | |||
| int32_t nextWidth, nextHeight; | |||
| 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), | |||
| sampleRate(sr), | |||
| frame(nullptr), | |||
| runloop(nullptr), | |||
| nextWidth(0), | |||
| nextHeight(0) | |||
| { | |||
| @@ -995,6 +999,11 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||
| { | |||
| d_stdout("~dpf_plugin_view()"); | |||
| connection = nullptr; | |||
| scale = nullptr; | |||
| #ifdef DPF_VST3_USING_HOST_RUN_LOOP | |||
| timer = nullptr; | |||
| #endif | |||
| uivst3 = 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_connection_point**)&view->connection); | |||
| /* | |||
| if (dpf_ui_connection_point* const conn = view->connection) | |||
| { | |||
| if (const int refcount = conn->refcounter) | |||
| { | |||
| 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 (const int refcount = scale->refcounter) | |||
| { | |||
| 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_cpp_obj_query_interface(view->frame, v3_run_loop_iid, &runloop); | |||
| DISTRHO_SAFE_ASSERT_RETURN(runloop != nullptr, V3_INVALID_ARG); | |||
| view->runloop = runloop; | |||
| #endif | |||
| 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 | |||
| // 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); | |||
| // 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) | |||
| { | |||
| view->timer->valid = false; | |||
| @@ -1197,11 +1195,9 @@ struct dpf_plugin_view : v3_plugin_view_cpp { | |||
| 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 | |||
| @@ -176,7 +176,7 @@ struct v3_event_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 { | |||