Browse Source

VST3: Added support for MIDI controller messages when hosting VST3 plug-ins

tags/2021-05-28
hogliux 7 years ago
parent
commit
55b92b83fc
2 changed files with 52 additions and 4 deletions
  1. +45
    -3
      modules/juce_audio_processors/format_types/juce_VST3Common.h
  2. +7
    -1
      modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp

+ 45
- 3
modules/juce_audio_processors/format_types/juce_VST3Common.h View File

@@ -492,7 +492,9 @@ public:
}
}
static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer)
static void toEventList (Steinberg::Vst::IEventList& result, MidiBuffer& midiBuffer,
Steinberg::Vst::IParameterChanges* parameterChanges = nullptr,
Steinberg::Vst::IMidiMapping* midiMapping = nullptr)
{
MidiBuffer::Iterator iterator (midiBuffer);
MidiMessage msg;
@@ -506,6 +508,28 @@ public:
if (++numEvents > maxNumEvents)
break;
if (midiMapping != nullptr && parameterChanges != nullptr)
{
Vst3MidiControlEvent controlEvent;
if (toVst3ControlEvent (msg, controlEvent))
{
Steinberg::Vst::ParamID controlParamID;
if (midiMapping->getMidiControllerAssignment (0, createSafeChannel (msg.getChannel()),
controlEvent.controllerNumber,
controlParamID) == Steinberg::kResultOk)
{
Steinberg::int32 ignore;
if (auto* queue = parameterChanges->addParameterData (controlParamID, ignore))
queue->addPoint (midiEventPosition, controlEvent.paramValue, ignore);
}
continue;
}
}
Steinberg::Vst::Event e = { 0 };
if (msg.isNoteOn())
@@ -534,12 +558,12 @@ public:
e.data.size = (uint32) msg.getSysExDataSize();
e.data.type = Steinberg::Vst::DataEvent::kMidiSysEx;
}
else if (msg.isAftertouch())
else if (msg.isChannelPressure())
{
e.type = Steinberg::Vst::Event::kPolyPressureEvent;
e.polyPressure.channel = createSafeChannel (msg.getChannel());
e.polyPressure.pitch = createSafeNote (msg.getNoteNumber());
e.polyPressure.pressure = normaliseMidiValue (msg.getAfterTouchValue());
e.polyPressure.pressure = normaliseMidiValue (msg.getChannelPressureValue());
}
else
{
@@ -566,6 +590,24 @@ private:
static float normaliseMidiValue (int value) noexcept { return jlimit (0.0f, 1.0f, (float) value / 127.0f); }
static int denormaliseToMidiValue (float value) noexcept { return roundToInt (jlimit (0.0f, 127.0f, value * 127.0f)); }
//==============================================================================
struct Vst3MidiControlEvent
{
Steinberg::Vst::CtrlNumber controllerNumber;
Steinberg::Vst::ParamValue paramValue;
};
static bool toVst3ControlEvent (const MidiMessage& msg, Vst3MidiControlEvent& result)
{
result.controllerNumber = -1;
if (msg.isController()) result = { (Steinberg::Vst::CtrlNumber) msg.getControllerNumber(), msg.getControllerValue() / 127.0};
else if (msg.isPitchWheel()) result = { Steinberg::Vst::kPitchBend, msg.getPitchWheelValue() / 16383.0};
else if (msg.isAftertouch()) result = { Steinberg::Vst::kAfterTouch, msg.getAfterTouchValue() / 127.0};
return (result.controllerNumber != -1);
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MidiEventList)
};


+ 7
- 1
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -1835,6 +1835,7 @@ struct VST3PluginInstance : public AudioPluginInstance
componentHandler2 = nullptr;
componentHandler = nullptr;
processor = nullptr;
midiMapping = nullptr;
editController2 = nullptr;
editController = nullptr;
}
@@ -2558,6 +2559,7 @@ private:
// Rudimentary interfaces:
ComSmartPtr<Vst::IEditController> editController;
ComSmartPtr<Vst::IEditController2> editController2;
ComSmartPtr<Vst::IMidiMapping> midiMapping;
ComSmartPtr<Vst::IAudioProcessor> processor;
ComSmartPtr<Vst::IComponentHandler> componentHandler;
ComSmartPtr<Vst::IComponentHandler2> componentHandler2;
@@ -2649,6 +2651,7 @@ private:
programListData.loadFrom (holder->component);
unitData.loadFrom (holder->component);
editController2.loadFrom (holder->component);
midiMapping.loadFrom (holder->component);
componentHandler.loadFrom (holder->component);
componentHandler2.loadFrom (holder->component);
trackInfoListener.loadFrom (holder->component);
@@ -2658,6 +2661,7 @@ private:
if (programListData == nullptr) programListData.loadFrom (editController);
if (unitData == nullptr) unitData.loadFrom (editController);
if (editController2 == nullptr) editController2.loadFrom (editController);
if (midiMapping == nullptr) midiMapping.loadFrom (editController);
if (componentHandler == nullptr) componentHandler.loadFrom (editController);
if (componentHandler2 == nullptr) componentHandler2.loadFrom (editController);
if (trackInfoListener == nullptr) trackInfoListener.loadFrom (editController);
@@ -2784,7 +2788,9 @@ private:
midiInputs->clear();
midiOutputs->clear();
MidiEventList::toEventList (*midiInputs, midiBuffer);
MidiEventList::toEventList (*midiInputs, midiBuffer,
destination.inputParameterChanges,
midiMapping);
destination.inputEvents = midiInputs;
destination.outputEvents = midiOutputs;


Loading…
Cancel
Save