Browse Source

Implement sendNote for VST2

Signed-off-by: falkTX <falktx@falktx.com>
pull/281/head
falkTX 4 years ago
parent
commit
624fe5dd96
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
2 changed files with 122 additions and 50 deletions
  1. +1
    -1
      distrho/extra/RingBuffer.hpp
  2. +121
    -49
      distrho/src/DistrhoPluginVST.cpp

+ 1
- 1
distrho/extra/RingBuffer.hpp View File

@@ -503,7 +503,6 @@ public:


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


protected:
/* /*
* Tie this ring buffer control to a ring buffer struct, optionally clearing its data. * Tie this ring buffer control to a ring buffer struct, optionally clearing its data.
*/ */
@@ -519,6 +518,7 @@ protected:


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


protected:
/** @internal try reading from the buffer, can fail. */ /** @internal try reading from the buffer, can fail. */
bool tryRead(void* const buf, const uint32_t size) noexcept bool tryRead(void* const buf, const uint32_t size) noexcept
{ {


+ 121
- 49
distrho/src/DistrhoPluginVST.cpp View File

@@ -27,6 +27,7 @@
# define DISTRHO_UI_USER_RESIZABLE 0 # define DISTRHO_UI_USER_RESIZABLE 0
# define DISTRHO_UI_IS_STANDALONE false # define DISTRHO_UI_IS_STANDALONE false
# include "DistrhoUIInternal.hpp" # include "DistrhoUIInternal.hpp"
# include "../extra/RingBuffer.hpp"
#endif #endif


#ifndef __cdecl #ifndef __cdecl
@@ -110,27 +111,44 @@ void snprintf_iparam(char* const dst, const int32_t value, const size_t size)


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


struct ParameterCheckHelper
struct ParameterAndNotesHelper
{ {
bool* parameterChecks;
float* parameterValues; float* parameterValues;
#if DISTRHO_PLUGIN_HAS_UI
bool* parameterChecks;
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
SmallStackBuffer notesRingBuffer;
# endif
#endif


ParameterCheckHelper()
: parameterChecks(nullptr),
parameterValues(nullptr) {}
ParameterAndNotesHelper()
: parameterValues(nullptr)
#if DISTRHO_PLUGIN_HAS_UI
, parameterChecks(nullptr)
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
, notesRingBuffer(StackBuffer_INIT)
# endif
#endif
{
#ifndef DISTRHO_PROPER_CPP11_SUPPORT
std::memset(&notesRingBuffer, 0, sizeof(notesRingBuffer));
#endif
}


virtual ~ParameterCheckHelper()
virtual ~ParameterAndNotesHelper()
{ {
if (parameterChecks != nullptr)
{
delete[] parameterChecks;
parameterChecks = nullptr;
}
if (parameterValues != nullptr) if (parameterValues != nullptr)
{ {
delete[] parameterValues; delete[] parameterValues;
parameterValues = nullptr; parameterValues = nullptr;
} }
#if DISTRHO_PLUGIN_HAS_UI
if (parameterChecks != nullptr)
{
delete[] parameterChecks;
parameterChecks = nullptr;
}
#endif
} }


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
@@ -141,12 +159,19 @@ struct ParameterCheckHelper
#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


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

class UIVst class UIVst
{ {
public: public:
UIVst(const audioMasterCallback audioMaster, UIVst(const audioMasterCallback audioMaster,
AEffect* const effect, AEffect* const effect,
ParameterCheckHelper* const uiHelper,
ParameterAndNotesHelper* const uiHelper,
PluginExporter* const plugin, PluginExporter* const plugin,
const intptr_t winId, const float scaleFactor) const intptr_t winId, const float scaleFactor)
: fAudioMaster(audioMaster), : fAudioMaster(audioMaster),
@@ -162,9 +187,17 @@ public:
nullptr, // TODO file request nullptr, // TODO file request
nullptr, nullptr,
plugin->getInstancePointer(), plugin->getInstancePointer(),
scaleFactor),
fKeyboardModifiers(0)
scaleFactor)
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
, fKeyboardModifiers(0)
# endif
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
, fNotesRingBuffer()
# endif
{ {
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
fNotesRingBuffer.setRingBuffer(&uiHelper->notesRingBuffer, false);
# endif
} }


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -352,45 +385,46 @@ protected:
hostCallback(audioMasterAutomate, index, 0, nullptr, perValue); hostCallback(audioMasterAutomate, index, 0, nullptr, perValue);
} }


void setState(const char* const key, const char* const value)
void setSize(const uint width, const uint height)
{ {
# if DISTRHO_PLUGIN_WANT_STATE
fUiHelper->setStateFromUI(key, value);
# else
return; // unused
(void)key;
(void)value;
# endif
fUI.setWindowSize(width, height);
hostCallback(audioMasterSizeWindow, width, height);
} }


# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity) void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity)
{ {
# if 0 //DISTRHO_PLUGIN_WANT_MIDI_INPUT
// TODO
# else
return; // unused
(void)channel;
(void)note;
(void)velocity;
# endif
uint8_t midiData[3];
midiData[0] = (velocity != 0 ? 0x90 : 0x80) | channel;
midiData[1] = note;
midiData[2] = velocity;
fNotesRingBuffer.writeCustomData(midiData, 3);
fNotesRingBuffer.commitWrite();
} }
# endif


void setSize(const uint width, const uint height)
# if DISTRHO_PLUGIN_WANT_STATE
void setState(const char* const key, const char* const value)
{ {
fUI.setWindowSize(width, height);
hostCallback(audioMasterSizeWindow, width, height);
fUiHelper->setStateFromUI(key, value);
} }
# endif


private: private:
// Vst stuff // Vst stuff
const audioMasterCallback fAudioMaster; const audioMasterCallback fAudioMaster;
AEffect* const fEffect; AEffect* const fEffect;
ParameterCheckHelper* const fUiHelper;
ParameterAndNotesHelper* const fUiHelper;
PluginExporter* const fPlugin; PluginExporter* const fPlugin;


// Plugin UI // Plugin UI
UIExporter fUI; UIExporter fUI;
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI
uint16_t fKeyboardModifiers; uint16_t fKeyboardModifiers;
# endif
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
RingBufferControl<SmallStackBuffer> fNotesRingBuffer;
# endif


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Callbacks // Callbacks
@@ -407,28 +441,32 @@ private:
handlePtr->setParameterValue(rindex, value); handlePtr->setParameterValue(rindex, value);
} }


