01 October 2008

Flash Player Audio Sync and Frame Rates

So, it's the end of my hiatus since I last posted. I got married, changed job, house, car - actually pretty much all my life.

I'm back to creating Flash games, which is always enjoyable. I'm currently building a multiplayer world and various games attached to it. At the moment I'm building a Dance Dance Revolution type game which initially sounds simple, and it would be, but for the fact the Flash Player frame rate is all over the place.

If you have a 24fps movie, each frame should fire every 41.166* ms - or they *should*. In reality the frame rate can vary +- 20ms, which means after a short while the animation drifts away from the audio quite considerably. This problem is caused by a number of factors, mainly CPU speed/load and platform. It's bad on PC but terrible on an Mac.

So the problem is how do you get your beat hits to be absolutely precise to the music? I've managed to solve this problem by creating a "deltaTime" variable which calculates the drift per frame. If you know how many milliseconds it should be and how much drift you have, you can convert that to pixels to move, based on frame rate.

The net effect is a bit weird. The beat hits are spot on with the music, but this comes at a price because as the instructions scroll down the screen, the distance the instruction icons move is different each frame. This results in a jerky scrolling motion.

I'm hoping FP10 has more accurate frame rates that would solve this problem.


Nick said...

Hi, I am doing a flash based dancing game.

However, I do not really know where to start. I've got the basics knowledge of Flash.

I have found a flash dance file. But, when I put the AS into the file and tried to play it, it ends up showing -
" A script in this movie is causing Flash Player to run slowly. If it continues to run, your computer may become unresponsive. Do you wish to abort the script?. "

Is it possible for you to show me the way to start? I need to start getting the arrow keys hit using buttons when they hit the area.

Dan Lavender said...

Hi Nick,

Basically you need to check the following things:

* the bmp (beats per minute of the track)
* the distance your "dance instruction" icon e.g. arrow has to travel before it reaches its "hit" point.
* the frame rate of your movie
* elapsed time / current position of the music

From that you should be able to work out the number of pixels to move the dance instruction icon per frame.

The problem is that frame rates and getTimer() are not accurate, especially on a Mac. You'll need to create a function that works out the "deltaTime" i.e. the time variance between each frame and then add/subtract from the actual time.

I found that using the SoundChannel.position was a more accurate source of time than anything else.

I'd love to post you the source, but it'd be against my employers NDA if I did. Once the game is live I should be able to post something.

trist said...

"I found that using the SoundChannel.position was a more accurate source of time than anything else."

Reminds me of an audio project I was doing some time ago I used a silent audio track to maintain a constant timer. Each time the audio finished would fire an event to sync everything up. It was far more accurate than frames or timers.