NiTroGen Posted September 10, 2007 Share Posted September 10, 2007 I am working on a very accurate timer with accuracy upto ms. However, it still gives around 4 ms error on my Athlon 2100+ (idle). I have set it with High priority and tried writing using AdLibEnable()/AdLibDisable()., but no help. Here is a simple test ProcessSetPriority(@AutoItExe,4) $StartTime = TimerInit() $delay=416 $soundFreq=500 while 1 $TimeDifference = $delay - TimerDiff($StartTime) If $TimeDifference < 0 Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : TimerDiff($startTime) = ' & TimerDiff($StartTime) & @CRLF);### Debug Console $StartTime = TimerInit() Beep($soundFreq, 100) EndIf WEnd Here is the result @@ Debug(8) : TimerDiff($startTime) = 420.433881959858 @@ Debug(8) : TimerDiff($startTime) = 417.418973640505 @@ Debug(8) : TimerDiff($startTime) = 416.124675063451 @@ Debug(8) : TimerDiff($startTime) = 416.191163960783 @@ Debug(8) : TimerDiff($startTime) = 416.032205210439 @@ Debug(8) : TimerDiff($startTime) = 416.692065611691 @@ Debug(8) : TimerDiff($startTime) = 416.751011650922 @@ Debug(8) : TimerDiff($startTime) = 416.032205210439 @@ Debug(8) : TimerDiff($startTime) = 422.75261241303 Anyone can give me some new idea? Link to comment Share on other sites More sharing options...
cppman Posted September 10, 2007 Share Posted September 10, 2007 For high-resolution Windows timers that have up to the nanosecond accuracy you can use the following functions(you need to do a DLL-call):QueryPerformanceFrequencyQueryPerformanceCounterand here are the corresponding MSDN links:http://msdn2.microsoft.com/en-us/library/ms644905.aspxhttp://msdn2.microsoft.com/en-us/library/ms644904.aspx Miva OS Project Link to comment Share on other sites More sharing options...
Toady Posted September 10, 2007 Share Posted September 10, 2007 For high-resolution Windows timers that have up to the nanosecond accuracy you can use the following functions(you need to do a DLL-call):QueryPerformanceFrequencyQueryPerformanceCounterand here are the corresponding MSDN links:http://msdn2.microsoft.com/en-us/library/ms644905.aspxhttp://msdn2.microsoft.com/en-us/library/ms644904.aspxCorrect me if I'm wrong but aren't TimerInit() and TimerDiff() based off those two functions? www.itoady.com A* (A-star) Searching Algorithm - A.I. Artificial Intelligence bot path finding Link to comment Share on other sites More sharing options...
The Kandie Man Posted September 10, 2007 Share Posted September 10, 2007 Correct me if I'm wrong but aren't TimerInit() and TimerDiff() based off those two functions? It most cetainly does:expandcollapse popup/////////////////////////////////////////////////////////////////////////////// // TimerInit() // Returns a floating point value that is a baseline system time. // Starts tracking a high performance counter allowing for accurate timers. /////////////////////////////////////////////////////////////////////////////// AUT_RESULT AutoIt_Script::F_TimerInit(VectorVariant &vParams, Variant &vResult) { __int64 now; if (!QueryPerformanceCounter((LARGE_INTEGER *)&now)) return AUT_OK; vResult = (double)now; return AUT_OK; } // TimerInit() /////////////////////////////////////////////////////////////////////////////// // TimerDiff(Baseline) // Takes the time difference between now and Baseline and returns the result. /////////////////////////////////////////////////////////////////////////////// AUT_RESULT AutoIt_Script::F_TimerDiff(VectorVariant &vParams, Variant &vResult) { __int64 freq, now; if (!QueryPerformanceFrequency((LARGE_INTEGER *)&freq)) return AUT_OK; if (!QueryPerformanceCounter((LARGE_INTEGER *)&now)) return AUT_OK; vResult = (((double)now - vParams[0].fValue()) / (double)freq) * 1000.0; return AUT_OK; } // TimerDiff() @NiTroGen, the same code gave me:@@ Debug(8) : TimerDiff($startTime) = 416.024244212438 @@ Debug(8) : TimerDiff($startTime) = 416.024360417612 @@ Debug(8) : TimerDiff($startTime) = 416.024142078983 @@ Debug(8) : TimerDiff($startTime) = 416.024503858375 @@ Debug(8) : TimerDiff($startTime) = 416.026355424421 @@ Debug(8) : TimerDiff($startTime) = 416.031213345438 @@ Debug(8) : TimerDiff($startTime) = 416.022971402633 @@ Debug(8) : TimerDiff($startTime) = 416.023870177031 @@ Debug(8) : TimerDiff($startTime) = 416.026211075806 @@ Debug(8) : TimerDiff($startTime) = 416.023836586473 @@ Debug(8) : TimerDiff($startTime) = 416.027840671811 @@ Debug(8) : TimerDiff($startTime) = 416.02621561507 @@ Debug(8) : TimerDiff($startTime) = 416.026092600999 @@ Debug(8) : TimerDiff($startTime) = 416.022873354517 @@ Debug(8) : TimerDiff($startTime) = 416.02594098956 @@ Debug(8) : TimerDiff($startTime) = 416.025518837948 @@ Debug(8) : TimerDiff($startTime) = 416.025945528824 @@ Debug(8) : TimerDiff($startTime) = 416.027456650023 @@ Debug(8) : TimerDiff($startTime) = 416.023802541988 There are times when it can jump up to odd amounts though when i do it over a long period of time. I am curious as to why the counter needs to be so precise? Could you please explain in more detail what it is exactly that you are trying to do that requires such high precision and we will tell you if there are any alternatives to doing what you are doing that would require less precision. - The Kandie Man ;-) "So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire Link to comment Share on other sites More sharing options...
NiTroGen Posted September 11, 2007 Author Share Posted September 11, 2007 (edited) It most cetainly does:expandcollapse popup/////////////////////////////////////////////////////////////////////////////// // TimerInit() // Returns a floating point value that is a baseline system time. // Starts tracking a high performance counter allowing for accurate timers. /////////////////////////////////////////////////////////////////////////////// AUT_RESULT AutoIt_Script::F_TimerInit(VectorVariant &vParams, Variant &vResult) { __int64 now; if (!QueryPerformanceCounter((LARGE_INTEGER *)&now)) return AUT_OK; vResult = (double)now; return AUT_OK; } // TimerInit() /////////////////////////////////////////////////////////////////////////////// // TimerDiff(Baseline) // Takes the time difference between now and Baseline and returns the result. /////////////////////////////////////////////////////////////////////////////// AUT_RESULT AutoIt_Script::F_TimerDiff(VectorVariant &vParams, Variant &vResult) { __int64 freq, now; if (!QueryPerformanceFrequency((LARGE_INTEGER *)&freq)) return AUT_OK; if (!QueryPerformanceCounter((LARGE_INTEGER *)&now)) return AUT_OK; vResult = (((double)now - vParams[0].fValue()) / (double)freq) * 1000.0; return AUT_OK; } // TimerDiff() @NiTroGen, the same code gave me:@@ Debug(8) : TimerDiff($startTime) = 416.024244212438 @@ Debug(8) : TimerDiff($startTime) = 416.024360417612 @@ Debug(8) : TimerDiff($startTime) = 416.024142078983 @@ Debug(8) : TimerDiff($startTime) = 416.024503858375 @@ Debug(8) : TimerDiff($startTime) = 416.026355424421 @@ Debug(8) : TimerDiff($startTime) = 416.031213345438 @@ Debug(8) : TimerDiff($startTime) = 416.022971402633 @@ Debug(8) : TimerDiff($startTime) = 416.023870177031 @@ Debug(8) : TimerDiff($startTime) = 416.026211075806 @@ Debug(8) : TimerDiff($startTime) = 416.023836586473 @@ Debug(8) : TimerDiff($startTime) = 416.027840671811 @@ Debug(8) : TimerDiff($startTime) = 416.02621561507 @@ Debug(8) : TimerDiff($startTime) = 416.026092600999 @@ Debug(8) : TimerDiff($startTime) = 416.022873354517 @@ Debug(8) : TimerDiff($startTime) = 416.02594098956 @@ Debug(8) : TimerDiff($startTime) = 416.025518837948 @@ Debug(8) : TimerDiff($startTime) = 416.025945528824 @@ Debug(8) : TimerDiff($startTime) = 416.027456650023 @@ Debug(8) : TimerDiff($startTime) = 416.023802541988 There are times when it can jump up to odd amounts though when i do it over a long period of time. I am curious as to why the counter needs to be so precise? Could you please explain in more detail what it is exactly that you are trying to do that requires such high precision and we will tell you if there are any alternatives to doing what you are doing that would require less precision. - The Kandie Man ;-)Wooo! Very accurate timing! Maybe my computer is too crappy. Or my cheap motherboard gives me bad timing? Actually, I need a little program to give a beep/play a wav files under a fixed time interval. 416ms is the shortest interval required. I have attached the whole program for your reference. Please let me know your result when playing a wave files. **OOpps, line 103 should be "If @error Then" Edited September 11, 2007 by NiTroGen Link to comment Share on other sites More sharing options...
cppman Posted September 11, 2007 Share Posted September 11, 2007 Correct me if I'm wrong but aren't TimerInit() and TimerDiff() based off those two functions?Oh, intesting.I had no idea. Miva OS Project Link to comment Share on other sites More sharing options...
The Kandie Man Posted September 11, 2007 Share Posted September 11, 2007 After looking at your script, I couldn't find any practical solutions for increasing the accuracy. I changed the adlib function around, did tests to find the fastest loop type, but when it came down to it there simply wasn't a good solution. The accuracy usually varies only slightly and only maybe by about 10ms. 10ms is 1/100th of a second and to a human is indistinguishable. Any further precision would require help from external libraries and would not be practical for application such as this. Also, I found your original post to have the most accurate timing, but this is also probably because it was a simple script with no GUI handling or anything like that.Sorry I couldn't find a better practical way of doing this in AutoIt.- The Kandie Man ;-) "So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire Link to comment Share on other sites More sharing options...
NiTroGen Posted September 11, 2007 Author Share Posted September 11, 2007 After looking at your script, I couldn't find any practical solutions for increasing the accuracy. I changed the adlib function around, did tests to find the fastest loop type, but when it came down to it there simply wasn't a good solution. The accuracy usually varies only slightly and only maybe by about 10ms. 10ms is 1/100th of a second and to a human is indistinguishable. Any further precision would require help from external libraries and would not be practical for application such as this. Also, I found your original post to have the most accurate timing, but this is also probably because it was a simple script with no GUI handling or anything like that.Sorry I couldn't find a better practical way of doing this in AutoIt.- The Kandie Man ;-)Hey KM, you have proved that my computer is not that crap! Thanks Would you post your console output as well? (Both using Beep and SoundPlay) Link to comment Share on other sites More sharing options...
The Kandie Man Posted September 11, 2007 Share Posted September 11, 2007 Hey KM, you have proved that my computer is not that crap! Thanks Would you post your console output as well? (Both using Beep and SoundPlay)Sure. Using your unmodified code provided in the zip file the output is as follows:Using Beep:CODE@@ Debug(135) : $delay = 416 422.383655469814 425.707515660463 422.795295960054 416.260572855197 424.412053109396 422.781886064458 423.767980027236 423.131923286428 425.363879709487 422.792737630504 423.771467998184 423.754028597367 423.768354516568 424.720556513845 423.306102133454 422.251554244212 422.780177031321 422.795754425783 417.893249659555 422.794171130277 415.932906491148 424.742760326827 422.773953245574 422.812894235134 423.130301407172 417.541291874716 422.782085792102 419.239088969587 424.378531093963 422.773027689514 418.881930549251 424.731210621879Using the .wav file:CODE@@ Debug(135) : $delay = 416 417.518198365865 424.730346799818 416.240759872901 423.474174307762 426.429482977758 424.017288697231 424.121273263731 420.464720835225 421.813876985928 417.899923740354 421.802278256922 421.023340898774 415.762064457558 421.796547889242 416.930138901498 420.849139809351 422.77808987744 415.940080344984 421.797333635951 416.924788470268 422.784982296868 429.483661824784 424.880694961416 421.800510213345 422.146773490695 421.471908306854 416.930139355424 423.751259192011 421.810121652292 424.296451656832 422.246960054471 418.899111211984 421.786801180209 417.166920108942 422.53982796187 420.830442124376 421.892652292329 424.663318202451As you can see there is variation, but the variation is usually never more than 10ms. As a result, the beep will never be more than 1/100th of a second off que.- The Kandie Man ;-) "So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire Link to comment Share on other sites More sharing options...
Toady Posted September 11, 2007 Share Posted September 11, 2007 If you want to manually adjust then heres something i found to help. expandcollapse popup;==================================================================== ; How to simulate the Timer functions in Autoit using DLL calls ;==================================================================== Global $starttime = _TimerInit() While 1 ToolTip(_TimerDiff($starttime)) WEnd ;==================================================================== ; Functions in Autoit ; TimerInit() ; TimerDiff() ; Functions in kernal32.dll ; _QueryPerformanceFrequency() ; _QueryPerformanceCounter() ;==================================================================== Func _TimerInit() Local $var = DllStructCreate("int64") DllCall("kernel32.dll", "int", "QueryPerformanceCounter", "ptr", DllStructGetPtr($var, 1)) Local $starttime = DllStructGetData($var, 1) $startvar = 0 Return $starttime EndFunc Func _TimerDiff($timer) Return 1000 * ( _QueryPerformanceCounter() - $timer ) / _QueryPerformanceFrequency() EndFunc Func _QueryPerformanceFrequency() Local $var = DllStructCreate("int64") DllCall("kernel32.dll", "int", "QueryPerformanceFrequency", "ptr", DllStructGetPtr($var, 1)) Local $returnval = DllStructGetData($var, 1) $var = 0 Return $returnval EndFunc Func _QueryPerformanceCounter() Local $var = DllStructCreate("int64") DllCall("kernel32.dll", "int", "QueryPerformanceCounter", "ptr", DllStructGetPtr($var, 1)) Local $returnval = DllStructGetData($var, 1) $var = 0 Return $returnval EndFunc www.itoady.com A* (A-star) Searching Algorithm - A.I. Artificial Intelligence bot path finding Link to comment Share on other sites More sharing options...
NiTroGen Posted September 13, 2007 Author Share Posted September 13, 2007 Thanks The Kandie Man If you want to manually adjust then heres something i found to help. expandcollapse popup;==================================================================== ; How to simulate the Timer functions in Autoit using DLL calls ;==================================================================== Global $starttime = _TimerInit() While 1 ToolTip(_TimerDiff($starttime)) WEnd ;==================================================================== ; Functions in Autoit ; TimerInit() ; TimerDiff() ; Functions in kernal32.dll ; _QueryPerformanceFrequency() ; _QueryPerformanceCounter() ;==================================================================== Func _TimerInit() Local $var = DllStructCreate("int64") DllCall("kernel32.dll", "int", "QueryPerformanceCounter", "ptr", DllStructGetPtr($var, 1)) Local $starttime = DllStructGetData($var, 1) $startvar = 0 Return $starttime EndFunc Func _TimerDiff($timer) Return 1000 * ( _QueryPerformanceCounter() - $timer ) / _QueryPerformanceFrequency() EndFunc Func _QueryPerformanceFrequency() Local $var = DllStructCreate("int64") DllCall("kernel32.dll", "int", "QueryPerformanceFrequency", "ptr", DllStructGetPtr($var, 1)) Local $returnval = DllStructGetData($var, 1) $var = 0 Return $returnval EndFunc Func _QueryPerformanceCounter() Local $var = DllStructCreate("int64") DllCall("kernel32.dll", "int", "QueryPerformanceCounter", "ptr", DllStructGetPtr($var, 1)) Local $returnval = DllStructGetData($var, 1) $var = 0 Return $returnval EndFunc @Toady Great code! I will try to mod it. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now