Browse Source

Import code for lv2 state UI

gh-pages
falkTX 11 years ago
parent
commit
efe9d4bab1
3 changed files with 142 additions and 8 deletions
  1. +111
    -3
      distrho/src/DistrhoPluginLV2.cpp
  2. +8
    -0
      distrho/src/DistrhoPluginLV2export.cpp
  3. +23
    -5
      distrho/src/DistrhoUILV2.cpp

+ 111
- 3
distrho/src/DistrhoPluginLV2.cpp View File

@@ -34,6 +34,7 @@
#endif #endif


#include <map> #include <map>
#include <string>


#ifndef DISTRHO_PLUGIN_URI #ifndef DISTRHO_PLUGIN_URI
# error DISTRHO_PLUGIN_URI undefined! # error DISTRHO_PLUGIN_URI undefined!
@@ -110,6 +111,20 @@ public:
#if DISTRHO_PLUGIN_WANT_LATENCY #if DISTRHO_PLUGIN_WANT_LATENCY
fPortLatency = nullptr; fPortLatency = nullptr;
#endif #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() ~PluginLv2()
@@ -127,6 +142,12 @@ public:
} }


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
if (fNeededUiSends != nullptr)
{
delete[] fNeededUiSends;
fNeededUiSends = nullptr;
}

fStateMap.clear(); fStateMap.clear();
#endif #endif
} }
@@ -384,7 +405,18 @@ public:
if (event->body.type == fURIDs.distrhoState && fWorker != nullptr) if (event->body.type == fURIDs.distrhoState && fWorker != nullptr)
{ {
const void* const data((const void*)(event + 1)); 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; continue;
} }
@@ -404,10 +436,76 @@ public:
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount); fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount);
#endif #endif


updateParameterOutputs();

#if DISTRHO_LV2_USE_EVENTS_OUT #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 +636,13 @@ public:
continue; continue;


setState(key, value); 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; return LV2_STATE_SUCCESS;
@@ -610,6 +715,7 @@ private:
LV2_URID atomFloat; LV2_URID atomFloat;
LV2_URID atomInt; LV2_URID atomInt;
LV2_URID atomLong; LV2_URID atomLong;
LV2_URID atomSequence;
LV2_URID atomString; LV2_URID atomString;
LV2_URID distrhoState; LV2_URID distrhoState;
LV2_URID midiEvent; LV2_URID midiEvent;
@@ -629,6 +735,7 @@ private:
atomFloat(uridMap->map(uridMap->handle, LV2_ATOM__Float)), atomFloat(uridMap->map(uridMap->handle, LV2_ATOM__Float)),
atomInt(uridMap->map(uridMap->handle, LV2_ATOM__Int)), atomInt(uridMap->map(uridMap->handle, LV2_ATOM__Int)),
atomLong(uridMap->map(uridMap->handle, LV2_ATOM__Long)), atomLong(uridMap->map(uridMap->handle, LV2_ATOM__Long)),
atomSequence(uridMap->map(uridMap->handle, LV2_ATOM__Sequence)),
atomString(uridMap->map(uridMap->handle, LV2_ATOM__String)), atomString(uridMap->map(uridMap->handle, LV2_ATOM__String)),
distrhoState(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")), distrhoState(uridMap->map(uridMap->handle, "urn:distrho:keyValueState")),
midiEvent(uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent)), midiEvent(uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent)),
@@ -650,6 +757,7 @@ private:


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
StringMap fStateMap; StringMap fStateMap;
bool* fNeededUiSends;


