How to handle sending MIDI events to buffer in a sequencer plugin

Hi all, I’m a compete beginner with JUCE and c++ in general. I’ve been working on making a MIDI step sequencer plugin. I feel like I’m getting close to something I can work with i.e. spit out MIDI messages with predetermined values every desired subdivision.

Currently in my plugin I have three sliders that change the values of a MIDI message, one for the channel, one for the note number and one for the velocity. I am also able to get the sample number at the start of each block in the processBlock function.

It makes sense to me that with this I could work out the desired time stamp to add to the MIDI message which will be sent to the MIDI buffer. I could then have a function inside the processBlock that iterates over the messages in the buffer so they can be sent to the MIDI output. What I can’t think of is a good way to handle sending the messages to the buffer.

One thought is to use a timer to determine when a message is added to the buffer but I’m worried that would risk going out of sync with the host. Another thought is to have the processBlock add the event but this sounds like it could create lots of duplicate messages. I don’t know, I’m at a loss.

Anyway, any thoughts on this would be really appreciated. Also feel free to correct me if my understanding of how this works is off.

1 Like

The stuff is overall somewhat tricky to handle. But one thing I can say is that don’t use a Timer (or HighResolutionTimer) to attempt to do a sequencer, that’s not the right approach. You need to instead count time in samples in processBlock and dispatch your MIDI events accordingly from your step sequence.

4 Likes

As @xenakios says, use the timeInSamples value from the playHead to process all your timings.

1 Like

Cheers guys, looks like keeping everything in the processBlock is the way to go. Quick update, I’ve been hacking away all day and have found a couple of different methods for keeping track of where I am in terms of samples or ppq position, but nothing I can use yet in terms of ‘do something at this point in time’.

I’m wondering if it might be an idea to keep track of the amount of samples until the next event. I could increment this value down to 0 and once it reaches 0 add an event to the buffer and reset the variable. I’m away from the computer so not sure exactly how to write this or if it would work but I think it could look something like this.

int samplesUntilNextNote = 48000;

for (int sample = 0; sample < maxBufferSize; ++ sample)
{
  samplesUntilNextNote - 1;

  if (samplesUntilNextNote == 0)
  {
   // add event to buffer
   samplesUntilNextNote = 48000;
  }
}

edit: I’m now thinking this wouldn’t work since to stay in sync with the host I’d need to be relating to the playheads position somehow :sweat_smile:

I think the example code in
“<path to your JUCE installation>\examples\Plugins\ArpeggiatorPluginDemo.h”
is may be what you need to peruse.