Building an accurate Timekeeper in AS3: III

Posted on March 6, 02008
Filed Under Development, Flash, Harrison

Download
Download the source files

Using Timekeeper class

The example above shows the Timekeeper class in action. You'll notice that the temporal drift is always being corrected and generally stays accurate to within 0.1 seconds. I only need accuracy to within one second for my clock so this should be fine. The two more common techniques are shown below again for comparison.

Using movie frame rate

Using AS3 Timer class

The Timekeeper works by using a very fast internal regulator to update a much slower 'user clock'. Periodic accuracy (isochronism) is achieved by maintaining an accumulator based on the system clock. When the value of the accumulator becomes greater than the tick frequency then a user tick event is produced. Abstracting the timekeeping functions from the periodic mechanism allowed me to add some cool features to the Timekeeper class:

getValue():Number
setValue( ms:Number ):void

Get and set the value of time in milliseconds since the Unix epoch. Notice the datatype is Number rather than a Date. This is for reasons of speed, capacity and interoperability with other timekeeping systems. I'll cover this design decision in more detail in a future entry. Conversion to Date is really simple though. If the value of the Timekeeper is ms then you can turn it into a Date like so: var d = new Date(ms)

getTickDuration():Number
setTickDuration( ms:Number ):void
Tick duration is the value in milliseconds that that gets added to the value of the timekeeper every time there is a tick event. The default is one second (e.g. one second per second). Changing the tick duration to one day would run the timekeeper much faster than real time (e.g. one day per second). Changing the tick duration to a negative number will run the timekeeper backwards. Fractional values of a second will work but are not recommended.

getTickFrequency():int
setTickFrequency( ms:int ):void

Tick frequency is the length of time between ticks. The default is one second (e.g. one second per second). Changing the tick frequency to two seconds would run the timekeeper at half real time (e.g. one second per two seconds). The datatype for tick frequency is int rather than Number as all values must be positive and large durations between ticks are impractical.

stopTicking():void
startTicking():void
It is often handy to be able to stop or pause the timekeeper. Tick events are ignored when the Timekeeper is stopped.

setRealTimeValue():void
setRealTimeTick():void
Two functions added for convenience. setRealTimeValue() sets the value of the Timekeeper to "now". setRealTimeTick() sets the running speed to "real time", i.e. one second per second.

Share/Bookmark

Related Journal Entries

  1. Building an accurate Timekeeper in AS3
  2. Building an accurate Timekeeper in AS3: II
  3. The project architecture
  4. Project updates April 2009
  5. Measuring Time: Datatypes
  6. Projects update March 2009
  7. The Computus Engine on Google Code
  8. A review of Temporal Web Standards
  9. AS3 Component: TimeStepper
  10. Inside the Antikythera Mechanism
  11. Building an AS3 component framework: Deferred Rendering
  12. Building an AS3 component framework: Planning
  13. Inside the AS3 Date class: Properties and methods
  14. Creating a main preloader in Flash CS3
  15. Inspiration: The Geochron clock

Comments

Leave a Comment

If you would like to make a comment, please fill out the form below.

Name (required)

Email (required)

Website

Comments

