@@ -28,6 +28,7 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 0 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/3BandEQ" | |||
@@ -28,6 +28,7 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 0 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/3BandSplitter" | |||
@@ -29,6 +29,7 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 | |||
#define DISTRHO_PLUGIN_WANT_STATE 0 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/Nekobi" | |||
@@ -29,6 +29,7 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 | |||
#define DISTRHO_PLUGIN_WANT_STATE 1 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/Notes" | |||
@@ -28,6 +28,7 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 0 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/PingPongPan" | |||
@@ -28,6 +28,7 @@ | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 0 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 0 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 0 | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/StereoEnhancer" | |||
@@ -87,7 +87,7 @@ struct ParameterRanges { | |||
value = max; | |||
} | |||
float fixValue(const float& value) const | |||
float fixedValue(const float& value) const | |||
{ | |||
if (value < min) | |||
return min; | |||
@@ -96,19 +96,19 @@ struct ParameterRanges { | |||
return value; | |||
} | |||
float normalizeValue(const float& value) const | |||
float normalizedValue(const float& value) const | |||
{ | |||
float newValue = (value - min) / (max - min); | |||
const float newValue((value - min) / (max - min)); | |||
if (newValue < 0.0f) | |||
newValue = 0.0f; | |||
return 0.0f; | |||
else if (newValue > 1.0f) | |||
newValue = 1.0f; | |||
return 1.0f; | |||
return newValue; | |||
} | |||
float unnormalizeValue(const float& value) const | |||
float unnormalizedValue(const float& value) const | |||
{ | |||
return value * (max - min) + min; | |||
} | |||
@@ -189,7 +189,9 @@ public: | |||
uint32_t d_bufferSize() const; | |||
double d_sampleRate() const; | |||
#if DISTRHO_PLUGIN_WANT_TIMEPOS | |||
const TimePos& d_timePos() const; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
void d_setLatency(uint32_t frames); | |||
#endif | |||
@@ -22,6 +22,7 @@ | |||
# include "src/DistrhoPluginLADSPA+DSSI.cpp" | |||
#elif defined(DISTRHO_PLUGIN_TARGET_LV2) | |||
# include "src/DistrhoPluginLV2.cpp" | |||
# include "src/DistrhoPluginLV2export.cpp" | |||
#elif defined(DISTRHO_PLUGIN_TARGET_VST) | |||
# include "src/DistrhoPluginVST.cpp" | |||
#endif |
@@ -51,6 +51,10 @@ | |||
# error DISTRHO_PLUGIN_WANT_STATE undefined! | |||
#endif | |||
#ifndef DISTRHO_PLUGIN_WANT_TIMEPOS | |||
# error DISTRHO_PLUGIN_WANT_TIMEPOS undefined! | |||
#endif | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
# if ! (defined(DISTRHO_UI_EXTERNAL) || defined(DISTRHO_UI_OPENGL) || defined(DISTRHO_UI_QT)) | |||
# error DISTRHO_PLUGIN_HAS_UI is defined but not its type; please define one of DISTRHO_UI_EXTERNAL, DISTRHO_UI_OPENGL or DISTRHO_UI_QT | |||
@@ -77,10 +77,12 @@ double Plugin::d_sampleRate() const | |||
return pData->sampleRate; | |||
} | |||
#if DISTRHO_PLUGIN_WANT_TIMEPOS | |||
const TimePos& Plugin::d_timePos() const | |||
{ | |||
return pData->timePos; | |||
} | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
void Plugin::d_setLatency(uint32_t frames) | |||
@@ -49,7 +49,11 @@ struct Plugin::PrivateData { | |||
uint32_t latency; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_TIMEPOS | |||
TimePos timePos; | |||
#endif | |||
char _d; // dummy | |||
PrivateData() | |||
: bufferSize(d_lastBufferSize), | |||
@@ -67,7 +71,7 @@ struct Plugin::PrivateData { | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
latency(0), | |||
#endif | |||
timePos() | |||
_d(0) | |||
{ | |||
assert(bufferSize != 0); | |||
assert(sampleRate != 0.0); | |||
@@ -76,16 +80,25 @@ struct Plugin::PrivateData { | |||
~PrivateData() | |||
{ | |||
if (parameterCount > 0 && parameters != nullptr) | |||
{ | |||
delete[] parameters; | |||
parameters = nullptr; | |||
} | |||
#if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
if (programCount > 0 && programNames != nullptr) | |||
{ | |||
delete[] programNames; | |||
programNames = nullptr; | |||
} | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
if (stateCount > 0 && stateKeys != nullptr) | |||
{ | |||
delete[] stateKeys; | |||
stateKeys = nullptr; | |||
} | |||
#endif | |||
} | |||
}; | |||
@@ -178,48 +191,48 @@ public: | |||
return (kData != nullptr) ? kData->parameterCount : 0; | |||
} | |||
uint32_t parameterHints(uint32_t index) const | |||
uint32_t parameterHints(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->parameterCount); | |||
return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].hints : 0x0; | |||
} | |||
bool parameterIsOutput(uint32_t index) const | |||
bool parameterIsOutput(const uint32_t index) const | |||
{ | |||
return (parameterHints(index) & PARAMETER_IS_OUTPUT); | |||
} | |||
const d_string& parameterName(uint32_t index) const | |||
const d_string& parameterName(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->parameterCount); | |||
return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].name : sFallbackString; | |||
} | |||
const d_string& parameterSymbol(uint32_t index) const | |||
const d_string& parameterSymbol(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->parameterCount); | |||
return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].symbol : sFallbackString; | |||
} | |||
const d_string& parameterUnit(uint32_t index) const | |||
const d_string& parameterUnit(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->parameterCount); | |||
return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].unit : sFallbackString; | |||
} | |||
const ParameterRanges& parameterRanges(uint32_t index) const | |||
const ParameterRanges& parameterRanges(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->parameterCount); | |||
return (kData != nullptr && index < kData->parameterCount) ? kData->parameters[index].ranges : sFallbackRanges; | |||
} | |||
float parameterValue(uint32_t index) | |||
float parameterValue(const uint32_t index) | |||
{ | |||
assert(kPlugin != nullptr && index < kData->parameterCount); | |||
return (kPlugin != nullptr && index < kData->parameterCount) ? kPlugin->d_parameterValue(index) : 0.0f; | |||
} | |||
void setParameterValue(uint32_t index, float value) | |||
void setParameterValue(const uint32_t index, const float value) | |||
{ | |||
assert(kPlugin != nullptr && index < kData->parameterCount); | |||
@@ -234,13 +247,13 @@ public: | |||
return (kData != nullptr) ? kData->programCount : 0; | |||
} | |||
const d_string& programName(uint32_t index) const | |||
const d_string& programName(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->programCount); | |||
return (kData != nullptr && index < kData->programCount) ? kData->programNames[index] : sFallbackString; | |||
} | |||
void setProgram(uint32_t index) | |||
void setProgram(const uint32_t index) | |||
{ | |||
assert(kPlugin != nullptr && index < kData->programCount); | |||
@@ -256,13 +269,13 @@ public: | |||
return kData != nullptr ? kData->stateCount : 0; | |||
} | |||
const d_string& stateKey(uint32_t index) const | |||
const d_string& stateKey(const uint32_t index) const | |||
{ | |||
assert(kData != nullptr && index < kData->stateCount); | |||
return (kData != nullptr && index < kData->stateCount) ? kData->stateKeys[index] : sFallbackString; | |||
} | |||
void setState(const char* key, const char* value) | |||
void setState(const char* const key, const char* const value) | |||
{ | |||
assert(kPlugin != nullptr && key != nullptr && value != nullptr); | |||
@@ -289,7 +302,7 @@ public: | |||
kPlugin->d_deactivate(); | |||
} | |||
void run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents) | |||
void run(float** const inputs, float** const outputs, const uint32_t frames, const uint32_t midiEventCount, const MidiEvent* const midiEvents) | |||
{ | |||
assert(kPlugin != nullptr); | |||
@@ -299,7 +312,7 @@ public: | |||
// --------------------------------------------- | |||
void setBufferSize(uint32_t bufferSize, bool doCallback = false) | |||
void setBufferSize(const uint32_t bufferSize, bool doCallback = false) | |||
{ | |||
assert(kData != nullptr && kPlugin != nullptr && bufferSize >= 2); | |||
@@ -319,7 +332,7 @@ public: | |||
} | |||
} | |||
void setSampleRate(double sampleRate, bool doCallback = false) | |||
void setSampleRate(const double sampleRate, bool doCallback = false) | |||
{ | |||
assert(kData != nullptr && kPlugin != nullptr && sampleRate > 0.0); | |||
@@ -28,12 +28,16 @@ | |||
# endif | |||
#endif | |||
typedef LADSPA_Data* LADSPA_DataPtr; | |||
#if DISTRHO_PLUGIN_WANT_TIMEPOS | |||
# warning LADSPA/DSSI does not support TimePos | |||
#endif | |||
// ------------------------------------------------- | |||
START_NAMESPACE_DISTRHO | |||
typedef LADSPA_Data* LADSPA_DataPtr; | |||
class PluginLadspaDssi | |||
{ | |||
public: | |||
@@ -84,9 +88,9 @@ public: | |||
void ladspa_connect_port(const unsigned long port, const LADSPA_DataPtr dataLocation) | |||
{ | |||
unsigned long i, count, index = 0; | |||
unsigned long index = 0; | |||
for (i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | |||
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | |||
{ | |||
if (port == index++) | |||
{ | |||
@@ -95,7 +99,7 @@ public: | |||
} | |||
} | |||
for (i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | |||
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | |||
{ | |||
if (port == index++) | |||
{ | |||
@@ -112,7 +116,7 @@ public: | |||
} | |||
#endif | |||
for (i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
for (unsigned long i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
{ | |||
if (port == index++) | |||
{ | |||
@@ -216,10 +220,10 @@ public: | |||
} | |||
} | |||
#ifdef DISTRHO_PLUGIN_TARGET_DSSI | |||
# if DISTRHO_PLUGIN_IS_SYNTH | |||
#if DISTRHO_PLUGIN_IS_SYNTH | |||
// Get MIDI Events | |||
uint32_t midiEventCount = 0; | |||
uint32_t midiEventCount = 0; | |||
MidiEvent midiEvents[eventCount]; | |||
for (uint32_t i=0, j; i < eventCount && midiEventCount < MAX_MIDI_EVENTS; ++i) | |||
{ | |||
@@ -232,71 +236,64 @@ public: | |||
{ | |||
case SND_SEQ_EVENT_NOTEON: | |||
j = midiEventCount++; | |||
fMidiEvents[j].frame = seqEvent.time.tick; | |||
fMidiEvents[j].buf[0] = 0x90 + seqEvent.data.note.channel; | |||
fMidiEvents[j].buf[1] = seqEvent.data.note.note; | |||
fMidiEvents[j].buf[2] = seqEvent.data.note.velocity; | |||
fMidiEvents[j].buf[3] = 0; | |||
fMidiEvents[j].size = 3; | |||
midiEvents[j].frame = seqEvent.time.tick; | |||
midiEvents[j].buf[0] = 0x90 + seqEvent.data.note.channel; | |||
midiEvents[j].buf[1] = seqEvent.data.note.note; | |||
midiEvents[j].buf[2] = seqEvent.data.note.velocity; | |||
midiEvents[j].buf[3] = 0; | |||
midiEvents[j].size = 3; | |||
break; | |||
case SND_SEQ_EVENT_NOTEOFF: | |||
j = midiEventCount++; | |||
fMidiEvents[j].frame = seqEvent.time.tick; | |||
fMidiEvents[j].buf[0] = 0x80 + seqEvent.data.note.channel; | |||
fMidiEvents[j].buf[1] = seqEvent.data.note.note; | |||
fMidiEvents[j].buf[2] = 0; | |||
fMidiEvents[j].buf[3] = 0; | |||
fMidiEvents[j].size = 3; | |||
midiEvents[j].frame = seqEvent.time.tick; | |||
midiEvents[j].buf[0] = 0x80 + seqEvent.data.note.channel; | |||
midiEvents[j].buf[1] = seqEvent.data.note.note; | |||
midiEvents[j].buf[2] = 0; | |||
midiEvents[j].buf[3] = 0; | |||
midiEvents[j].size = 3; | |||
break; | |||
case SND_SEQ_EVENT_KEYPRESS: | |||
j = midiEventCount++; | |||
fMidiEvents[j].frame = seqEvent.time.tick; | |||
fMidiEvents[j].buf[0] = 0xA0 + seqEvent.data.note.channel; | |||
fMidiEvents[j].buf[1] = seqEvent.data.note.note; | |||
fMidiEvents[j].buf[2] = seqEvent.data.note.velocity; | |||
fMidiEvents[j].buf[3] = 0; | |||
fMidiEvents[j].size = 3; | |||
midiEvents[j].frame = seqEvent.time.tick; | |||
midiEvents[j].buf[0] = 0xA0 + seqEvent.data.note.channel; | |||
midiEvents[j].buf[1] = seqEvent.data.note.note; | |||
midiEvents[j].buf[2] = seqEvent.data.note.velocity; | |||
midiEvents[j].buf[3] = 0; | |||
midiEvents[j].size = 3; | |||
break; | |||
case SND_SEQ_EVENT_CONTROLLER: | |||
j = midiEventCount++; | |||
fMidiEvents[j].frame = seqEvent.time.tick; | |||
fMidiEvents[j].buf[0] = 0xB0 + seqEvent.data.control.channel; | |||
fMidiEvents[j].buf[1] = seqEvent.data.control.param; | |||
fMidiEvents[j].buf[2] = seqEvent.data.control.value; | |||
fMidiEvents[j].buf[3] = 0; | |||
fMidiEvents[j].size = 3; | |||
midiEvents[j].frame = seqEvent.time.tick; | |||
midiEvents[j].buf[0] = 0xB0 + seqEvent.data.control.channel; | |||
midiEvents[j].buf[1] = seqEvent.data.control.param; | |||
midiEvents[j].buf[2] = seqEvent.data.control.value; | |||
midiEvents[j].buf[3] = 0; | |||
midiEvents[j].size = 3; | |||
break; | |||
case SND_SEQ_EVENT_CHANPRESS: | |||
j = midiEventCount++; | |||
fMidiEvents[j].frame = seqEvent.time.tick; | |||
fMidiEvents[j].buf[0] = 0xD0 + seqEvent.data.control.channel; | |||
fMidiEvents[j].buf[1] = seqEvent.data.control.value; | |||
fMidiEvents[j].buf[2] = 0; | |||
fMidiEvents[j].buf[3] = 0; | |||
fMidiEvents[j].size = 2; | |||
midiEvents[j].frame = seqEvent.time.tick; | |||
midiEvents[j].buf[0] = 0xD0 + seqEvent.data.control.channel; | |||
midiEvents[j].buf[1] = seqEvent.data.control.value; | |||
midiEvents[j].buf[2] = 0; | |||
midiEvents[j].buf[3] = 0; | |||
midiEvents[j].size = 2; | |||
break; | |||
case SND_SEQ_EVENT_PITCHBEND: // TODO | |||
#if 0 // TODO | |||
case SND_SEQ_EVENT_PITCHBEND: | |||
j = midiEventCount++; | |||
fMidiEvents[j].frame = seqEvent.time.tick; | |||
fMidiEvents[j].buf[0] = 0xE0 + seqEvent.data.control.channel; | |||
fMidiEvents[j].buf[1] = 0; | |||
fMidiEvents[j].buf[2] = 0; | |||
fMidiEvents[j].buf[3] = 0; | |||
fMidiEvents[j].size = 3; | |||
midiEvents[j].frame = seqEvent.time.tick; | |||
midiEvents[j].buf[0] = 0xE0 + seqEvent.data.control.channel; | |||
midiEvents[j].buf[1] = 0; | |||
midiEvents[j].buf[2] = 0; | |||
midiEvents[j].buf[3] = 0; | |||
midiEvents[j].size = 3; | |||
break; | |||
#endif | |||
} | |||
} | |||
# else | |||
return; | |||
// unused | |||
(void)events; | |||
(void)eventCount; | |||
# endif | |||
#endif | |||
// Run plugin for this cycle | |||
#if DISTRHO_PLUGIN_IS_SYNTH | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, midiEventCount, fMidiEvents); | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, midiEventCount, midiEvents); | |||
#else | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, 0, nullptr); | |||
#endif | |||
@@ -316,10 +313,6 @@ private: | |||
LADSPA_DataPtr fPortLatency; | |||
#endif | |||
#if DISTRHO_PLUGIN_IS_SYNTH | |||
MidiEvent fMidiEvents[MAX_MIDI_EVENTS]; | |||
#endif | |||
LADSPA_Data* fLastControlValues; | |||
// --------------------------------------------- | |||
@@ -480,38 +473,38 @@ public: | |||
d_lastSampleRate = 0.0; | |||
// Get port count, init | |||
unsigned long i, port = 0; | |||
unsigned long port = 0; | |||
unsigned long portCount = DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS + plugin.parameterCount(); | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
portCount += 1; | |||
#endif | |||
const char** const portNames = new const char* [portCount]; | |||
LADSPA_PortDescriptor* portDescriptors = new LADSPA_PortDescriptor [portCount]; | |||
LADSPA_PortRangeHint* portRangeHints = new LADSPA_PortRangeHint [portCount]; | |||
const char** const portNames = new const char*[portCount]; | |||
LADSPA_PortDescriptor* portDescriptors = new LADSPA_PortDescriptor[portCount]; | |||
LADSPA_PortRangeHint* portRangeHints = new LADSPA_PortRangeHint [portCount]; | |||
// Set ports | |||
for (i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++port) | |||
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++port) | |||
{ | |||
char portName[24] = { '\0' }; | |||
sprintf(portName, "Audio Input %lu", i+1); | |||
std::sprintf(portName, "Audio Input %lu", i+1); | |||
portNames[port] = strdup(portName); | |||
portDescriptors[port] = LADSPA_PORT_AUDIO | LADSPA_PORT_INPUT; | |||
portRangeHints[port].HintDescriptor = 0; | |||
portRangeHints[port].HintDescriptor = 0x0; | |||
portRangeHints[port].LowerBound = 0.0f; | |||
portRangeHints[port].UpperBound = 1.0f; | |||
} | |||
for (i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++port) | |||
for (unsigned long i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++port) | |||
{ | |||
char portName[24] = { '\0' }; | |||
sprintf(portName, "Audio Output %lu", i+1); | |||
std::sprintf(portName, "Audio Output %lu", i+1); | |||
portNames[port] = strdup(portName); | |||
portDescriptors[port] = LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT; | |||
portRangeHints[port].HintDescriptor = 0; | |||
portRangeHints[port].HintDescriptor = 0x0; | |||
portRangeHints[port].LowerBound = 0.0f; | |||
portRangeHints[port].UpperBound = 1.0f; | |||
} | |||
@@ -526,7 +519,7 @@ public: | |||
++port; | |||
#endif | |||
for (i=0; i < plugin.parameterCount(); ++i, ++port) | |||
for (unsigned long i=0, count=plugin.parameterCount(); i < count; ++i, ++port) | |||
{ | |||
portNames[port] = strdup((const char*)plugin.parameterName(i)); | |||
portDescriptors[port] = LADSPA_PORT_CONTROL; | |||
@@ -538,7 +531,7 @@ public: | |||
{ | |||
const ParameterRanges& ranges(plugin.parameterRanges(i)); | |||
const float defValue = ranges.def; | |||
const float defValue(ranges.def); | |||
portRangeHints[port].HintDescriptor = LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE; | |||
portRangeHints[port].LowerBound = ranges.min; | |||
@@ -558,9 +551,9 @@ public: | |||
portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_MAXIMUM; | |||
else | |||
{ | |||
const float middleValue = ranges.min/2 + ranges.max/2; | |||
const float middleLow = (ranges.min/2 + middleValue/2)/2 + middleValue/2; | |||
const float middleHigh = (ranges.max/2 + middleValue/2)/2 + middleValue/2; | |||
const float middleValue = ranges.min/2.0f + ranges.max/2.0f; | |||
const float middleLow = (ranges.min/2.0f + middleValue/2.0f)/2.0f + middleValue/2.0f; | |||
const float middleHigh = (ranges.max/2.0f + middleValue/2.0f)/2.0f + middleValue/2.0f; | |||
if (defValue < middleLow) | |||
portRangeHints[port].HintDescriptor |= LADSPA_HINT_DEFAULT_LOW; | |||
@@ -598,37 +591,59 @@ public: | |||
~DescriptorInitializer() | |||
{ | |||
if (sLadspaDescriptor.Label != nullptr) | |||
free((void*)sLadspaDescriptor.Label); | |||
{ | |||
std::free((void*)sLadspaDescriptor.Label); | |||
sLadspaDescriptor.Label = nullptr; | |||
} | |||
if (sLadspaDescriptor.Name != nullptr) | |||
free((void*)sLadspaDescriptor.Name); | |||
{ | |||
std::free((void*)sLadspaDescriptor.Name); | |||
sLadspaDescriptor.Name = nullptr; | |||
} | |||
if (sLadspaDescriptor.Maker != nullptr) | |||
free((void*)sLadspaDescriptor.Maker); | |||
{ | |||
std::free((void*)sLadspaDescriptor.Maker); | |||
sLadspaDescriptor.Maker = nullptr; | |||
} | |||
if (sLadspaDescriptor.Copyright != nullptr) | |||
free((void*)sLadspaDescriptor.Copyright); | |||
{ | |||
std::free((void*)sLadspaDescriptor.Copyright); | |||
sLadspaDescriptor.Copyright = nullptr; | |||
} | |||
if (sLadspaDescriptor.PortDescriptors != nullptr) | |||
{ | |||
delete[] sLadspaDescriptor.PortDescriptors; | |||
sLadspaDescriptor.PortDescriptors = nullptr; | |||
} | |||
if (sLadspaDescriptor.PortRangeHints != nullptr) | |||
{ | |||
delete[] sLadspaDescriptor.PortRangeHints; | |||
sLadspaDescriptor.PortRangeHints = nullptr; | |||
} | |||
if (sLadspaDescriptor.PortNames != nullptr) | |||
{ | |||
for (unsigned long i=0; i < sLadspaDescriptor.PortCount; ++i) | |||
{ | |||
if (sLadspaDescriptor.PortNames[i] != nullptr) | |||
free((void*)sLadspaDescriptor.PortNames[i]); | |||
{ | |||
std::free((void*)sLadspaDescriptor.PortNames[i]); | |||
sLadspaDescriptor.PortNames[i] = nullptr; | |||
} | |||
} | |||
delete[] sLadspaDescriptor.PortNames; | |||
sLadspaDescriptor.PortNames = nullptr; | |||
} | |||
} | |||
}; | |||
static DescriptorInitializer sInit; | |||
static DescriptorInitializer sDescInit; | |||
END_NAMESPACE_DISTRHO | |||
@@ -0,0 +1,663 @@ | |||
/* | |||
* DISTRHO Plugin Toolkit (DPT) | |||
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* For a full copy of the license see the LGPL.txt file | |||
*/ | |||
#include "DistrhoPluginInternal.hpp" | |||
#include "lv2/lv2.h" | |||
#include "lv2/atom.h" | |||
#include "lv2/buf-size.h" | |||
#include "lv2/options.h" | |||
#include "lv2/programs.h" | |||
#include "lv2/state.h" | |||
#include "lv2/urid.h" | |||
#include "lv2/worker.h" | |||
// #include "lv2/atom-util.h" | |||
// #include "lv2/midi.h" | |||
#include <map> | |||
#ifndef DISTRHO_PLUGIN_URI | |||
# error DISTRHO_PLUGIN_URI undefined! | |||
#endif | |||
#if DISTRHO_PLUGIN_IS_SYNTH | |||
# warning LV2 Synth still TODO | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
# warning LV2 State still TODO | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_TIMEPOS | |||
# warning LV2 TimePos still TODO | |||
#endif | |||
#define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_STATE || DISTRHO_PLUGIN_WANT_TIMEPOS) | |||
#define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_STATE) | |||
// ------------------------------------------------- | |||
START_NAMESPACE_DISTRHO | |||
typedef float* floatptr; | |||
typedef std::map<d_string,d_string> stringMap; | |||
class PluginLv2 | |||
{ | |||
public: | |||
PluginLv2(const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker) | |||
: fPortControls(nullptr), | |||
fLastControlValues(nullptr), | |||
fUridMap(uridMap), | |||
fWorker(worker) | |||
{ | |||
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | |||
fPortAudioIns[i] = nullptr; | |||
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | |||
fPortAudioOuts[i] = nullptr; | |||
{ | |||
const uint32_t count(fPlugin.parameterCount()); | |||
fPortControls = new floatptr[count];; | |||
fLastControlValues = new float[count];; | |||
for (uint32_t i=0; i < count; ++i) | |||
{ | |||
fPortControls[i] = nullptr; | |||
fLastControlValues[i] = fPlugin.parameterValue(i); | |||
} | |||
} | |||
#if DISTRHO_LV2_USE_EVENTS_IN | |||
fPortEventsIn = nullptr; | |||
#endif | |||
#if DISTRHO_LV2_USE_EVENTS_OUT | |||
fPortEventsOut = nullptr; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
fPortLatency = nullptr; | |||
#endif | |||
// #if DISTRHO_LV2_USE_EVENTS | |||
// uridIdAtomString = 0; | |||
// # if DISTRHO_PLUGIN_IS_SYNTH | |||
// uridIdMidiEvent = 0; | |||
// # endif | |||
// # if DISTRHO_PLUGIN_WANT_STATE | |||
// # endif | |||
// | |||
// for (uint32_t i=0; features[i]; i++) | |||
// { | |||
// if (strcmp(features[i]->URI, LV2_URID__map) == 0) | |||
// { | |||
// uridMap = (LV2_URID_Map*)features[i]->data; | |||
// | |||
// uridIdAtomString = uridMap->map(uridMap->handle, LV2_ATOM__String); | |||
// # if DISTRHO_PLUGIN_IS_SYNTH | |||
// uridIdMidiEvent = uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent); | |||
// # endif | |||
// # if DISTRHO_PLUGIN_WANT_STATE | |||
// uridIdPatchMessage = uridMap->map(uridMap->handle, LV2_PATCH__Message); | |||
// # endif | |||
// } | |||
// else if (strcmp(features[i]->URI, LV2_WORKER__schedule) == 0) | |||
// { | |||
// workerSchedule = (LV2_Worker_Schedule*)features[i]->data; | |||
// } | |||
// } | |||
// #endif | |||
} | |||
~PluginLv2() | |||
{ | |||
if (fPortControls != nullptr) | |||
{ | |||
delete[] fPortControls; | |||
fPortControls = nullptr; | |||
} | |||
if (fLastControlValues) | |||
{ | |||
delete[] fLastControlValues; | |||
fLastControlValues = nullptr; | |||
} | |||
// #if DISTRHO_PLUGIN_WANT_STATE | |||
// stateMap.clear(); | |||
// #endif | |||
} | |||
void lv2_activate() | |||
{ | |||
fPlugin.activate(); | |||
} | |||
void lv2_deactivate() | |||
{ | |||
fPlugin.deactivate(); | |||
} | |||
void lv2_connect_port(const uint32_t port, void* const dataLocation) | |||
{ | |||
uint32_t index = 0; | |||
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | |||
{ | |||
if (port == index++) | |||
{ | |||
fPortAudioIns[i] = (floatptr)dataLocation; | |||
return; | |||
} | |||
} | |||
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | |||
{ | |||
if (port == index++) | |||
{ | |||
fPortAudioOuts[i] = (floatptr)dataLocation; | |||
return; | |||
} | |||
} | |||
#if DISTRHO_LV2_USE_EVENTS_IN | |||
if (port == index++) | |||
{ | |||
fPortEventsIn = (LV2_Atom_Sequence*)dataLocation; | |||
return; | |||
} | |||
#endif | |||
#if DISTRHO_LV2_USE_EVENTS_OUT | |||
if (port == index++) | |||
{ | |||
fPortEventsOut = (LV2_Atom_Sequence*)dataLocation; | |||
return; | |||
} | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
if (port == index++) | |||
{ | |||
fPortLatency = (floatptr)dataLocation; | |||
return; | |||
} | |||
#endif | |||
for (uint32_t i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
{ | |||
if (port == index++) | |||
{ | |||
fPortControls[i] = (floatptr)dataLocation; | |||
return; | |||
} | |||
} | |||
} | |||
void lv2_run(const uint32_t bufferSize) | |||
{ | |||
if (bufferSize == 0) | |||
{ | |||
updateParameterOutputs(); | |||
return; | |||
} | |||
// Check for updated parameters | |||
float curValue; | |||
for (uint32_t i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
{ | |||
assert(fPortControls[i] != nullptr); | |||
curValue = *fPortControls[i]; | |||
if (fLastControlValues[i] != curValue && ! fPlugin.parameterIsOutput(i)) | |||
{ | |||
fLastControlValues[i] = curValue; | |||
fPlugin.setParameterValue(i, curValue); | |||
} | |||
} | |||
#if DISTRHO_PLUGIN_IS_SYNTH | |||
// Get Events, xxx | |||
uint32_t midiEventCount = 0; | |||
#if DISTRHO_LV2_USE_EVENTS | |||
LV2_ATOM_SEQUENCE_FOREACH(portEventsIn, iter) | |||
{ | |||
const LV2_Atom_Event* event = /*(const LV2_Atom_Event*)*/iter; | |||
if (! event) | |||
continue; | |||
# if DISTRHO_PLUGIN_IS_SYNTH | |||
if (event->body.type == uridIdMidiEvent) | |||
{ | |||
if (event->time.frames >= bufferSize || midiEventCount >= MAX_MIDI_EVENTS) | |||
break; | |||
if (event->body.size > 3) | |||
continue; | |||
const uint8_t* data = (const uint8_t*)(event + 1); | |||
midiEvents[midiEventCount].frame = event->time.frames; | |||
memcpy(midiEvents[midiEventCount].buffer, data, event->body.size); | |||
midiEventCount += 1; | |||
continue; | |||
} | |||
# endif | |||
# if DISTRHO_PLUGIN_WANT_STATE | |||
if (event->body.type == uridIdPatchMessage) | |||
{ | |||
// TODO | |||
//if (workerSchedule) | |||
// workerSchedule->schedule_work(workerSchedule->handle, event->body.size, ) | |||
} | |||
# endif | |||
} | |||
#endif | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, midiEventCount, midiEvents); | |||
#else | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, 0, nullptr); | |||
#endif | |||
updateParameterOutputs(); | |||
} | |||
uint32_t lv2_get_options(LV2_Options_Option* const /*options*/) | |||
{ | |||
// currently unused | |||
return LV2_OPTIONS_SUCCESS; | |||
} | |||
uint32_t lv2_set_options(const LV2_Options_Option* const options) | |||
{ | |||
for (int i=0; options[i].key != 0; ++i) | |||
{ | |||
if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__maxBlockLength)) | |||
{ | |||
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Int)) | |||
{ | |||
const int bufferSize(*(const int*)options[i].value); | |||
fPlugin.setBufferSize(bufferSize); | |||
} | |||
else | |||
d_stderr("Host changed maxBlockLength but with wrong value type"); | |||
} | |||
else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate)) | |||
{ | |||
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double)) | |||
{ | |||
const double sampleRate(*(const double*)options[i].value); | |||
fPlugin.setSampleRate(sampleRate); | |||
} | |||
else | |||
d_stderr("Host changed sampleRate but with wrong value type"); | |||
} | |||
} | |||
return LV2_OPTIONS_SUCCESS; | |||
} | |||
#if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
const LV2_Program_Descriptor* lv2_get_program(const uint32_t index) | |||
{ | |||
if (index >= fPlugin.programCount()) | |||
return nullptr; | |||
static LV2_Program_Descriptor desc; | |||
desc.bank = index / 128; | |||
desc.program = index % 128; | |||
desc.name = fPlugin.programName(index); | |||
return &desc; | |||
} | |||
void lv2_select_program(const uint32_t bank, const uint32_t program) | |||
{ | |||
const uint32_t realProgram(bank * 128 + program); | |||
if (realProgram >= fPlugin.programCount()) | |||
return; | |||
fPlugin.setProgram(realProgram); | |||
// Update parameters | |||
for (uint32_t i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
{ | |||
if (! fPlugin.parameterIsOutput(i)) | |||
{ | |||
fLastControlValues[i] = fPlugin.parameterValue(i); | |||
if (fPortControls[i] != nullptr) | |||
*fPortControls[i] = fLastControlValues[i]; | |||
} | |||
} | |||
} | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
LV2_State_Status lv2_save(LV2_State_Store_Function store, LV2_State_Handle handle, const uint32_t flags, const LV2_Feature* const* /*features*/) | |||
{ | |||
// flags = LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE; | |||
// for (auto i = stateMap.begin(); i != stateMap.end(); i++) | |||
// { | |||
// const d_string& key = i->first; | |||
// const d_string& value = i->second; | |||
// | |||
// store(handle, uridMap->map(uridMap->handle, (const char*)key), (const char*)value, value.length(), uridIdAtomString, flags); | |||
// } | |||
return LV2_STATE_SUCCESS; | |||
} | |||
LV2_State_Status lv2_restore(LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, const uint32_t flags, const LV2_Feature* const* /*features*/) | |||
{ | |||
// size_t size; | |||
// uint32_t type; | |||
// for (uint32_t i=0; i < plugin.stateCount(); i++) | |||
// { | |||
// const d_string& key = plugin.stateKey(i); | |||
// | |||
// const void* data = retrieve(handle, uridMap->map(uridMap->handle, (const char*)key), &size, &type, &flags); | |||
// | |||
// if (size == 0 || ! data) | |||
// continue; | |||
// if (type != uridIdAtomString) | |||
// continue; | |||
// | |||
// const char* value = (const char*)data; | |||
// setState(key, value); | |||
// } | |||
return LV2_STATE_SUCCESS; | |||
} | |||
LV2_Worker_Status lv2_work(LV2_Worker_Respond_Function /*respond*/, LV2_Worker_Respond_Handle /*handle*/, const uint32_t /*size*/, const void* /*data*/) | |||
{ | |||
// TODO | |||
return LV2_WORKER_SUCCESS; | |||
} | |||
LV2_Worker_Status lv2_work_response(const uint32_t /*size*/, const void* /*body*/) | |||
{ | |||
// TODO | |||
return LV2_WORKER_SUCCESS; | |||
} | |||
#endif | |||
private: | |||
PluginInternal fPlugin; | |||
// LV2 ports | |||
floatptr fPortAudioIns[DISTRHO_PLUGIN_NUM_INPUTS]; | |||
floatptr fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS]; | |||
floatptr* fPortControls; | |||
#if DISTRHO_LV2_USE_EVENTS_IN | |||
LV2_Atom_Sequence* fPortEventsIn; | |||
#endif | |||
#if DISTRHO_LV2_USE_EVENTS_OUT | |||
LV2_Atom_Sequence* fPortEventsOut; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
floatptr fPortLatency; | |||
#endif | |||
// Temporary data | |||
float* fLastControlValues; | |||
// #if DISTRHO_PLUGIN_IS_SYNTH | |||
// MidiEvent fMidiEvents[MAX_MIDI_EVENTS]; | |||
// #endif | |||
// Feature data | |||
const LV2_URID_Map* const fUridMap; | |||
const LV2_Worker_Schedule* const fWorker; | |||
// xxx | |||
// #if DISTRHO_LV2_USE_EVENTS | |||
// | |||
// // URIDs | |||
// LV2_URID_Map* uridMap; | |||
// LV2_URID uridIdAtomString; | |||
// # if DISTRHO_PLUGIN_IS_SYNTH | |||
// LV2_URID uridIdMidiEvent; | |||
// # endif | |||
// # if DISTRHO_PLUGIN_WANT_STATE | |||
// LV2_URID uridIdPatchMessage; | |||
// LV2_Worker_Schedule* workerSchedule; | |||
// # endif | |||
// #endif | |||
// #if DISTRHO_PLUGIN_WANT_STATE | |||
// stringMap stateMap; | |||
// | |||
// void setState(const char* newKey, const char* newValue) | |||
// { | |||
// plugin.setState(newKey, newValue); | |||
// | |||
// // check if key already exists | |||
// for (auto i = stateMap.begin(); i != stateMap.end(); i++) | |||
// { | |||
// const d_string& key = i->first; | |||
// | |||
// if (key == newKey) | |||
// { | |||
// i->second = newValue; | |||
// return; | |||
// } | |||
// } | |||
// | |||
// // add a new one then | |||
// stateMap[newKey] = newValue; | |||
// } | |||
// #endif | |||
void updateParameterOutputs() | |||
{ | |||
for (uint32_t i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
{ | |||
if (fPlugin.parameterIsOutput(i)) | |||
{ | |||
fLastControlValues[i] = fPlugin.parameterValue(i); | |||
if (fPortControls[i] != nullptr) | |||
*fPortControls[i] = fLastControlValues[i]; | |||
} | |||
} | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
if (fPortLatency != nullptr) | |||
*fPortLatency = fPlugin.latency(); | |||
#endif | |||
} | |||
}; | |||
// ------------------------------------------------- | |||
static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, const char*, const LV2_Feature* const* features) | |||
{ | |||
const LV2_Options_Option* options = nullptr; | |||
const LV2_URID_Map* uridMap = nullptr; | |||
const LV2_Worker_Schedule* worker = nullptr; | |||
for (int i=0; features[i] != nullptr; ++i) | |||
{ | |||
if (std::strcmp(features[i]->URI, LV2_OPTIONS__options) == 0) | |||
options = (const LV2_Options_Option*)features[i]->data; | |||
else if (std::strcmp(features[i]->URI, LV2_URID__map) == 0) | |||
uridMap = (const LV2_URID_Map*)features[i]->data; | |||
else if (std::strcmp(features[i]->URI, LV2_WORKER__schedule) == 0) | |||
worker = (const LV2_Worker_Schedule*)features[i]->data; | |||
} | |||
if (uridMap == nullptr) | |||
{ | |||
d_stderr("URID Map feature missing, cannot continue!"); | |||
return nullptr; | |||
} | |||
for (int i=0; options[i].key != 0; ++i) | |||
{ | |||
if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength)) | |||
{ | |||
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int)) | |||
d_lastBufferSize = *(const int*)options[i].value; | |||
else | |||
d_stderr("Host provides maxBlockLength but has wrong value type"); | |||
break; | |||
} | |||
} | |||
if (d_lastBufferSize == 0) | |||
d_lastBufferSize = 512; | |||
d_lastSampleRate = sampleRate; | |||
return new PluginLv2(uridMap, worker); | |||
} | |||
#define instancePtr ((PluginLv2*)instance) | |||
static void lv2_connect_port(LV2_Handle instance, uint32_t port, void* dataLocation) | |||
{ | |||
instancePtr->lv2_connect_port(port, dataLocation); | |||
} | |||
static void lv2_activate(LV2_Handle instance) | |||
{ | |||
instancePtr->lv2_activate(); | |||
} | |||
static void lv2_run(LV2_Handle instance, uint32_t sampleCount) | |||
{ | |||
instancePtr->lv2_run(sampleCount); | |||
} | |||
static void lv2_deactivate(LV2_Handle instance) | |||
{ | |||
instancePtr->lv2_deactivate(); | |||
} | |||
static void lv2_cleanup(LV2_Handle instance) | |||
{ | |||
delete instancePtr; | |||
} | |||
static uint32_t lv2_get_options(LV2_Handle instance, LV2_Options_Option* options) | |||
{ | |||
return instancePtr->lv2_get_options(options); | |||
} | |||
static uint32_t lv2_set_options(LV2_Handle instance, const LV2_Options_Option* options) | |||
{ | |||
return instancePtr->lv2_set_options(options); | |||
} | |||
#if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
static const LV2_Program_Descriptor* lv2_get_program(LV2_Handle instance, uint32_t index) | |||
{ | |||
return instancePtr->lv2_get_program(index); | |||
} | |||
static void lv2_select_program(LV2_Handle instance, uint32_t bank, uint32_t program) | |||
{ | |||
instancePtr->lv2_select_program(bank, program); | |||
} | |||
#endif | |||
#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* features) | |||
{ | |||
return instancePtr->lv2_save(store, handle, flags, features); | |||
} | |||
static LV2_State_Status lv2_restore(LV2_Handle instance, LV2_State_Retrieve_Function retrieve, LV2_State_Handle handle, uint32_t flags, const LV2_Feature* const* features) | |||
{ | |||
return instancePtr->lv2_restore(retrieve, handle, flags, features); | |||
} | |||
LV2_Worker_Status lv2_work(LV2_Handle instance, LV2_Worker_Respond_Function respond, LV2_Worker_Respond_Handle handle, uint32_t size, const void* data) | |||
{ | |||
return instancePtr->lv2_work(respond, handle, size, data); | |||
} | |||
LV2_Worker_Status lv2_work_response(LV2_Handle instance, uint32_t size, const void* body) | |||
{ | |||
return instancePtr->lv2_work_response(size, body); | |||
} | |||
#endif | |||
static const void* lv2_extension_data(const char* uri) | |||
{ | |||
static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options }; | |||
if (std::strcmp(uri, LV2_OPTIONS__interface) == 0) | |||
return &options; | |||
#if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
static const LV2_Programs_Interface programs = { lv2_get_program, lv2_select_program }; | |||
if (std::strcmp(uri, LV2_PROGRAMS__Interface) == 0) | |||
return &programs; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
static const LV2_State_Interface state = { lv2_save, lv2_restore }; | |||
static const LV2_Worker_Interface worker = { lv2_work, lv2_work_response, nullptr }; | |||
if (std::strcmp(uri, LV2_STATE__interface) == 0) | |||
return &state; | |||
if (std::strcmp(uri, LV2_WORKER__interface) == 0) | |||
return &worker; | |||
#endif | |||
return nullptr; | |||
} | |||
#undef instancePtr | |||
// ------------------------------------------------- | |||
static LV2_Descriptor sLv2Descriptor = { | |||
DISTRHO_PLUGIN_URI, | |||
lv2_instantiate, | |||
lv2_connect_port, | |||
lv2_activate, | |||
lv2_run, | |||
lv2_deactivate, | |||
lv2_cleanup, | |||
lv2_extension_data | |||
}; | |||
END_NAMESPACE_DISTRHO | |||
// ------------------------------------------------- | |||
DISTRHO_PLUGIN_EXPORT | |||
const LV2_Descriptor* lv2_descriptor(uint32_t index) | |||
{ | |||
USE_NAMESPACE_DISTRHO | |||
return (index == 0) ? &sLv2Descriptor : nullptr; | |||
} |
@@ -0,0 +1,359 @@ | |||
/* | |||
* DISTRHO Plugin Toolkit (DPT) | |||
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* For a full copy of the license see the LGPL.txt file | |||
*/ | |||
#include "DistrhoPluginInternal.hpp" | |||
#include "lv2/lv2.h" | |||
#include "lv2/atom.h" | |||
#include "lv2/buf-size.h" | |||
// #include "lv2/midi.h" | |||
#include "lv2/options.h" | |||
#include "lv2/programs.h" | |||
// #include "lv2/state.h" | |||
#include "lv2/time.h" | |||
// #include "lv2/ui.h" | |||
#include "lv2/urid.h" | |||
#include "lv2/units.h" | |||
// #include "lv2/worker.h" | |||
#include <fstream> | |||
#include <iostream> | |||
#ifndef DISTRHO_PLUGIN_URI | |||
# error DISTRHO_PLUGIN_URI undefined! | |||
#endif | |||
// TODO: UI | |||
#undef DISTRHO_PLUGIN_HAS_UI | |||
#undef DISTRHO_PLUGIN_WANT_LATENCY | |||
#undef DISTRHO_PLUGIN_WANT_PROGRAMS | |||
#undef DISTRHO_PLUGIN_WANT_STATE | |||
#undef DISTRHO_PLUGIN_WANT_TIMEPOS | |||
#define DISTRHO_PLUGIN_WANT_LATENCY 1 | |||
#define DISTRHO_PLUGIN_WANT_PROGRAMS 1 | |||
#define DISTRHO_PLUGIN_WANT_STATE 1 | |||
#define DISTRHO_PLUGIN_WANT_TIMEPOS 1 | |||
#define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_STATE || DISTRHO_PLUGIN_WANT_TIMEPOS) | |||
#define DISTRHO_LV2_USE_EVENTS_OUT (DISTRHO_PLUGIN_WANT_STATE) | |||
// ------------------------------------------------- | |||
DISTRHO_PLUGIN_EXPORT | |||
void lv2_generate_ttl(const char* const basename) | |||
{ | |||
USE_NAMESPACE_DISTRHO | |||
// Dummy plugin to get data from | |||
d_lastBufferSize = 512; | |||
d_lastSampleRate = 44100.0; | |||
PluginInternal plugin; | |||
d_lastBufferSize = 0; | |||
d_lastSampleRate = 0.0; | |||
d_string pluginLabel(basename); | |||
d_string pluginTTL(pluginLabel + ".ttl"); | |||
// --------------------------------------------- | |||
{ | |||
std::cout << "Writing manifest.ttl..."; std::cout.flush(); | |||
std::fstream manifestFile("manifest.ttl", std::ios::out); | |||
d_string manifestString; | |||
manifestString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||
manifestString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n"; | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
manifestString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||
#endif | |||
manifestString += "\n"; | |||
manifestString += "<" DISTRHO_PLUGIN_URI ">\n"; | |||
manifestString += " a lv2:Plugin ;\n"; | |||
manifestString += " lv2:binary <" + pluginLabel + "." DISTRHO_DLL_EXTENSION "> ;\n"; | |||
manifestString += " rdfs:seeAlso <" + pluginTTL + "> .\n"; | |||
manifestString += "\n"; | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
manifestString += "<" DISTRHO_UI_URI ">\n"; | |||
# if DISTRHO_OS_HAIKU | |||
manifestString += " a ui:BeUI ;\n"; | |||
# elif DISTRHO_OS_MACOS | |||
manifestString += " a ui:CocoaUI ;\n"; | |||
# elif DISTRHO_OS_WINDOWS | |||
manifestString += " a ui:WindowsUI ;\n"; | |||
# else | |||
manifestString += " a ui:X11UI ;\n"; | |||
# endif | |||
manifestString += " ui:binary <" + pluginLabel + "_ui." DISTRHO_DLL_EXTENSION "> .\n"; | |||
// # if DISTRHO_LV2_USE_EVENTS | |||
// manifestString += " lv2:optionalFeature <" LV2_URID__map "> ,\n"; | |||
// manifestString += " ui:noUserResize .\n"; | |||
// # else | |||
// manifestString += " lv2:optionalFeature ui:noUserResize .\n"; | |||
// # endif | |||
manifestString += "\n"; | |||
#endif | |||
manifestFile << manifestString << std::endl; | |||
manifestFile.close(); | |||
std::cout << " done!" << std::endl; | |||
} | |||
// --------------------------------------------- | |||
{ | |||
std::cout << "Writing " << pluginTTL << "..."; std::cout.flush(); | |||
std::fstream pluginFile(pluginTTL, std::ios::out); | |||
d_string pluginString; | |||
#if DISTRHO_LV2_USE_EVENTS_IN | |||
pluginString += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n"; | |||
#endif | |||
pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n"; | |||
pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"; | |||
pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n"; | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
pluginString += "@prefix ui: <" LV2_UI_PREFIX "> .\n"; | |||
#endif | |||
pluginString += "@prefix unit: <" LV2_UNITS_PREFIX "> .\n"; | |||
pluginString += "\n"; | |||
pluginString += "<" DISTRHO_PLUGIN_URI ">\n"; | |||
#if DISTRHO_PLUGIN_IS_SYNTH | |||
pluginString += " a lv2:InstrumentPlugin, lv2:Plugin ;\n"; | |||
#else | |||
pluginString += " a lv2:Plugin ;\n"; | |||
#endif | |||
pluginString += "\n"; | |||
#if (DISTRHO_PLUGIN_WANT_STATE || DISTRHO_PLUGIN_WANT_PROGRAMS) | |||
pluginString += " lv2:extensionData <" LV2_OPTIONS__interface "> ,\n"; | |||
# if DISTRHO_PLUGIN_WANT_STATE | |||
pluginString += " <" LV2_STATE__interface "> ,\n"; | |||
pluginString += " <" LV2_WORKER__interface "> \n"; | |||
# if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
pluginString += ",\n"; | |||
# else | |||
pluginString += ";\n"; | |||
# endif | |||
# endif | |||
# if DISTRHO_PLUGIN_WANT_PROGRAMS | |||
pluginString += " <" LV2_PROGRAMS__Interface "> ;\n"; | |||
# endif | |||
#endif | |||
pluginString += "\n"; | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
pluginString += " lv2:optionalFeature <" LV2_CORE__hardRTCapable "> ,\n"; | |||
pluginString += " <" LV2_WORKER__schedule "> ;\n"; | |||
#else | |||
pluginString += " lv2:optionalFeature <" LV2_CORE__hardRTCapable "> ;\n"; | |||
#endif | |||
pluginString += "\n"; | |||
pluginString += " lv2:requiredFeature <" LV2_BUF_SIZE__boundedBlockLength "> ,\n"; | |||
pluginString += " <" LV2_URID__map "> ;\n"; | |||
pluginString += "\n"; | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
pluginString += " ui:ui <" DISTRHO_UI_URI "> ;\n"; | |||
pluginString += "\n"; | |||
#endif | |||
{ | |||
uint32_t portIndex = 0; | |||
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i) | |||
{ | |||
if (i == 0) | |||
pluginString += " lv2:port [\n"; | |||
else | |||
pluginString += " [\n"; | |||
pluginString += " a lv2:InputPort, lv2:AudioPort ;\n"; | |||
pluginString += " lv2:index " + d_string(portIndex++) + " ;\n"; | |||
pluginString += " lv2:symbol \"lv2_audio_in_" + d_string(i+1) + "\" ;\n"; | |||
pluginString += " lv2:name \"Audio Input " + d_string(i+1) + "\" ;\n"; | |||
if (i+1 == DISTRHO_PLUGIN_NUM_INPUTS) | |||
pluginString += " ] ;\n\n"; | |||
else | |||
pluginString += " ] ,\n"; | |||
} | |||
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) | |||
{ | |||
if (i == 0) | |||
pluginString += " lv2:port [\n"; | |||
else | |||
pluginString += " [\n"; | |||
pluginString += " a lv2:OutputPort, lv2:AudioPort ;\n"; | |||
pluginString += " lv2:index " + d_string(portIndex++) + " ;\n"; | |||
pluginString += " lv2:symbol \"lv2_audio_out_" + d_string(i+1) + "\" ;\n"; | |||
pluginString += " lv2:name \"Audio Output " + d_string(i+1) + "\" ;\n"; | |||
if (i+1 == DISTRHO_PLUGIN_NUM_OUTPUTS) | |||
pluginString += " ] ;\n\n"; | |||
else | |||
pluginString += " ] ,\n"; | |||
} | |||
#if DISTRHO_LV2_USE_EVENTS_IN | |||
pluginString += " lv2:port [\n"; | |||
pluginString += " a lv2:InputPort, atom:AtomPort ;\n"; | |||
pluginString += " lv2:index " + d_string(portIndex++) + " ;\n"; | |||
pluginString += " lv2:name \"Events Input\" ;\n"; | |||
pluginString += " lv2:symbol \"lv2_events_in\" ;\n"; | |||
pluginString += " atom:bufferType atom:Sequence ;\n"; | |||
# if (DISTRHO_PLUGIN_IS_SYNTH && DISTRHO_PLUGIN_WANT_TIMEPOS) // TODO | |||
pluginString += " atom:supports <" LV2_MIDI__MidiEvent "> ,\n"; | |||
pluginString += " <" LV2_TIME__Position "> ;\n"; | |||
# elif DISTRHO_PLUGIN_IS_SYNTH | |||
pluginString += " atom:supports <" LV2_MIDI__MidiEvent "> ;\n"; | |||
# else | |||
pluginString += " atom:supports <" LV2_TIME__Position "> ;\n"; | |||
# endif | |||
pluginString += " ] ;\n"; | |||
#endif | |||
#if DISTRHO_LV2_USE_EVENTS_OUT | |||
pluginString += " lv2:port [\n"; | |||
pluginString += " a lv2:OutputPort, atom:AtomPort ;\n"; | |||
pluginString += " lv2:index " + d_string(portIndex++) + " ;\n"; | |||
pluginString += " lv2:name \"Events Output\" ;\n"; | |||
pluginString += " lv2:symbol \"lv2_events_out\" ;\n"; | |||
pluginString += " atom:bufferType atom:Sequence ;\n"; | |||
pluginString += " atom:supports <something_here> ;\n"; // TODO | |||
pluginString += " ] ;\n"; | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_LATENCY | |||
pluginString += " lv2:port [\n"; | |||
pluginString += " a lv2:OutputPort, lv2:ControlPort ;\n"; | |||
pluginString += " lv2:index " + d_string(portIndex++) + " ;\n"; | |||
pluginString += " lv2:name \"Latency\" ;\n"; | |||
pluginString += " lv2:symbol \"lv2_latency\" ;\n"; | |||
pluginString += " lv2:designation lv2:latency ;\n"; | |||
pluginString += " ] ;\n"; | |||
#endif | |||
for (uint32_t i=0; i < plugin.parameterCount(); ++i) | |||
{ | |||
if (i == 0) | |||
pluginString += " lv2:port [\n"; | |||
else | |||
pluginString += " [\n"; | |||
if (plugin.parameterIsOutput(i)) | |||
pluginString += " a lv2:OutputPort, lv2:ControlPort ;\n"; | |||
else | |||
pluginString += " a lv2:InputPort, lv2:ControlPort ;\n"; | |||
pluginString += " lv2:index " + d_string(portIndex++) + " ;\n"; | |||
pluginString += " lv2:name \"" + plugin.parameterName(i) + "\" ;\n"; | |||
// symbol | |||
{ | |||
d_string symbol(plugin.parameterSymbol(i)); | |||
if (symbol.isEmpty()) | |||
symbol = "lv2_port_" + d_string(portIndex-1); | |||
pluginString += " lv2:symbol \"" + symbol + "\" ;\n"; | |||
} | |||
// ranges | |||
{ | |||
const ParameterRanges& ranges(plugin.parameterRanges(i)); | |||
if (plugin.parameterHints(i) & PARAMETER_IS_INTEGER) | |||
{ | |||
pluginString += " lv2:default " + d_string(int(plugin.parameterValue(i))) + " ;\n"; | |||
pluginString += " lv2:minimum " + d_string(int(ranges.min)) + " ;\n"; | |||
pluginString += " lv2:maximum " + d_string(int(ranges.max)) + " ;\n"; | |||
} | |||
else | |||
{ | |||
pluginString += " lv2:default " + d_string(plugin.parameterValue(i)) + " ;\n"; | |||
pluginString += " lv2:minimum " + d_string(ranges.min) + " ;\n"; | |||
pluginString += " lv2:maximum " + d_string(ranges.max) + " ;\n"; | |||
} | |||
} | |||
// unit | |||
{ | |||
const d_string& unit(plugin.parameterUnit(i)); | |||
if (! unit.isEmpty()) | |||
{ | |||
if (unit == "db" || unit == "dB") | |||
{ | |||
pluginString += " unit:unit unit:db ;\n"; | |||
} | |||
else if (unit == "hz" || unit == "Hz") | |||
{ | |||
pluginString += " unit:unit unit:hz ;\n"; | |||
} | |||
else if (unit == "khz" || unit == "kHz") | |||
{ | |||
pluginString += " unit:unit unit:khz ;\n"; | |||
} | |||
else if (unit == "mhz" || unit == "mHz") | |||
{ | |||
pluginString += " unit:unit unit:mhz ;\n"; | |||
} | |||
else | |||
{ | |||
pluginString += " unit:unit [\n"; | |||
pluginString += " a unit:Unit ;\n"; | |||
pluginString += " unit:name \"" + unit + "\" ;\n"; | |||
pluginString += " unit:symbol \"" + unit + "\" ;\n"; | |||
pluginString += " unit:render \"%f f\" ;\n"; | |||
pluginString += " ] ;\n"; | |||
} | |||
} | |||
} | |||
// hints | |||
{ | |||
const uint32_t hints(plugin.parameterHints(i)); | |||
if (hints & PARAMETER_IS_BOOLEAN) | |||
pluginString += " lv2:portProperty lv2:toggled ;\n"; | |||
if (hints & PARAMETER_IS_INTEGER) | |||
pluginString += " lv2:portProperty lv2:integer ;\n"; | |||
if (hints & PARAMETER_IS_LOGARITHMIC) | |||
pluginString += " lv2:portProperty <http://lv2plug.in/ns/ext/port-props#logarithmic> ;\n"; | |||
} | |||
if (i+1 == plugin.parameterCount()) | |||
pluginString += " ] ;\n\n"; | |||
else | |||
pluginString += " ] ,\n"; | |||
} | |||
} | |||
pluginString += " doap:name \"" + d_string(plugin.name()) + "\" ;\n"; | |||
pluginString += " doap:maintainer [ foaf:name \"" + d_string(plugin.maker()) + "\" ] .\n"; | |||
pluginFile << pluginString << std::endl; | |||
pluginFile.close(); | |||
std::cout << " done!" << std::endl; | |||
} | |||
} |
@@ -18,7 +18,7 @@ | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
# include "DistrhoUIInternal.hpp" | |||
# ifdef DISTRHO_UI_QT4 | |||
# ifdef DISTRHO_UI_QT | |||
# include <QtGui/QApplication> | |||
# endif | |||
#endif | |||
@@ -33,7 +33,7 @@ | |||
//# include "vestige/aeffectx.h" | |||
//# define effSetProgramName 4 | |||
//#else | |||
#include "vst/aeffectx.h" | |||
#include "aeffectx.h" | |||
//#endif | |||
START_NAMESPACE_DISTRHO | |||
@@ -42,7 +42,7 @@ START_NAMESPACE_DISTRHO | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
# ifdef DISTRHO_UI_QT4 | |||
# ifdef DISTRHO_UI_QT | |||
class QStaticScopedAppInit | |||
{ | |||
public: | |||
@@ -57,14 +57,14 @@ public: | |||
fInitiated = true; | |||
if (qApp != nullptr) | |||
if (QApplication* app = qApp) | |||
{ | |||
fApp = qApp; | |||
fApp = app; | |||
} | |||
else | |||
{ | |||
static int qargc = 0; | |||
static char** qargv = nullptr; | |||
static int qargc = 0; | |||
static char* qargv[] = { nullptr }; | |||
fApp = new QApplication(qargc, qargv, true); | |||
fApp->setQuitOnLastWindowClosed(false); | |||
} | |||
@@ -95,7 +95,7 @@ public: | |||
fParameterChecks(nullptr), | |||
fParameterValues(nullptr) | |||
{ | |||
uint32_t paramCount = plugin->parameterCount(); | |||
const uint32_t paramCount(plugin->parameterCount()); | |||
if (paramCount > 0) | |||
{ | |||
@@ -121,10 +121,16 @@ public: | |||
~UIVst() | |||
{ | |||
if (fParameterChecks != nullptr) | |||
{ | |||
delete[] fParameterChecks; | |||
fParameterChecks = nullptr; | |||
} | |||
if (fParameterValues != nullptr) | |||
{ | |||
delete[] fParameterValues; | |||
fParameterValues = nullptr; | |||
} | |||
} | |||
// --------------------------------------------- | |||
@@ -156,18 +162,18 @@ public: | |||
fUi.idle(); | |||
} | |||
int16_t getWidth() | |||
int16_t getWidth() const | |||
{ | |||
return fUi.width(); | |||
} | |||
int16_t getHeight() | |||
int16_t getHeight() const | |||
{ | |||
return fUi.height(); | |||
} | |||
// --------------------------------------------- | |||
// functions called from the plugin side, no block | |||
// functions called from the plugin side, RT no block | |||
void setParameterValueFromPlugin(uint32_t index, float perValue) | |||
{ | |||
@@ -204,8 +210,8 @@ protected: | |||
void setParameterValue(uint32_t index, float realValue) | |||
{ | |||
const ParameterRanges& ranges = kPlugin->parameterRanges(index); | |||
float perValue = ranges.normalizeValue(realValue); | |||
const ParameterRanges& ranges(kPlugin->parameterRanges(index)); | |||
const float perValue(ranges.normalizeValue(realValue)); | |||
kPlugin->setParameterValue(index, realValue); | |||
hostCallback(audioMasterAutomate, index, 0, nullptr, perValue); | |||
@@ -355,7 +361,9 @@ public: | |||
case effGetProgramName: | |||
if (ptr != nullptr && fCurProgram >= 0 && fCurProgram < static_cast<int32_t>(fPlugin.programCount())) | |||
{ | |||
std::strncpy((char*)ptr, fPlugin.programName(fCurProgram), kVstMaxProgNameLen); | |||
char* buf = (char*)ptr; | |||
std::strncpy(buf, fPlugin.programName(fCurProgram), kVstMaxProgNameLen); | |||
buf[kVstMaxProgNameLen] = '\0'; | |||
ret = 1; | |||
} | |||
break; | |||
@@ -364,7 +372,9 @@ public: | |||
case effGetParamDisplay: | |||
if (ptr != nullptr && index < static_cast<int32_t>(fPlugin.parameterCount())) | |||
{ | |||
snprintf((char*)ptr, kVstMaxParamStrLen, "%f", fPlugin.parameterValue(index)); | |||
char* buf = (char*)ptr; | |||
std::snprintf((char*)ptr, kVstMaxParamStrLen, "%f", fPlugin.parameterValue(index)); | |||
buf[kVstMaxParamStrLen] = '\0'; | |||
ret = 1; | |||
} | |||
break; | |||
@@ -392,7 +402,7 @@ public: | |||
break; | |||
case effEditOpen: | |||
createUiIfNeeded((intptr_t)ptr); | |||
createUiIfNeeded((intptr_t)ptr); // FIXME - use FromVstPtr<> | |||
ret = 1; | |||
break; | |||
@@ -461,14 +471,14 @@ public: | |||
float vst_getParameter(int32_t index) | |||
{ | |||
const ParameterRanges& ranges = fPlugin.parameterRanges(index); | |||
const ParameterRanges& ranges(fPlugin.parameterRanges(index)); | |||
return ranges.normalizeValue(fPlugin.parameterValue(index)); | |||
} | |||
void vst_setParameter(int32_t index, float value) | |||
{ | |||
const ParameterRanges& ranges = fPlugin.parameterRanges(index); | |||
float realValue = ranges.unnormalizeValue(value); | |||
const ParameterRanges& ranges(fPlugin.parameterRanges(index)); | |||
const float realValue(ranges.unnormalizeValue(value)); | |||
fPlugin.setParameterValue(index, realValue); | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
@@ -585,9 +595,6 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
d_lastBufferSize = audioMaster(effect, audioMasterGetBlockSize, 0, 0, nullptr, 0.0f); | |||
d_lastSampleRate = audioMaster(effect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f); | |||
effect->object = new PluginVst(audioMaster, effect); | |||
#ifdef DISTRHO_UI_QT4 | |||
QStaticScopedAppInit::addOne(); | |||
#endif | |||
return 1; | |||
} | |||
return 0; | |||
@@ -598,14 +605,11 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t | |||
delete (PluginVst*)effect->object; | |||
effect->object = nullptr; | |||
delete effect; | |||
#ifdef DISTRHO_UI_QT4 | |||
QStaticScopedAppInit::removeOne(); | |||
#endif | |||
return 1; | |||
} | |||
return 0; | |||
case effGetParamLabel: | |||
case effGetParamLabel: // FIXME - proper close buf/ptr | |||
if (ptr != nullptr && index < static_cast<int32_t>(plugin.parameterCount())) | |||
{ | |||
std::strncpy((char*)ptr, plugin.parameterUnit(index), kVstMaxParamStrLen); | |||
@@ -165,7 +165,6 @@ public: | |||
{ | |||
fOscData.idle(); | |||
fUI.idle(); | |||
glApp.idle(); | |||
dgl_msleep(50); | |||
} | |||
#endif | |||
@@ -218,15 +218,14 @@ public: | |||
void idle() | |||
{ | |||
#if defined(DISTRHO_UI_EXTERNAL) | |||
// needed? | |||
#elif defined(DISTRHO_UI_OPENGL) | |||
glApp.idle(); | |||
#endif | |||
assert(kUi != nullptr); | |||
if (kUi != nullptr) | |||
kUi->d_uiIdle(); | |||
#ifdef DISTRHO_UI_OPENGL | |||
glApp.idle(); | |||
#endif | |||
} | |||
#if defined(DISTRHO_UI_EXTERNAL) | |||