Timer with higher granularity


#1

Hi,

I was using a Juce Timer to pick up frames from a camera. I noticed, however, that the Timer only triggers every 16 msecs or so on Windows, even if I set it to trigger every 5 msecs. The camera frames are coming in every 10 msecs though. So, I need to write my own Timer class that triggers more often.

I was thinking about the best way to do this, but before I do anything I thought it would be a good idea to try to understand why it is that the Timer is only triggering every 16 msecs even when I tell it to trigger more frequently. I was considering creating a Thread and having it sleep for a few msecs. But perhaps this is what the Timer is doing already, and it’s just not being woken up from its sleep at the time requested. So, I would appreciate any clues explaining the Timer classes behavior as well as tips regarding how I could create a Timer class that triggers more often.

Thanks,
Greg


#2

as far as i remember jules said that Timer() is not for those high resolution operations. I was writing a midi master clock component and i used a Thread and a normal loop to get better perfrormance.

here is how i did it:
http://code.google.com/p/sklepseq/source/browse/trunk/xsync.cpp

and it works pretty well. if you want rock solid sync you can always set the threads priority a bit higher.


#3

The Timer class runs on the event loop, so you get absolutely no guarantee about how accurate it is - if something blocks the event loop for 10 seconds, any timers will have to wait for it to complete before they can run. (It does explain this in the comments for the Timer class).


#4

Hi, atom. Thanks for the link to your code. I created a new class called HighResolutionTimer based on your work, but unfortunately, when I’d call Time::waitForMillisecondCounter (timeNow + 3) as you did, it would wait 15-16 milliseconds rather than 3 milliseconds, and this is of course the same problem that I had using the Timer class.

I wonder what this method is actually doing. Is it calling the underlying sleep() function in the Windows threading API? If so, I’m pretty much stumped about how else I might get around this problem, because a thread isn’t going to do it… Before I started using Juce, I’d do this on the application’s main thread, and that worked fine. Perhaps, I’ll have to see if I couldn’t somehow do that as well with Juce…


#5

Okay, I looked into waitForMillisecondCounter(). Oddly enough, it’s making this call: Thread::sleep (jmin (20, toWait >> 1))

I tried calling Thread::sleep(5) directly. And even more oddly, that seems to cause the thread to wake up either after 0 msecs or 15 msecs. It oscillates more or less between the two possibilities. But it also causes the CPU use to jump from 4% to 50%.

Hm…


#6

You’re always at the mercy of the OS scheduler with this kind of thing, though I always found it to work to within 1ms on a high-priority thread, especially if you boost your process priority.


#7

i based my code on suggestions from here:
http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=2992&highlight=waitformillisecondcounter

i have to say this was enough for me, but i never finished this so i don’t know how this will act in different situations.


#8

This has nothing to do with JUCE; it has to do with the native granularity of the Windows scheduler. Search around for timeBeginPeriod to learn more.

Matt