Browse Source

Update DPF

tags/v1.2
falkTX 6 years ago
parent
commit
bb6fbd4580
21 changed files with 868 additions and 249 deletions
  1. +1
    -1
      dpf/dgl/Application.hpp
  2. +2
    -2
      dpf/dgl/src/Application.cpp
  3. +3
    -3
      dpf/dgl/src/NanoVG.cpp
  4. +4
    -4
      dpf/dgl/src/WidgetPrivateData.hpp
  5. +3
    -1
      dpf/dgl/src/Window.cpp
  6. +0
    -3
      dpf/dgl/src/pugl/pugl_osx.m
  7. +102
    -4
      dpf/distrho/DistrhoPlugin.hpp
  8. +2
    -1
      dpf/distrho/DistrhoUI.hpp
  9. +7
    -7
      dpf/distrho/src/DistrhoPlugin.cpp
  10. +55
    -6
      dpf/distrho/src/DistrhoPluginInternal.hpp
  11. +83
    -11
      dpf/distrho/src/DistrhoPluginJack.cpp
  12. +33
    -13
      dpf/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
  13. +105
    -35
      dpf/distrho/src/DistrhoPluginLV2.cpp
  14. +47
    -24
      dpf/distrho/src/DistrhoPluginLV2export.cpp
  15. +257
    -80
      dpf/distrho/src/DistrhoPluginVST.cpp
  16. +1
    -1
      dpf/distrho/src/DistrhoUI.cpp
  17. +14
    -3
      dpf/distrho/src/DistrhoUIDSSI.cpp
  18. +17
    -12
      dpf/distrho/src/DistrhoUIInternal.hpp
  19. +34
    -1
      dpf/distrho/src/DistrhoUILV2.cpp
  20. +92
    -31
      dpf/distrho/src/vestige/vestige.h
  21. +6
    -6
      dpf/utils/generate-ttl.sh

+ 1
- 1
dpf/dgl/Application.hpp View File

@@ -62,7 +62,7 @@ public:
idle() is called at regular intervals.
@note This function is meant for standalones only, *never* call this from plugins.
*/
void exec();
void exec(int idleTime = 10);

/**
Quit the application.


+ 2
- 2
dpf/dgl/src/Application.cpp View File

@@ -44,12 +44,12 @@ void Application::idle()
}
}

void Application::exec()
void Application::exec(int idleTime)
{
for (; pData->doLoop;)
{
idle();
d_msleep(10);
d_msleep(idleTime);
}
}



+ 3
- 3
dpf/dgl/src/NanoVG.cpp View File

@@ -472,8 +472,8 @@ void NanoVG::skewY(float angle)
void NanoVG::scale(float x, float y)
{
if (fContext == nullptr) return;
DISTRHO_SAFE_ASSERT_RETURN(x > 0.0f,);
DISTRHO_SAFE_ASSERT_RETURN(y > 0.0f,);
DISTRHO_SAFE_ASSERT_RETURN(d_isNotZero(x),);
DISTRHO_SAFE_ASSERT_RETURN(d_isNotZero(y),);

nvgScale(fContext, x, y);
}
@@ -865,7 +865,7 @@ float NanoVG::textBounds(float x, float y, const char* string, const char* end,

float b[4];
const float ret = nvgTextBounds(fContext, x, y, string, end, b);
bounds = Rectangle<float>(b[0], b[1], b[2], b[3]);
bounds = Rectangle<float>(b[0], b[1], b[2] - b[0], b[3] - b[1]);
return ret;
}



+ 4
- 4
dpf/dgl/src/WidgetPrivateData.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -63,9 +63,9 @@ struct Widget::PrivateData {
subWidgets.clear();
}

void display(const uint width, const uint height)
void display(const uint width, const uint height, const bool renderingSubWidget)
{
if (skipDisplay || ! visible)
if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible)
return;

bool needsDisableScissor = false;
@@ -123,7 +123,7 @@ struct Widget::PrivateData {
Widget* const widget(*it);
DISTRHO_SAFE_ASSERT_CONTINUE(widget->pData != this);

widget->pData->display(width, height);
widget->pData->display(width, height, true);
}
}



+ 3
- 1
dpf/dgl/src/Window.cpp View File

@@ -33,6 +33,8 @@
#if defined(DISTRHO_OS_WINDOWS)
# include "pugl/pugl_win.cpp"
#elif defined(DISTRHO_OS_MAC)
# define PuglWindow DISTRHO_JOIN_MACRO(PuglWindow, DGL_NAMESPACE)
# define PuglOpenGLView DISTRHO_JOIN_MACRO(PuglOpenGLView, DGL_NAMESPACE)
# include "pugl/pugl_osx.m"
#else
# include <sys/types.h>
@@ -721,7 +723,7 @@ struct Window::PrivateData {
FOR_EACH_WIDGET(it)
{
Widget* const widget(*it);
widget->pData->display(fWidth, fHeight);
widget->pData->display(fWidth, fHeight, false);
}

fSelf->onDisplayAfter();


+ 0
- 3
dpf/dgl/src/pugl/pugl_osx.m View File

@@ -24,9 +24,6 @@

#include "pugl_internal.h"

#define PuglWindow PuglWindow ## DGL_NAMESPACE
#define PuglOpenGLView PuglOpenGLView ## DGL_NAMESPACE

@interface PuglWindow : NSWindow
{
@public


+ 102
- 4
dpf/distrho/DistrhoPlugin.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -89,6 +89,15 @@ static const uint32_t kParameterIsLogarithmic = 0x08;
*/
static const uint32_t kParameterIsOutput = 0x10;

/**
Parameter value is a trigger.@n
This means the value resets back to its default after each process/run call.@n
Cannot be used for output parameters.

@note Only officially supported under LV2. For other formats DPF simulates the behaviour.
*/
static const uint32_t kParameterIsTrigger = 0x20 | kParameterIsBoolean;

/** @} */

/* ------------------------------------------------------------------------------------------------------------
@@ -274,6 +283,90 @@ struct ParameterRanges {
}
};

/**
Parameter enumeration value.@n
A string representation of a plugin parameter value.@n
Used together can be used to give meaning to parameter values, working as an enumeration.
*/
struct ParameterEnumerationValue {
/**
Parameter value.
*/
float value;

/**
String representation of this value.
*/
String label;

/**
Default constructor, using 0.0 as value and empty label.
*/
ParameterEnumerationValue() noexcept
: value(0.0f),
label() {}

/**
Constructor using custom values.
*/
ParameterEnumerationValue(float v, const char* l) noexcept
: value(v),
label(l) {}
};

/**
Collection of parameter enumeration values.@n
Handy class to handle the lifetime and count of all enumeration values.
*/
struct ParameterEnumerationValues {
/**
Number of elements allocated in @values.
*/
uint8_t count;

/**
Wherever the host is to be restricted to only use enumeration values.

@note This mode is only a hint! Not all hosts and plugin formats support this mode.
*/
bool restrictedMode;

/**
Array of @ParameterEnumerationValue items.@n
This pointer must be null or have been allocated on the heap with `new`.
*/
const ParameterEnumerationValue* values;

/**
Default constructor, for zero enumeration values.
*/
ParameterEnumerationValues() noexcept
: count(0),
restrictedMode(false),
values() {}

/**
Constructor using custom values.@n
The pointer to @values must have been allocated on the heap with `new`.
*/
ParameterEnumerationValues(uint32_t c, bool r, const ParameterEnumerationValue* v) noexcept
: count(c),
restrictedMode(r),
values(v) {}

~ParameterEnumerationValues() noexcept
{
count = 0;
restrictedMode = false;

if (values != nullptr)
{
delete[] values;
values = nullptr;
}
}
};

