Browse Source

Save & restore plugin parameters in VST chunks

Fixes #35
pull/61/head
falkTX 4 years ago
parent
commit
421fdc2cce
2 changed files with 121 additions and 4 deletions
  1. +12
    -0
      distrho/src/DistrhoPluginInternal.hpp
  2. +109
    -4
      distrho/src/DistrhoPluginVST.cpp

+ 12
- 0
distrho/src/DistrhoPluginInternal.hpp View File

@@ -356,6 +356,18 @@ public:
return (getParameterHints(index) & kParameterIsOutput) != 0x0;
}

bool isParameterOutputOrTrigger(const uint32_t index) const noexcept
{
const uint32_t hints = getParameterHints(index);

if (hints & kParameterIsOutput)
return true;
if ((hints & kParameterIsTrigger) == kParameterIsTrigger)
return true;

return false;
}

const String& getParameterName(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackString);


+ 109
- 4
distrho/src/DistrhoPluginVST.cpp View File

@@ -37,6 +37,7 @@
#define VESTIGE_HEADER
#define VST_FORCE_DEPRECATED 0

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

@@ -93,6 +94,32 @@ void snprintf_iparam(char* const dst, const int32_t value, const size_t size)

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

class ScopedSafeLocale {
public:
ScopedSafeLocale() noexcept
: locale(::strdup(::setlocale(LC_NUMERIC, nullptr)))
{
::setlocale(LC_NUMERIC, "C");
}

~ScopedSafeLocale() noexcept
{
if (locale != nullptr)
{
::setlocale(LC_NUMERIC, locale);
std::free(locale);
}
}

private:
char* const locale;

DISTRHO_DECLARE_NON_COPY_CLASS(ScopedSafeLocale)
DISTRHO_PREVENT_HEAP_ALLOCATION
};

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

class ParameterCheckHelper
{
public:
@@ -618,6 +645,7 @@ public:

#if DISTRHO_PLUGIN_WANT_STATE
case effGetChunk:
{
if (ptr == nullptr)
return 0;

@@ -627,7 +655,9 @@ public:
fStateChunk = nullptr;
}

if (fPlugin.getStateCount() == 0)
const uint32_t paramCount = fPlugin.getParameterCount();

if (fPlugin.getStateCount() == 0 && paramCount == 0)
{
fStateChunk = new char[1];
fStateChunk[0] = '\0';
@@ -661,6 +691,30 @@ public:
chunkStr += tmpStr;
}

if (paramCount != 0)
{
// add another separator
chunkStr += "\xff";

// temporarily set locale to "C" while converting floats
const ScopedSafeLocale ssl;

for (uint32_t i=0; i<paramCount; ++i)
{
if (fPlugin.isParameterOutputOrTrigger(i))
continue;

// join key and value
String tmpStr;
tmpStr = fPlugin.getParameterSymbol(i);
tmpStr += "\xff";
tmpStr += String(fPlugin.getParameterValue(i));
tmpStr += "\xff";

chunkStr += tmpStr;
}
}

const std::size_t chunkSize(chunkStr.length()+1);

fStateChunk = new char[chunkSize];
@@ -678,21 +732,27 @@ public:

*(void**)ptr = fStateChunk;
return ret;
}

case effSetChunk:
{
if (value <= 1 || ptr == nullptr)
return 0;

const size_t chunkSize = static_cast<size_t>(value);

const char* key = (const char*)ptr;
const char* value = nullptr;
size_t size, bytesRead = 0;

for (;;)
while (bytesRead < chunkSize)
{
if (key[0] == '\0')
break;

value = key+(std::strlen(key)+1);
size = std::strlen(key)+1;
value = key + size;
bytesRead += size;

setStateFromUI(key, value);

@@ -702,7 +762,52 @@ public:
# endif

// get next key
key = value+(std::strlen(value)+1);
size = std::strlen(value)+1;
key = value + size;
bytesRead += size;
}

const uint32_t paramCount = fPlugin.getParameterCount();

if (bytesRead+4 < chunkSize && paramCount != 0)
{
++key;
float fvalue;

// temporarily set locale to "C" while converting floats
const ScopedSafeLocale ssl;

while (bytesRead < chunkSize)
{
if (key[0] == '\0')
break;

size = std::strlen(key)+1;
value = key + size;
bytesRead += size;

// find parameter with this symbol, and set its value
for (uint32_t i=0; i<paramCount; ++i)
{
if (fPlugin.isParameterOutputOrTrigger(i))
continue;
if (fPlugin.getParameterSymbol(i) != key)
continue;

fvalue = std::atof(value);
fPlugin.setParameterValue(i, fvalue);
# if DISTRHO_PLUGIN_HAS_UI
if (fVstUI != nullptr)
setParameterValueFromPlugin(i, fvalue);
# endif
break;
}

// get next key
size = std::strlen(value)+1;
key = value + size;
bytesRead += size;
}
}

return 1;


Loading…
Cancel
Save