Author Topic: Properly Looping an MP3  (Read 7150 times)

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Properly Looping an MP3
« on: Tue, Jan 11, 2011 »
In Short:
1. Does anyone know how to encode MP3s without that silence in the beginning?
2. Does anyone know how to properly adapt FlxSound to play adjusted start/end points for sounds so they can be set to loop through only the audible part?

The Long Version:

MP3s inherently have silence inserted in the beginning (and a tiny bit at the end, it seeems?), so making a looping sound (like an engine, flowing water, an elevator, etc) can be a pain in the butt. I've searched around, and have not been able to find an MP3 encoder (right now I export MP3s using the LAME v3.98.3 codec for Audacity) that offers the option of creating an MP3 without adding the ID3 information (aka silence) at the beginning. Does anybody know of one?

How I currently deal with the problem is by playing two staggered instances of the (airplane engine, for example) sound, whose volume was manually ramped up and down using envelopes in Audacity so that, at any given moment, the cumulative volume of the two instances makes it seem like a single constant sound. It works okay, but probably wouldn't suffice if you needed more precision, like if you wanted to smoothly loop music.

I did try taking a single uniform volume sound and making it loop from the start of the actual noise to the end of the actual noise. In a test project with only that one sound, I hacked FlxSound to start playing all sounds at position 51 (for reference, my 3.996 second sound was coming up in Flixel as having a length of 4022), which translates to about .05 seconds. I also changed any lines of code that set _position = 0 to _position = 51.

Playing the sound, it seemed better, but you could still hear a hiccup of silence when it looped. Maybe I imagined the improvement, because the tiny amount of silence at the end (less than a millisecond) should have had very little effect, but the sound was obviously dropping and coming back with each loop.

Running some traces, I did prove that the variable _position was never dropping below 51. Trying to get the sound to stop and loop at a position earlier than the end was much harder, and running a trace on the playhead position during playback gave some interesting data: the playhead was never showing a position higher than 3835, which is well short of the end of the file, and well short of the point at which the noise drops to silence.

I don't know where to go with this next. Maybe it is what it is, and we'll have to live with it. But if anyone's come up with a good workaround, I'd be grateful to hear it!
« Last Edit: Tue, Jan 11, 2011 by Bonemonkey »

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Properly Looping an MP3
« Reply #1 on: Tue, Jan 11, 2011 »
The Flash IDE can create perfect seamless MP3 files. What I do is load my music files into an FLA, set-up the export parameters I need (bit rate, etc), give the sounds a linkage name, and then publish to an SWC file. This is linked into my Flixel project. Once that is done I can access the sounds just by using their linkage name (titleMusicMP3) for example, and FlxSound will loop them seamlessly, because Flash has pre-processed them when publishing.

This isn't a Flixel problem per-se, it's a flash player / mp3 one, and the IDE is the only 100% solution I know of to get around it.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Re: Properly Looping an MP3
« Reply #2 on: Tue, Jan 11, 2011 »
What's a FLA file?

j/k  ;)

That's good news, I'll take a look into using the IDE...thanks!

wonkytonk

  • Member
  • **
  • Posts: 73
  • Karma: +0/-0
  • don't panic
    • View Profile
Re: Properly Looping an MP3
« Reply #3 on: Tue, Jan 11, 2011 »
there's also an updated FlxSound class that does just what you want it to do in this thread:

http://flixel.org/forums/index.php?topic=2794.0

the last time i tried to download it the link was broken, but if it sounds like what you want i can PM you the text of the class, and you could just paste it.

hopefully this helps!

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Re: Properly Looping an MP3
« Reply #4 on: Wed, Jan 12, 2011 »
Hey wonkytonk,

That updated FlxSound sounds interesting. I'd like to check that out, but like you said, the link didn't work for me either. Can you PM that to me? Thanks!

I'm going to take a look at the SWC solution today as well, that seems like a solid way to solve the problem...

boogaga

  • Member
  • **
  • Posts: 33
  • Karma: +0/-0
    • View Profile
    • Fun Pixel Games
