Sequencing Event (e.g. MIDI) timing

Hi,

I was thinking of creating a means to play back a MIDI file or event list in OF.
Although, I do have jvcleave’s ofxThreadedMidiPlayer running, so actually that works well.

But I wondered how accurate the timing would be and generally, how does one ensure accuracy of timing?

If say one wants to sequence an event in OF, are we doing that at the update rate? or is it possible to schedule, so that if the desired time is Xms, and the update is at Yms (happening at every Z ms) then we schedule an event at Y that happens at X by sending a timed delay of (X-Y)ms to a function.

I know you could use audio thread to happen every 512 audio samples (11.2ms), but if you wanted it more accurate is there a way?

This is common in MaxMSP where they schedule with clocks. Are there common ways to do that here, or are these kinds of latencies (< 30ms) not really considered a problem?

So I guess I’m wondering:
does ofxThreadedMIDI do so, and whereabouts?
what kind fo code practice needs to happen regards timing?

thanks,
Andrew

curious on this as well - putting it into a thread was kinda a quick fix approach.

Here is my solution. I used it since 8/2009, never had problems with it.

http://forum.openframeworks.cc/t/my-struggle-with-the-timing/2440/1

Set the variable hdelay to your own needs.

if peaple are interested I can make an addon of that

Thanks Bernard.

So I’ve taken that example and created an example

https://github.com/Venetian/ofxPocoEventTimer

It would be good to see how to change it to specifically schedule an event. I’m still working through how the timing functions are routed together. Clearly it setups up the timer in setup() that is calling every 10 ms. How are the Poco times then used?

I think addon wise, maybe something like a delayed event depending on where you click the mouse - e.g. delay of 2*mouseX ms to print or draw something - would show it well.

Yes, the timer function is called every 10 ms. You can set a smaller value if it is not enought for you.

The function look if the delay you want is reached: ( if(curTime >= nextTime) … )
and does what to do if yes.

In my example 125000 represents the number of microseconds between 2 quarter notes at 120 bpm.

If you want that the timer works only under certain conditions you can call timer->stop() and call timer->start() if the condition is satisfied (must do some initialisations again there too, I don’t remember exactly without looking at my sequencer code)

so I was wondering about a sequence of values, e.g. midi notes or control commands you may want to send

how would you run through those?
would it be best to have this as an addon class that is called - maybe in update() - that the checks the timing and schedules relevant events?
I have some ideas but not quite sure how best to do that. I’ve added you on the Github repo.

Andrew

i’ve dealt with this ‘timed midi events’ thing for sequencing before https://github.com/YCAMInterlab/ProCamToolkit/blob/library/ModelProjector/src/Sequencer.h

the problem is this line:

  
  
ofSleepMillis(1);  
  

it causes some huge cpu usage.

one solution i’ve tried looks like this:

  
  
// sleep for 1/2 of the remaining time, unless there's only 30 ms left  
float remaining = colLength * (1. - fmodf(getPosition(), 1.));  
if(remaining > 30) {  
	ofSleepMillis(remaining / 2);  
} else {  
	ofSleepMillis(1);  
}  
  

in other words, sleep for half the time until the next event. unless you have less than 30 milliseconds till the next event, in which case just sleep for 1 millisecond.

the issue i ran into is that sometimes after running for a long time, the thread would be not be called for longer than 30 milliseconds. this means that the events start stuttering. i never figured this out. it could be some kind of floating point precision error, but it’s hard to replicate.

in theory the above idea should work fine for having low-CPU usage event scheduling. it’s kind of the inverse of this idea https://en.wikipedia.org/wiki/Exponential-backoff from networking.

also see this example from venetian, using poco for scheduling events https://github.com/Venetian/ofxPocoEventTimer/blob/master/src/testApp.cpp

That’s kind of you to say so Kyle…

To really nail this we need to figure out how to schedule a MIDI event from an update routine that runs slower, say every 30ms (~30Hz). Any ideas on the kind of function that would ensure accurate execution of MIDI with that in mind? Presumably software programs like Logic schedule MIDI events from a similar AudioInputRecieved() function or whatever…

Any advice on the current state of thinking is on this? Did anyone make any progress on a solid solution?