/**
Parameter.
*/
@@ -312,6 +405,12 @@ struct Parameter {
*/
ParameterRanges ranges;

/**
Enumeration values.@n
Can be used to give meaning to parameter values, working as an enumeration.
*/
ParameterEnumerationValues enumValues;

/**
Designation for this parameter.
*/
@@ -334,6 +433,7 @@ struct Parameter {
symbol(),
unit(),
ranges(),
enumValues(),
designation(kParameterDesignationNull),
midiCC(0) {}

@@ -346,6 +446,7 @@ struct Parameter {
symbol(s),
unit(u),
ranges(def, min, max),
enumValues(),
designation(kParameterDesignationNull),
midiCC(0) {}

@@ -593,9 +694,6 @@ public:
Write a MIDI output event.@n
This function must only be called during run().@n
Returns false when the host buffer is full, in which case do not call this again until the next run().
@note This function is not implemented yet!@n
It's here so that developers can prepare MIDI plugins in advance.@n
If you plan to use this, please report to DPF authors so it can be implemented.
*/
bool writeMidiEvent(const MidiEvent& midiEvent) noexcept;
#endif


+ 2
- 1
dpf/distrho/DistrhoUI.hpp View File

@@ -90,10 +90,11 @@ public:
void setState(const char* key, const char* value);
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
/**
sendNote.
@TODO Document this.
@note Work in progress. Implemented for DSSI and LV2 formats.
*/
void sendNote(uint8_t channel, uint8_t note, uint8_t velocity);
#endif


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

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -27,9 +27,10 @@ double d_lastSampleRate = 0.0;
/* ------------------------------------------------------------------------------------------------------------
* Static fallback data, see DistrhoPluginInternal.hpp */

const String PluginExporter::sFallbackString;
const AudioPort PluginExporter::sFallbackAudioPort;
const ParameterRanges PluginExporter::sFallbackRanges;
const String PluginExporter::sFallbackString;
const AudioPort PluginExporter::sFallbackAudioPort;
const ParameterRanges PluginExporter::sFallbackRanges;
const ParameterEnumerationValues PluginExporter::sFallbackEnumValues;

/* ------------------------------------------------------------------------------------------------------------
* Plugin */
@@ -102,10 +103,9 @@ void Plugin::setLatency(uint32_t frames) noexcept
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool Plugin::writeMidiEvent(const MidiEvent& /*midiEvent*/) noexcept
bool Plugin::writeMidiEvent(const MidiEvent& midiEvent) noexcept
{
// TODO
return false;
return pData->writeMidiCallback(midiEvent);
}
#endif



+ 55
- 6
dpf/distrho/src/DistrhoPluginInternal.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -32,6 +32,11 @@ static const uint32_t kMaxMidiEvents = 512;
extern uint32_t d_lastBufferSize;
extern double d_lastSampleRate;

// -----------------------------------------------------------------------
// DSP callbacks

typedef bool (*writeMidiFunc) (void* ptr, const MidiEvent& midiEvent);

// -----------------------------------------------------------------------
// Plugin private data

@@ -65,6 +70,10 @@ struct Plugin::PrivateData {
TimePosition timePosition;
#endif

// Callbacks
void* callbacksPtr;
writeMidiFunc writeMidiCallbackFunc;

uint32_t bufferSize;
double sampleRate;

@@ -88,6 +97,8 @@ struct Plugin::PrivateData {
#if DISTRHO_PLUGIN_WANT_LATENCY
latency(0),
#endif
callbacksPtr(nullptr),
writeMidiCallbackFunc(nullptr),
bufferSize(d_lastBufferSize),
sampleRate(d_lastSampleRate)
{
@@ -149,6 +160,16 @@ struct Plugin::PrivateData {
}
#endif
}

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool writeMidiCallback(const MidiEvent& midiEvent)
{
if (writeMidiCallbackFunc != nullptr)
return writeMidiCallbackFunc(callbacksPtr, midiEvent);

return false;
}
#endif
};

// -----------------------------------------------------------------------
@@ -157,7 +178,7 @@ struct Plugin::PrivateData {
class PluginExporter
{
public:
PluginExporter()
PluginExporter(void* const callbacksPtr, const writeMidiFunc writeMidiCall)
: fPlugin(createPlugin()),
fData((fPlugin != nullptr) ? fPlugin->pData : nullptr),
fIsActive(false)
@@ -191,6 +212,9 @@ public:
for (uint32_t i=0, count=fData->stateCount; i < count; ++i)
fPlugin->initState(i, fData->stateKeys[i], fData->stateDefValues[i]);
#endif

fData->callbacksPtr = callbacksPtr;
fData->writeMidiCallbackFunc = writeMidiCall;
}

~PluginExporter()
@@ -322,9 +346,26 @@ public:
return fData->parameters[index].designation;
}

bool isParameterInput(const uint32_t index) const noexcept
{
return (getParameterHints(index) & kParameterIsOutput) == 0x0;
}

bool isParameterOutput(const uint32_t index) const noexcept
{
return (getParameterHints(index) & kParameterIsOutput);
return (getParameterHints(index) & kParameterIsOutput) != 0x0;
}

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

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

return false;
}

const String& getParameterName(const uint32_t index) const noexcept
@@ -348,6 +389,13 @@ public:
return fData->parameters[index].unit;
}

const ParameterEnumerationValues& getParameterEnumValues(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackEnumValues);

return fData->parameters[index].enumValues;
}

const ParameterRanges& getParameterRanges(const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && index < fData->parameterCount, sFallbackRanges);
@@ -601,9 +649,10 @@ private:
// -------------------------------------------------------------------
// Static fallback data, see DistrhoPlugin.cpp

static const String sFallbackString;
static const AudioPort sFallbackAudioPort;
static const ParameterRanges sFallbackRanges;
static const String sFallbackString;
static const AudioPort sFallbackAudioPort;
static const ParameterRanges sFallbackRanges;
static const ParameterEnumerationValues sFallbackEnumValues;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter)
DISTRHO_PREVENT_HEAP_ALLOCATION


+ 83
- 11
dpf/distrho/src/DistrhoPluginJack.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 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
@@ -42,6 +42,9 @@ START_NAMESPACE_DISTRHO
#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_WANT_STATE
static const setStateFunc setStateCallback = nullptr;
#endif
#if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
static const writeMidiFunc writeMidiCallback = nullptr;
#endif

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

@@ -91,7 +94,7 @@ class PluginJack
{
public:
PluginJack(jack_client_t* const client)
: fPlugin(),
: fPlugin(this, writeMidiCallback),
#if DISTRHO_PLUGIN_HAS_UI
fUI(this, 0, nullptr, setParameterValueCallback, setStateCallback, nullptr, setSizeCallback, fPlugin.getInstancePointer()),
#endif
@@ -119,6 +122,11 @@ public:

fPortEventsIn = jack_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fPortMidiOut = jack_port_register(fClient, "midi-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
fPortMidiOutBuffer = nullptr;
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fPlugin.getProgramCount() > 0)
{
@@ -196,11 +204,24 @@ public:
fLastOutputValues = nullptr;
}

#if DISTRHO_PLUGIN_HAS_UI
if (fParametersChanged != nullptr)
{
delete[] fParametersChanged;
fParametersChanged = nullptr;
}
#endif

fPlugin.deactivate();

if (fClient == nullptr)
return;

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
jack_port_unregister(fClient, fPortMidiOut);
fPortMidiOut = nullptr;
#endif

jack_port_unregister(fClient, fPortEventsIn);
fPortEventsIn = nullptr;

@@ -330,6 +351,11 @@ protected:

void* const midiBuf = jack_port_get_buffer(fPortEventsIn, nframes);

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fPortMidiOutBuffer = jack_port_get_buffer(fPortMidiOut, nframes);
jack_midi_clear_buffer(fPortMidiOutBuffer);
#endif

if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf))
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -408,6 +434,12 @@ protected:
#else
fPlugin.run(audioIns, audioOuts, nframes);
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fPortMidiOutBuffer = nullptr;
#endif

