Playback MP3-Loop (gapless)

April 9th, 2010

This is one of the most frequently asked question in my inbox.

Is it possible to loop MP3 without gaps?
Yes, but to answer the question I like to explain, why gap-less MP3 looping was actually not possible before Flash10 (Except for Flash-IDE encoded MP3 or ugly hacks).

Encoding Audio
Every audio encoder works by subdivided the audio stream into frames. Each time-frame contains information about the current frequency bands in use. You can easily follow, why an algorithm needs at least a couple of amplitudes (called a window) to analyze the spectrum. A single amplitude does not have any information about frequencies. Imagine a snapshot of a speakers membrane. There is no way to say anything about its velocity, not even its sign.

MP3 loss-less
MP3 also encodes audio with a certain amount of samples each frame. The length of a frame however is not free to choose. That is why encoder add more data (encoder delay) to the audio stream then actually necessary to ensure minimal frame length (depending on algorithm). Unfortunately the engineers of MP3 back then forgot to add the information how much silence they added to the encoded file. To make it absolutely clear: This information is lost for all times. You may write algorithms to estimate the delay, but it is not possible to recover exactly.

Btw: FlashIDE encoded MP3 loop gap-less, cause the SWF contains the original amount.

Does Lame help?
Lame offers embedding this missing information in a hidden MP3 frame. But to get this information you have to load the MP3 as a flash.utils.ByteArray, parse all MP3 frame-headers (no decoding necessary) and do some calculations. But afterward you need to load it again into a flash.media.Sound object to make use of the extract method. So better store this information of each loop in your database or simply somewhere in the Actionscript.

Solution
Once you have access to the original amount of samples you can use the Flash10 Playback API to playback your loop and wrap it seamlessly on low-level. You only have to take the encoder delay into account. If you extract from the very beginning you read nothing else than zero amplitudes. Check out the magic-number provided in the source code. This number works perfectly with Lame encoded MP3. This number is not Magic of course. It simply combines the amount of samples LAME added in front of the MP3 - plus - the amount of samples the Flash decoder thinks it were added. You can actually loop waveforms now.

Example

Get Adobe Flash player

Track Void Panic | wav | mp3 | 124417 samples | Sourcecode

Still to complicated?
Vote for native Vorbis support!

Filed under: +

