7 Replies Latest reply on Dec 7, 2011 11:38 PM by Dimontez

    flash.utils.Timer is distressingly inaccurate

    ReubenH
      Hi,

      I am writing a music synthesizer program. For it to play fast pieces of music where notes are, say, 100ms to 200ms apart, accurate timing is essential. Yet the Flex Timer class has a relatively large error... on my XP laptop the timer events arrive 0 to 30ms late (and thats with GUI updates turned off!), which is sufficient to make playback sound very bad indeed.

      I am wondering if there is anything I can do about this? At the moment I think my best bet is have my timer events complete 50ms early (assuming 50ms is worst-case lateness) and busy-wait the last up-to-50ms bit of time before playing the next note. But that seems pretty hideous.

      Questions:

      #1. Is there anything I can do to reduce the delay, or at least make it more predictable?

      #2. Is there a "nice" way to busy-wait? AFAICS all I can do is spin until flash.utils.getTimer() >= desired_timer_time...

      #3. Maybe my whole design could be better. Is there a way to play two consecutive MP3s (on the same SoundChannel) with an accurate period of time between them that doesnt involve the Timer class?

      Many thanks!
        • 1. Re: flash.utils.Timer is distressingly inaccurate
          Level 7

          "ReubenH" <webforumsuser@macromedia.com> wrote in message
          news:ge4ab0$79v$1@forums.macromedia.com...
          > Hi,
          >
          > I am writing a music synthesizer program. For it to play fast pieces of
          > music
          > where notes are, say, 100ms to 200ms apart, accurate timing is essential.
          > Yet
          > the Flex Timer class has a relatively large error... on my XP laptop the
          > timer
          > events arrive 0 to 30ms late (and thats with GUI updates turned off!),
          > which is
          > sufficient to make playback sound very bad indeed.
          >
          > I am wondering if there is anything I can do about this? At the moment I
          > think
          > my best bet is have my timer events complete 50ms early (assuming 50ms is
          > worst-case lateness) and busy-wait the last up-to-50ms bit of time before
          > playing the next note. But that seems pretty hideous.
          >
          > Questions:
          >
          > #1. Is there anything I can do to reduce the delay, or at least make it
          > more
          > predictable?
          >
          > #2. Is there a "nice" way to busy-wait? AFAICS all I can do is spin until
          > flash.utils.getTimer() >= desired_timer_time...
          >
          > #3. Maybe my whole design could be better. Is there a way to play two
          > consecutive MP3s (on the same SoundChannel) with an accurate period of
          > time
          > between them that doesnt involve the Timer class?

          I think the timer logic may be in the enterFrameHandler function, so it is
          tied to when the playhead enters the next frame. I think your only solution
          is to go with a really high frame rate.


          • 2. Re: flash.utils.Timer is distressingly inaccurate
            ReubenH Level 1
            Thanks for the reply!

            enterFrameHandler... that sounds like something in Flash. I'm only really familiar with the Flex SDK... is there an ActionScript class you can point me at? How is the overall framerate for an .swf set? That might well be the key to getting accurate timing....
            • 3. Re: flash.utils.Timer is distressingly inaccurate
              Level 7

              "ReubenH" <webforumsuser@macromedia.com> wrote in message
              news:ge4i00$h7g$1@forums.macromedia.com...
              > Thanks for the reply!
              >
              > enterFrameHandler... that sounds like something in Flash. I'm only really
              > familiar with the Flex SDK... is there an ActionScript class you can point
              > me
              > at? How is the overall framerate for an .swf set? That might well be the
              > key to
              > getting accurate timing....

              I think this is a private method in most classes. But if you want to go
              crawling around in the UIComponent code, knock yourself out ;-).

              I'd have to look up how to change the frame rate, same as you, but I'm
              confident it is in the Help.


              • 4. Re: flash.utils.Timer is distressingly inaccurate
                ReubenH Level 1
                frameRate appears to be a writable property of flash.display.Stage (see http://livedocs.adobe.com/flex/2/langref/flash/display/Stage.html#frameRate). I look forward to experimenting with this property's effect on Timer behaviour later.

                Thanks for your reply.
                • 5. Re: flash.utils.Timer is distressingly inaccurate
                  ReubenH Level 1
                  Well whaddyaknow! The frame rate absolutely affects timer accuracy in a beautifully deterministic way...

                  I coded up an experimental app which used a timer set to 100ms and a slider to control the framerate. If the frameRate is 10 (frames per second) then the frame period is 100ms which matches the timer period exactly and there is no error at all, not a single millisecond.

                  But if the frame rate is 11, the frame period is 90.9ms, and the timer event arrives a constant 98ms late.

                  Further experimentation showed the timer event lateness is directly and reliably proportional to the frame period.

                  I suspect this an artefact of event dispatching... what I guess happens is the OS-level timer fires, an event gets added to an internal queue somewhere, but dispatching doesn't happen until the next frame.

                  All I need to do, in theory, is ensure the frame period modulo the timer period is zero and all should be fine...
                  • 6. Re: flash.utils.Timer is distressingly inaccurate
                    williamjgrand Level 1

                    Reuben, I'm finding the same issue -- did you find a way to achieve accuracy independent of frame rate?

                    • 7. Re: flash.utils.Timer is distressingly inaccurate
                      Dimontez

                      I think that the only reliable way to play generated sound is to use sampleData event of Sound object. See http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html# event:sampleData if you're not familiar with the topic.