DPF

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

commit 1e4941fa69595515d00d0d2aa4a30832ae1ebc19
parent 5ee20f23adcbaa9267a90857b6b6f6cf8f69e7fa
Author: falkTX <falktx@gmail.com>
Date:   Sun, 20 Apr 2014 11:57:16 +0100

Fix VST state build; Add possible UI<->DSP direct access

Diffstat:
Mdistrho/DistrhoUI.hpp | 7+++++++
Mdistrho/src/DistrhoDefines.h | 4++++
Mdistrho/src/DistrhoPluginCarla.cpp | 2+-
Mdistrho/src/DistrhoPluginInternal.hpp | 5+++++
Mdistrho/src/DistrhoPluginLV2.cpp | 33+++++++++++++++++++++++++++++++++
Mdistrho/src/DistrhoPluginLV2export.cpp | 16+++++++++++++---
Mdistrho/src/DistrhoPluginVST.cpp | 2+-
Mdistrho/src/DistrhoUI.cpp | 10++++++++++
Mdistrho/src/DistrhoUIDSSI.cpp | 4++++
Mdistrho/src/DistrhoUIInternal.hpp | 15++++++++++++++-
Mdistrho/src/DistrhoUILV2.cpp | 42+++++++++++++++++++++++++++++++++++++++---
11 files changed, 131 insertions(+), 9 deletions(-)

