View Full Version : Seamless MP3 or OGG looping in _anything_
Joseph Duchesne
2004.08.08, 01:39 PM
Hi, I've had a hard time over the past few days getting anything to load MP3s or OGGs and loop them seamlessly (without a break). Does anyone have any example code (C) that does this? I have tried SDL, Quicktime openAL and I can't get any to loop them, if even load them. can anyone help?
NSSound loads in one line of code :)
ThemsAllTook
2004.08.08, 01:51 PM
http://www.sacredsoftware.net/cgi-bin/download.cgi?fileID=watertowersource
Look in waterTowerMusic.c. I use QuickTime to load an MP3 and decompress it into RAM, and then I use the Sound Manager to play the decompressed sound.
Alex Diener
Joseph Duchesne
2004.08.08, 05:24 PM
[edit]
unfortunately this code isn't working with mine for one reason or another. It crashes my program every 2-3 runs and doesn't work otherwise.
Does anyone else have any suggestions?
aegidian
2004.08.08, 07:17 PM
NSSound loads in one line of code :)
NSSound is the business, BUT it doesn't loop seamlessly, nor does a QT movie.
I should think here's a clever hack to manage this, blending one sound channel with another or somehow, but I'm blowed if I can see an easy way to manage looping without some click or pause or using some other library like SDL (which might be a bit much just to use for sound if the rest of the project doesn't use it).
I'd like to find a way to do this too. Oolite could use some background loops, but ATM I can't see an easy way to manage it.
imported_kelvin
2004.08.08, 10:02 PM
In my experience QTmovies loop pretty seemlessly when the loop is callback triggered. For some easy Cocoa code on loading/playing sounds as movies, check out the CBMovie class in the CocoaBlitz source (http://variableaspect.com/experiments/CocoaBlitz/).
MattDiamond
2004.08.08, 10:20 PM
Kelvin's source code was very easy to use, I found, and I am in his debt for lending it to me last year on short notice! However, in my experience the music loops it produced weren't quite seamless. (Perhaps if my game was less of a CPU hog? Hmm, maybe I should disable the visuals, just to see...)
I had heard that QT was better at looping good old AIFF rather than MP3, but converting my sounds didn't seem to make a difference. So like everyone else, I'm still hunting for a solution. I suspect I'll have to abandon the simple QT/Cocoa approaches and see if a more raw, Core Audio/Carbon solution works better. If anyone has had luck with OpenAL or SDL sound, that would also be interesting to hear.
(A low-tech solution is to make the music hide the seam better by using loops that have breathing room between the notes at the end instead of a solid wall of sound.)
aegidian
2004.08.08, 10:25 PM
In my experience QTmovies loop pretty seemlessly when the loop is callback triggered. For some easy Cocoa code on loading/playing sounds as movies, check out the CBMovie class in the CocoaBlitz source (http://variableaspect.com/experiments/CocoaBlitz/).
I tried looping aiffs as QT movies both with and without callback triggers. Each method left a noticeable gap between the end of a sound and the start, and this was on a dual 1.8GHz G5 (so I don't think CPU power's an issue).
I think the only way I can get smooth background sounds may be to allow half-second fade-in/fade-outs at the start and end of each sample, and overlap them by a half-second.
FCCovett
2004.08.08, 11:01 PM
I've created an audio player with CoreAudio that works quite well - it does loop seamlessly without a hitch, but it just loads AIFF files and it doesn't work with M-Audio cards for now. I was working on decoding FLAC files as well, but it's still pending.
The Daisy.app example that comes with the CoreAudio SDK shows how to convert files to L-PCM 32 bit. That particular functionality doesn't seem to be hard to implement.
Now, there's a problem with looping MP3 files that's inherent to the format. MP3 files ALWAYS come with a blank (silence) at the beginning of the track. If you are planning on looping seamlessly, you'll need to skip that blank. I tried to to that before but it still didn't sound as good as importing an AIFF file. Converting from MP3 to AIFF won't solve the problem. You'd need to load the original track from another format and then convert it to AIFF.
The source code of my player can be downloaded from: http://webpages.charter.net/utopiaplanetia/BasicCarbonStruct.dmg
If you want to see the audio player working, just download Pharaoh's Gold from the web-site: http://pharaohsgold.danlabgames.com
MattDiamond
2004.08.09, 07:56 AM
I've created an audio player with CoreAudio that works quite well - it does loop seamlessly without a hitch, but it just loads AIFF files and it doesn't work with M-Audio cards for now. I was working on decoding FLAC files as well, but it's still pending.
Now, there's a problem with looping MP3 files that's inherent to the format. MP3 files ALWAYS come with a blank (silence) at the beginning of the track. If you are planning on looping seamlessly, you'll need to skip that blank. I tried to to that before but it still didn't sound as good as importing an AIFF file. Converting from MP3 to AIFF won't solve the problem. You'd need to load the original track from another format and then convert it to AIFF.
The source code of my player can be downloaded from: http://webpages.charter.net/utopiaplanetia/BasicCarbonStruct.dmg
If you want to see the audio player working, just download Pharaoh's Gold from the web-site: http://pharaohsgold.danlabgames.com
This is intriguing. When I tried AIFF I may have converted from MP3. I'll have to try that again, see if I can at least reduce the gap.
I didn't try your player last year because I was too short of time, but it sounds promising (no pun intended.) Thanks!
FCCovett
2004.08.09, 02:22 PM
That audio player is very easy to use. You just need to put all sound files in a folder, or organize them in separate folders. I am loading all the game sounds at the same time, but it's not hard to load specific sound for a level, and then unload them. Also, you can create as many playback channels as the computer can take, each with volume and pan, and call sounds by either name or ID#. ;)
If you need any help getting started, AIM or e-mail me.
imported_diordna
2004.08.10, 11:12 AM
In theory, you could get the time length of the movie, measure the break time between loops, load the movie in 2 places, and start the 2nd movie at movieLength-breakLength...
aegidian
2004.08.10, 11:43 AM
That's exactly the sort of trick I had to resort to:
// time delay method for playing afterburner sounds
// this overlaps two sounds each 2 seconds long, but with a .5s
// crossfade
NSSound* burnersound;
- (void) loopAfterburnerSound
{
SEL _loopAfterburnerSoundSelector = @selector(loopAfterburnerSound);
if (!afterburner_engaged) // end the loop cycle
{
afterburnerSoundLooping = NO;
return;
}
afterburnerSoundLooping = YES;
if (burnersound == afterburner1Sound)
burnersound = afterburner2Sound;
else
burnersound = afterburner1Sound;
// NSLog(@"DEBUG loopAfterburnerSound playing sound %@", burnersound);
[burnersound play];
[self performSelector:_loopAfterburnerSoundSelector
withObject:NULL
afterDelay:1.25]; // and swap sounds in 1.25s time
}
- (void) stopAfterburnerSound
{
[burnersound stop];
}
vBulletin® v3.6.7, Copyright ©2000-2008, Jelsoft Enterprises Ltd.