-
-
Notifications
You must be signed in to change notification settings - Fork 186
VST3 only handles note on / note off events #126
Comments
I was able to make some rewrites to capture control messages. Here is the process (only Mod Wheel and Pitch Bend are implemented -- should be easy to see how to add other messages): IPlugVST3.hModify class declare to inherit from IMidiMapping: class IPlugVST3 : public IPlugBase,
public Steinberg::Vst::SingleComponentEffect,
public Steinberg::Vst::IMidiMapping Under virtual Steinberg::tresult PLUGIN_API getMidiControllerAssignment(Steinberg::int32 busIndex, Steinberg::int16 channel, Steinberg::Vst::CtrlNumber midiControllerNumber, Steinberg::Vst::ParamID& id/*out*/); Under DEFINE_INTERFACES place DEF_INTERFACE(IMidiMapping) so the result looks like: OBJ_METHODS (IPlugVST3, SingleComponentEffect)
DEFINE_INTERFACES
DEF_INTERFACE(IMidiMapping)
END_DEFINE_INTERFACES (SingleComponentEffect)
REFCOUNT_METHODS(SingleComponentEffect) Modify this enum as desired: enum
{
kBypassParam = 'bpas',
kPresetParam = 'prst',
kModWheelParam = 'modw',
// kBreathParam = 'brth',
// kCtrler3Param = 'ct03',
// kExpressionParam = 'expr',
kPitchBendParam = 'pitb'
// kSustainParam = 'sust',
// kAftertouchParam = 'aftt',
}; IPlugVST3.cppAdd getMidiControllerAssignment function (I put it above process()): tresult PLUGIN_API IPlugVST3::getMidiControllerAssignment(int32 busIndex, int16 channel, CtrlNumber midiControllerNumber, ParamID& id/*out*/) {
if (busIndex == 0) {
id = -1;
switch (midiControllerNumber) {
case kPitchBend:
id = kPitchBendParam;
break;
case kCtrlModWheel:
id = kModWheelParam;
break;
}
if (id == -1) {
id = 0;
return kResultFalse;
}
else
return kResultTrue;
}
} This maps the incoming MIDI to a param. Next, initialize the parameters under Parameter * param;
param = new RangeParameter(USTRING("MIDI Mod Wheel"), kModWheelParam, USTRING(""), 0.0, 1.0, 0.5); // outputs values [0.0, 1.0]
param->setPrecision(1);
parameters.addParameter(param);
param = new RangeParameter(USTRING("MIDI Pitch Bend"), kPitchBendParam, USTRING(""), 0.0, 1.0, 0.5);
param->setPrecision(1);
parameters.addParameter(param); Next, find this case structure in IPlugVST3::process(): int idx = paramQueue->getParameterId();
switch (idx)
{
case kBypassParam:
{
bool bypassed = (value > 0.5);
if (bypassed != mIsBypassed)
{
mIsBypassed = bypassed;
}
break;
}
case kPresetParam:
RestorePreset(FromNormalizedParam(value, 0, NPresets(), 1.));
break;
//TODO pitch bend, modwheel etc
default:
if (idx >= 0 && idx < NParams())
{
GetParam(idx)->SetNormalized((double)value);
if (GetGUI()) GetGUI()->SetParameterFromPlug(idx, (double)value, true);
OnParamChange(idx);
}
break;
} Make it look like this: int idx = paramQueue->getParameterId();
IMidiMsg msg;
switch (idx)
{
case kBypassParam:
{
bool bypassed = (value > 0.5);
if (bypassed != mIsBypassed)
{
mIsBypassed = bypassed;
}
break;
}
case kPresetParam:
RestorePreset(FromNormalizedParam(value, 0, NPresets(), 1.));
break;
//TODO pitch bend, modwheel etc
// Done. -Jon Keller
case kPitchBendParam:
msg.MakePitchWheelMsg(value*2.0-1.0); // convert unipolar to bipolar
ProcessMidiMsg(&msg);
break;
case kModWheelParam:
msg.MakeControlChangeMsg(IMidiMsg::EControlChangeMsg::kModWheel, value); // TODO: differentiate channels
ProcessMidiMsg(&msg);
break;
default:
if (idx >= 0 && idx < NParams())
{
GetParam(idx)->SetNormalized((double)value);
if (GetGUI()) GetGUI()->SetParameterFromPlug(idx, (double)value, true);
OnParamChange(idx);
}
break;
} Note that VST3 seems to interpret all control messages as being on the scale [0.0, 1.0], so if you want to scale it to [-1.0, 1.0] (like for pitch bend), you have to make sure to do that conversion in IPlugVST3::process() as I have done in the code above. |
hi Jon, Thanks for your mods. This is all already done for iPlug 2 (which is currently on a private git repo). I agree, since VST2 is gone... iPlug VST3 support needs to be complete. oli |
Hello,
A little over a year ago i asked about instructions to install. Ive been
looking at the documentation, the video posted on YouTube in regards to
installing iplug; but how would i use the software? I use visual studio and
have downloaded the sdk. Are there any instructions on how to get started?
I appreciate your time.
Thanks,
James
…On Thu, Dec 6, 2018, 1:52 PM Oli Larkin ***@***.*** wrote:
hi Jon,
Thanks for your mods.
This is all already done for iPlug 2 (which is currently on a private git
repo). I agree, since VST2 is gone... iPlug VST3 support needs to be
complete.
oli
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#126 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ATKfBzaVFBAiuewRTL6a7zlWbT8jrot-ks5u2XWNgaJpZM4ZGwTB>
.
|
hi James, not really with the current WDL-OL, but i am working hard to release a new "iPlug2" soon, which will have more instructions/docs |
Is there any ETA for when iPlug 2 is going to be released? I'm very much looking forward to it! 👍 |
Before the end of the year! |
In IPlugVST3.cpp, IPlugVST3::process(), the code does not handle any MIDI messages outside note-on/note-off. There is even a comment saying, "//process events.. only midi note on and note off?".
This is extremely limiting considering Steinberg has officially discontinued VST2 and you cannot acquire the VST 2 API from them, so all new plugins should be VST3.
When digging deeper I discovered that the IPlug core wasn't written to handle MIDI controllers from VST3. Generally these seem to be handled from a "controller" class that is separate from the "audio effect" class (enumerated as kVstAudioEffectClass and kVstComponentControllerClass). The "controller" class is not implemented in IPlug.
Apparently in VST3 the MIDI messages for pitch bend, control messages, etc must be mapped to a parameter with its own parameter ID, so some rewrites to IPlug are required to remedy this issue.
The text was updated successfully, but these errors were encountered: