diff options
author | Damien Zammit <damien@zamaudio.com> | 2014-04-26 01:13:51 +1000 |
---|---|---|
committer | Damien Zammit <damien@zamaudio.com> | 2014-04-26 01:13:51 +1000 |
commit | e44944f0b4164b879119a195b6bc97713b66d07b (patch) | |
tree | 8a1c5297edc978a493c387867d9f086d978cf60d | |
parent | 013c381724758e54650d3b6d5d2c7081f3a40c51 (diff) | |
parent | bc4c5cfa53b543e88368ae478436e862b34057e2 (diff) |
Merge pull request #9 from falkTX/master
lv2 ui state stuff
-rw-r--r-- | libs/distrho/src/DistrhoPluginLV2.cpp | 113 | ||||
-rw-r--r-- | libs/distrho/src/DistrhoPluginLV2export.cpp | 14 | ||||
-rw-r--r-- | libs/distrho/src/DistrhoUILV2.cpp | 24 |
3 files changed, 137 insertions, 14 deletions
diff --git a/libs/distrho/src/DistrhoPluginLV2.cpp b/libs/distrho/src/DistrhoPluginLV2.cpp index 17b16c1..0e359c1 100644 --- a/libs/distrho/src/DistrhoPluginLV2.cpp +++ b/libs/distrho/src/DistrhoPluginLV2.cpp @@ -110,6 +110,20 @@ public: #if DISTRHO_PLUGIN_WANT_LATENCY fPortLatency = nullptr; #endif + +#if DISTRHO_PLUGIN_WANT_STATE + if (const uint32_t count = fPlugin.getStateCount()) + { + fNeededUiSends = new bool[count]; + + for (uint32_t i=0; i < count; ++i) + fNeededUiSends[i] = false; + } + else + { + fNeededUiSends = nullptr; + } +#endif } ~PluginLv2() @@ -127,6 +141,12 @@ public: } #if DISTRHO_PLUGIN_WANT_STATE + if (fNeededUiSends != nullptr) + { + delete[] fNeededUiSends; + fNeededUiSends = nullptr; + } + fStateMap.clear(); #endif } @@ -384,7 +404,18 @@ public: if (event->body.type == fURIDs.distrhoState && fWorker != nullptr) { const void* const data((const void*)(event + 1)); - fWorker->schedule_work(fWorker->handle, event->body.size, data); + + // check if this is our special message + if (std::strcmp((const char*)data, "__dpf_ui_data__") == 0) + { + for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) + fNeededUiSends[i] = true; + } + else + // no, send to DSP as usual + { + fWorker->schedule_work(fWorker->handle, event->body.size, data); + } continue; } @@ -404,10 +435,76 @@ public: fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); #endif + updateParameterOutputs(); + #if DISTRHO_LV2_USE_EVENTS_OUT -#endif + const uint32_t capacity = fPortEventsOut->atom.size; - updateParameterOutputs(); + bool needsInit = true; + uint32_t size, offset = 0; + LV2_Atom_Event* aev; + + for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) + { + if (! fNeededUiSends[i]) + continue; + + const d_string& key = fPlugin.getStateKey(i); + + for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it) + { + const d_string& curKey = it->first; + + if (curKey != key) + continue; + + const d_string& value = it->second; + + // TODO - RT safe + d_stdout("Got msg (from DSP to UI via host):\n%s\n%s", (const char*)key, (const char*)value); + + // join key and value + std::string tmpStr; + tmpStr += std::string(key); + tmpStr += std::string("\0", 1); + tmpStr += std::string(value); + + // get msg size + const size_t msgSize(tmpStr.size()+1); + + if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset) + return; + + if (needsInit) + { + fPortEventsOut->atom.size = 0; + fPortEventsOut->atom.type = fURIDs.atomSequence; + fPortEventsOut->body.unit = 0; + fPortEventsOut->body.pad = 0; + needsInit = false; + } + + // reserve atom space + const size_t atomSize(lv2_atom_pad_size(sizeof(LV2_Atom) + msgSize)); + char atomBuf[atomSize]; + std::memset(atomBuf, 0, atomSize); + + // put data + aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fPortEventsOut) + offset); + aev->time.frames = 0; + aev->body.type = fURIDs.distrhoState; + aev->body.size = msgSize; + std::memcpy(LV2_ATOM_BODY(&aev->body), tmpStr.data(), msgSize-1); + + size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + msgSize); + offset += size; + fPortEventsOut->atom.size += size; + + fNeededUiSends[i] = false; + break; + } + } +#endif } // ------------------------------------------------------------------- @@ -538,6 +635,13 @@ public: continue; setState(key, value); + + d_stdout("Got state msg:\n%s\n%s", (const char*)key, value); + +#if DISTRHO_LV2_USE_EVENTS_OUT + // signal msg needed for UI + fNeededUiSends[i] = true; +#endif } return LV2_STATE_SUCCESS; @@ -610,6 +714,7 @@ private: LV2_URID atomFloat; LV2_URID atomInt; LV2_URID atomLong; + LV2_URID atomSequence; LV2_URID atomString; LV2_URID distrhoState; LV2_URID midiEvent; @@ -629,6 +734,7 @@ private: atomFloat(uridMap->map(uridMap->handle, LV2_ATOM__Float)), atomInt(uridMap->map(uridMap->handle, LV2_ATOM__Int)), atomLong(uridMap->map(uridMap->handle, LV2_ATOM__Long)), + atomSequence(uridMap->map(uridMap->handle, LV2_ATOM__Sequence)), atomString(uridMap->map(uridMap->handle, LV2_ATOM__String)), distrhoState(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")), midiEvent(uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent)), @@ -650,6 +756,7 @@ private: #if DISTRHO_PLUGIN_WANT_STATE StringMap fStateMap; + bool* fNeededUiSends; void setState(const char* const key, const char* const newValue) { diff --git a/libs/distrho/src/DistrhoPluginLV2export.cpp b/libs/distrho/src/DistrhoPluginLV2export.cpp index 59dd088..a920f40 100644 --- a/libs/distrho/src/DistrhoPluginLV2export.cpp +++ b/libs/distrho/src/DistrhoPluginLV2export.cpp @@ -22,6 +22,7 @@ #include "lv2/instance-access.h" #include "lv2/midi.h" #include "lv2/options.h" +#include "lv2/resize-port.h" #include "lv2/state.h" #include "lv2/time.h" #include "lv2/ui.h" @@ -37,6 +38,10 @@ # error DISTRHO_PLUGIN_URI undefined! #endif +#ifndef DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE +# define DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE 2048 +#endif + #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) @@ -130,7 +135,7 @@ void lv2_generate_ttl(const char* const basename) pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; - pluginString += "@prefix resizeatom: <http://lv2plug.in/ns/ext/resize-port#> .\n"; + pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n"; #if DISTRHO_PLUGIN_HAS_UI pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; #endif @@ -152,9 +157,6 @@ void lv2_generate_ttl(const char* const basename) pluginString += ",\n <" LV2_OPTIONS__interface "> "; pluginString += ",\n <" LV2_WORKER__interface "> "; #endif -#if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT - pluginString += ",\n resizeatom:interface "; -#endif #if DISTRHO_PLUGIN_WANT_PROGRAMS pluginString += ",\n <" LV2_PROGRAMS__Interface "> "; #endif @@ -230,8 +232,8 @@ void lv2_generate_ttl(const char* const basename) pluginString += " lv2:index " + d_string(portIndex) + " ;\n"; pluginString += " lv2:name \"Events Input\" ;\n"; pluginString += " lv2:symbol \"lv2_events_in\" ;\n"; + pluginString += " rsz:minimumSize " + d_string(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n"; pluginString += " atom:bufferType atom:Sequence ;\n"; - pluginString += " resizeatom:minimumSize 2048 ;\n"; # if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) pluginString += " atom:supports <" LV2_ATOM__String "> ;\n"; # endif @@ -252,7 +254,7 @@ void lv2_generate_ttl(const char* const basename) pluginString += " lv2:index " + d_string(portIndex) + " ;\n"; pluginString += " lv2:name \"Events Output\" ;\n"; pluginString += " lv2:symbol \"lv2_events_out\" ;\n"; - pluginString += " resizeatom:minimumSize 2048 ;\n"; + pluginString += " rsz:minimumSize " + d_string(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n"; pluginString += " atom:bufferType atom:Sequence ;\n"; pluginString += " atom:supports <" LV2_ATOM__String "> ;\n"; pluginString += " ] ;\n\n"; diff --git a/libs/distrho/src/DistrhoUILV2.cpp b/libs/distrho/src/DistrhoUILV2.cpp index d535e23..1c8f4f3 100644 --- a/libs/distrho/src/DistrhoUILV2.cpp +++ b/libs/distrho/src/DistrhoUILV2.cpp @@ -40,9 +40,14 @@ public: fUiResize(uiResz), fUiTouch(uiTouch), fController(controller), - fWriteFunction(writeFunc) + fWriteFunction(writeFunc), + fEventTransferURID(uridMap->map(uridMap->handle, LV2_ATOM__eventTransfer)), + fKeyValueURID(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")) { fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight()); + + // tell the DSP we're ready to receive msgs + setState("__dpf_ui_data__", ""); } // ------------------------------------------------------------------- @@ -61,9 +66,14 @@ public: const float value(*(const float*)buffer); fUI.parameterChanged(rindex-parameterOffset, value); } - else + else if (format == fEventTransferURID) { - //fUI.stateChanged(key, value); + const LV2_Atom* const atom((const LV2_Atom*)buffer); + const char* const stateKey((const char*)LV2_ATOM_BODY_CONST(atom)); + const char* const stateValue(stateKey+std::strlen(stateKey)+1); + + d_stdout("Got MSG in UI from DSP ==> %s | %s", stateKey, stateValue); + fUI.stateChanged(stateKey, stateValue); } } @@ -125,13 +135,13 @@ protected: // set atom info LV2_Atom* const atom((LV2_Atom*)atomBuf); atom->size = msgSize; - atom->type = fUridMap->map(fUridMap->handle, "urn:distrho:keyValueState"); + atom->type = fKeyValueURID; // set atom data std::memcpy(atomBuf + sizeof(LV2_Atom), tmpStr.data(), msgSize-1); // send to DSP side - fWriteFunction(fController, eventInPortIndex, atomSize, fUridMap->map(fUridMap->handle, LV2_ATOM__eventTransfer), atom); + fWriteFunction(fController, eventInPortIndex, atomSize, fEventTransferURID, atom); } void sendNote(const uint8_t /*channel*/, const uint8_t /*note*/, const uint8_t /*velocity*/) @@ -156,6 +166,10 @@ private: const LV2UI_Controller fController; const LV2UI_Write_Function fWriteFunction; + // Need to save this + const LV2_URID fEventTransferURID; + const LV2_URID fKeyValueURID; + // ------------------------------------------------------------------- // Callbacks |