I’m having an issue where the first note at position 0 on a MIDI track does not play properly when calling TransportControl::play. It starts to play but then is cut off immediately before its end. When played in a loop, it plays when it wraps around just fine. Other notes play fine also. Monitoring the MIDI, I see that the note is cut off early and an all notes off is also sent:
14:0 Note on 0, note 60, velocity 63 // 1) my note on
14:0 Note off 0, note 60, velocity 0 // 2) note cut off early
14:0 Control change 0, controller 123, value 0 // 3) all notes off
14:0 Note off 0, note 60, velocity 0 // 4) my note's actual end
The first note on and last note off are my note. But in between, after the initial note on message, MidiNoteDispatcher::hiResTimerCallback calls MidiOutputDevice::sendNoteOffMessages() and sends the early note off and all notes off messages (messages 2 and 3 above).
If I change the code in MidiNoteDispatcher::hiResTimerCallback from
if (buffer.isAllNotesOff)
midiOut.sendNoteOffMessages();
to
if (buffer.isAllNotesOff) {
buffer.isAllNotesOff = false;
midiOut.sendNoteOffMessages();
}
Then the note plays normally and I get just the midi note on and off messages that I expect:
14:0 Note on 0, note 60, velocity 63
14:0 Note off 0, note 60, velocity 0
I’m not sure if this is the right fix or what other consequences this change might have. I’m looking for a way to make sure the note is not cut off after it starts by MidiOutputDevice::sendNoteOffMessages(). This could perhaps be some race condition or MidiOutputDevice::sendNoteOffMessages() is expected to be called before playing actually starts but is called after since it is called multiple times when starting to play (I counted 6 though it may vary).
