VST3 MIDI events ordering



My plugin, when running on Dorico, sometimes receives (when starting playback) an ‘AllNotesOff’ and a ‘NoteOn’ event with the exact same sampleNumber value. Since those two events start on the same sample, their relative ordering is unsure. If the NoteOn is handled before AllNotesOff, then the note is immediately cut, otherwise it is playing normally. The issue with the VST3 stuff is that the noteOn/noteOff stuff events are added to the midiBuffer object with:

MidiEventList::toMidiBuffer (midiBuffer, *data.inputEvents);

And the AllNotesOffs/AllSoundsOff, which are controller events, are added to the midiBuffer object by the call to:

processParameterChanges (*data.inputParameterChanges);

And these two calls currently happen in that order in the juce_VST3_Wrapper.cpp, so when the VST3 timestamp of the NoteOn and AllNotesOff is the same, the AllNotesOff event will be always placed after the NoteOn in the MidiBuffer object. NoteOns are cut off immediately, and users are unhappy.

So I suggest to fix this by moving the

   #if JucePlugin_WantsMidiInput 
    if (data.inputEvents != nullptr)
        MidiEventList::toMidiBuffer (midiBuffer, *data.inputEvents);

in the processAudio() function, just after the call to

   if (data.inputParameterChanges != nullptr)
        processParameterChanges (*data.inputParameterChanges);

that way, in case of simultaneous controller and noteon/off events, the controller events will always be placed before the noteon/off events. It seems to me it is better that way than the other.


OK sounds like a reasonable change. However, I moved the processParameterChanges before the MidiEventList::toMidiBuffer so that the processParameterChanges is not in the templated code-path anymore - I think that makes more sense. Also, processParameterChanges was called inside the audio callback lock which I think was unnecessary.

The fix for this is on develop with commit d95edfd.


Great, thanks Fabian !