AS3 Sound Channel Bug
I don't know if this has been documented or not.
If you set a Sound to loop, it's channel.position property returns a number out of range of the Sound.length after it loops. The position property just keeps on incrementing beyond the length when you loop a sound.
If you try to play a Sound from that out of range position, the Sound glitches out, because that position is invalid, even though Flash returns it to you, implying it's valid. Flash should not return an invalid position to you.
This all revolves around the fact that Sound has absolutely no way to pause right now. I don't know why Adobe did not give us a channel.pause() method. Because they chose not to, this bug has bad consequences.
The only way to pause and unpause a sound in Flash is to store the current position of the channel and call channel.stop(), and when you unpause, you call sound.play(position). This works fine if you're only playing the sound once. If you're looping, however, it doesn't at all.
If the sound is looping, the position returned will eventually be higher than the length, which means the Sound glitches because you're passing an out of range position; a position, once again, that Flash returned to you as valid.
Wait, it gets worse. If you unpause a looping sound by passing its position, when it loops, it will loop from that position, not the beginning of the Sound. Problem!
There is no pause method for channel, and without a pause method, there is no workaround for the above bug and issue except to manually loop a Sound by adding an event listener to the sound complete event (which can be unreliable), calling play on it again and managing the looping manually, which undermines the loops argument of the Sound.play() method and requires a fair amount of code.
Adobe, we need a channel.pause(flag:Boolean) method.
Posted in Actionscript, Bugs, Flash, Rants

August 7th, 2008 at 6:40 am
currentPosition = position%length;
November 9th, 2008 at 11:11 pm
Does AS3 not have a modulus function? If so, position [mod] length would return the position you're looking for.
December 6th, 2008 at 5:48 pm
Please explain the modulus solution a little more? I can only get it to loop from the start not from where I paused it.
December 19th, 2008 at 9:34 am
Use it in good health!
pausePosition = channel.position%this.music.length;
February 4th, 2009 at 10:19 am
There is one "workaround"…
Do not use repating sound clip (set it to 1) and then add listener to SOUND_COMPLETE where you will play sound from position 0 again).
Below is a function that plays hides this and plays from a given position (so that you can play/pause). This function also preserves current soundTransgorm (i.w., volue and pan).
function playClip(snd:Sound, chn:SoundChannel, pos:Number):void {
chn = snd.play(pos, 1, (chn != null ? chn.soundTransform : null));
chn.addEventListener(Event.SOUND_COMPLETE, function(event:Event):void {playClip(0)});
}
I hope that this helps…
March 30th, 2009 at 11:12 pm
Nice idea Vladimir,
Thanks for your solution.
Unfortunately, I have found another AS3 Sound bug during use your solution. The the SOUND_COMPLETE event gose crazy after call over 4~500 times the snd.play() method. The SOUND_COMPLETE event raises too slow, it raise when flash want.
May 22nd, 2009 at 6:18 am
This is a bit of an oversight from Adobe.
So the upshot is you can't pause a looping sound without handcoding an onComplete handler with your own manual loop counter, making things much more complex than they need to be.
And if you want the loop to be seamless, forget it. Ouch.