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;
#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:
/* --------------------------------------------------------------------------------------------------------
* Information */


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

@@ -145,6 +145,13 @@ bool Plugin::requestParameterValueChange(const uint32_t index, const float value
}
#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 */



+ 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 (*requestParameterValueChangeFunc) (void* ptr, uint32_t index, float value);
typedef bool (*updateStateValueFunc) (void* ptr, const char* key, const char* value);

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

uint32_t bufferSize;
double sampleRate;
@@ -159,6 +161,7 @@ struct Plugin::PrivateData {
callbacksPtr(nullptr),
writeMidiCallbackFunc(nullptr),
requestParameterValueChangeCallbackFunc(nullptr),
updateStateValueCallbackFunc(nullptr),
bufferSize(d_nextBufferSize),
sampleRate(d_nextSampleRate),
bundlePath(d_nextBundlePath != nullptr ? strdup(d_nextBundlePath) : nullptr)
@@ -257,6 +260,17 @@ struct Plugin::PrivateData {
return false;
}
#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:
PluginExporter(void* const callbacksPtr,
const writeMidiFunc writeMidiCall,
const requestParameterValueChangeFunc requestParameterValueChangeCall)
const requestParameterValueChangeFunc requestParameterValueChangeCall,
const updateStateValueFunc updateStateValueCall)
: fPlugin(createPlugin()),
fData((fPlugin != nullptr) ? fPlugin->pData : nullptr),
fIsActive(false)
@@ -409,6 +424,7 @@ public:
fData->callbacksPtr = callbacksPtr;
fData->writeMidiCallbackFunc = writeMidiCall;
fData->requestParameterValueChangeCallbackFunc = requestParameterValueChangeCall;
fData->updateStateValueCallbackFunc = updateStateValueCall;
}

~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
static const requestParameterValueChangeFunc requestParameterValueChangeCallback = nullptr;
#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_ControlInputPort_Change_Request* const ctrlInPortChangeReq,
const bool usingNominal)
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback),
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, updateStateValueCallback),
fUsingNominal(usingNominal),
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
fRunCount(0),
@@ -727,7 +730,11 @@ public:
if (hints & kStateIsHostVisible)
{
// 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
{
@@ -737,7 +744,8 @@ public:

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;
}

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

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

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

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

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);
}
@@ -768,6 +778,7 @@ public:
aev->body.type = fURIDs.dpfKeyValue;
aev->body.size = msgSize;

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

// write key and value in atom buffer
@@ -1248,11 +1259,14 @@ private:
{
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)
{
const String& dkey(it->first);
@@ -1260,11 +1274,25 @@ private:
if (dkey == key)
{
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);
return false;
}
#endif

@@ -1306,6 +1334,13 @@ private:
}
#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
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_nextSampleRate = 44100.0;
d_nextPluginIsDummy = true;
PluginExporter plugin(nullptr, nullptr, nullptr);
PluginExporter plugin(nullptr, nullptr, nullptr, nullptr);
d_nextBufferSize = 0;
d_nextSampleRate = 0.0;
d_nextPluginIsDummy = false;


Loading…
Cancel
Save