updateParameterTriggers();
}

void jackShutdown()
@@ -440,6 +472,35 @@ protected:
}
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool writeMidi(const MidiEvent& midiEvent)
{
DISTRHO_SAFE_ASSERT_RETURN(fPortMidiOutBuffer != nullptr, false);

return jack_midi_event_write(fPortMidiOutBuffer,
midiEvent.frame,
midiEvent.size > MidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data,
midiEvent.size) == 0;
}
#endif

// NOTE: no trigger support for JACK, simulate it here
void updateParameterTriggers()
{
float defValue;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) != kParameterIsTrigger)
continue;

defValue = fPlugin.getParameterRanges(i).def;

if (d_isNotEqual(defValue, fPlugin.getParameterValue(i)))
fPlugin.setParameterValue(i, defValue);
}
}

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

private:
@@ -457,6 +518,10 @@ private:
jack_port_t* fPortAudioOuts[DISTRHO_PLUGIN_NUM_OUTPUTS];
#endif
jack_port_t* fPortEventsIn;
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
jack_port_t* fPortMidiOut;
void* fPortMidiOutBuffer;
#endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS
TimePosition fTimePosition;
#endif
@@ -475,51 +540,58 @@ private:
// -------------------------------------------------------------------
// Callbacks

#define uiPtr ((PluginJack*)ptr)
#define thisPtr ((PluginJack*)ptr)

static int jackBufferSizeCallback(jack_nframes_t nframes, void* ptr)
{
uiPtr->jackBufferSize(nframes);
thisPtr->jackBufferSize(nframes);
return 0;
}

static int jackSampleRateCallback(jack_nframes_t nframes, void* ptr)
{
uiPtr->jackSampleRate(nframes);
thisPtr->jackSampleRate(nframes);
return 0;
}

static int jackProcessCallback(jack_nframes_t nframes, void* ptr)
{
uiPtr->jackProcess(nframes);
thisPtr->jackProcess(nframes);
return 0;
}

static void jackShutdownCallback(void* ptr)
{
uiPtr->jackShutdown();
thisPtr->jackShutdown();
}

static void setParameterValueCallback(void* ptr, uint32_t index, float value)
{
uiPtr->setParameterValue(index, value);
thisPtr->setParameterValue(index, value);
}

#if DISTRHO_PLUGIN_WANT_STATE
static void setStateCallback(void* ptr, const char* key, const char* value)
{
uiPtr->setState(key, value);
thisPtr->setState(key, value);
}
#endif

#if DISTRHO_PLUGIN_HAS_UI
static void setSizeCallback(void* ptr, uint width, uint height)
{
uiPtr->setSize(width, height);
thisPtr->setSize(width, height);
}
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
static bool writeMidiCallback(void* ptr, const MidiEvent& midiEvent)
{
return thisPtr->writeMidi(midiEvent);
}
#endif

#undef uiPtr
#undef thisPtr
};

END_NAMESPACE_DISTRHO


+ 33
- 13
dpf/distrho/src/DistrhoPluginLADSPA+DSSI.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -22,9 +22,12 @@

#ifdef DISTRHO_PLUGIN_TARGET_DSSI
# include "dssi/dssi.h"
# if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
# error DSSI does not support MIDI output
# endif
#else
# include "ladspa/ladspa.h"
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
# error Cannot use MIDI with LADSPA
# endif
# if DISTRHO_PLUGIN_WANT_STATE
@@ -44,7 +47,8 @@ class PluginLadspaDssi
{
public:
PluginLadspaDssi()
: fPortControls(nullptr),
: fPlugin(nullptr, nullptr),
fPortControls(nullptr),
fLastControlValues(nullptr)
{
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
@@ -171,7 +175,7 @@ public:
{
// pre-roll
if (sampleCount == 0)
return updateParameterOutputs();
return updateParameterOutputsAndTriggers();

// Check for updated parameters
float curValue;
@@ -183,7 +187,7 @@ public:

curValue = *fPortControls[i];

if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i))
if (fPlugin.isParameterInput(i) && d_isNotEqual(fLastControlValues[i], curValue))
{
fLastControlValues[i] = curValue;
fPlugin.setParameterValue(i, curValue);
@@ -268,7 +272,7 @@ public:
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount);
#endif

updateParameterOutputs();
updateParameterOutputsAndTriggers();

#if defined(DISTRHO_PLUGIN_TARGET_DSSI) && ! DISTRHO_PLUGIN_WANT_MIDI_INPUT
return; // unused
@@ -371,17 +375,33 @@ private:

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

void updateParameterOutputs()
void updateParameterOutputsAndTriggers()
{
float value;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (! fPlugin.isParameterOutput(i))
continue;
if (fPlugin.isParameterOutput(i))
{
value = fLastControlValues[i] = fPlugin.getParameterValue(i);

fLastControlValues[i] = fPlugin.getParameterValue(i);
if (fPortControls[i] != nullptr)
*fPortControls[i] = value;
}
else if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) == kParameterIsTrigger)
{
// NOTE: no trigger support in LADSPA control ports, simulate it here
value = fPlugin.getParameterRanges(i).def;

if (fPortControls[i] != nullptr)
*fPortControls[i] = fLastControlValues[i];
if (d_isEqual(value, fPlugin.getParameterValue(i)))
continue;

fLastControlValues[i] = value;
fPlugin.setParameterValue(i, value);

if (fPortControls[i] != nullptr)
*fPortControls[i] = value;
}
}

#if DISTRHO_PLUGIN_WANT_LATENCY
@@ -531,7 +551,7 @@ public:
// Create dummy plugin to get data from
d_lastBufferSize = 512;
d_lastSampleRate = 44100.0;
PluginExporter plugin;
PluginExporter plugin(nullptr, nullptr);
d_lastBufferSize = 0;
d_lastSampleRate = 0.0;



+ 105
- 35
dpf/distrho/src/DistrhoPluginLV2.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -32,7 +32,7 @@
#include "lv2/lv2_programs.h"

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
# include "libmodauth.h"
# include "libmodla.h"
#endif

#ifdef noexcept
@@ -56,13 +56,18 @@ START_NAMESPACE_DISTRHO

typedef std::map<const String, String> StringMap;

#if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
static const writeMidiFunc writeMidiCallback = nullptr;
#endif

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

class PluginLv2
{
public:
PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal)
: fUsingNominal(usingNominal),
: fPlugin(this, writeMidiCallback),
fUsingNominal(usingNominal),
#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
fRunCount(0),
#endif
@@ -107,9 +112,6 @@ public:
#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
@@ -226,7 +228,7 @@ public:
#if DISTRHO_LV2_USE_EVENTS_OUT
if (port == index++)
{
fPortEventsOut = (LV2_Atom_Sequence*)dataLocation;
fEventsOutData.port = (LV2_Atom_Sequence*)dataLocation;
return;
}
#endif
@@ -517,14 +519,12 @@ public:

curValue = *fPortControls[i];

if (fLastControlValues[i] != curValue && ! fPlugin.isParameterOutput(i))
if (fPlugin.isParameterInput(i) && d_isNotEqual(fLastControlValues[i], curValue))
{
fLastControlValues[i] = curValue;

if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass)
{
curValue = 1.0f - curValue;
}

fPlugin.setParameterValue(i, curValue);
}
@@ -607,20 +607,14 @@ public:
#endif
}

updateParameterOutputs();
updateParameterOutputsAndTriggers();

#if DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI
const uint32_t capacity = fPortEventsOut->atom.size;
fEventsOutData.initIfNeeded(fURIDs.atomSequence);

