Sending Midi noteOn and delayed noteOff


#1

Please help me!
I´ve searched everywhere and tried a lot of things for the last two days now, but I´m stuck!
Basically I´m programming a step sequencer, that is supposed to fire a noteOn at every step (so far it has eight) and then automatically a noteOff after some (user adjustable) time has passed.
My approach so far has been:

  • call startBackgroundThread() on my MidiOutput (I do this at init of the output)
    For every step:
  • add my Messages to a MidiBuffer (MidiBuffer::addEvent)
  • send the buffer via MidiOutput::sendBlockOfMessages()

I get note output, but the problem now is, that I cannot really set the time between noteOn and noteOff. Where would I do this anyway? I tried giving my messages timeStamps (makes no difference, as somehow the note messages come out without timestamps at all), and also using a higher “sampleNumber” with the addEvent command. This works to some extent, but then fails an assertion if the time gets too big.

Do I have the right approch anyway? Or do I need a single thread for every note? (I don´t have much experience with threads yet)

Any help would be greatly appreciated!

Thanks in advance,
Christian


#2

I thnik I’d use a timer for this.
You have to implements Timer class and send the noteOff in your timerCallback method. Then you just have to callstartTimer(timeSetByUser) when you send the noteOn event.


#3

This has been discussed on other threads before, so you might want to do a search, as I think it was quite well explained.

Basically it’s a bit trickier than it sounds. Using a timer is easy, but hopelessly inaccurate because it runs on the message thread. The best way is to use your own dedicated thread that waits for the appropriate time and triggers events.


#4

you should post your events in a prority queue based on event timestamps

and pop your priority queue for pending events that are due in the current time-slice.

that way you can schedule note-off right away when sending the note-on and let the priority queue do the rest.


#5

Thanks for your answers, guys!

So, jules, I think I´m gonna go with the threads. I´ve read the other posts again and it´s slowly getting clear to me.
Something I don´t quite understand though is if I need multiple threads, one for each note? Cause if I wait for the appropriate time in the thread then I couldn´t handle other incoming notes right?
If so, would a ThreadPool be the right thing to use?

mdsp, could you please clarify your idea? One point that is still unclear to me is how I could keep track of time in my priority queue…

Cheers!
Christian


#6

A thread per message would be… interesting! No - you’d just use one thread that sends the messages in order.

Have a look in MidiOutput::run(), because it already has a thread that it uses for the sendBlockOfMessages() call, and you’d need to do something similar to that.