Re: Properly Looping an MP3
« Reply #5 on: Wed, Jan 12, 2011 »
Yeah, downloading does not work :( . Could you please send this class to me too?

wonkytonk

  • Member
  • **
  • Posts: 73
  • Karma: +0/-0
  • don't panic
    • View Profile
Re: Properly Looping an MP3
« Reply #6 on: Wed, Jan 12, 2011 »
Bonemonkey and boogaga, check your inboxes, the file has been sent!

Gold_Ninja

  • Member
  • **
  • Posts: 80
  • Karma: +0/-0
  • Yeah Yeah!! Wall Echo Saw - War  よろしくね♡
    • View Profile
Re: Properly Looping an MP3
« Reply #7 on: Wed, Jan 12, 2011 »
Me too!

Can you just upload it somewhere like flashgamedojo or send it to me and I'll host it.
- Gold_Ninja

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Re: Properly Looping an MP3
« Reply #8 on: Wed, Jan 12, 2011 »
photonstorm: I created an SWC per your instructions and brought it in to my AS3 project, but the sound still doesn't loop without a gap of silence(?). Do I have to edit out the silence in Flash somehow? I rarely use Flash itself so I don't even know how I would do that (right clicking on the sound file in the library just offers me external sound editors, which I assume will just resave the file with the silence again).

wonkytonk: thanks for the file! Going to check my inbox now...

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Re: Properly Looping an MP3
« Reply #9 on: Wed, Jan 12, 2011 »
Oh, photonstorm, I should've added that I'm using Flash CS4, right now, in case that's part of the reason my sound isn't looping right.

wonkytonk

  • Member
  • **
  • Posts: 73
  • Karma: +0/-0
  • don't panic
    • View Profile
Re: Properly Looping an MP3
« Reply #10 on: Wed, Jan 12, 2011 »
Me too!

Can you just upload it somewhere like flashgamedojo or send it to me and I'll host it.

i could host it too, it's just that it's someone else's work, and i didn't want to host it without permission, maybe i'll just PM Geti to say that the link is broken.
also, it's in your inbox!

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Re: Properly Looping an MP3
« Reply #11 on: Wed, Jan 12, 2011 »
Hey, just tried the modified FlxSound - it seems to work pretty good! A couple of notes for other amateurs like myself:

1. To use FlxG.play you'll have to add a "totalSamples:int = 0" parameter to that function (though I have some additional thoughts on doing so below in #4). Also, you'll need to add "totalSamples" to the FlxSound loadEmbedded function call below. It all looks like this:

Code: [Select]
static public function play(EmbeddedSound:Class,Volume:Number=1.0,Looped:Boolean=false, totalSamples:int = 0):FlxSound
{
var sl:uint = sounds.length;
for(var i:uint = 0; i < sl; i++)
if(!(sounds[i] as FlxSound).active)
break;
if(sounds[i] == null)
sounds[i] = new FlxSound();
var s:FlxSound = sounds[i];
s.loadEmbedded(EmbeddedSound,Looped,totalSamples);
s.volume = Volume;
s.play();
return s;
}

2. The "totalSamples" (integer) number that you need to use is the length of your sound file * the sample rate. For example, my sound was 3.970 seconds long and had a sample rate of 44.1kHz, so totalSamples was 3.97 * 44100 = 175077. It's worth noting that you may want to play around with shortening that - my sound actually cycles better if I set totalSamples to 174977 (100 samples less).

3. When I closed the debug window, I found that the executable was actually still running! Had to close it using the Task Manager. Turns out the program was hanging on a while-loop in FlxSound:

Code: [Select]
if(_looped)
{
while(_position >= _sound.length)
_position -= _sound.length;
}

I've seen this before when trying to incorporate byte-level changes to sounds. It seems to be safe to just comment that whole block out. As far as I can tell, all it does is lower the _position variable so that it effectively resets the number of times the sound has been played (sounds don't actually loop forever, they just loop for a maximum of 9999 times). If your sound is 2 second long, 9999 loops will take over 5 hours, and that's only while your sound is playing (so it doesn't count if the player pauses and walks away for several hours). I think in most cases it shouldn't be a problem.

4. Since figuring out the samples for every sound in game will be hassle, I don't see why you couldn't duplicate the FlxG.play function with a different name (say, "playSeamlessLoop"), add the extra parameter in, and only use that for those relatively few times you have a sound that should loop seamlessly.

If anybody has additional thoughts (or disagrees!), please let me know.

photonstorm

  • Administrator
  • Key Contributor
  • *****
  • Posts: 1502
  • Karma: +1/-0
    • View Profile
    • Photon Storm