diff --git a/distrho/DistrhoUI.hpp b/distrho/DistrhoUI.hpp @@ -74,6 +74,13 @@ protected: virtual void d_uiIdle() {} +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + // ------------------------------------------------------------------- + // Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! + + void* d_getPluginInstancePointer(); +#endif + // ------------------------------------------------------------------- private: diff --git a/distrho/src/DistrhoDefines.h b/distrho/src/DistrhoDefines.h @@ -55,6 +55,10 @@ # error DISTRHO_PLUGIN_WANT_TIMEPOS undefined! #endif +#ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +# define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0 +#endif + /* Compatibility with non-clang compilers */ #ifndef __has_feature # define __has_feature(x) 0 diff --git a/distrho/src/DistrhoPluginCarla.cpp b/distrho/src/DistrhoPluginCarla.cpp @@ -43,7 +43,7 @@ public: UICarla(const NativeHostDescriptor* const host, PluginExporter* const plugin) : fHost(host), fPlugin(plugin), - fUI(this, 0, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback) + fUI(this, 0, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback, plugin->getInstancePointer()) { fUI.setTitle(host->uiName); diff --git a/distrho/src/DistrhoPluginInternal.hpp b/distrho/src/DistrhoPluginInternal.hpp @@ -173,6 +173,11 @@ public: return (fPlugin != nullptr) ? fPlugin->d_getUniqueId() : 0; } + void* getInstancePointer() const noexcept + { + return fPlugin; + } + // ------------------------------------------------------------------- #if DISTRHO_PLUGIN_WANT_LATENCY diff --git a/distrho/src/DistrhoPluginLV2.cpp b/distrho/src/DistrhoPluginLV2.cpp @@ -19,6 +19,8 @@ #include "lv2/atom.h" #include "lv2/atom-util.h" #include "lv2/buf-size.h" +#include "lv2/data-access.h" +#include "lv2/instance-access.h" #include "lv2/midi.h" #include "lv2/options.h" #include "lv2/state.h" @@ -556,6 +558,15 @@ public: // ------------------------------------------------------------------- +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + void* lv2_get_instance_pointer() + { + return fPlugin.getInstancePointer(); + } +#endif + + // ------------------------------------------------------------------- + private: PluginExporter fPlugin; @@ -824,6 +835,15 @@ LV2_Worker_Status lv2_work(LV2_Handle instance, LV2_Worker_Respond_Function, LV2 // ----------------------------------------------------------------------- +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +static void* lv2_get_instance_pointer(LV2_Handle instance) +{ + return instancePtr->lv2_get_instance_pointer(); +} +#endif + +// ----------------------------------------------------------------------- + static const void* lv2_extension_data(const char* uri) { static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options }; @@ -848,6 +868,19 @@ static const void* lv2_extension_data(const char* uri) return &worker; #endif +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +# define DISTRHO_DIRECT_ACCESS_URI "urn:distrho:direct-access" + + struct LV2_DirectAccess_Interface { + void* (*get_instance_pointer)(LV2_Handle handle); + }; + + static const LV2_DirectAccess_Interface directaccess = { lv2_get_instance_pointer }; + + if (std::strcmp(uri, DISTRHO_DIRECT_ACCESS_URI) == 0) + return &directaccess; +#endif + return nullptr; } diff --git a/distrho/src/DistrhoPluginLV2export.cpp b/distrho/src/DistrhoPluginLV2export.cpp @@ -18,6 +18,8 @@ #include "lv2/atom.h" #include "lv2/buf-size.h" +#include "lv2/data-access.h" +#include "lv2/instance-access.h" #include "lv2/midi.h" #include "lv2/options.h" #include "lv2/state.h" @@ -86,16 +88,24 @@ void lv2_generate_ttl(const char* const basename) # else manifestString += " a ui:X11UI ;\n"; # endif +# if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS manifestString += " ui:binary <" + pluginLabel + "_ui." DISTRHO_DLL_EXTENSION "> ;\n"; -#if DISTRHO_PLUGIN_WANT_PROGRAMS +# else + manifestString += " ui:binary <" + pluginLabel + "." DISTRHO_DLL_EXTENSION "> ;\n"; +#endif +# if DISTRHO_PLUGIN_WANT_PROGRAMS manifestString += " lv2:extensionData ui:idleInterface ,\n"; manifestString += " <" LV2_PROGRAMS__Interface "> ;\n"; -#else +# else manifestString += " lv2:extensionData ui:idleInterface ;\n"; -#endif +# endif manifestString += " lv2:optionalFeature ui:noUserResize ,\n"; manifestString += " ui:touch ;\n"; manifestString += " lv2:requiredFeature ui:resize ,\n"; +# if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + manifestString += " <" LV2_DATA_ACCESS_URI "> ,\n"; + manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n"; +# endif manifestString += " <" LV2_OPTIONS__options "> ,\n"; manifestString += " <" LV2_URID__map "> .\n"; #endif diff --git a/distrho/src/DistrhoPluginVST.cpp b/distrho/src/DistrhoPluginVST.cpp @@ -119,7 +119,7 @@ public: fEffect(effect), fUiHelper(uiHelper), fPlugin(plugin), - fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback) + fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback, plugin->getInstancePointer()) { } diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp @@ -84,6 +84,16 @@ void UI::d_uiResize(unsigned int width, unsigned int height) pData->uiResizeCallback(width, height); } +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +// ----------------------------------------------------------------------- +// Direct DSP access + +void* UI::d_getPluginInstancePointer() +{ + return pData->dspPtr; +} +#endif + // ----------------------------------------------------------------------- END_NAMESPACE_DISTRHO diff --git a/distrho/src/DistrhoUIDSSI.cpp b/distrho/src/DistrhoUIDSSI.cpp @@ -16,6 +16,10 @@ #include "DistrhoUIInternal.hpp" +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +# error DSSI UIs do not support direct access! +#endif + #include <lo/lo.h> START_NAMESPACE_DISTRHO diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp @@ -45,6 +45,9 @@ struct UI::PrivateData { // DSP double sampleRate; uint32_t parameterOffset; +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + void* dspPtr; +#endif // Callbacks editParamFunc editParamCallbackFunc; @@ -57,6 +60,9 @@ struct UI::PrivateData { PrivateData() noexcept : sampleRate(d_lastUiSampleRate), parameterOffset(0), +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + dspPtr(nullptr), +#endif editParamCallbackFunc(nullptr), setParamCallbackFunc(nullptr), setStateCallbackFunc(nullptr), @@ -120,7 +126,7 @@ class UIExporter { public: UIExporter(void* const ptr, const intptr_t winId, - const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const uiResizeFunc uiResizeCall) + const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const uiResizeFunc uiResizeCall, void* const dspPtr = nullptr) : glApp(), glWindow(glApp, winId), fUi(createUI()), @@ -140,6 +146,13 @@ public: glWindow.setSize(fUi->d_getWidth(), fUi->d_getHeight()); glWindow.setResizable(false); + +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + fData->dspPtr = dspPtr; +#else + return; // unused + (void)dspPtr; +#endif } ~UIExporter() diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp @@ -18,6 +18,8 @@ #include "lv2/atom.h" #include "lv2/atom-util.h" +#include "lv2/data-access.h" +#include "lv2/instance-access.h" #include "lv2/options.h" #include "lv2/ui.h" #include "lv2/urid.h" @@ -32,8 +34,8 @@ START_NAMESPACE_DISTRHO class UiLv2 { public: - UiLv2(const intptr_t winId, const LV2_URID_Map* const uridMap, const LV2UI_Resize* const uiResz, const LV2UI_Touch* uiTouch, const LV2UI_Controller controller, const LV2UI_Write_Function writeFunc) - : fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback), + UiLv2(const intptr_t winId, const LV2_URID_Map* const uridMap, const LV2UI_Resize* const uiResz, const LV2UI_Touch* uiTouch, const LV2UI_Controller controller, const LV2UI_Write_Function writeFunc, void* const dspPtr) + : fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback, dspPtr), fUridMap(uridMap), fUiResize(uiResz), fUiTouch(uiTouch), @@ -202,6 +204,16 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, const LV2UI_Resize* uiResize = nullptr; const LV2UI_Touch* uiTouch = nullptr; void* parentId = nullptr; + void* instance = nullptr; + +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +# define DISTRHO_DIRECT_ACCESS_URI "urn:distrho:direct-access" + + struct LV2_DirectAccess_Interface { + void* (*get_instance_pointer)(LV2_Handle handle); + }; + const LV2_Extension_Data_Feature* extData = nullptr; +#endif for (int i=0; features[i] != nullptr; ++i) { @@ -213,6 +225,12 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, uiResize = (const LV2UI_Resize*)features[i]->data; else if (std::strcmp(features[i]->URI, LV2_UI__parent) == 0) parentId = features[i]->data; +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + else if (std::strcmp(features[i]->URI, LV2_DATA_ACCESS_URI) == 0) + extData = (const LV2_Extension_Data_Feature*)features[i]->data; + else if (std::strcmp(features[i]->URI, LV2_INSTANCE_ACCESS_URI) == 0) + instance = features[i]->data; +#endif } if (options == nullptr) @@ -239,6 +257,24 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, return nullptr; } +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS + if (extData == nullptr || instance == nullptr) + { + d_stderr("Data or instance access missing, cannot continue!"); + return nullptr; + } + + if (const LV2_DirectAccess_Interface* const directAccess = (const LV2_DirectAccess_Interface*)extData->data_access(DISTRHO_DIRECT_ACCESS_URI)) + { + instance = directAccess->get_instance_pointer(instance); + } + else + { + d_stderr("Failed to get direct access, cannot continue!"); + return nullptr; + } +#endif + *widget = parentId; const intptr_t winId(*((intptr_t*)&parentId)); @@ -259,7 +295,7 @@ static LV2UI_Handle lv2ui_instantiate(const LV2UI_Descriptor*, const char* uri, if (d_lastUiSampleRate == 0.0) d_lastUiSampleRate = 44100.0; - return new UiLv2(winId, uridMap, uiResize, uiTouch, controller, writeFunction); + return new UiLv2(winId, uridMap, uiResize, uiTouch, controller, writeFunction, instance); } #define uiPtr ((UiLv2*)ui)