Browse Source

Update DISTRHO stuff

tags/1.9.4
falkTX 12 years ago
parent
commit
d1c2d07ef3
17 changed files with 1201 additions and 134 deletions
  1. +1
    -0
      source/backend/native/3bandeq/DistrhoPluginInfo.h
  2. +1
    -0
      source/backend/native/3bandsplitter/DistrhoPluginInfo.h
  3. +1
    -0
      source/backend/native/nekobi/DistrhoPluginInfo.h
  4. +1
    -0
      source/backend/native/notes/DistrhoPluginInfo.h
  5. +1
    -0
      source/backend/native/pingpongpan/DistrhoPluginInfo.h
  6. +1
    -0
      source/backend/native/stereoenhancer/DistrhoPluginInfo.h
  7. +8
    -6
      source/libs/distrho/DistrhoPlugin.hpp
  8. +1
    -0
      source/libs/distrho/DistrhoPluginMain.cpp
  9. +4
    -0
      source/libs/distrho/src/DistrhoDefines.h
  10. +2
    -0
      source/libs/distrho/src/DistrhoPlugin.cpp
  11. +29
    -16
      source/libs/distrho/src/DistrhoPluginInternal.hpp
  12. +95
    -80
      source/libs/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
  13. +663
    -0
      source/libs/distrho/src/DistrhoPluginLV2.cpp
  14. +359
    -0
      source/libs/distrho/src/DistrhoPluginLV2export.cpp
  15. +30
    -26
      source/libs/distrho/src/DistrhoPluginVST.cpp
  16. +0
    -1
      source/libs/distrho/src/DistrhoUIDSSI.cpp
  17. +4
    -5
      source/libs/distrho/src/DistrhoUIInternal.hpp

+ 1
- 0
source/backend/native/3bandeq/DistrhoPluginInfo.h View File

@@ -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"



+ 1
- 0
source/backend/native/3bandsplitter/DistrhoPluginInfo.h View File

@@ -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"



+ 1
- 0
source/backend/native/nekobi/DistrhoPluginInfo.h View File

@@ -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"



+ 1
- 0
source/backend/native/notes/DistrhoPluginInfo.h View File

@@ -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"



+ 1
- 0
source/backend/native/pingpongpan/DistrhoPluginInfo.h View File

@@ -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"



+ 1
- 0
source/backend/native/stereoenhancer/DistrhoPluginInfo.h View File

@@ -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"



+ 8
- 6
source/libs/distrho/DistrhoPlugin.hpp View File

@@ -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


+ 1
- 0
source/libs/distrho/DistrhoPluginMain.cpp View File

@@ -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

+ 4
- 0
source/libs/distrho/src/DistrhoDefines.h View File

@@ -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


+ 2
- 0
source/libs/distrho/src/DistrhoPlugin.cpp View File

@@ -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)


+ 29
- 16
source/libs/distrho/src/DistrhoPluginInternal.hpp View File

@@ -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);



+ 95
- 80
source/libs/distrho/src/DistrhoPluginLADSPA+DSSI.cpp View File

@@ -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



+ 663
- 0
source/libs/distrho/src/DistrhoPluginLV2.cpp View File

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

+ 359
- 0
source/libs/distrho/src/DistrhoPluginLV2export.cpp View File

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

+ 30
- 26
source/libs/distrho/src/DistrhoPluginVST.cpp View File

@@ -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);


+ 0
- 1
source/libs/distrho/src/DistrhoUIDSSI.cpp View File

@@ -165,7 +165,6 @@ public:
{
fOscData.idle();
fUI.idle();
glApp.idle();
dgl_msleep(50);
}
#endif


+ 4
- 5
source/libs/distrho/src/DistrhoUIInternal.hpp View File

@@ -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)


Loading…
Cancel
Save