summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfalkTX <falktx@gmail.com>2018-08-04 02:08:08 +0200
committerfalkTX <falktx@gmail.com>2018-08-04 02:08:08 +0200
commitffdfaa6174adaa538150e95a128bf4f5f5f6d292 (patch)
tree22c1f528445494bebee3646f5845d296d50d3c10
parentf2ed265a003e5d426953bb9d91aec7de093986e0 (diff)
Implement MIDI output for all formats
Needs testing, I did none :)
-rw-r--r--distrho/DistrhoPlugin.hpp3
-rw-r--r--distrho/src/DistrhoPluginInternal.hpp24
-rw-r--r--distrho/src/DistrhoPluginJack.cpp66
-rw-r--r--distrho/src/DistrhoPluginLADSPA+DSSI.cpp12
-rw-r--r--distrho/src/DistrhoPluginLV2.cpp110
-rw-r--r--distrho/src/DistrhoPluginLV2export.cpp4
-rw-r--r--distrho/src/DistrhoPluginVST.cpp56
-rw-r--r--distrho/src/DistrhoUIInternal.hpp29
8 files changed, 239 insertions, 65 deletions
diff --git a/distrho/DistrhoPlugin.hpp b/distrho/DistrhoPlugin.hpp
index 9974aeaf..cbafc47c 100644
--- a/distrho/DistrhoPlugin.hpp
+++ b/distrho/DistrhoPlugin.hpp
@@ -691,9 +691,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
diff --git a/distrho/src/DistrhoPluginInternal.hpp b/distrho/src/DistrhoPluginInternal.hpp
index fcb3304e..007a98bf 100644
--- a/distrho/src/DistrhoPluginInternal.hpp
+++ b/distrho/src/DistrhoPluginInternal.hpp
@@ -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
@@ -33,6 +33,11 @@ extern uint32_t d_lastBufferSize;
extern double d_lastSampleRate;
// -----------------------------------------------------------------------
+// DSP callbacks
+
+typedef bool (*writeMidiFunc) (void* ptr, const MidiEvent& midiEvent);
+
+// -----------------------------------------------------------------------
// Plugin private data
struct Plugin::PrivateData {
@@ -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,12 @@ struct Plugin::PrivateData {
}
#endif
}
+
+ void writeMidiCallback(const MidiEvent& midiEvent)
+ {
+ if (writeMidiCallbackFunc != nullptr)
+ writeMidiCallbackFunc(callbacksPtr, midiEvent);
+ }
};
// -----------------------------------------------------------------------
@@ -157,7 +174,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 +208,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()
diff --git a/distrho/src/DistrhoPluginJack.cpp b/distrho/src/DistrhoPluginJack.cpp
index 4b1e5d5b..7381aed3 100644
--- a/distrho/src/DistrhoPluginJack.cpp
+++ b/distrho/src/DistrhoPluginJack.cpp
@@ -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)
{
@@ -201,6 +209,11 @@ public:
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 +343,10 @@ protected:
void* const midiBuf = jack_port_get_buffer(fPortEventsIn, nframes);
+#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+ fPortMidiOutBuffer = jack_port_get_buffer(fPortMidiOut, nframes);
+#endif
+
if (const uint32_t eventCount = jack_midi_get_event_count(midiBuf))
{
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -408,6 +425,10 @@ protected:
#else
fPlugin.run(audioIns, audioOuts, nframes);
#endif
+
+#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
+ fPortMidiOutBuffer = nullptr;
+#endif
}
void jackShutdown()
@@ -440,6 +461,18 @@ 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
+
// -------------------------------------------------------------------
private:
@@ -457,6 +490,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 +512,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
diff --git a/distrho/src/DistrhoPluginLADSPA+DSSI.cpp b/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
index 01bb19d7..40049f28 100644
--- a/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
+++ b/distrho/src/DistrhoPluginLADSPA+DSSI.cpp
@@ -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
@@ -531,7 +535,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;
diff --git a/distrho/src/DistrhoPluginLV2.cpp b/distrho/src/DistrhoPluginLV2.cpp
index 6b25ad71..9edcf8fd 100644
--- a/distrho/src/DistrhoPluginLV2.cpp
+++ b/distrho/src/DistrhoPluginLV2.cpp
@@ -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
@@ -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
@@ -610,17 +612,11 @@ public:
updateParameterOutputs();
#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 +641,7 @@ public:
break;
// reserve msg space
+ // FIXME create a large enough buffer beforehand
char msgBuf[msgSize];
std::memset(msgBuf, 0, msgSize);
@@ -653,21 +650,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 +882,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 +918,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;
@@ -1016,6 +1050,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
};
// -----------------------------------------------------------------------
diff --git a/distrho/src/DistrhoPluginLV2export.cpp b/distrho/src/DistrhoPluginLV2export.cpp
index 295525b5..d2fa86ae 100644
--- a/distrho/src/DistrhoPluginLV2export.cpp
+++ b/distrho/src/DistrhoPluginLV2export.cpp
@@ -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;
diff --git a/distrho/src/DistrhoPluginVST.cpp b/distrho/src/DistrhoPluginVST.cpp
index 78ebe7bf..516cc79e 100644
--- a/distrho/src/DistrhoPluginVST.cpp
+++ b/distrho/src/DistrhoPluginVST.cpp
@@ -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
@@ -68,6 +68,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)
@@ -351,7 +357,8 @@ class PluginVst
{
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));
@@ -453,15 +460,15 @@ 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)
{
DISTRHO_NAMESPACE::snprintf_iparam((char*)ptr, (int32_t)std::round(value), 24);
@@ -881,13 +888,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];
@@ -937,6 +944,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
@@ -1002,7 +1040,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)
{
diff --git a/distrho/src/DistrhoUIInternal.hpp b/distrho/src/DistrhoUIInternal.hpp
index b2dd7e67..bcd4c042 100644
--- a/distrho/src/DistrhoUIInternal.hpp
+++ b/distrho/src/DistrhoUIInternal.hpp
@@ -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;