Re: Properly Looping an MP3
« Reply #12 on: Wed, Jan 12, 2011 »
Oh, photonstorm, I should've added that I'm using Flash CS4, right now, in case that's part of the reason my sound isn't looping right.

CS4 should be fine. Can you email me the sound? (rdavey@gmail.com) so I can have a look to see if there actually is silence at the start or end of it. CS4 will make it seamless, I guarantee, but if there actually is silence in the waveform it can't do anything about that.
http://www.photonstorm.com



"Tell me and I will forget, show me and I might remember, involve me and I will understand" - Confucius

wonkytonk

  • Member
  • **
  • Posts: 73
  • Karma: +0/-0
  • don't panic
    • View Profile
Re: Properly Looping an MP3
« Reply #13 on: Wed, Jan 12, 2011 »
also, if you don't feel like mathing it out, most daws have a sample length indicator.
if you're using audacity you can just double click on the mp3 region and there's a box at the bottom that will tell you the selection's length in minutes and seconds, or as you'd need in this case, samples.
you can import multiple files at a time, so all you'll need to do is double click the audio regions and write down the sample lengths.
i had the best luck doing it this way, as other methods either left that annoying silence in, or cut off a section that i wanted to loop.
and, as Bonemonkey said, you can increase/decrease the total number of samples if it's not looping properly.

Backward pieS

  • Active Member
  • ***
  • Posts: 110
  • Karma: +0/-0
    • View Profile
    • Backward pieS, LLC
Re: Properly Looping an MP3
« Reply #14 on: Wed, Jan 12, 2011 »
Oh! photonstorm, as soon as I read your post I realized what was wrong: without thinking, I had brought my MP3 into Flash instead of the seamlessly looping WAV source file. Problem solved. duh :)

Between the two approaches, I think I prefer the SWC method because I like knowing the source sound itself is seamless. That said, I have some game sounds for which I also want to be able to dynamically control the pitch (see my other recent post), and I think there is promise in the modified version of FlxSound for doing that. The code is very similar to the dynamic pitch code I already have working (but on a Sound object, not a Flixel-managed FlxSound).

I'll be sure to post my progress with that...
« Last Edit: Wed, Jan 12, 2011 by Bonemonkey »

arcanetbc

  • Member
  • **
  • Posts: 15
  • Karma: +0/-0
    • View Profile
Re: Properly Looping an MP3
« Reply #15 on: Wed, Jan 12, 2011 »
This worked for me earlier. It's not perfect, but it does make for better loops.:

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

Put the MP3Loop utility in the same directory as LAME, and add your WAV file.

Here's a link to a precompiled command line version of LAME:

http://www.rarewares.org/mp3-lame-bundle.php
« Last Edit: Wed, Jan 12, 2011 by arcanetbc »

wonkytonk

  • Member
  • **
  • Posts: 73
  • Karma: +0/-0
  • don't panic
    • View Profile
Re: Properly Looping an MP3
« Reply #16 on: Thu, Jan 13, 2011 »
okay, so there's a new link for Geti's modified FlxSound class, it's now available here

Koshmaar

  • Game Developer
  • Member
  • **
  • Posts: 15
  • Karma: +0/-0
    • View Profile
    • Koshmaar Games
Re: Properly Looping an MP3
« Reply #17 on: Sat, Oct 20, 2012 »
Hey, the wonkytonk link is also dead :(

Could anybody just paste the modified FxlSound here??

xyroclast

  • Contributor
  • ****
  • Posts: 389
  • Karma: +0/-0
    • View Profile
Re: Properly Looping an MP3
« Reply #18 on: Wed, Nov 7, 2012 »
The original link works, but *BEWARE*, it seems to clash with the current incarnation of Flixel (so, basically, it won't work without modification somewhere). I couldn't get it to compile and I didn't want to mess with it further.

http://www.1bardesign.com/src/flixel/FlxSound.as

Anyone brave enough to make it 2.55 compatible?


mightiest_hero

  • Member
  • **
  • Posts: 51
  • Karma: +0/-0
    • View Profile
Re: Properly Looping an MP3
« Reply #19 on: Wed, Nov 7, 2012 »
you can see original post in here http://forums.flixel.org/index.php?topic=2794.0