uint32_t size, offset = 0;
LV2_Atom_Event* aev;

fPortEventsOut->atom.size = sizeof(LV2_Atom_Sequence_Body);
fPortEventsOut->atom.type = fURIDs.atomSequence;
fPortEventsOut->body.unit = 0;
fPortEventsOut->body.pad = 0;

// TODO - MIDI Output
uint32_t offset = fEventsOutData.offset;
const uint32_t capacity = fEventsOutData.capacity;

for (uint32_t i=0, count=fPlugin.getStateCount(); i < count; ++i)
{
@@ -645,6 +639,7 @@ public:
break;

// reserve msg space
// FIXME create a large enough buffer beforehand
char msgBuf[msgSize];
std::memset(msgBuf, 0, msgSize);

@@ -653,21 +648,23 @@ public:
std::memcpy(msgBuf+(key.length()+1), value.buffer(), value.length());

// put data
aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fPortEventsOut) + offset);
aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fEventsOutData.port) + offset);
aev->time.frames = 0;
aev->body.type = fURIDs.distrhoState;
aev->body.size = msgSize;
std::memcpy(LV2_ATOM_BODY(&aev->body), msgBuf, msgSize-1);

size = lv2_atom_pad_size(sizeof(LV2_Atom_Event) + msgSize);
offset += size;
fPortEventsOut->atom.size += size;
fEventsOutData.growBy(lv2_atom_pad_size(sizeof(LV2_Atom_Event) + msgSize));

fNeededUiSends[i] = false;
break;
}
}
#endif

#if DISTRHO_LV2_USE_EVENTS_OUT
fEventsOutData.endRun();
#endif
}

// -------------------------------------------------------------------
@@ -883,9 +880,6 @@ private:
#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
float* fPortLatency;
#endif
@@ -922,6 +916,44 @@ private:
} fLastPositionData;
#endif

#if DISTRHO_LV2_USE_EVENTS_OUT
struct Lv2EventsOutData {
uint32_t capacity, offset;
LV2_Atom_Sequence* port;

Lv2EventsOutData()
: capacity(0),
offset(0),
port(nullptr) {}

void initIfNeeded(const LV2_URID uridAtomSequence)
{
if (capacity != 0)
return;

capacity = port->atom.size;

port->atom.size = sizeof(LV2_Atom_Sequence_Body);
port->atom.type = uridAtomSequence;
port->body.unit = 0;
port->body.pad = 0;
}

void growBy(const uint32_t size)
{
offset += size;
port->atom.size += size;
}

void endRun()
{
capacity = 0;
offset = 0;
}

} fEventsOutData;
#endif

// LV2 URIDs
struct URIDs {
LV2_URID atomBlank;
@@ -998,17 +1030,23 @@ private:
}
#endif

void updateParameterOutputs()
void updateParameterOutputsAndTriggers()
{
float curValue;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (! fPlugin.isParameterOutput(i))
continue;

fLastControlValues[i] = fPlugin.getParameterValue(i);
if (fPlugin.isParameterOutput(i))
{
curValue = fLastControlValues[i] = fPlugin.getParameterValue(i);

if (fPortControls[i] != nullptr)
*fPortControls[i] = fLastControlValues[i];
if (fPortControls[i] != nullptr)
*fPortControls[i] = curValue;
}
else if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) == kParameterIsTrigger)
{
// NOTE: host is responsible for auto-updating control port buffers
}
}

#if DISTRHO_PLUGIN_WANT_LATENCY
@@ -1016,6 +1054,38 @@ private:
*fPortLatency = fPlugin.getLatency();
#endif
}

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool writeMidi(const MidiEvent& midiEvent)
{
DISTRHO_SAFE_ASSERT_RETURN(fEventsOutData.port != nullptr, false);

fEventsOutData.initIfNeeded(fURIDs.atomSequence);

const uint32_t capacity = fEventsOutData.capacity;
const uint32_t offset = fEventsOutData.offset;

if (sizeof(LV2_Atom_Event) + midiEvent.size > capacity - offset)
return false;

LV2_Atom_Event* const aev = (LV2_Atom_Event*)(LV2_ATOM_CONTENTS(LV2_Atom_Sequence, fEventsOutData.port) + offset);
aev->time.frames = midiEvent.frame;
aev->body.type = fURIDs.midiEvent;
aev->body.size = midiEvent.size;
std::memcpy(LV2_ATOM_BODY(&aev->body),
midiEvent.size > MidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data,
midiEvent.size);

fEventsOutData.growBy(lv2_atom_pad_size(sizeof(LV2_Atom_Event) + midiEvent.size));

return true;
}

static bool writeMidiCallback(void* ptr, const MidiEvent& midiEvent)
{
return ((PluginLv2*)ptr)->writeMidi(midiEvent);
}
#endif
};

// -----------------------------------------------------------------------
@@ -1057,7 +1127,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons
#endif

#ifdef DISTRHO_PLUGIN_LICENSED_FOR_MOD
mod_check_license(features, DISTRHO_PLUGIN_URI);
mod_license_check(features, DISTRHO_PLUGIN_URI);
#endif

d_lastBufferSize = 0;


+ 47
- 24
dpf/distrho/src/DistrhoPluginLV2export.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2017 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -80,7 +80,7 @@ void lv2_generate_ttl(const char* const basename)
// Dummy plugin to get data from
d_lastBufferSize = 512;
d_lastSampleRate = 44100.0;
PluginExporter plugin;
PluginExporter plugin(nullptr, nullptr);
d_lastBufferSize = 0;
d_lastSampleRate = 0.0;

@@ -202,6 +202,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n";
#endif
pluginString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n";
pluginString += "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n";
pluginString += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
pluginString += "@prefix rsz: <" LV2_RESIZE_PORT_PREFIX "> .\n";
#if DISTRHO_PLUGIN_HAS_UI
@@ -398,7 +399,7 @@ void lv2_generate_ttl(const char* const basename)
bool designated = false;

// designation
if (! plugin.isParameterOutput(i))
if (plugin.isParameterInput(i))
{
switch (plugin.getParameterDesignation(i))
{
@@ -417,10 +418,10 @@ void lv2_generate_ttl(const char* const basename)
}
}

// name and symbol
if (! designated)
{
pluginString += " lv2:name \"" + plugin.getParameterName(i) + "\" ;\n";
// name and symbol
pluginString += " lv2:name \"\"\"" + plugin.getParameterName(i) + "\"\"\" ;\n";

String symbol(plugin.getParameterSymbol(i));

@@ -428,32 +429,53 @@ void lv2_generate_ttl(const char* const basename)
symbol = "lv2_port_" + String(portIndex-1);

pluginString += " lv2:symbol \"" + symbol + "\" ;\n";
}

// ranges
if (! designated)
{
// ranges
const ParameterRanges& ranges(plugin.getParameterRanges(i));

if (plugin.getParameterHints(i) & kParameterIsInteger)
{
if (! plugin.isParameterOutput(i))
if (plugin.isParameterInput(i))
pluginString += " lv2:default " + String(int(plugin.getParameterValue(i))) + " ;\n";
pluginString += " lv2:minimum " + String(int(ranges.min)) + " ;\n";
pluginString += " lv2:maximum " + String(int(ranges.max)) + " ;\n";
}
else
{
if (! plugin.isParameterOutput(i))
if (plugin.isParameterInput(i))
pluginString += " lv2:default " + String(plugin.getParameterValue(i)) + " ;\n";
pluginString += " lv2:minimum " + String(ranges.min) + " ;\n";
pluginString += " lv2:maximum " + String(ranges.max) + " ;\n";
}
}

