I have a game with a visible running timer, but can only achieve 2 digits of accuracy (#.##) beyond the decimal. Is this a limit of the framework, or is there a workaround? I am trying to achieve 4-6 digits of accuracy (#.######) on this timer.
A timer on iOS runs at the max frequency of 60Hz so thats why you only get 2 digit accuracy.
You could make a work around by taking the time and the start of your event and then take the time at the end of the event and calculate the difference. This time won't take into account things like frame rate drops, pausing and moving into the background though.
This is a limitation of the underlying system. iOS is not a realtime system and timers get scheduled on the so called run loop, which dispatches timers once they are due. However, for a timer to get dispatched accurate, the run loop has to run often enough and check the timer on every iteration. The run loop however runs also other stuff, for example the whole event mechanism, messages and networking are run on the run loop, so your timer aren't checked every few nanoseconds (also, the run loop ins't run consistently but gives some time back to the system as well)
Related
I am making an app that has a timer function; the smallest time period it times is seconds, so I don't really think I need to use date subtraction, as an Timer.scheduledTimer doesn't lose accuracy until it starts getting to intervals of about 0.1-0.2.
My question is: Should Timer.scheduledTimer be alright for this timer app, and are there any particular advantages/disadvantages of using either method (note I am showing multiple timers at once)?
Note: the reason I am asking this is because I have seen some people talk about date subtraction, but I think this is only needed for timing very accurately.
I'm coding an emulator in XNA. The emulator's accuracy depends greatly on real fps. The fps must be 60 per second. While Microsoft claims their update function on FIXED TIME SETUP, should be called exactly 60 times per second, in my emulator (or a blank XNA 4.0 refresh project), I've collected these values so far, using differect processors: AMD athlon 2x 6000 (the unsynced ones, that need an extra optimized update from AMD to run correctly) 60-61 tps. Intel i5 (2.8 i think) 55tps. On an old Lenovo laptop with a slow centrino 59-60tps (the desired one). Same goes for an old intel p4 hyperthreading; exactly 60 tps. On a DELL implementation (don't remember the cpu) it was 52-53 tps.
So what should I do. Timer's accuracy on seperate threads is horrible too. Besides, the update function will be called too in parallel (using almost 100% of the cpu).
Make a different profile for each cpu? (Assume that the tps, [times per second] counting is correct)
The Update method calls are not 100% fixed. On a PC they will try to be made 60 times per second, but that depends on the machine and the logic of your game.
You can check if the system is working slower than it should by checking the GameTime.IsRunningSlowly property on your game (link here).
Also, you can modify the ticks it makes every second, for example a phone project starts with 33 ticks per second configured, against the 60 of a normal Windows Game project.
It would be wise to check Shawn Hargreaves blog post about GameTime, it won't fix your problem but you will give you a better understanding of how the Update method works and maybe get an idea on how to fix the problem.
I quote part of his post here:
By default XNA runs in fixed timestep mode, with a TargetElapsedTime
of 60 frames per second. This provides a simple guarantee: •We will
call your Update method exactly 60 times per second •We will call your
Draw method whenever we feel like it
Digging into exactly what that means, you will realize there are
several possible scenarios depending on how long your Update and Draw
methods take to execute.
The simplest situation is that the total time you spend in Update +
Draw is exactly 1/60 of a second. In this case we will call Update,
then call Draw, then look at the clock and notice it is time for
another Update, then Draw, and so on. Simple!
What if your Update + Draw takes less than 1/60 of a second? Also
simple. Here we call Update, then call Draw, then look at the clock,
notice we have some time left over, so wait around twiddling our
thumbs until it is time to call Update again.
What if Update + Draw takes longer than 1/60 of a second? This is
where things get complicated. There are many reasons why this could
happen:
1.The computer might be slightly too slow to run the game at the desired speed.
2.Or the computer might be way too slow to run the game at the desired speed!
3.The computer might be basically fast enough, but this particular frame might have taken an unusually long time for some reason. Perhaps
there were too many explosions on screen, or the game had to load a
new texture, or there was a garbage collection.
4.You could have paused the program in the debugger.
We do the same thing in response to all four causes of slowness: •Set
GameTime.IsRunningSlowly to true. •Call Update extra times (without
calling Draw) until we catch up. •If things are getting ridiculous and
we are too far behind, we just give up.
If this doesn't help you, then posting some code showing what you think may be making the process slower would help.
I have created an iOS 5/iOS 6 app with a display that responds to changes in the musical pitch performed by the user. It uses the record function in the sample SpeakHere code but does not actually save a file because it is designed to respond in real time.
I would now like to extend this app to respond simultaneously to the pitch itself and the duration that the same pitch is sustained (for example, changing the color when the same pitch is held steadily for a minimum period of time). I have been reading about NSTimer and NSDate functions, which seem straightforward, as well as AudioTimeStamp functions, which are apparently C based and which I find very confusing. Based on other posts, it seems like NSTimer and NSDate checks might cause the display's real-time response to an actual musical performance to lag. How about dispatchAfter? Could I expect the block to execute at the scheduled time?
My question is, what approach is most likely to yield the desired result of allowing me to measure duration of a particular pitch in the AudioQueue and update my display continuously in real time? Do I need to be saving to a file for this to work?
I am self-taught and have only been programming for a few months, so no matter what I will have to do a lot of learning of APIs/C language features that are new to me. I'm hoping someone can point me in a fruitful direction. Thanks!
You're definitely getting into pretty advanced stuff here. Here are a few thoughts:
Your audio processing seems to be the most intensive operation. Because this processing needs to be continuous, you're probably going to have to do this processing in another thread. By processing, I mean examining the audio to determine pitch.
Once you've identified the pitch, you should store the time for which it began.
Then, in the main thread, setup an NSTimer that repeats continuously and in the NSTimer's fire method, subtract the pitch's start date from the current date to get the elapsed time, as an NSTimeInterval.
Send the NSTimeInterval to your display logic so that you can update the color on screen.
Some things to check out:
Beginner's tutorial on multi-threading and Grand Central Dispatch on iOS
NSTimer
Using NSTimers
Hope that helps you out!
Is there a way to work around the Limits of the Ttimer's inteval so it can be preciser? for example instead of only integers like 1000ms , to use 1000.5ms . And if no, which component can I use instead which will give me preciser interval
You are trying to keep track of time to a reasonable degree of accuracy. However, the standard system timer cannot be used for that purpose. All that the system timer guarantees is that it will fire no sooner than the interval which you specify. And you can get the message late if you are tardy in pumping your message queue. Quite simply, the system timer is not designed to be used as a stopwatch and to attempt to do so is inappropriate.
Instead you need to use the high resolution performance counter which you can get hold of by calling QueryPerformanceCounter.
If you are using Delphi 2010 or later then you can use Diagnostics.TStopwatch which provides a very convenient wrapper to the high performance timer.
You can still use a system timer to give your app a regular tick or pulse, but make sure that you keep track of time with the high resolution timer.
Having said all of that, I'm not sure that you will ever be able to achieve what you are hoping to do. If you want to keep reasonably accurate time then what I say above is true. Trying to maintain lock-step synchronisation with code running on another machine somewhere remote over the net sounds pretty much intractable to me.
1) The TTimer class is not accurate enough for your task, period! (then again, neither would the web-site timer be, either)
2) If you increase the timer resolution using the TimeBeginPeriod() API call, this will get you closer, but still nowhere near close enough
3) If you adjust the TTimer interval each time based on a constant start time (and synchronised with the PC clock), you can average a set number of milliseconds for each time event compared to the PC clock
4) I don't know if the TTimer class handles 3) correctly, but I have a TTimer equivalent that does
5) To account for PC clock drift you will need to synchronise the PC clock periodically with an NTP server
6) I have a system that keeps the PC clock on a good machine to with +/- 5 milliseconds of a reference time permanently (I adjust every minute) and a timer with a resolution of +/- 2 milliseconds as long as the machine is not overloaded (Windows is not a real-time OS)
7) It took me a long time to get to this point - is this what you really need, or are you asking the wrong question?
My app has a feature like the BlackBerry Stopwatch application:
A label displaying the time, updated every 100 milliseconds.
I've used a separate thread for a Timer which schedules a TimerTask to update the label.
Everything works fine, but I've noticed the the stopwatch in my app runs a little bit slower than the built-in BlackBerry stopwatch -- it loses 1 second per minute.
Sometimes the timer in my app halts for a while, about 300-500 milliseconds, for unknown reasons.
What could make the Timer in my app slower than the BlackBerry stopwatch?
Any suggestions to create a stopwatch which run as smoothly as the BlackBerry stopwatch?
You should use System.currentTimeMillis() to compute the time. The Timer does not guarantee when it will execute - the guarantee is that the specified time is the minimum delay until execution starts, but there is no maximum, as you've noticed. So use the Timer to schedule UI updates, but calculate the elapsed time using System.currentTimeMillis().
I guess you shouldn't rely on adding time periods.
So 60 times sleep for 1 second should not be treated as minute.
Instead sleep for a second and after waking up check the system time.