-
timeSetEvent problem
Hello,
I'm making a real time synthesizer, and i've set it up so that it uses timeSetEvent to call a function to update the sound to be played every 10 milliseconds. But this doesnt really work, because when the sound has been streaming for long enough, it starts clicking because the timer has fallen behind. I couldnt figure out why this is happening since it takes alot less than 10 milliseconds to put the data into the stream. I've since read an article that said that multimedia timers are known to fall behind eventually so i dont know how to solve this one...
I hear QueryPerformanceCounter is a high res timer, but you can pass a callback function into that like you cant with timeSetEvent.
So if anyone has any advice on what to do i'd really appreciate it.
Thanks.
-
Yeah, timers will fall behind when the system is busy, that's why most people don't use them for precision timing operations. Try using the GetTickCount() function. More on it here: GetTickCount. An acceptable way to utilize this is something like this:
Code:
static int iTickTrigger=0;
int iTickCount,timeToWait;
//make timeToWait whatever amount of time you want to pause
iTickCount=GetTickCount();
if(iTickCount<iTickTrigger)
{
//perform operations here
iTickTrigger=iTickCount+timeToWait;
}
Remember GetTickCount is in milliseconds, which is what you want fromt the sound of it, so timeToWait should be in milliseconds as well. Also the code above, excluding the initialization of the variables, needs to be in a loop so those two variables constantly are getting checked to see if your operations need to be performed. Hope that helps.
-
well i tried with GetTickCount but it seemed to be worse. I had a look in msdn and it only updates its value every 40 or 50 milliseconds. I'll try the high res timer in queryper........ and see if it works.
Thanks alot.
-
Windows is a multi-tasking operating system. Typically, this is what happens:
- Your thread runs for up to about 10ms. It will typically voluntarily yield before this with a call to Sleep, GetMessage, WaitForSingleObject, etc.
- Once your thread yields (either voluntarily or forcefully), all the other threads ready to go are run by the OS. Like your thread, they each get up to about 10ms.
From this description, you can see why having an event run every 10ms is very difficult. Consider a system with 5 busy threads. In this scenario, your thread will run for roughly 10ms and sleep for roughly 40ms while the other threads are running. Performance this poor is not typical because most threads voluntarily yield before their time slice is up.
You have a couple of options I can think of:
Buffer your data so an event delay does not cause such a problem. This is the best solution if it is possible.
Raise the priority of your thread and use QueryPerformanceCounter. This will prevent lower priority threads running if your thread is ready to go. Of course this also leads to system performance degradation.
Game programmers must regularly deal with timing issues, so you may get a better answer by posting on the gaming forum.
-
well i've got it set up so the timeSetEvent is supposed to be called every 10 ms. but when it is called it uses timeGetTime or GetTickCount to figure out how much time has really passed...
I think the theory's ok it's just all those function are a bit crap....
i'll try the high res one when i get round to it...
-
-
thanks for the link. i didnt know about timer queues so ill give that a go too. The combination of timeSetEvent and QueryPerformanceCounter seems to be working ok,though its still sometimes going a bit weird. I dont think this can be helped at all really but i'll see if timer queues makes it any better.
thanks again.