Browse Source

Start API for changing state from DSP

Signed-off-by: falkTX <falktx@falktx.com>
pull/375/head
parent
commit
53fd80aa9c
5 changed files with 80 additions and 13 deletions
  1. +9
    -0
      distrho/DistrhoPlugin.hpp
  2. +7
    -0
      distrho/src/DistrhoPlugin.cpp
  3. +17
    -1
      distrho/src/DistrhoPluginInternal.hpp
  4. +46
    -11
      distrho/src/DistrhoPluginLV2.cpp
  5. +1
    -1
      distrho/src/DistrhoPluginLV2export.cpp

+ 9
- 0
distrho/DistrhoPlugin.hpp View File

@@ -926,6 +926,15 @@ public:
bool requestParameterValueChange(uint32_t index, float value) noexcept; bool requestParameterValueChange(uint32_t index, float value) noexcept;
#endif #endif


#if DISTRHO_PLUGIN_WANT_STATE
/**
Notify the host about a state value change.
This function will automatically trigger a state update on the UI side.
It must not be called during run.
*/
bool updateStateValue(const char* key, const char* value) noexcept;
#endif

protected: protected:
/* -------------------------------------------------------------------------------------------------------- /* --------------------------------------------------------------------------------------------------------
* Information */ * Information */


+ 7
- 0
distrho/src/DistrhoPlugin.cpp View File

@@ -145,6 +145,13 @@ bool Plugin::requestParameterValueChange(const uint32_t index, const float value
} }
#endif #endif


#if DISTRHO_PLUGIN_WANT_STATE
bool Plugin::updateStateValue(const char* const key, const char* const value) noexcept
{
return pData->updateStateValueCallback(key, value);
}
#endif

/* ------------------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------------------
* Init */ * Init */




+ 17
- 1
distrho/src/DistrhoPluginInternal.hpp View File

@@ -46,6 +46,7 @@ extern bool d_nextCanRequestParameterValueChanges;


typedef bool (*writeMidiFunc) (void* ptr, const MidiEvent& midiEvent); typedef bool (*writeMidiFunc) (void* ptr, const MidiEvent& midiEvent);
typedef bool (*requestParameterValueChangeFunc) (void* ptr, uint32_t index, float value); typedef bool (*requestParameterValueChangeFunc) (void* ptr, uint32_t index, float value);
typedef bool (*updateStateValueFunc) (void* ptr, const char* key, const char* value);


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Helpers // Helpers
@@ -127,6 +128,7 @@ struct Plugin::PrivateData {
void* callbacksPtr; void* callbacksPtr;
writeMidiFunc writeMidiCallbackFunc; writeMidiFunc writeMidiCallbackFunc;
requestParameterValueChangeFunc requestParameterValueChangeCallbackFunc; requestParameterValueChangeFunc requestParameterValueChangeCallbackFunc;
updateStateValueFunc updateStateValueCallbackFunc;


uint32_t bufferSize; uint32_t bufferSize;
double sampleRate; double sampleRate;
@@ -159,6 +161,7 @@ struct Plugin::PrivateData {
callbacksPtr(nullptr), callbacksPtr(nullptr),
writeMidiCallbackFunc(nullptr), writeMidiCallbackFunc(nullptr),
requestParameterValueChangeCallbackFunc(nullptr), requestParameterValueChangeCallbackFunc(nullptr),
updateStateValueCallbackFunc(nullptr),
bufferSize(d_nextBufferSize), bufferSize(d_nextBufferSize),
sampleRate(d_nextSampleRate), sampleRate(d_nextSampleRate),
bundlePath(d_nextBundlePath != nullptr ? strdup(d_nextBundlePath) : nullptr) bundlePath(d_nextBundlePath != nullptr ? strdup(d_nextBundlePath) : nullptr)
@@ -257,6 +260,17 @@ struct Plugin::PrivateData {
return false; return false;
} }
#endif #endif

#if DISTRHO_PLUGIN_WANT_STATE
bool updateStateValueCallback(const char* const key, const char* const value)
{
d_stdout("updateStateValueCallback %p", updateStateValueCallbackFunc);
if (updateStateValueCallbackFunc != nullptr)
return updateStateValueCallbackFunc(callbacksPtr, key, value);

return false;
}
#endif
}; };


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -267,7 +281,8 @@ class PluginExporter
public: public:
PluginExporter(void* const callbacksPtr, PluginExporter(void* const callbacksPtr,
const writeMidiFunc writeMidiCall, const writeMidiFunc writeMidiCall,
const requestParameterValueChangeFunc requestParameterValueChangeCall)
const requestParameterValueChangeFunc requestParameterValueChangeCall,
const updateStateValueFunc updateStateValueCall)
: fPlugin(createPlugin()), : fPlugin(createPlugin()),
fData((fPlugin != nullptr) ? fPlugin->pData : nullptr), fData((fPlugin != nullptr) ? fPlugin->pData : nullptr),
fIsActive(false) fIsActive(false)
@@ -409,6 +424,7 @@ public:
fData->callbacksPtr = callbacksPtr; fData->callbacksPtr = callbacksPtr;
fData->writeMidiCallbackFunc = writeMidiCall; fData->writeMidiCallbackFunc = writeMidiCall;
fData->requestParameterValueChangeCallbackFunc = requestParameterValueChangeCall; fData->requestParameterValueChangeCallbackFunc = requestParameterValueChangeCall;
fData->updateStateValueCallbackFunc = updateStateValueCall;
} }