static void setStateCallback(void* ptr, const char* key, const char* value)
static void setSizeCallback(void* ptr, uint width, uint height)
{ {
handlePtr->setState(key, value);
handlePtr->setSize(width, height);
} }


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


static void setSizeCallback(void* ptr, uint width, uint height)
# if DISTRHO_PLUGIN_WANT_STATE
static void setStateCallback(void* ptr, const char* key, const char* value)
{ {
handlePtr->setSize(width, height);
handlePtr->setState(key, value);
} }
# endif


#undef handlePtr #undef handlePtr
}; };
#endif
#endif // DISTRHO_PLUGIN_HAS_UI


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


class PluginVst : public ParameterCheckHelper
class PluginVst : public ParameterAndNotesHelper
{ {
public: public:
PluginVst(const audioMasterCallback audioMaster, AEffect* const effect) PluginVst(const audioMasterCallback audioMaster, AEffect* const effect)
@@ -439,6 +477,16 @@ public:
std::memset(fProgramName, 0, sizeof(char)*(32+1)); std::memset(fProgramName, 0, sizeof(char)*(32+1));
std::strcpy(fProgramName, "Default"); std::strcpy(fProgramName, "Default");


const uint32_t parameterCount = fPlugin.getParameterCount();

if (parameterCount != 0)
{
parameterValues = new float[parameterCount];

for (uint32_t i=0; i < parameterCount; ++i)
parameterValues[i] = NAN;
}

#if DISTRHO_PLUGIN_WANT_MIDI_INPUT #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
fMidiEventCount = 0; fMidiEventCount = 0;
#endif #endif
@@ -451,17 +499,12 @@ public:
fVstRect.right = 0; fVstRect.right = 0;
fLastScaleFactor = 1.0f; fLastScaleFactor = 1.0f;


if (const uint32_t paramCount = fPlugin.getParameterCount())
if (parameterCount != 0)
{ {
parameterChecks = new bool[paramCount];
parameterValues = new float[paramCount];

for (uint32_t i=0; i < paramCount; ++i)
{
parameterChecks[i] = false;
parameterValues[i] = NAN;
}
parameterChecks = new bool[parameterCount];
memset(parameterChecks, 0, sizeof(bool)*parameterCount);
} }

# if DISTRHO_OS_MAC # if DISTRHO_OS_MAC
# ifdef __LP64__ # ifdef __LP64__
fUsingNsView = true; fUsingNsView = true;
@@ -472,6 +515,10 @@ public:
fUsingNsView = false; fUsingNsView = false;
# endif # endif
# endif // DISTRHO_OS_MAC # endif // DISTRHO_OS_MAC

# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
fNotesRingBuffer.setRingBuffer(&notesRingBuffer, true);
# endif
#endif // DISTRHO_PLUGIN_HAS_UI #endif // DISTRHO_PLUGIN_HAS_UI


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
@@ -1066,6 +1113,28 @@ public:
#endif #endif


#if DISTRHO_PLUGIN_WANT_MIDI_INPUT #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
# if DISTRHO_PLUGIN_HAS_UI
if (fMidiEventCount != kMaxMidiEvents && fNotesRingBuffer.isDataAvailableForReading())
{
uint8_t midiData[3];
uint32_t frame = fMidiEventCount != 0 ? fMidiEvents[fMidiEventCount-1].frame : 0;

while (fNotesRingBuffer.isDataAvailableForReading())
{
if (! fNotesRingBuffer.readCustomData(midiData, 3))
break;

MidiEvent& midiEvent(fMidiEvents[fMidiEventCount++]);
midiEvent.frame = frame;
midiEvent.size = 3;
std::memcpy(midiEvent.data, midiData, 3);

if (fMidiEventCount == kMaxMidiEvents)
break;
}
}
# endif

fPlugin.run(inputs, outputs, sampleFrames, fMidiEvents, fMidiEventCount); fPlugin.run(inputs, outputs, sampleFrames, fMidiEvents, fMidiEventCount);
fMidiEventCount = 0; fMidiEventCount = 0;
#else #else
@@ -1107,6 +1176,9 @@ private:
# if DISTRHO_OS_MAC # if DISTRHO_OS_MAC
bool fUsingNsView; bool fUsingNsView;
# endif # endif
# if DISTRHO_PLUGIN_WANT_MIDI_INPUT
RingBufferControl<SmallStackBuffer> fNotesRingBuffer;
# endif
#endif #endif


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE


Loading…
Cancel
Save