DPF

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

commit 0dfcaeb3b7370c4aa39cb770b96a5c3a05c94520
parent 0f0bacab5d200b3177eec4a176f1bea74c04f424
Author: falkTX <falktx@gmail.com>
Date:   Tue, 19 Aug 2014 05:04:31 +0100

Complete LV2 state support, remove warning

Diffstat:
Mdistrho/src/DistrhoPluginLV2.cpp | 102+++++++++++++++++++++++++++++++++----------------------------------------------
Mdistrho/src/DistrhoUILV2.cpp | 37+++++++++++++++++++------------------
2 files changed, 62 insertions(+), 77 deletions(-)

diff --git a/distrho/src/DistrhoPluginLV2.cpp b/distrho/src/DistrhoPluginLV2.cpp @@ -34,15 +34,11 @@ #endif #include <map> -#include <string> #ifndef DISTRHO_PLUGIN_URI # error DISTRHO_PLUGIN_URI undefined! #endif -#if DISTRHO_PLUGIN_WANT_STATE -# warning LV2 State still TODO (working but needs final testing) -#endif #if DISTRHO_PLUGIN_WANT_TIMEPOS # warning LV2 TimePos still TODO #endif @@ -451,29 +447,20 @@ public: const d_string& key = fPlugin.getStateKey(i); - for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it) + for (StringMap::const_iterator cit=fStateMap.cbegin(), cite=fStateMap.cend(); cit != cite; ++cit) { - const d_string& curKey = it->first; + const d_string& curKey = cit->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); + const d_string& value = cit->second; - // 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); + // set msg size (key + value + separator + 2x null terminator) + const size_t msgSize(key.length()+value.length()+3); if (sizeof(LV2_Atom_Event) + msgSize > capacity - offset) - return; + break; if (needsInit) { @@ -484,17 +471,20 @@ public: 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); + // reserve msg space + char msgBuf[msgSize]; + std::memset(msgBuf, 0, msgSize); + + // write key and value in atom bufer + std::memcpy(msgBuf, key.buffer(), key.length()); + std::memcpy(msgBuf+(key.length()+1), value.buffer(), value.length()); // put data - aev = (LV2_Atom_Event*)((char*)LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fPortEventsOut) + offset); + aev = (LV2_Atom_Event*)(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); + std::memcpy(LV2_ATOM_BODY(&aev->body), msgBuf, msgSize-1); size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + msgSize); offset += size; @@ -525,12 +515,12 @@ public: { const int bufferSize(*(const int*)options[i].value); fPlugin.setBufferSize(bufferSize); - return LV2_OPTIONS_SUCCESS; + continue; } else { d_stderr("Host changed maxBlockLength but with wrong value type"); - return LV2_OPTIONS_ERR_BAD_VALUE; + continue; } } else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate)) @@ -539,17 +529,17 @@ public: { const double sampleRate(*(const double*)options[i].value); fPlugin.setSampleRate(sampleRate); - return LV2_OPTIONS_SUCCESS; + continue; } else { d_stderr("Host changed sampleRate but with wrong value type"); - return LV2_OPTIONS_ERR_BAD_VALUE; + continue; } } } - return LV2_OPTIONS_ERR_BAD_KEY; + return LV2_OPTIONS_SUCCESS; } // ------------------------------------------------------------------- @@ -595,16 +585,14 @@ public: // ------------------------------------------------------------------- #if DISTRHO_PLUGIN_WANT_STATE - LV2_State_Status lv2_save(const LV2_State_Store_Function store, const LV2_State_Handle handle, const uint32_t flags) + LV2_State_Status lv2_save(const LV2_State_Store_Function store, const LV2_State_Handle handle) { - //flags = LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE; - - for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it) + for (StringMap::const_iterator cit=fStateMap.cbegin(), cite=fStateMap.cend(); cit != cite; ++cit) { - const d_string& key = it->first; - const d_string& value = it->second; + const d_string& key = cit->first; + const d_string& value = cit->second; - store(handle, fUridMap->map(fUridMap->handle, (const char*)key), (const char*)value, value.length()+1, fURIDs.atomString, flags); + store(handle, fUridMap->map(fUridMap->handle, key.buffer()), value.buffer(), value.length(), fURIDs.atomString, LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE); } return LV2_STATE_SUCCESS; @@ -612,32 +600,28 @@ public: LV2_State_Status lv2_restore(const LV2_State_Retrieve_Function retrieve, const LV2_State_Handle handle) { - size_t size = 0; - uint32_t type = 0; - uint32_t flags = LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE; + size_t size; + uint32_t type, flags; for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i) { - const d_string& key = fPlugin.getStateKey(i); + const d_string& key(fPlugin.getStateKey(i)); - const void* data = retrieve(handle, fUridMap->map(fUridMap->handle, (const char*)key), &size, &type, &flags); + size = 0; + type = 0; + flags = LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE; + const void* data = retrieve(handle, fUridMap->map(fUridMap->handle, key.buffer()), &size, &type, &flags); - if (size == 0) - continue; - if (data == nullptr) - continue; - if (type != fURIDs.atomString) + if (data == nullptr || size == 0) continue; - const char* const value((const char*)data); + DISTRHO_SAFE_ASSERT_CONTINUE(type == fURIDs.atomString); - if (std::strlen(value) != size) - continue; + const char* const value((const char*)data); + DISTRHO_SAFE_ASSERT_CONTINUE(std::strlen(value) == size); 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; @@ -651,10 +635,10 @@ public: LV2_Worker_Status lv2_work(const void* const data) { - const char* const stateKey((const char*)data); - const char* const stateValue(stateKey+std::strlen(stateKey)+1); + const char* const key((const char*)data); + const char* const value(key+std::strlen(key)+1); - setState(stateKey, stateValue); + setState(key, value); return LV2_WORKER_SUCCESS; } @@ -767,9 +751,9 @@ private: return; // check if key already exists - for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it) + for (StringMap::iterator it=fStateMap.begin(), ite=fStateMap.end(); it != ite; ++it) { - const d_string& d_key = it->first; + const d_string& d_key(it->first); if (d_key == key) { @@ -924,9 +908,9 @@ static void lv2_select_program(LV2_Handle instance, uint32_t bank, uint32_t prog // ----------------------------------------------------------------------- #if DISTRHO_PLUGIN_WANT_STATE -static LV2_State_Status lv2_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const*) +static LV2_State_Status lv2_save(LV2_Handle instance, LV2_State_Store_Function store, LV2_State_Handle handle, uint32_t, const LV2_Feature* const*) { - return instancePtr->lv2_save(store, handle, flags); + return instancePtr->lv2_save(store, handle); } static LV2_State_Status lv2_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t, const LV2_Feature* const*) diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp @@ -16,6 +16,8 @@ #include "DistrhoUIInternal.hpp" +#include "../extra/d_string.hpp" + #include "lv2/atom.h" #include "lv2/atom-util.h" #include "lv2/data-access.h" @@ -25,8 +27,6 @@ #include "lv2/urid.h" #include "lv2/lv2_programs.h" -#include <string> - START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------- @@ -115,13 +115,12 @@ public: { const LV2_Atom* const atom((const LV2_Atom*)buffer); - // TODO - check atom type + DISTRHO_SAFE_ASSERT_RETURN(atom->type == fKeyValueURID,); - const char* const stateKey((const char*)LV2_ATOM_BODY_CONST(atom)); - const char* const stateValue(stateKey+std::strlen(stateKey)+1); + const char* const key = (const char*)LV2_ATOM_BODY_CONST(atom); + const char* const value = key+(std::strlen(key)+1); - d_stdout("Got MSG in UI from DSP ==> %s | %s", stateKey, stateValue); - fUI.stateChanged(stateKey, stateValue); + fUI.stateChanged(key, value); } #endif } @@ -168,25 +167,27 @@ protected: void setParameterValue(const uint32_t rindex, const float value) { - if (fWriteFunction != nullptr) - fWriteFunction(fController, rindex, sizeof(float), 0, &value); + DISTRHO_SAFE_ASSERT_RETURN(fWriteFunction != nullptr,); + + fWriteFunction(fController, rindex, sizeof(float), 0, &value); } void setState(const char* const key, const char* const value) { - if (fWriteFunction == nullptr) - return; + DISTRHO_SAFE_ASSERT_RETURN(fWriteFunction != nullptr,); const uint32_t eventInPortIndex(DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS); // join key and value - std::string tmpStr; - tmpStr += std::string(key); - tmpStr += std::string("\0", 1); - tmpStr += std::string(value); + d_string tmpStr; + tmpStr += key; + tmpStr += "\xff"; + tmpStr += value; + + tmpStr[std::strlen(key)] = '\0'; - // get msg size - const size_t msgSize(tmpStr.size()+1); + // set msg size (key + separator + value + null terminator) + const size_t msgSize(tmpStr.length()+1); // reserve atom space const size_t atomSize(lv2_atom_pad_size(sizeof(LV2_Atom) + msgSize)); @@ -199,7 +200,7 @@ protected: atom->type = fKeyValueURID; // set atom data - std::memcpy(atomBuf + sizeof(LV2_Atom), tmpStr.data(), msgSize-1); + std::memcpy(atomBuf + sizeof(LV2_Atom), tmpStr.buffer(), msgSize); // send to DSP side fWriteFunction(fController, eventInPortIndex, atomSize, fEventTransferURID, atom);