@@ -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 | |||
@@ -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,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() | |||
@@ -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 | |||
@@ -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; | |||
@@ -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 | |||
}; | |||
// ----------------------------------------------------------------------- | |||
@@ -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; | |||
@@ -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) | |||
{ | |||
@@ -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; | |||