~PluginExporter() ~PluginExporter()


+ 46
- 11
distrho/src/DistrhoPluginLV2.cpp View File

@@ -62,6 +62,9 @@ static const writeMidiFunc writeMidiCallback = nullptr;
#if ! DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST #if ! DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST
static const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr; static const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr;
#endif #endif
#if ! DISTRHO_PLUGIN_WANT_STATE
static const updateStateValueFunc updateStateValueCallback = nullptr;
#endif


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


@@ -73,7 +76,7 @@ public:
const LV2_Worker_Schedule* const worker, const LV2_Worker_Schedule* const worker,
const LV2_ControlInputPort_Change_Request* const ctrlInPortChangeReq, const LV2_ControlInputPort_Change_Request* const ctrlInPortChangeReq,
const bool usingNominal) const bool usingNominal)
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback),
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback),
fUsingNominal(usingNominal), fUsingNominal(usingNominal),
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD #ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
fRunCount(0), fRunCount(0),
@@ -727,7 +730,11 @@ public:
if (hints & kStateIsHostVisible) if (hints & kStateIsHostVisible)
{ {
// object, prop key, prop urid, value key, value // object, prop key, prop urid, value key, value
msgSize = sizeof(LV2_Atom_Object) + sizeof(LV2_URID) * 3 + value.length() + 1;
msgSize = sizeof(LV2_Atom_Object)
+ sizeof(LV2_Atom_Property_Body) * 4
+ sizeof(LV2_Atom_URID) * 3
+ sizeof(LV2_Atom_String)
+ value.length() + 1;
} }
else else
{ {
@@ -737,7 +744,8 @@ public:


if (sizeof(LV2_Atom_Event) + msgSize > capacity - fEventsOutData.offset) if (sizeof(LV2_Atom_Event) + msgSize > capacity - fEventsOutData.offset)
{ {
d_stdout("Sending key '%s' to UI failed, out of space", key.buffer());
d_stdout("Sending key '%s' to UI failed, out of space (needs %u bytes)",
key.buffer(), msgSize);
break; break;
} }


@@ -745,10 +753,9 @@ public:
aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fEventsOutData.port) + fEventsOutData.offset); aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fEventsOutData.port) + fEventsOutData.offset);
aev->time.frames = 0; aev->time.frames = 0;


uint8_t* const msgBuf = LV2_ATOM_BODY(&aev->body);

