Audio synchronization in Flash has always been something of a black art. It’s a lot better these days, but there are still some interesting glitches floating around.
I’ve currently got a doozy of an issue in a project that I thought I was done with over a month ago 🙂
There are two and a half ways to manipulate sound in Flash.
- You can just drop audio tracks onto the timeline and hope for the best.
- You can instantiate Sound objects in, attach the audio tracks, and play them.
- A hybrid method where sounds are loaded onto the timeline but are then manipulated with a Sound object.
In 90% of cases, my game uses the second method. In the other 10%, I used the third. I have a simple flag (stored at _global.audio) that is set to true if people want sound playing and false otherwise. Any of my sound handling code monitors changes in the flag and sets volume on the appropriate sound objects accordingly. Nothing too fancy.
However, we’ve found an interesting fringe case when trying to control timeline sounds via actionscript. To duplicate the problem:
- Take one stage with a 2 frame timeline and one movie clip.
- On the movie clip, load a sound onto the timeline.
- Put the clip onto frame 2 of the stage, leaving frame 1 empty.
- Put a stop() action on the second frame of the main timeline.
This works as intended – ie, the sound plays exctly once.
- Now, add some code to the movie clip’s timeline to control the volume:
var snd:Sound = new Sound(this);
snd.setVolume( 0 );
This also works as intended – ie, the sound does not play at all.
- Replace the stop() action on the main timeline with a gotoAndStop(1) call.
Now if you play the swf… the sound will happen… even though we’re explicitly telling it not to – and you’re jumping to a state where the movie clip containing the sound should not be loaded.
I suspect that what is happening is that when you leave the portion of the timeline where the Sound object exists, there is a bit of confusion in the VM. In stead of discarding the movie clip in its entirety as makes sense, it’s discarding the sound object first. The timeline then continues playing the audio where it left off (after being muted for only one frame).
So… if you want reliable control over your audio assets, the solution might then be to put your Sound object responsible for playing them in a location where it won’t be destroyed when the timeline updates. Unfortunately, that doesn’t seem to work either. I’ve tried locating my Sound object in _global or _root, but that doesn’t solve the problem either.
What appears to happen is that sounds on the timeline are attached to the stage when their individual timelines disappear. Telling my Sound object to listen to the stage in stead of to the movie clip works.
I’m investigating this more… maybe… but shrug. More likely, I will simply find a way to stop using sounds on the timeline at all in this one problem spot in the game. 😛