From: Gabriel <mystml@adinet.com.uy>
authorRyan C. Gordon <icculus@icculus.org>
Sat, 19 Nov 2005 18:43:48 +0000
changeset 28133730d0864d8
parent 280 1e6fd744d20c
child 282 2d902a2c815e
From: Gabriel <mystml@adinet.com.uy>
To: SDL Mailing List <sdl@libsdl.org>
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
music_ogg.c
music_ogg.h
     1.1 --- a/music.c	Sat Nov 19 18:37:45 2005 +0000
     1.2 +++ b/music.c	Sat Nov 19 18:43:48 2005 +0000
     1.3 @@ -167,6 +167,36 @@
     1.4  }
     1.5  
     1.6  
     1.7 +/* If music isn't playing, halt it if no looping is required, restart it */
     1.8 +/* otherwhise. NOP if the music is playing */
     1.9 +static int music_halt_or_loop (void)
    1.10 +{
    1.11 +	/* Restart music if it has to loop */
    1.12 +	
    1.13 +	if (!music_internal_playing()) 
    1.14 +	{
    1.15 +		/* Restart music if it has to loop at a high level */
    1.16 +		if (music_loops && --music_loops)
    1.17 +		{
    1.18 +			Mix_Fading current_fade = music_playing->fading;
    1.19 +			music_internal_play(music_playing, 0.0);
    1.20 +			music_playing->fading = current_fade;
    1.21 +		} 
    1.22 +		else 
    1.23 +		{
    1.24 +			music_internal_halt();
    1.25 +			if (music_finished_hook)
    1.26 +				music_finished_hook();
    1.27 +			
    1.28 +			return 0;
    1.29 +		}
    1.30 +	}
    1.31 +	
    1.32 +	return 1;
    1.33 +}
    1.34 +
    1.35 +
    1.36 +
    1.37  /* Mixing function */
    1.38  void music_mixer(void *udata, Uint8 *stream, int len)
    1.39  {
    1.40 @@ -195,21 +225,11 @@
    1.41  				music_playing->fading = MIX_NO_FADING;
    1.42  			}
    1.43  		}
    1.44 -		/* Restart music if it has to loop */
    1.45 -		if ( !music_internal_playing() ) {
    1.46 -			/* Restart music if it has to loop at a high level */
    1.47 -			if ( music_loops && --music_loops ) {
    1.48 -				Mix_Fading current_fade = music_playing->fading;
    1.49 -				music_internal_play(music_playing, 0.0);
    1.50 -				music_playing->fading = current_fade;
    1.51 -			} else {
    1.52 -				music_internal_halt();
    1.53 -				if ( music_finished_hook ) {
    1.54 -					music_finished_hook();
    1.55 -				}
    1.56 -				return;
    1.57 -			}
    1.58 -		}
    1.59 +		
    1.60 +		if (music_halt_or_loop() == 0)
    1.61 +			return;
    1.62 +		
    1.63 +		
    1.64  		switch (music_playing->type) {
    1.65  #ifdef CMD_MUSIC
    1.66  			case MUS_CMD:
    1.67 @@ -309,7 +329,11 @@
    1.68  #endif
    1.69  #ifdef OGG_MUSIC
    1.70  			case MUS_OGG:
    1.71 -				OGG_playAudio(music_playing->data.ogg, stream, len);
    1.72 +				
    1.73 +				len = OGG_playAudio(music_playing->data.ogg, stream, len);
    1.74 +				if (len > 0 && music_halt_or_loop())
    1.75 +					OGG_playAudio(music_playing->data.ogg, stream, len);
    1.76 +			
    1.77  				break;
    1.78  #endif
    1.79  #ifdef MP3_MUSIC
     2.1 --- a/music_ogg.c	Sat Nov 19 18:37:45 2005 +0000
     2.2 +++ b/music_ogg.c	Sat Nov 19 18:43:48 2005 +0000
     2.3 @@ -192,7 +192,7 @@
     2.4  }
     2.5  
     2.6  /* Play some of a stream previously started with OGG_play() */
     2.7 -void OGG_playAudio(OGG_music *music, Uint8 *snd, int len)
     2.8 +int OGG_playAudio(OGG_music *music, Uint8 *snd, int len)
     2.9  {
    2.10  	int mixable;
    2.11  
    2.12 @@ -215,6 +215,8 @@
    2.13  		len -= mixable;
    2.14  		snd += mixable;
    2.15  	}
    2.16 +	
    2.17 +	return len;
    2.18  }
    2.19  
    2.20  /* Stop playback of a stream previously started with OGG_play() */
     3.1 --- a/music_ogg.h	Sat Nov 19 18:37:45 2005 +0000
     3.2 +++ b/music_ogg.h	Sat Nov 19 18:43:48 2005 +0000
     3.3 @@ -59,7 +59,7 @@
     3.4  extern int OGG_playing(OGG_music *music);
     3.5  
     3.6  /* Play some of a stream previously started with OGG_play() */
     3.7 -extern void OGG_playAudio(OGG_music *music, Uint8 *stream, int len);
     3.8 +extern int OGG_playAudio(OGG_music *music, Uint8 *stream, int len);
     3.9  
    3.10  /* Stop playback of a stream previously started with OGG_play() */
    3.11  extern void OGG_stop(OGG_music *music);