24 Responses to “Playback MP3-Loop (gapless)”

  1. Jeff Says:
    April 9th, 2010 at 8:22 pm

    I prefer to import wav’s in IDE fla’s, for the looping and also because if you start with good quality wav’s you can easily tune the audio compression (in bulk).

  2. phihochzwei Says:
    April 9th, 2010 at 10:36 pm

    About a year ago, I found a little command-line tool to convert wav and mp3 into seamless mp3. Worked fine for loading from outside the swf.

    So I am a little bit confused because you said that gapless looping only works since FP10

  3. Andre Michelle Says:
    April 9th, 2010 at 10:39 pm

    @phihochzwei Any chance to recall, what it was? Are you sure it exported MP3, not SWF?

  4. phihochzwei Says:
    April 9th, 2010 at 10:42 pm

    Sure, still got it at home. Will give it to you next week in cologne :)

  5. Andre Michelle Says:
    April 9th, 2010 at 10:44 pm

    @phihochzwei Alright. Sounds perfect ;)

  6. shawn Says:
    April 9th, 2010 at 10:59 pm

    I’ve been waiting for someone to go over this for a looooooong time. thank you so much!

  7. David Wilhelm Says:
    April 10th, 2010 at 5:26 am

    Thanks for sharing this. It is helpful for something I’m working on. So that explains the 0’s at the start of the mp3 data…funny that they put the gap at the start of the track, not the end.

  8. Bart Wttewaall Says:
    April 10th, 2010 at 12:27 pm

    Here’s a tool I used for looping mp3’s seamlessly in a track mixer project. It works great, and there’s no need for extracting the sound or anything, just load and play (repeatedly).

    http://www.compuphase.com/mp3/mp3loops.htm

  9. Andre Michelle Says:
    April 10th, 2010 at 12:34 pm

    @Bart:

    Can you show us your project? I am positive, that it won’t work as described in the article. A Flash timer won’t produce sample-exact results.

    However the mass of websites with badly looped MP3s show me, that it might not be a problem for everyone. No offense ;)

  10. mc Says:
    April 11th, 2010 at 12:18 pm

    Hi and thanks for sharing this !
    I am trying to apply it to my own loops but I don’t know how to find the samplesTotal information.
    You say you have to load an mp3 as a ByteArray, parse all MP3 frame-headers and do some calculations. Could you precise what those calculations are ? (or could you precise where this information is to be found in the lame encoded mp3 data ?)

  11. Weekly Digest for April 11th — Hello. My name is Václav Vančura. Says:
    April 11th, 2010 at 7:36 pm

    [...] Shared Playback MP3-Loop (gapless). [...]

  12. Tony Says:
    April 15th, 2010 at 9:02 pm

    Having trouble with this. If I let Flash handle wav to mp3 conversion on compile, then I’m left with no idea what the values should be for totalSamples and MAGIC_DELAY.

    Other than that, works like a charm! Almost!

  13. Tony Says:
    April 16th, 2010 at 2:39 am

    Ceased to have trouble with this! If Flash is handling wav to mp3 conversion for you, then the totalSamples will be 44100 * mp3.length / 1000. (44100 samples per second, and a sound length is measured in milliseconds).

    MAGIC_DELAY = 0!

  14. mc Says:
    April 16th, 2010 at 8:19 am

    Yes ! Groovy !
    Works wonderfully !

    Thank you Tony !

  15. Andre Michelle Says:
    April 16th, 2010 at 8:59 am

    @Tony

    Sorry to disappoint you, but you are totally wrong. You formula returns the number of samples of all MP3 frames, which is NOT the exact number of samples of the original audio. This information is still lost.

  16. Timewave Games Says:
    April 22nd, 2010 at 3:10 am

    [...] is pretty effective. There is one loop that is impossible for me to achieve though. I’ll try Andre Michelle’s trick on that one (the most important one, the ingame music. All the other files were not even loops. I [...]

  17. Weekly Digest for May 2nd — Hello. My name is Václav Vančura. Says:
    May 2nd, 2010 at 7:29 pm

    [...] Andre Michelle » Blog Archive » Playback MP3-Loop (gapless) [...]

  18. Kenny Says:
    May 19th, 2010 at 5:54 pm

    Hey Andre,

    Great write up. I have two questions:

    1. Is the MAGIC_DELAY supposed to work for all LAME encoded mp3s? Or does it require some understanding or trial and error to get the MAGIC_DELAY if you do not know how it was encoded?

    2. I tried this with different loops with different lengths, such as in the case of a mixer, the loops fall out of sync over time. Is this normal?

    Thanks,
    Kenny

  19. Matt Says:
    June 4th, 2010 at 4:45 pm

    Andre,

    I understand the logic, but Tony and mc appear to be correct! I figured this out a few months ago using the same formula as Tony and it works perfectly. When I run a trace statement on the result, and compare it to the total samples in my audio editor, it gives a figure accurate down to the sample! And it works with mp3s of different length too. Occasionally it might be off by a few samples (1-4), but I think this is due to internal rounding error in Flash than anything else! Any inaccuracies are so small they are virtually inaudible!

    I don`t know what to make of it, but it does work!

  20. swinburn Says:
    June 14th, 2010 at 3:30 pm

    im currently working on a project that takes an mp3 encrypted stream decrypts it and plays. The problem i face is that i break up the stream into 200kb chunks.The chunks play fine only problem is that when i jump from one to the next there a small delay of a 100msec which i cant solve. Any ideas would be appreciated
    thanks man

  21. mp3-pitch und loop - Flashforum Says:
    June 16th, 2010 at 3:11 pm

    [...] [...]

  22. Andre Michelle Says:
    June 23rd, 2010 at 4:56 pm

    @Matt
    “I understand the logic, but Tony and mc appear to be correct!”

    That doesn’t make sense at all ;)

  23. Aaron Says:
    July 20th, 2010 at 6:53 pm

    Hey Andre,

    Does lame need any special options to embed the hidden MP3 frame? I gave it a test and the mp3 that lame generated isn’t playing gapless for me, rather it tries to loop early.

    I didnt update samplesTotal yet, I’m not sure where to get that value.
    How do I find out samplesTotal for a given track?

    Here’s what I see with lame: http://pastebin.com/raw.php?i=fxYSAZKe

    Thanks for this solution and your time!

    -A

  24. yueveron Says:
    July 26th, 2010 at 9:02 am

    Hi Ahdre,
    Can i combine two mp3’s ByteArray in one mp3, i want to combine two mp3 as one.
    Thank you very much!

Leave a Reply