// unit
if (! designated)
{
// enumeration
const ParameterEnumerationValues& enumValues(plugin.getParameterEnumValues(i));

if (enumValues.count > 0)
{
if (enumValues.count >= 2 && enumValues.restrictedMode)
pluginString += " lv2:portProperty lv2:enumeration ;\n";

for (uint8_t j=0; j < enumValues.count; ++j)
{
const ParameterEnumerationValue& enumValue(enumValues.values[j]);

if (j == 0)
pluginString += " lv2:scalePoint [\n";
else
pluginString += " [\n";

pluginString += " rdfs:label \"\"\"" + enumValue.label + "\"\"\" ;\n";
pluginString += " rdf:value " + String(enumValue.value) + " ;\n";

if (j+1 == enumValues.count)
pluginString += " ] ;\n\n";
else
pluginString += " ] ,\n";
}
}

// unit
const String& unit(plugin.getParameterUnit(i));

if (! unit.isEmpty())
@@ -495,25 +517,26 @@ void lv2_generate_ttl(const char* const basename)
pluginString += " ] ;\n";
}
}
}

// hints
if (! designated)
{
// hints
const uint32_t hints(plugin.getParameterHints(i));

if (hints & kParameterIsBoolean)
{
if ((hints & kParameterIsTrigger) == kParameterIsTrigger)
pluginString += " lv2:portProperty <" LV2_PORT_PROPS__trigger "> ;\n";
pluginString += " lv2:portProperty lv2:toggled ;\n";
}
if (hints & kParameterIsInteger)
pluginString += " lv2:portProperty lv2:integer ;\n";
if (hints & kParameterIsLogarithmic)
pluginString += " lv2:portProperty <" LV2_PORT_PROPS__logarithmic "> ;\n";
if ((hints & kParameterIsAutomable) == 0 && ! plugin.isParameterOutput(i))
if ((hints & kParameterIsAutomable) == 0 && plugin.isParameterInput(i))
{
pluginString += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ,\n";
pluginString += " <" LV2_KXSTUDIO_PROPERTIES__NonAutomable "> ;\n";
}
}
} // ! designated

if (i+1 == count)
pluginString += " ] ;\n\n";
@@ -537,7 +560,7 @@ void lv2_generate_ttl(const char* const basename)
#endif

// name
pluginString += " doap:name \"" + String(plugin.getName()) + "\" ;\n";
pluginString += " doap:name \"\"\"" + String(plugin.getName()) + "\"\"\" ;\n";

// license
{
@@ -546,7 +569,7 @@ void lv2_generate_ttl(const char* const basename)
if (license.contains("://"))
pluginString += " doap:license <" + license + "> ;\n\n";
else
pluginString += " doap:license \"" + license + "\" ;\n\n";
pluginString += " doap:license \"\"\"" + license + "\"\"\" ;\n\n";
}

// developer
@@ -554,7 +577,7 @@ void lv2_generate_ttl(const char* const basename)
const String homepage(plugin.getHomePage());

pluginString += " doap:maintainer [\n";
pluginString += " foaf:name \"" + String(plugin.getMaker()) + "\" ;\n";
pluginString += " foaf:name \"\"\"" + String(plugin.getMaker()) + "\"\"\" ;\n";

if (homepage.isNotEmpty())
pluginString += " foaf:homepage <" + homepage + "> ;\n";


+ 257
- 80
dpf/distrho/src/DistrhoPluginVST.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -37,11 +37,12 @@
#define VESTIGE_HEADER
#define VST_FORCE_DEPRECATED 0

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

#ifdef VESTIGE_HEADER
# include "vestige/aeffectx.h"
# include "vestige/vestige.h"
#define effFlagsProgramChunks (1 << 5)
#define effSetProgramName 4
#define effGetParamLabel 6
@@ -51,11 +52,8 @@
#define effCanBeAutomated 26
#define effGetProgramNameIndexed 29
#define effGetPlugCategory 35
#define effIdle 53
#define effEditKeyDown 59
#define effEditKeyUp 60
#define kPlugCategEffect 1
#define kPlugCategSynth 2
#define kVstVersion 2400
struct ERect {
int16_t top, left, bottom, right;
@@ -68,6 +66,12 @@ START_NAMESPACE_DISTRHO

typedef std::map<const String, String> StringMap;

static const int kVstMidiEventSize = static_cast<int>(sizeof(VstMidiEvent));

#if ! DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
static const writeMidiFunc writeMidiCallback = nullptr;
#endif

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

void strncpy(char* const dst, const char* const src, const size_t size)
@@ -88,17 +92,42 @@ void snprintf_iparam(char* const dst, const int32_t value, const size_t size)
dst[size-1] = '\0';
}

#if DISTRHO_PLUGIN_HAS_UI
// -----------------------------------------------------------------------

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

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

private:
char* const locale;

DISTRHO_DECLARE_NON_COPY_CLASS(ScopedSafeLocale)
DISTRHO_PREVENT_HEAP_ALLOCATION
};

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

class ParameterCheckHelper
{
public:
UiHelper()
ParameterCheckHelper()
: parameterChecks(nullptr),
parameterValues(nullptr) {}

virtual ~UiHelper()
virtual ~ParameterCheckHelper()
{
if (parameterChecks != nullptr)
{
@@ -112,20 +141,21 @@ public:
}
}

bool* parameterChecks;
float* parameterValues;
bool* parameterChecks;
float* parameterValues;

# if DISTRHO_PLUGIN_WANT_STATE
#if DISTRHO_PLUGIN_WANT_STATE
virtual void setStateFromUI(const char* const newKey, const char* const newValue) = 0;
# endif
#endif
};

#if DISTRHO_PLUGIN_HAS_UI
// -----------------------------------------------------------------------

class UIVst
{
public:
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, UiHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId)
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, ParameterCheckHelper* const uiHelper, PluginExporter* const plugin, const intptr_t winId)
: fAudioMaster(audioMaster),
fEffect(effect),
fUiHelper(uiHelper),
@@ -300,7 +330,7 @@ private:
// Vst stuff
const audioMasterCallback fAudioMaster;
AEffect* const fEffect;
UiHelper* const fUiHelper;
ParameterCheckHelper* const fUiHelper;
PluginExporter* const fPlugin;

// Plugin UI
@@ -343,15 +373,12 @@ private:

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

#if DISTRHO_PLUGIN_HAS_UI
class PluginVst : public UiHelper
#else
class PluginVst
#endif
class PluginVst : public ParameterCheckHelper
{
public:
PluginVst(const audioMasterCallback audioMaster, AEffect* const effect)
: fAudioMaster(audioMaster),
: fPlugin(this, writeMidiCallback),
fAudioMaster(audioMaster),
fEffect(effect)
{
std::memset(fProgramName, 0, sizeof(char)*(32+1));
@@ -376,14 +403,14 @@ public:
for (uint32_t i=0; i < paramCount; ++i)
{
parameterChecks[i] = false;
parameterValues[i] = 0.0f;
parameterValues[i] = NAN;
}
}
# if DISTRHO_OS_MAC
# ifdef __LP64__
fUsingNsView = true;
# else
# warning 32bit VST UIs on OSX only work if the host supports "hasCockosViewAsConfig"
# warning 32bit VST UIs on OSX only work if the host supports "hasCockosViewAsConfig"
fUsingNsView = false;
# endif
# endif // DISTRHO_OS_MAC
@@ -453,24 +480,35 @@ public:
{
const uint32_t hints = fPlugin.getParameterHints(index);
float value = fPlugin.getParameterValue(index);
if (hints & kParameterIsBoolean)
{
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
const float midRange = ranges.min + (ranges.max - ranges.min) / 2.0f;
value = value > midRange ? ranges.max : ranges.min;
}
if (hints & kParameterIsInteger)
else if (hints & kParameterIsInteger)
{
DISTRHO_NAMESPACE::snprintf_iparam((char*)ptr, (int32_t)std::round(value), 24);
value = std::round(value);
}
else

const ParameterEnumerationValues& enumValues(fPlugin.getParameterEnumValues(index));

for (uint8_t i = 0; i < enumValues.count; ++i)
{
DISTRHO_NAMESPACE::snprintf_param((char*)ptr, value, 24);
if (d_isNotEqual(value, enumValues.values[i].value))
continue;

DISTRHO_NAMESPACE::strncpy((char*)ptr, enumValues.values[i].label.buffer(), 24);
return 1;
}

if (hints & kParameterIsInteger)
DISTRHO_NAMESPACE::snprintf_iparam((char*)ptr, (int32_t)value, 24);
else
DISTRHO_NAMESPACE::snprintf_param((char*)ptr, value, 24);

return 1;
}
break;
@@ -607,6 +645,7 @@ public:

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

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

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

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

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

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

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

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

chunkStr += tmpStr;
}
}

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

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

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

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

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

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

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

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

