From 1a88d93bfc2d0d25cf1facda4001ae0e816620bd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 19 Nov 2005 18:43:48 +0000 Subject: [PATCH] From: Gabriel To: SDL Mailing List Date: Thu, 13 Oct 2005 15:00:22 -0300 Subject: [SDL] [PATCH] Correct OGG music looping Bug description : looping music when playing .ogg files left an audible gap in the mixer buffer. Bug fix : OGG_playAudio() now returns the actual read length. music_mixer restarts the music and calls OGG_playAudio() again if it didn't fill the buffer. Notes : Tested in Linux and works fine. Since there's no platform dependent code involved, it should work everywhere else. A similar fix for the rest of the music formats should be easy, but since I can't test it at the time, I opted not to do it. --Gabriel -- Gabriel Gambetta Mystery Studio - http://www.mysterystudio.com Gabriel on Graphics - http://gabrielongraphics.blogspot.com --- music.c | 56 ++++++++++++++++++++++++++++++++++++++--------------- music_ogg.c | 4 +++- music_ogg.h | 2 +- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/music.c b/music.c index 3136a215..c2731906 100644 --- a/music.c +++ b/music.c @@ -167,6 +167,36 @@ void Mix_HookMusicFinished(void (*music_finished)(void)) } +/* If music isn't playing, halt it if no looping is required, restart it */ +/* otherwhise. NOP if the music is playing */ +static int music_halt_or_loop (void) +{ + /* Restart music if it has to loop */ + + if (!music_internal_playing()) + { + /* Restart music if it has to loop at a high level */ + if (music_loops && --music_loops) + { + Mix_Fading current_fade = music_playing->fading; + music_internal_play(music_playing, 0.0); + music_playing->fading = current_fade; + } + else + { + music_internal_halt(); + if (music_finished_hook) + music_finished_hook(); + + return 0; + } + } + + return 1; +} + + + /* Mixing function */ void music_mixer(void *udata, Uint8 *stream, int len) { @@ -195,21 +225,11 @@ void music_mixer(void *udata, Uint8 *stream, int len) music_playing->fading = MIX_NO_FADING; } } - /* Restart music if it has to loop */ - if ( !music_internal_playing() ) { - /* Restart music if it has to loop at a high level */ - if ( music_loops && --music_loops ) { - Mix_Fading current_fade = music_playing->fading; - music_internal_play(music_playing, 0.0); - music_playing->fading = current_fade; - } else { - music_internal_halt(); - if ( music_finished_hook ) { - music_finished_hook(); - } - return; - } - } + + if (music_halt_or_loop() == 0) + return; + + switch (music_playing->type) { #ifdef CMD_MUSIC case MUS_CMD: @@ -309,7 +329,11 @@ void music_mixer(void *udata, Uint8 *stream, int len) #endif #ifdef OGG_MUSIC case MUS_OGG: - OGG_playAudio(music_playing->data.ogg, stream, len); + + len = OGG_playAudio(music_playing->data.ogg, stream, len); + if (len > 0 && music_halt_or_loop()) + OGG_playAudio(music_playing->data.ogg, stream, len); + break; #endif #ifdef MP3_MUSIC diff --git a/music_ogg.c b/music_ogg.c index 40610733..eeb3cb86 100644 --- a/music_ogg.c +++ b/music_ogg.c @@ -192,7 +192,7 @@ static void OGG_getsome(OGG_music *music) } /* Play some of a stream previously started with OGG_play() */ -void OGG_playAudio(OGG_music *music, Uint8 *snd, int len) +int OGG_playAudio(OGG_music *music, Uint8 *snd, int len) { int mixable; @@ -215,6 +215,8 @@ void OGG_playAudio(OGG_music *music, Uint8 *snd, int len) len -= mixable; snd += mixable; } + + return len; } /* Stop playback of a stream previously started with OGG_play() */ diff --git a/music_ogg.h b/music_ogg.h index 988bb08f..e34f5ca0 100644 --- a/music_ogg.h +++ b/music_ogg.h @@ -59,7 +59,7 @@ extern void OGG_play(OGG_music *music); extern int OGG_playing(OGG_music *music); /* Play some of a stream previously started with OGG_play() */ -extern void OGG_playAudio(OGG_music *music, Uint8 *stream, int len); +extern int OGG_playAudio(OGG_music *music, Uint8 *stream, int len); /* Stop playback of a stream previously started with OGG_play() */ extern void OGG_stop(OGG_music *music);