/dev/nikc/blog

Kuolleiden purjehduskenkien seura

Jun 10th 2009

Seamless mp3-playback in flash

20:52

I have the pleasure of working with flash. And when I say pleasure, I actually mean it. Except for on those special occasions, which are more frequent than I'd like them to be.

My latest task was to create a simple tracker. You've all seen one of them; drag the samples on to the timeline and press play on tape to hear your masterpiece. All good and dandy, sounds like a fun little project. My only worry was regarding playing back the samples one after another, as working with sounds in flash isn't quite as smooth as I'd like it to be.

Luckily, we've already (heh) migrated to Flash 9 and AS3, so I figured most of the pain I remembered from the days of AS2 would be gone by now. But how wrong was I...

Flash is not alone to take the blame though. As it turns out, mp3 encoders always create a short lead in and out when encoding. That's problem number 1.

Problem number 2 is that the Event.SOUND_COMPLETE-event flash so conveniently provides you with, isn't usable in this case, because playing sounds sequentially when the event triggers, results in a short but disastrous gap between sounds, making the event useless (in this case).

Problem number 3 is an interesting one. Let's say, that I have a 1.8 seconds long sound. When I load that sound into my flash movie, the Sound-object will say that the duration is 1800 milliseconds. However, when I play it back, the SoundChannel-object will trigger the soundComplete-event a bit before the Sound.position reaches that magical 1800 marker.

It seems, that the good folks at Macromedia Adobe have tried to create a mechanism that works around the automagically inserted lead in and out. The article linked to at the top notes that importing a wav-file into the library will result in gapless mp3-encoded sound, and it seems (just speculating here) that the SoundChannel-object is trying to mimic that behaviour, but failing to do so, or perhaps it's just the Sound-object that fails at accounting for the lead in and out when setting its own length.

Firstly, it does in no way account for the lead in. Secondly, the unconsistency between Sound.length and the point where the soundComplete-event triggers, makes the situation even worse when trying to programmatically work around the shortcomings of the mp3-format and the Sound API.

Lastly, I've found no pattern in the manner that the Sound.length relates to the point where the soundComplete-event triggers, so I can't calculate it. (Disclaimer: my tests have not been thorough, rigorous and scientific, so this is not to be taken as absolute truth -- it also most probably related to mp3-encoding and not the Sound API, but I'm mostly guessing.) The "solution" I came up with, was to play back the sound silently and record the position where the soundComplete-event triggers -- certainly not elegant, but it works.

For the overall problem of gapless playback, I used an existing "solution" (scroll down to part b) which is basically an event triggering every millisecond to stop and start sounds at the right moment. Quite resource wasteful and certainly not foolproof, but it solved circumvented the problem at hand.

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Meta

Pages

Search blog

Latest comments