setStateFromUI(key, value);

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

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

const uint32_t paramCount = fPlugin.getParameterCount();

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

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

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

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

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

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

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

return 1;
@@ -805,7 +921,10 @@ public:
void vst_processReplacing(const float** const inputs, float** const outputs, const int32_t sampleFrames)
{
if (sampleFrames <= 0)
{
updateParameterOutputsAndTriggers();
return;
}

if (! fPlugin.isActive())
{
@@ -864,16 +983,7 @@ public:
fPlugin.run(inputs, outputs, sampleFrames);
#endif

#if DISTRHO_PLUGIN_HAS_UI
if (fVstUI == nullptr)
return;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (fPlugin.isParameterOutput(i))
setParameterValueFromPlugin(i, fPlugin.getParameterValue(i));
}
#endif
updateParameterOutputsAndTriggers();
}

// -------------------------------------------------------------------
@@ -881,13 +991,13 @@ public:
friend class UIVst;

private:
// Plugin
PluginExporter fPlugin;

// VST stuff
const audioMasterCallback fAudioMaster;
AEffect* const fEffect;

// Plugin
PluginExporter fPlugin;

// Temporary data
char fProgramName[32+1];

@@ -929,6 +1039,56 @@ private:
// -------------------------------------------------------------------
// functions called from the plugin side, RT no block

void updateParameterOutputsAndTriggers()
{
float curValue;

for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
{
if (fPlugin.isParameterOutput(i))
{
// NOTE: no output parameter support in VST, simulate it here
curValue = fPlugin.getParameterValue(i);

if (d_isEqual(curValue, parameterValues[i]))
continue;

#if DISTRHO_PLUGIN_HAS_UI
if (fVstUI != nullptr)
setParameterValueFromPlugin(i, curValue);
else
#endif
parameterValues[i] = curValue;

#ifndef DPF_VST_SHOW_PARAMETER_OUTPUTS
// skip automating parameter outputs from plugin if we disable them on VST
continue;
#endif
}
else if ((fPlugin.getParameterHints(i) & kParameterIsTrigger) == kParameterIsTrigger)
{
// NOTE: no trigger support in VST parameters, simulate it here
curValue = fPlugin.getParameterValue(i);

if (d_isEqual(curValue, fPlugin.getParameterRanges(i).def))
continue;

#if DISTRHO_PLUGIN_HAS_UI
if (fVstUI != nullptr)
setParameterValueFromPlugin(i, curValue);
#endif
fPlugin.setParameterValue(i, curValue);
}
else
{
continue;
}

const ParameterRanges& ranges(fPlugin.getParameterRanges(i));
hostCallback(audioMasterAutomate, i, 0, nullptr, ranges.getNormalizedValue(curValue));
}
}

#if DISTRHO_PLUGIN_HAS_UI
void setParameterValueFromPlugin(const uint32_t index, const float realValue)
{
@@ -937,6 +1097,37 @@ private:
}
#endif

#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
bool writeMidi(const MidiEvent& midiEvent)
{
if (midiEvent.size > 4)
return true;

VstEvents vstEvents;
std::memset(&vstEvents, 0, sizeof(VstEvents));

VstMidiEvent vstMidiEvent;
std::memset(&vstMidiEvent, 0, sizeof(VstMidiEvent));

vstEvents.numEvents = 1;
vstEvents.events[0] = (VstEvent*)&vstMidiEvent;

vstMidiEvent.type = kVstMidiType;
vstMidiEvent.byteSize = kVstMidiEventSize;
vstMidiEvent.deltaFrames = midiEvent.frame;

for (uint8_t i=0; i<midiEvent.size; ++i)
vstMidiEvent.midiData[i] = midiEvent.data[i];

return hostCallback(audioMasterProcessEvents, 0, 0, &vstEvents) == 1;
}

static bool writeMidiCallback(void* ptr, const MidiEvent& midiEvent)
{
return ((PluginVst*)ptr)->writeMidi(midiEvent);
}
#endif

#if DISTRHO_PLUGIN_WANT_STATE
// -------------------------------------------------------------------
// functions called from the UI side, may block
@@ -977,17 +1168,10 @@ struct VstObject {
PluginVst* plugin;
};

#ifdef VESTIGE_HEADER
# define validObject effect != nullptr && effect->ptr3 != nullptr
# define validPlugin effect != nullptr && effect->ptr3 != nullptr && ((VstObject*)effect->ptr3)->plugin != nullptr
# define vstObjectPtr (VstObject*)effect->ptr3
#else
# define validObject effect != nullptr && effect->object != nullptr
# define validPlugin effect != nullptr && effect->object != nullptr && ((VstObject*)effect->object)->plugin != nullptr
# define vstObjectPtr (VstObject*)effect->object
#endif

#define pluginPtr (vstObjectPtr)->plugin
#define validObject effect != nullptr && effect->object != nullptr
#define validPlugin effect != nullptr && effect->object != nullptr && ((VstObject*)effect->object)->plugin != nullptr
#define vstObjectPtr (VstObject*)effect->object
#define pluginPtr (vstObjectPtr)->plugin

static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
@@ -1002,7 +1186,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
}

// Create dummy plugin to get data from
static PluginExporter plugin;
static PluginExporter plugin(nullptr, nullptr);

if (doInternalInit)
{
@@ -1055,11 +1239,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
/* This code invalidates the object created in VSTPluginMain
* Probably not safe against all hosts */
obj->audioMaster = nullptr;
# ifdef VESTIGE_HEADER
effect->ptr3 = nullptr;
# else
vstObjectPtr = nullptr;
# endif
effect->object = nullptr;
delete obj;
#endif

@@ -1083,14 +1263,14 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
return 1;
}
return 0;
case effGetParameterProperties:
if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount()))
{
if (VstParameterProperties* const properties = (VstParameterProperties*)ptr)
{
memset(properties, 0, sizeof(VstParameterProperties));
const uint32_t hints = plugin.getParameterHints(index);

if (hints & kParameterIsOutput)
@@ -1100,7 +1280,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
{
properties->flags |= kVstParameterIsSwitch;
}
if (hints & kParameterIsInteger)
{
properties->flags |= kVstParameterUsesIntegerMinMax;
@@ -1119,7 +1299,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
}
}
return 0;
case effGetPlugCategory:
#if DISTRHO_PLUGIN_IS_SYNTH
return kPlugCategSynth;
@@ -1226,20 +1406,18 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
// vst fields
effect->magic = kEffectMagic;
effect->uniqueID = plugin->getUniqueId();
#ifdef VESTIGE_HEADER
int32_t* const version = (int32_t*)&effect->unknown1;
*version = plugin->getVersion();
#else
effect->version = plugin->getVersion();
#endif
effect->version = plugin->getVersion();

// VST doesn't support parameter outputs, hide them
// VST doesn't support parameter outputs. we can fake them, but it is a hack. Disabled by default.
#ifdef DPF_VST_SHOW_PARAMETER_OUTPUTS
const int numParams = plugin->getParameterCount();
#else
int numParams = 0;
bool outputsReached = false;

for (uint32_t i=0, count=plugin->getParameterCount(); i < count; ++i)
{
if (! plugin->isParameterOutput(i))
if (plugin->isParameterInput(i))
{
// parameter outputs must be all at the end
DISTRHO_SAFE_ASSERT_BREAK(! outputsReached);
@@ -1248,6 +1426,7 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
}
outputsReached = true;
}
#endif

// plugin fields
effect->numParams = numParams;
@@ -1278,11 +1457,9 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
VstObject* const obj(new VstObject());
obj->audioMaster = audioMaster;
obj->plugin = nullptr;
#ifdef VESTIGE_HEADER
effect->ptr3 = obj;
#else

// done
effect->object = obj;
#endif

return effect;
}


