Playing a MidiSequence


#1

Hmmmm … easy question for the juce gods …

The proper way to play a MIDI File (as I understand it) is:

  1. Open the File, read to a midi sequence …

  2. 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++; }

  1. 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?


#2

You could also use sendBlockOfMessages() if you don’t want to run the thread yourself.


#3

Thanks.

This eventually got working fine … for anyone looking and wondering if this is actually the way to do it.

Seems like the sine wave synth has some issues at high velocities, and another synth I was using was producing only one channel of data and it took me a while to notice (the other channel was coming back as noise).

Anyway, good stuff, glad to have midi sequencing working so well … thanks as always Jules.


#4

Sorry, just to be sure, did you use the “sendBlockOfMessages()” method or did you run the thread yourself ? :slight_smile:


#5

I ran the thread myself, with waitForMillisecondCounter.

But I’m sure either way works fine.


#6

Yes, it works. I used sendBlockOfMessages() method and i got the solution. I have done some changes in that and then after i had applied this method. Now it is working well no problem i am facing now.