summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2014-04-26 01:13:51 +1000
committerDamien Zammit <damien@zamaudio.com>2014-04-26 01:13:51 +1000
commite44944f0b4164b879119a195b6bc97713b66d07b (patch)
tree8a1c5297edc978a493c387867d9f086d978cf60d
parent013c381724758e54650d3b6d5d2c7081f3a40c51 (diff)
parentbc4c5cfa53b543e88368ae478436e862b34057e2 (diff)
Merge pull request #9 from falkTX/master
lv2 ui state stuff
-rw-r--r--libs/distrho/src/DistrhoPluginLV2.cpp113
-rw-r--r--libs/distrho/src/DistrhoPluginLV2export.cpp14
-rw-r--r--libs/distrho/src/DistrhoUILV2.cpp24
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