+ 1
- 1
dpf/distrho/src/DistrhoUI.cpp View File

@@ -82,7 +82,7 @@ void UI::setState(const char* key, const char* value)
}
#endif

#if DISTRHO_PLUGIN_IS_SYNTH
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
void UI::sendNote(uint8_t channel, uint8_t note, uint8_t velocity)
{
pData->sendNoteCallback(channel, note, velocity);


+ 14
- 3
dpf/distrho/src/DistrhoUIDSSI.cpp View File

@@ -26,6 +26,10 @@

START_NAMESPACE_DISTRHO

#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT
static const sendNoteFunc sendNoteCallback = nullptr;
#endif

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

struct OscData {
@@ -180,6 +184,7 @@ protected:
fOscData.send_configure(key, value);
}

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity)
{
if (fOscData.server == nullptr)
@@ -187,11 +192,15 @@ protected:
if (channel > 0xF)
return;

uint8_t mdata[4] = { 0, channel, note, velocity };
mdata[1] += (velocity != 0) ? 0x90 : 0x80;

uint8_t mdata[4] = {
0,
channel + (velocity != 0 ? 0x90 : 0x80),
note,
velocity
};
fOscData.send_midi(mdata);
}
#endif

void setSize(const uint width, const uint height)
{
@@ -219,10 +228,12 @@ private:
uiPtr->setState(key, value);
}

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity)
{
uiPtr->sendNote(channel, note, velocity);
}
#endif

