processBlock() for MIDI playback


#1

Hello, I am trying to make a plugin that plays back MIDI from a MIDI file. I have gone over the Arpeggiator plugin example and have come up with this for processBlock():

void MidiPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midi)
{
    int currentPosition = 0;
    int numEvents = MidiSequence.getNumEvents();
    while ((currentPosition < numEvents))
    {
        MidiMessage msg = MidiSequence.getEventPointer(currentPosition)->message;
        midi.addEvent (msg, msg.getTimeStamp());
    }
}

MidiSequence is a global attribute I have added a MidiMessageSequence to.

From what I understand and have read this is the correct way to pass on MIDI messages to a synth but I am wondering how processBlock() is called? Even in the Arpeggiator example I’m wondering how it works.

Even so, I hook my plugin up to a synth with the plugin host to test it out and don’t get any playback.

Could someone clarify what I’m missing?


#2

Well, for a start you could increment currentPosition somewhere in the loop.


#3

Ah yes thanks, was at the end of a long hackathon, sorry about that. I’ll
have another go at it and report back.


#4

Okay that’s fixed but how/when is processBlock() called for plugins?


#5

It’s called by the host, so you have little/no guarantees about when that’s going to happen, what block size you’ll be asked to process, etc.


#6

Did you manage to get the Arpeggiator example running?


#7

Yes, I never had a problem getting the Arpeggiator example to run. I am having trouble making my own plugin that outputs MIDI notes from a MIDI file.

Right now I have a plugin with a button and when I press the button it parses a MIDI file and saves the notes in a MidiMessageSequence. The remaining task is to playback the sequence through a synth via the processBlock() method:

void MidiPluginAudioProcessorEditor::buttonClicked(Button* button)
{
    processor.makeRequest();
    MidiMessageSequence sequence = processor.parseMidi();
    //play midi sequence
}

Is it possible to begin the playback from this button like that?


#8

Sort of. You need to pass the sequence to the audio callback in a thread safe manner as the buttonClicked will be executed on one thread, while your processBlock may be in the middle of processing on the other thread. You need to make sure that you replace the sequence while the audio plug-in isn’t doing any work. You can use AudioProcessor::getCallbackLock for that.

Please also have a look at the Arpeggiator example. It should really work out of the box. You may need to pull from develop again to pick up the newest changes.