void setState(const char* const key, const char* const newValue) void setState(const char* const key, const char* const newValue)
{ {


+ 8
- 0
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -22,6 +22,7 @@
#include "lv2/instance-access.h" #include "lv2/instance-access.h"
#include "lv2/midi.h" #include "lv2/midi.h"
#include "lv2/options.h" #include "lv2/options.h"
#include "lv2/resize-port.h"
#include "lv2/state.h" #include "lv2/state.h"
#include "lv2/time.h" #include "lv2/time.h"
#include "lv2/ui.h" #include "lv2/ui.h"
@@ -37,6 +38,10 @@
# error DISTRHO_PLUGIN_URI undefined! # error DISTRHO_PLUGIN_URI undefined!
#endif #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_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) #define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)


@@ -130,6 +135,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n";
#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n";
#endif #endif
@@ -226,6 +232,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " lv2:index " + d_string(portIndex) + " ;\n"; pluginString += " lv2:index " + d_string(portIndex) + " ;\n";
pluginString += " lv2:name \"Events Input\" ;\n"; pluginString += " lv2:name \"Events Input\" ;\n";
pluginString += " lv2:symbol \"lv2_events_in\" ;\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 += " atom:bufferType atom:Sequence ;\n";
# if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) # if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)
pluginString += " atom:supports <" LV2_ATOM__String "> ;\n"; pluginString += " atom:supports <" LV2_ATOM__String "> ;\n";
@@ -247,6 +254,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " lv2:index " + d_string(portIndex) + " ;\n"; pluginString += " lv2:index " + d_string(portIndex) + " ;\n";
pluginString += " lv2:name \"Events Output\" ;\n"; pluginString += " lv2:name \"Events Output\" ;\n";
pluginString += " lv2:symbol \"lv2_events_out\" ;\n"; pluginString += " lv2:symbol \"lv2_events_out\" ;\n";
pluginString += " rsz:minimumSize " + d_string(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n";
pluginString += " atom:bufferType atom:Sequence ;\n"; pluginString += " atom:bufferType atom:Sequence ;\n";
pluginString += " atom:supports <" LV2_ATOM__String "> ;\n"; pluginString += " atom:supports <" LV2_ATOM__String "> ;\n";
pluginString += " ] ;\n\n"; pluginString += " ] ;\n\n";


+ 23
- 5
distrho/src/DistrhoUILV2.cpp View File

@@ -40,9 +40,16 @@ public:
fUiResize(uiResz), fUiResize(uiResz),
fUiTouch(uiTouch), fUiTouch(uiTouch),
fController(controller), 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()); fUiResize->ui_resize(fUiResize->handle, fUI.getWidth(), fUI.getHeight());

#if DISTRHO_PLUGIN_WANT_STATE
// tell the DSP we're ready to receive msgs
setState("__dpf_ui_data__", "");
#endif
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -61,10 +68,17 @@ public:
const float value(*(const float*)buffer); const float value(*(const float*)buffer);
fUI.parameterChanged(rindex-parameterOffset, value); fUI.parameterChanged(rindex-parameterOffset, value);
} }
else
#if DISTRHO_PLUGIN_WANT_STATE
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);
} }
#endif
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -125,13 +139,13 @@ protected:
// set atom info // set atom info
LV2_Atom* const atom((LV2_Atom*)atomBuf); LV2_Atom* const atom((LV2_Atom*)atomBuf);
atom->size = msgSize; atom->size = msgSize;
atom->type = fUridMap->map(fUridMap->handle, "urn:distrho:keyValueState");
atom->type = fKeyValueURID;


// set atom data // set atom data
std::memcpy(atomBuf + sizeof(LV2_Atom), tmpStr.data(), msgSize-1); std::memcpy(atomBuf + sizeof(LV2_Atom), tmpStr.data(), msgSize-1);


// send to DSP side // 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*/) void sendNote(const uint8_t /*channel*/, const uint8_t /*note*/, const uint8_t /*velocity*/)
@@ -156,6 +170,10 @@ private:
const LV2UI_Controller fController; const LV2UI_Controller fController;
const LV2UI_Write_Function fWriteFunction; const LV2UI_Write_Function fWriteFunction;


// Need to save this
const LV2_URID fEventTransferURID;
const LV2_URID fKeyValueURID;

// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Callbacks // Callbacks




Loading…
Cancel
Save