static void setSizeCallback(void* ptr, uint width, uint height)
{


+ 17
- 12
dpf/distrho/src/DistrhoUIInternal.hpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2018 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -61,12 +61,12 @@ struct UI::PrivateData {
#endif

// Callbacks
void* callbacksPtr;
editParamFunc editParamCallbackFunc;
setParamFunc setParamCallbackFunc;
setStateFunc setStateCallbackFunc;
sendNoteFunc sendNoteCallbackFunc;
setSizeFunc setSizeCallbackFunc;
void* ptr;

PrivateData() noexcept
: sampleRate(d_lastUiSampleRate),
@@ -74,12 +74,12 @@ struct UI::PrivateData {
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
dspPtr(d_lastUiDspPtr),
#endif
callbacksPtr(nullptr),
editParamCallbackFunc(nullptr),
setParamCallbackFunc(nullptr),
setStateCallbackFunc(nullptr),
sendNoteCallbackFunc(nullptr),
setSizeCallbackFunc(nullptr),
ptr(nullptr)
setSizeCallbackFunc(nullptr)
{
DISTRHO_SAFE_ASSERT(d_isNotZero(sampleRate));

@@ -103,31 +103,31 @@ struct UI::PrivateData {
void editParamCallback(const uint32_t rindex, const bool started)
{
if (editParamCallbackFunc != nullptr)
editParamCallbackFunc(ptr, rindex, started);
editParamCallbackFunc(callbacksPtr, rindex, started);
}

void setParamCallback(const uint32_t rindex, const float value)
{
if (setParamCallbackFunc != nullptr)
setParamCallbackFunc(ptr, rindex, value);
setParamCallbackFunc(callbacksPtr, rindex, value);
}

void setStateCallback(const char* const key, const char* const value)
{
if (setStateCallbackFunc != nullptr)
setStateCallbackFunc(ptr, key, value);
setStateCallbackFunc(callbacksPtr, key, value);
}

void sendNoteCallback(const uint8_t channel, const uint8_t note, const uint8_t velocity)
{
if (sendNoteCallbackFunc != nullptr)
sendNoteCallbackFunc(ptr, channel, note, velocity);
sendNoteCallbackFunc(callbacksPtr, channel, note, velocity);
}

void setSizeCallback(const uint width, const uint height)
{
if (setSizeCallbackFunc != nullptr)
setSizeCallbackFunc(ptr, width, height);
setSizeCallbackFunc(callbacksPtr, width, height);
}
};

@@ -221,8 +221,13 @@ UI* createUiWrapper(void* const dspPtr, const uintptr_t winId, const char* const
class UIExporter
{
public:
UIExporter(void* const ptr, const intptr_t winId,
const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const setSizeFunc setSizeCall,
UIExporter(void* const callbacksPtr,
const intptr_t winId,
const editParamFunc editParamCall,
const setParamFunc setParamCall,
const setStateFunc setStateCall,
const sendNoteFunc sendNoteCall,
const setSizeFunc setSizeCall,
void* const dspPtr = nullptr,
const char* const bundlePath = nullptr)
#ifdef HAVE_DGL
@@ -238,7 +243,7 @@ public:
DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);

fData->ptr = ptr;
fData->callbacksPtr = callbacksPtr;
fData->editParamCallbackFunc = editParamCall;
fData->setParamCallbackFunc = setParamCall;
fData->setStateCallbackFunc = setStateCall;


+ 34
- 1
dpf/distrho/src/DistrhoUILV2.cpp View File

@@ -22,6 +22,7 @@
#include "lv2/atom-util.h"
#include "lv2/data-access.h"
#include "lv2/instance-access.h"
#include "lv2/midi.h"
#include "lv2/options.h"
#include "lv2/parameters.h"
#include "lv2/ui.h"
@@ -35,6 +36,15 @@

START_NAMESPACE_DISTRHO

typedef struct _LV2_Atom_MidiEvent {
LV2_Atom atom; /**< Atom header. */
uint8_t data[3]; /**< MIDI data (body). */
} LV2_Atom_MidiEvent;

#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT
static const sendNoteFunc sendNoteCallback = nullptr;
#endif

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

class UiLv2
@@ -51,6 +61,7 @@ public:
fController(controller),
fWriteFunction(writeFunc),
fEventTransferURID(uridMap->map(uridMap->handle, LV2_ATOM__eventTransfer)),
fMidiEventURID(uridMap->map(uridMap->handle, LV2_MIDI__MidiEvent)),
fKeyValueURID(uridMap->map(uridMap->handle, DISTRHO_PLUGIN_LV2_STATE_PREFIX "KeyValueState")),
fWinIdWasNull(winId == 0)
{
@@ -256,9 +267,28 @@ protected:
fWriteFunction(fController, eventInPortIndex, atomSize, fEventTransferURID, atom);
}

void sendNote(const uint8_t /*channel*/, const uint8_t /*note*/, const uint8_t /*velocity*/)
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity)
{
DISTRHO_SAFE_ASSERT_RETURN(fWriteFunction != nullptr,);

if (channel > 0xF)
return;

const uint32_t eventInPortIndex(DISTRHO_PLUGIN_NUM_INPUTS + DISTRHO_PLUGIN_NUM_OUTPUTS);

LV2_Atom_MidiEvent atomMidiEvent;
atomMidiEvent.atom.size = 3;
atomMidiEvent.atom.type = fMidiEventURID;

atomMidiEvent.data[0] = channel + (velocity != 0 ? 0x90 : 0x80);
atomMidiEvent.data[1] = note;
atomMidiEvent.data[2] = velocity;

// send to DSP side
fWriteFunction(fController, eventInPortIndex, sizeof(LV2_Atom_MidiEvent), fEventTransferURID, &atomMidiEvent);
}
#endif

void setSize(const uint width, const uint height)
{
@@ -282,6 +312,7 @@ private:

// Need to save this
const LV2_URID fEventTransferURID;
const LV2_URID fMidiEventURID;
const LV2_URID fKeyValueURID;

// using ui:showInterface if true
@@ -307,10 +338,12 @@ private:
uiPtr->setState(key, value);
}

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity)
{
uiPtr->sendNote(channel, note, velocity);
}
#endif

static void setSizeCallback(void* ptr, uint width, uint height)
{


dpf/distrho/src/vestige/aeffectx.h → dpf/distrho/src/vestige/vestige.h View File

@@ -1,9 +1,18 @@
/*
* aeffectx.h - simple header to allow VeSTige compilation and eventually work
* IMPORTANT: The author of DPF has no connection with the
* author of the VeSTige VST-compatibility header, has had no
* involvement in its creation.
*
* The VeSTige header is included in this package in the good-faith
* belief that it has been cleanly and legally reverse engineered
* without reference to the official VST SDK and without its
* developer(s) having agreed to the VST SDK license agreement.
*/

/*
* simple header to allow VeSTige compilation and eventually work
*
* Copyright (c) 2006 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -22,8 +31,8 @@
*
*/
#include <stdint.h>
#ifndef _AEFFECTX_H
#define _AEFFECTX_H
#ifndef _VESTIGE_H
#define _VESTIGE_H

#define CCONST(a, b, c, d)( ( ( (int) a ) << 24 ) | \
( ( (int) b ) << 16 ) | \
@@ -87,11 +96,11 @@
#define effFlagsIsSynth (1 << 8) // currently unused

#define effOpen 0
#define effClose 1 // currently unused
#define effSetProgram 2 // currently unused
#define effGetProgram 3 // currently unused
#define effGetProgramName 5 // currently unused
#define effGetParamName 8 // currently unused
#define effClose 1
#define effSetProgram 2
#define effGetProgram 3
#define effGetProgramName 5
#define effGetParamName 8
#define effSetSampleRate 10
#define effSetBlockSize 11
#define effMainsChanged 12
@@ -101,22 +110,42 @@
#define effEditIdle 19
#define effEditTop 20
#define effProcessEvents 25
#define effGetPlugCategory 35
#define effGetEffectName 45
#define effGetVendorString 47
#define effGetProductString 48
#define effGetVendorVersion 49
#define effCanDo 51 // currently unused
/* from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
#define effCanDo 51
#define effIdle 53
#define effGetParameterProperties 56
#define effGetVstVersion 58 // currently unused
#define effGetVstVersion 58
#define effShellGetNextPlugin 70
#define effStartProcess 71
#define effStopProcess 72

#define effBeginSetProgram 67
#define effEndSetProgram 68

#ifdef WORDS_BIGENDIAN
// "VstP"
#define kEffectMagic 0x50747356
#else
// "PtsV"
#define kEffectMagic 0x56737450
#endif

#define kEffectMagic (CCONST( 'V', 's', 't', 'P' ))
#define kVstLangEnglish 1
#define kVstMidiType 1

struct RemoteVstPlugin;

#define kVstTransportChanged 1
#define kVstTransportPlaying (1 << 1)
#define kVstTransportCycleActive (1 << 2)
#define kVstTransportRecording (1 << 3)

#define kVstAutomationWriting (1 << 6)
#define kVstAutomationReading (1 << 7)

#define kVstNanosValid (1 << 8)
#define kVstPpqPosValid (1 << 9)
@@ -174,26 +203,57 @@ struct _VstEvents
VstEvent * events[2];
};

enum Vestige2StringConstants
{
VestigeMaxNameLen = 64,
VestigeMaxLabelLen = 64,
VestigeMaxShortLabelLen = 8,
VestigeMaxCategLabelLen = 24,
VestigeMaxFileNameLen = 100
};


enum VstPlugCategory
{
kPlugCategUnknown = 0,
kPlugCategEffect,
kPlugCategSynth,
kPlugCategAnalysis,
kPlugCategMastering,
kPlugCategSpacializer,
kPlugCategRoomFx,
kPlugSurroundFx,
kPlugCategRestoration,
kPlugCategOfflineProcess,
kPlugCategShell,
kPlugCategGenerator,
kPlugCategMaxCount
};

typedef struct _VstEvents VstEvents;

/* this struct taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
struct _VstParameterProperties
{
float stepFloat;
float smallStepFloat;
float largeStepFloat;
char label[64];
int32_t flags;
int32_t minInteger;
int32_t maxInteger;
int32_t stepInteger;
int32_t largeStepInteger;
char shortLabel[8];
float stepFloat; /* float step */
float smallStepFloat; /* small float step */
float largeStepFloat; /* large float step */
char label[VestigeMaxLabelLen]; /* parameter label */
int32_t flags; /* @see VstParameterFlags */
int32_t minInteger; /* integer minimum */
int32_t maxInteger; /* integer maximum */
int32_t stepInteger; /* integer step */
int32_t largeStepInteger; /* large integer step */
char shortLabel[VestigeMaxShortLabelLen]; /* short label, recommended: 6 + delimiter */
int16_t displayIndex; /* index where this parameter should be displayed (starting with 0) */
int16_t category; /* 0: no category, else group index + 1 */
int16_t numParametersInCategory; /* number of parameters in category */
int16_t reserved; /* zero */
char categoryLabel[VestigeMaxCategLabelLen]; /* category label, e.g. "Osc 1" */
char future[16]; /* reserved for future use */
};

typedef struct _VstParameterProperties VstParameterProperties;

/* this enum taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
enum VstParameterFlags
{
kVstParameterIsSwitch = 1 << 0, /* parameter is a switch (on/off) */
@@ -231,18 +291,19 @@ struct _AEffect
// Fill somewhere 28-2b
void *ptr1;
void *ptr2;
// Zeroes 2c-2f 30-33 34-37 38-3b
char empty3[4 + 4 + 4];
int initialDelay;
// Zeroes 30-33 34-37 38-3b
char empty2[4 + 4];
// 1.0f 3c-3f
float unkown_float;
// An object? pointer 40-43
void *ptr3;
void *object;
// Zeroes 44-47
void *user;
// Id 48-4b
int32_t uniqueID;
// Don't know 4c-4f
char unknown1[4];
// plugin version 4c-4f
int32_t version;
// processReplacing 50-53
void (* processReplacing) (struct _AEffect *, float **, float **, int);
};

+ 6
- 6
dpf/utils/generate-ttl.sh View File

@@ -9,13 +9,13 @@ else
exit
fi

PWD=`dirname $0`
PWD="$(dirname "$0")"

if [ -f $PWD/lv2_ttl_generator.exe ]; then
GEN=$PWD/lv2_ttl_generator.exe
if [ -f "$PWD/lv2_ttl_generator.exe" ]; then
GEN="$PWD/lv2_ttl_generator.exe"
EXT=dll
else
GEN=$PWD/lv2_ttl_generator
GEN="$PWD/lv2_ttl_generator"
if [ -d /Library/Audio ]; then
EXT=dylib
else
@@ -27,7 +27,7 @@ FOLDERS=`find . -type d -name \*.lv2`

for i in $FOLDERS; do
cd $i
FILE=`ls *.$EXT | sort | head -n 1`
$GEN ./$FILE
FILE="$(ls *.$EXT | sort | head -n 1)"
"$GEN" "./$FILE"
cd ..
done

Loading…
Cancel
Save