|
|
@@ -1,6 +1,6 @@ |
|
|
|
/* |
|
|
|
* DISTRHO Plugin Toolkit (DPT) |
|
|
|
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> |
|
|
|
* DISTRHO Plugin Framework (DPF) |
|
|
|
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> |
|
|
|
* |
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any purpose with |
|
|
|
* or without fee is hereby granted, provided that the above copyright notice and this |
|
|
@@ -60,7 +60,7 @@ struct ERect { |
|
|
|
# warning VST State still TODO (working but needs final testing) |
|
|
|
#endif |
|
|
|
#if DISTRHO_PLUGIN_WANT_TIMEPOS |
|
|
|
# warning VST TimePos still TODO |
|
|
|
# warning VST TimePos still TODO (only basic BBT working) |
|
|
|
#endif |
|
|
|
|
|
|
|
typedef std::map<d_string,d_string> StringMap; |
|
|
@@ -75,66 +75,52 @@ void strncpy(char* const dst, const char* const src, const size_t size) |
|
|
|
dst[size] = '\0'; |
|
|
|
} |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_HAS_UI |
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
class StateHelper |
|
|
|
class UiHelper |
|
|
|
{ |
|
|
|
public: |
|
|
|
virtual ~StateHelper() {} |
|
|
|
virtual void setSharedState(const char* const newKey, const char* const newValue) = 0; |
|
|
|
}; |
|
|
|
#else |
|
|
|
typedef void StateHelper; |
|
|
|
UiHelper() |
|
|
|
: parameterChecks(nullptr), |
|
|
|
parameterValues(nullptr), |
|
|
|
nextProgram(-1) {} |
|
|
|
|
|
|
|
virtual ~UiHelper() |
|
|
|
{ |
|
|
|
if (parameterChecks != nullptr) |
|
|
|
{ |
|
|
|
delete[] parameterChecks; |
|
|
|
parameterChecks = nullptr; |
|
|
|
} |
|
|
|
if (parameterValues != nullptr) |
|
|
|
{ |
|
|
|
delete[] parameterValues; |
|
|
|
parameterValues = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool* parameterChecks; |
|
|
|
float* parameterValues; |
|
|
|
int32_t nextProgram; |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
virtual void setStateFromUi(const char* const newKey, const char* const newValue) = 0; |
|
|
|
#endif |
|
|
|
}; |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_HAS_UI |
|
|
|
class UIVst |
|
|
|
{ |
|
|
|
public: |
|
|
|
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, PluginExporter* const plugin, StateHelper* const stateHelper, const intptr_t winId) |
|
|
|
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, UiHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId) |
|
|
|
: fAudioMaster(audioMaster), |
|
|
|
fEffect(effect), |
|
|
|
fUiHelper(uiHelper), |
|
|
|
fPlugin(plugin), |
|
|
|
fStateHelper(stateHelper), |
|
|
|
fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback), |
|
|
|
fParameterChecks(nullptr), |
|
|
|
fParameterValues(nullptr) |
|
|
|
{ |
|
|
|
const uint32_t paramCount(plugin->getParameterCount()); |
|
|
|
|
|
|
|
if (paramCount > 0) |
|
|
|
{ |
|
|
|
fParameterChecks = new bool[paramCount]; |
|
|
|
fParameterValues = new float[paramCount]; |
|
|
|
|
|
|
|
for (uint32_t i=0; i < paramCount; ++i) |
|
|
|
{ |
|
|
|
fParameterChecks[i] = false; |
|
|
|
fParameterValues[i] = 0.0f; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_PROGRAMS |
|
|
|
fNextProgram = -1; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
~UIVst() |
|
|
|
fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback) |
|
|
|
{ |
|
|
|
if (fParameterChecks != nullptr) |
|
|
|
{ |
|
|
|
delete[] fParameterChecks; |
|
|
|
fParameterChecks = nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
if (fParameterValues != nullptr) |
|
|
|
{ |
|
|
|
delete[] fParameterValues; |
|
|
|
fParameterValues = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
@@ -142,19 +128,19 @@ public: |
|
|
|
void idle() |
|
|
|
{ |
|
|
|
#if DISTRHO_PLUGIN_WANT_PROGRAMS |
|
|
|
if (fNextProgram != -1) |
|
|
|
if (fUiHelper->nextProgram != -1) |
|
|
|
{ |
|
|
|
fUI.programChanged(fNextProgram); |
|
|
|
fNextProgram = -1; |
|
|
|
fUI.programChanged(fUiHelper->nextProgram); |
|
|
|
fUiHelper->nextProgram = -1; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
for (uint32_t i=0, count = fPlugin->getParameterCount(); i < count; ++i) |
|
|
|
{ |
|
|
|
if (fParameterChecks[i]) |
|
|
|
if (fUiHelper->parameterChecks[i]) |
|
|
|
{ |
|
|
|
fParameterChecks[i] = false; |
|
|
|
fUI.parameterChanged(i, fParameterValues[i]); |
|
|
|
fUiHelper->parameterChecks[i] = false; |
|
|
|
fUI.parameterChanged(i, fUiHelper->parameterValues[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -172,27 +158,7 @@ public: |
|
|
|
} |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
|
// functions called from the plugin side, RT no block |
|
|
|
|
|
|
|
void setParameterValueFromPlugin(const uint32_t index, const float perValue) |
|
|
|
{ |
|
|
|
fParameterChecks[index] = true; |
|
|
|
fParameterValues[index] = perValue; |
|
|
|
} |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_PROGRAMS |
|
|
|
void setProgramFromPlugin(const uint32_t index) |
|
|
|
{ |
|
|
|
fNextProgram = index; |
|
|
|
|
|
|
|
// set previous parameters invalid |
|
|
|
for (uint32_t i=0, count = fPlugin->getParameterCount(); i < count; ++i) |
|
|
|
fParameterChecks[i] = false; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
|
// functions called from the plugin side, block |
|
|
|
// functions called from the plugin side, may block |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
void setStateFromPlugin(const char* const key, const char* const value) |
|
|
@@ -229,7 +195,7 @@ protected: |
|
|
|
void setState(const char* const key, const char* const value) |
|
|
|
{ |
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
fStateHelper->setSharedState(key, value); |
|
|
|
fUiHelper->setStateFromUi(key, value); |
|
|
|
#else |
|
|
|
return; // unused |
|
|
|
(void)key; |
|
|
@@ -259,19 +225,12 @@ private: |
|
|
|
// Vst stuff |
|
|
|
const audioMasterCallback fAudioMaster; |
|
|
|
AEffect* const fEffect; |
|
|
|
UiHelper* const fUiHelper; |
|
|
|
PluginExporter* const fPlugin; |
|
|
|
StateHelper* const fStateHelper; |
|
|
|
|
|
|
|
// Plugin UI |
|
|
|
UIExporter fUI; |
|
|
|
|
|
|
|
// Temporary data |
|
|
|
bool* fParameterChecks; |
|
|
|
float* fParameterValues; |
|
|
|
#if DISTRHO_PLUGIN_WANT_PROGRAMS |
|
|
|
int32_t fNextProgram; |
|
|
|
#endif |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
|
// Callbacks |
|
|
|
|
|
|
@@ -308,8 +267,8 @@ private: |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------- |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
class PluginVst : public StateHelper |
|
|
|
#if DISTRHO_PLUGIN_HAS_UI |
|
|
|
class PluginVst : public UiHelper |
|
|
|
#else |
|
|
|
class PluginVst |
|
|
|
#endif |
|
|
@@ -333,6 +292,18 @@ public: |
|
|
|
fVstRect.left = 0; |
|
|
|
fVstRect.bottom = 0; |
|
|
|
fVstRect.right = 0; |
|
|
|
|
|
|
|
if (const uint32_t paramCount = fPlugin.getParameterCount()) |
|
|
|
{ |
|
|
|
parameterChecks = new bool[paramCount]; |
|
|
|
parameterValues = new float[paramCount]; |
|
|
|
|
|
|
|
for (uint32_t i=0; i < paramCount; ++i) |
|
|
|
{ |
|
|
|
parameterChecks[i] = false; |
|
|
|
parameterValues[i] = 0.0f; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
@@ -368,7 +339,7 @@ public: |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_HAS_UI |
|
|
|
if (fVstUi != nullptr) |
|
|
|
fVstUi->setProgramFromPlugin(fCurProgram); |
|
|
|
setProgramFromPlugin(fCurProgram); |
|
|
|
#endif |
|
|
|
|
|
|
|
ret = 1; |
|
|
@@ -452,14 +423,14 @@ public: |
|
|
|
|
|
|
|
d_lastUiSampleRate = fAudioMaster(fEffect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f); |
|
|
|
|
|
|
|
fVstUi = new UIVst(fAudioMaster, fEffect, &fPlugin, this, (intptr_t)ptr); |
|
|
|
fVstUi = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr); |
|
|
|
|
|
|
|
# if DISTRHO_PLUGIN_WANT_PROGRAMS |
|
|
|
if (fCurProgram >= 0) |
|
|
|
fVstUi->setProgramFromPlugin(fCurProgram); |
|
|
|
setProgramFromPlugin(fCurProgram); |
|
|
|
# endif |
|
|
|
for (uint32_t i=0, count = fPlugin.getParameterCount(); i < count; ++i) |
|
|
|
fVstUi->setParameterValueFromPlugin(i, fPlugin.getParameterValue(i)); |
|
|
|
setParameterValueFromPlugin(i, fPlugin.getParameterValue(i)); |
|
|
|
|
|
|
|
fVstUi->idle(); |
|
|
|
|
|
|
@@ -663,20 +634,31 @@ public: |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_HAS_UI |
|
|
|
if (fVstUi != nullptr) |
|
|
|
fVstUi->setParameterValueFromPlugin(index, realValue); |
|
|
|
setParameterValueFromPlugin(index, realValue); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void vst_processReplacing(float** const inputs, float** const outputs, const int32_t sampleFrames) |
|
|
|
{ |
|
|
|
#if DISTRHO_PLUGIN_WANT_TIMEPOS |
|
|
|
if (const VstTimeInfo* const timeInfo = (const VstTimeInfo*)fEffect->dispatcher(fEffect, audioMasterGetTime, 0, kVstTempoValid, nullptr, 0.0f)) |
|
|
|
static const int kWantedVstTimeFlags(kVstTransportPlaying|kVstTempoValid|kVstTimeSigValid); |
|
|
|
|
|
|
|
if (const VstTimeInfo* const vstTimeInfo = (const VstTimeInfo*)fAudioMaster(fEffect, audioMasterGetTime, 0, kWantedVstTimeFlags, nullptr, 0.0f)) |
|
|
|
{ |
|
|
|
fTimePos.playing = (timeInfo->flags & kVstTransportPlaying); |
|
|
|
fTimePos.frame = timeInfo->samplePos; |
|
|
|
fTimePos.playing = (vstTimeInfo->flags & kVstTransportPlaying); |
|
|
|
fTimePos.frame = vstTimeInfo->samplePos; |
|
|
|
|
|
|
|
// TODO: BBT |
|
|
|
// timeInfo->tempo etc |
|
|
|
if (vstTimeInfo->flags & kVstTempoValid) |
|
|
|
{ |
|
|
|
fTimePos.bbt.valid = true; |
|
|
|
fTimePos.bbt.beatsPerMinute = vstTimeInfo->tempo; |
|
|
|
} |
|
|
|
if (vstTimeInfo->flags & kVstTimeSigValid) |
|
|
|
{ |
|
|
|
fTimePos.bbt.valid = true; |
|
|
|
fTimePos.bbt.beatsPerBar = vstTimeInfo->timeSigNumerator; |
|
|
|
fTimePos.bbt.beatType = vstTimeInfo->timeSigDenominator; |
|
|
|
} |
|
|
|
|
|
|
|
fPlugin.setTimePos(fTimePos); |
|
|
|
} |
|
|
@@ -688,6 +670,17 @@ public: |
|
|
|
#else |
|
|
|
fPlugin.run(inputs, outputs, sampleFrames); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_HAS_UI |
|
|
|
if (fVstUi == nullptr) |
|
|
|
return; |
|
|
|
|
|
|
|
for (uint32_t i=0, count = fPlugin.getParameterCount(); i < count; ++i) |
|
|
|
{ |
|
|
|
if (fPlugin.isParameterOutput(i)) |
|
|
|
setParameterValueFromPlugin(i, fPlugin.getParameterValue(i)); |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
@@ -725,8 +718,33 @@ private: |
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
char* fStateChunk; |
|
|
|
StringMap fStateMap; |
|
|
|
#endif |
|
|
|
|
|
|
|
// ------------------------------------------------------------------- |
|
|
|
// functions called from the plugin side, RT no block |
|
|
|
|
|
|
|
void setParameterValueFromPlugin(const uint32_t index, const float realValue) |
|
|
|
{ |
|
|
|
parameterValues[index] = realValue; |
|
|
|
parameterChecks[index] = true; |
|
|
|
} |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_PROGRAMS |
|
|
|
void setProgramFromPlugin(const uint32_t index) |
|
|
|
{ |
|
|
|
// set previous parameters invalid |
|
|
|
for (uint32_t i=0, count = fPlugin.getParameterCount(); i < count; ++i) |
|
|
|
parameterChecks[i] = false; |
|
|
|
|
|
|
|
nextProgram = index; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_STATE |
|
|
|
// ------------------------------------------------------------------- |
|
|
|
// functions called from the UI side, may block |
|
|
|
|
|
|
|
void setSharedState(const char* const newKey, const char* const newValue) override |
|
|
|
void setStateFromUi(const char* const newKey, const char* const newValue) override |
|
|
|
{ |
|
|
|
fPlugin.setState(newKey, newValue); |
|
|
|
|
|
|
|