One main thing I want to do with openFrameWorks is to implement my midi sequencer on it, and to combine it with the display of pictures and video.
I use rtMidi, and it works correctely on Mac (Tiger) and Windows (XP).
To do this I need precise timing.
My first attempt was to use the following code :
float CurTime = 0, NextTime = 0, fDelay = 0.17045; // initialisations…
// and inside of the method testApp::draw(
CurTime = ofGetElapsedTimef();
if(CurTime >= NextTime) {
seqTimerFunc(); // midi processing here …
NextTime = CurTime + fDelay;
}
Problems with this technique :
Slow down when moving the mouse, or selecting another window
On Windows : Stop playing when click on windows bar
On Macintosh : Stop playing when selecting a menu
After a few hours the program crash (maybe overflow on ofGetElapsedTimef() ?)
After that I tried the famous glut timer function. It is a little better, specially in a separate thread,
but still not precise enough.
Finally, the best solution I found was to use the Timer of Poco, by adapting an example file in
the poco library to my needs.
Here is my code : (quick and dirty example but works)
// in file “testApp.h” :
#include “ofMain.h”
#include “Poco/Stopwatch.h”
#include “Poco/Thread.h”
#include “Poco/Timestamp.h”
#include “Poco/Timer.h”
using Poco::Stopwatch;
using Poco::Thread;
using Poco::Timer;
using Poco::TimerCallback;
class seqTimer
{
public:
seqTimer()
{
stopwatch.start();
}
void onTimer(Timer& timer)
{
void seqTimerFunc(Poco::Timestamp::TimeDiff curTime); // prototype of my function
seqTimerFunc(stopwatch.elapsed()); // function call
}
private:
Stopwatch stopwatch;
};
// and I declare in class testApp : public ofBaseApp
seqTimer sTimer;
Timer * timer;
// in file “testApp.cpp” :
Poco::Timestamp::TimeDiff hdelay = 125000; // delay between 2 events, in microseconds
Poco::Timestamp::TimeDiff nextTime = 0; // time when next event occurs (calculated in seqTimerFunc)
void seqTimerFunc(Poco::Timestamp::TimeDiff curTime);
void seqTimerFunc(Poco::Timestamp::TimeDiff curTime)
// Events that are regularely sent are processed here
{
if(curTime >= nextTime) {
nextTime += hdelay;
cout << (long)(curTime / 1000) << " … " << (long)(nextTime / 1000) << endl;
// Execute real messages (midi etc) here …
}
}
// and in the method void testApp::setup(){
timer = new Timer(0, 10); // parameters : immediate and delay of 10 milliseconds (fast enough i think)
timer->start(TimerCallback(sTimer, &seqTimer::onTimer), Thread::PRIO_HIGHEST);
My tests :
On a 1 GHz Macintosh with Tiger it works without problem
On a 2.66 GHZ PC with Windows XP it is ok if no other program (f.e. Firefox) is extensely used, otherwise there are notes that become irregular.
Maybe Windows ignores the Thread::PRIO_HIGHEST parameter ?