Hmmmm … easy question for the juce gods …
The proper way to play a MIDI File (as I understand it) is:
-
Open the File, read to a midi sequence …
-
On a separate thread execute something like the following to wait until the proper time, and then send the midiMessage to a MidiMessageCollector:
while (currentIndex < mySequence.getNumEvents())
{
Time::waitForMillisecondCounter(1000*(mySequence.getEventTime(currentIndex)));
myMidiMessageCollector->addMessageToQueue(mySequence.getEventPointer(currentIndex)->message);
currentIndex++;
}
- execute the MidiMessageCollector->removeNextBlockOfMessages() regularly … usually in an AudioProcessor processBlock or something like it to act as a synth (I’m using an AU plugin in this case), processing the midiMessages and filling the audiobuffer with whatever appropriate sound.
Works like a charm for me … except that I am getting constant nonlinearities in the sound. Step 3 above is definitely not the problem (as I can send real time midi to the midiMessageCollector from a keyboardStateComponent or midiInput callback, then process it as above and the sound comes out perfectly).
Also, the timing is fine (that is, the proper sequence notes will play at the right time for the right duration).
So it seems like the sequence is correct, and the synth plugin is fine … but something like note velocities is getting mangled.
Perhaps the note velocities are not properly converted somehow? I did run the updateMatchedPairs (since I added a time offset).
Or do I maybe need to write to midiBuffer and iterate through that instead of a midiSequence … not sure why that would be though.
Should I be adding the notes to a keyboardState or some other object instead of to the midiMessageCollector?
Not sure … I’ve been trying different things all day but keep coming up short. Anyone have a quick ideas?