18 Comments so far
  1. Tedbot July 30, 2008 5:27 pm

    Thanks so much for this– great work. You should mention that the accuracy of the Timekeeper is dependent on the frequency of the regulator, which defaults to 50ms. I haven’t tried changing the regulator but found out quickly that things get crazy when you try to keep time below it ;)

  2. John July 30, 2008 11:17 pm

    Hiya Todbot. You’re right about the regulator – that’s the tradeoff really. The class offers accuracy at the expense of granularity. Glad you found it useful though.

  3. makc November 10, 2008 3:51 pm

    Hey there, my own tests show that timer events cannot be generated more often than 10 times per frame; maybe the drift is a “round-off” error steaming from there. Any way, increasing SWF frame rate should improve timer accuracy, and allow corrections for intervals lower than 50 ms as well.

  4. John November 10, 2008 7:29 pm

    Hiya Makc, My guess is the drift is just a side effect of processing spikes. Flash doesn’t try and ‘catch up’ it just moves onto the next frame and does it’s best.

    My solution is a trade off. You lose resolution (only 10 ticks per second) but you know those ticks will be consistent and on time. It works great for what I need (i.e. real time) but wouldn’t be much use in say, a game engine where number of ticks per second is probably more useful.

  5. Arthur Mingard January 19, 2009 1:29 pm

    Just wanted to say thank you for this tutorial. I have been designing a drum sound sequencer for my final year production and was having a hard time using the timer function in flash. Now my timing is almost perfect although when multiple sounds play at once there can be a delay but that’s always going to be the case.

  6. John January 19, 2009 1:38 pm

    Hi Arthur, Glad you found it helpful. Would love to see a link to the sequencer when you’re done. :)

  7. Aneurin Barker Snook February 25, 2009 12:10 am

    Hi John,

    I’ve been collaborating with Arthur Mingard above on his project and as part of development I rewrote the Timekeeper class to better suit our requirements. As my interpretation is mostly based on yours it seems only polite to let you know about my developments!

    I’ve written about it at http://aneuri.net/1235517374 if you’d care to read up on my changes. It may lack some of the flexible features of your Timekeeper but I believe that in imitating a Timer class it may be a little more accessible to less confident developers.

  8. John February 25, 2009 10:58 am

    Hi Aneurin, glad the code was helpful.

    Appreciate the link-back – it’s always nice to see something you’ve written being used in projects you’ve never considered! Cheers, jd

  9. Futurefabric March 6, 2009 4:04 pm

    I’ve been planning to build some sort of clock in AS3 for a while and have come against the pitfall of Timer’s inaccuracy.

    Cheers for your work on this – a massive help and an excellent workaround to the problem.

  10. John March 6, 2009 5:49 pm

    Cheers Guy, nice to hear from you (I’m a long time Airside/Lemon Jelly fan :) )

    Glad the Timekeeper is working out for you – post me link if you build anything cool!

  11. Futurefabric March 9, 2009 11:13 pm

    Will be sure to let you know and link to you John if I create anything of note.

    Thanks again,
    Guy

  12. Alastair April 15, 2009 10:01 pm

    Good stuff. I built a generative sequencer in AS3 last year and has similar fun trying to build the core sequencer clock. Like Aneurin, I wanted a tracker-style system with Beats Per Minute, Beats Per Bar and Ticks Per Beat.

    I solved the timing drift issues in the end by avoiding the Timer and ENTER_FRAME solutions altogether.

    The Flash engine places pretty much all processing on a single thread using a timesharing system. Look up Ted Patrick’s “elastic racetrack” article for a clearer description of what I’m referring to.

    As makc pointed out, Timer events just get lumped into the first section of each frame processing segment so aren’t really any better or more granular than enter frame.

    However, the sound playback engine is managed on a separate thread. Consequently, SOUND_COMPLETE events can be a good way to keep time independently. Create a blank MP3 file and mathematically determine how much of it you need to play back to cover the duration of a tick, then just play back this section of the sound. You’ll get a pretty accurate SOUND_COMPLETE event at the end of the required time frame.

    This can then be built into a clock with similar internal regulation functions to those you mention.

    Happy to send you some code if you’d like an example of what I’m talking about.

  13. John April 15, 2009 11:33 pm

    Hiya Alistair, yeah I’d love to see some code. That sounds really cool! I’ve heard of the blank audio track technique being used in video to ensure steady streaming, but I hadn’t considered it as timekeeper before – great idea :)

  14. Bart May 7, 2009 9:32 pm

    I am trying to make a tape ticker, but the inaccurate Timer / EnterFrame give a flickering effect, not so nice.

    I like the idea of using the sound engine as time generator, have you tried it yet?

  15. John May 9, 2009 11:16 pm

    Hiya Bart. No not yet, but I did manage to catch up with Alastair on Friday for a pint or two. Lots to talk about :)

  16. Aneurin Barker Snook May 24, 2009 12:15 am

    Hi again,

    Just wanted to let you – and those clicking through, of whom it seems there are quite a few! – know that my AS3 Timekeeper thing has moved to a new address in an upgrade to WordPress from my previous bespoke blog.

    http://aneuri.net/2009/02/as3-timekeeper/

    Regards,
    Aneurin

  17. [...] is something I coded six months ago and need to rehost. This Timekeeper class, based on John Dalziel’s Timekeeper, imitates an ordinary Timer, giving you an accurate relative clock with a very regular, [...]

  18. Aneurin Barker Snook August 23, 2009 12:48 pm

    Hi again John,

    Migrated to a new server and name, my version of the AS3 Timekeeper is now at http://anny.fm/2009/08/as3-timekeeper/

    Sorry about comment spamming!