if (hints & kStateIsHostVisible) if (hints & kStateIsHostVisible)
{ {
uint8_t* const msgBuf = (uint8_t*)&aev->body;
LV2_Atom_Forge atomForge = fAtomForge; LV2_Atom_Forge atomForge = fAtomForge;
lv2_atom_forge_set_buffer(&atomForge, msgBuf, msgSize); lv2_atom_forge_set_buffer(&atomForge, msgBuf, msgSize);


@@ -759,7 +766,10 @@ public:
lv2_atom_forge_urid(&atomForge, fUrids[i]); lv2_atom_forge_urid(&atomForge, fUrids[i]);


lv2_atom_forge_key(&atomForge, fURIDs.patchValue); lv2_atom_forge_key(&atomForge, fURIDs.patchValue);
lv2_atom_forge_path(&atomForge, value.buffer(), static_cast<uint32_t>(value.length()+1));
if ((hints & kStateIsFilenamePath) == kStateIsFilenamePath)
lv2_atom_forge_path(&atomForge, value.buffer(), static_cast<uint32_t>(value.length()+1));
else
lv2_atom_forge_string(&atomForge, value.buffer(), static_cast<uint32_t>(value.length()+1));


lv2_atom_forge_pop(&atomForge, &forgeFrame); lv2_atom_forge_pop(&atomForge, &forgeFrame);
} }
@@ -768,6 +778,7 @@ public:
aev->body.type = fURIDs.dpfKeyValue; aev->body.type = fURIDs.dpfKeyValue;
aev->body.size = msgSize; aev->body.size = msgSize;


uint8_t* const msgBuf = LV2_ATOM_BODY(&aev->body);
std::memset(msgBuf, 0, msgSize); std::memset(msgBuf, 0, msgSize);


// write key and value in atom buffer // write key and value in atom buffer
@@ -1248,11 +1259,14 @@ private:
{ {
fPlugin.setState(key, newValue); fPlugin.setState(key, newValue);


// check if we want to save this key
if (! fPlugin.wantStateKey(key))
return;
// save this key if necessary
if (fPlugin.wantStateKey(key))
updateState(key, newValue, false);
}


// check if key already exists
bool updateState(const char* const key, const char* const newValue, const bool sendToUI)
{
// key must already exist
for (StringToStringMap::iterator it=fStateMap.begin(), ite=fStateMap.end(); it != ite; ++it) for (StringToStringMap::iterator it=fStateMap.begin(), ite=fStateMap.end(); it != ite; ++it)
{ {
const String& dkey(it->first); const String& dkey(it->first);
@@ -1260,11 +1274,25 @@ private:
if (dkey == key) if (dkey == key)
{ {
it->second = newValue; it->second = newValue;
return;

if (sendToUI)
{
for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i)
{
if (fPlugin.getStateKey(i) == key)
{
fNeededUiSends[i] = true;
break;
}
}
}

return true;
} }
} }


d_stderr("Failed to find plugin state with key \"%s\"", key); d_stderr("Failed to find plugin state with key \"%s\"", key);
return false;
} }
#endif #endif


@@ -1306,6 +1334,13 @@ private:
} }
#endif #endif


#if DISTRHO_PLUGIN_WANT_STATE
static bool updateStateValueCallback(void* const ptr, const char* const key, const char* const value)
{
return ((PluginLv2*)ptr)->updateState(key, value, true);
}
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool writeMidi(const MidiEvent& midiEvent) bool writeMidi(const MidiEvent& midiEvent)
{ {


+ 1
- 1
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -244,7 +244,7 @@ void lv2_generate_ttl(const char* const basename)
d_nextBufferSize = 512; d_nextBufferSize = 512;
d_nextSampleRate = 44100.0; d_nextSampleRate = 44100.0;
d_nextPluginIsDummy = true; d_nextPluginIsDummy = true;
PluginExporter plugin(nullptr, nullptr, nullptr);
PluginExporter plugin(nullptr, nullptr, nullptr, nullptr);
d_nextBufferSize = 0; d_nextBufferSize = 0;
d_nextSampleRate = 0.0; d_nextSampleRate = 0.0;
d_nextPluginIsDummy = false; d_nextPluginIsDummy = false;


Loading…
Cancel
Save