From 39827e25b35a526459bb5294389c892b32acd3a3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 2 Oct 2009 14:16:12 +0000 Subject: [PATCH] Sam Lantinga - Fri Oct 2 07:15:35 PDT 2009 * Implemented seamless looping for music playback --- CHANGES | 2 ++ music.c | 22 ++++++++++++---------- music_mad.c | 5 +++-- music_mad.h | 2 +- wavestream.c | 11 ++++++++--- wavestream.h | 2 +- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index e11a4c8c..865c2c44 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ 1.2.9: +Sam Lantinga - Fri Oct 2 07:15:35 PDT 2009 + * Implemented seamless looping for music playback Forrest Voight - 2009-06-13 20:31:38 PDT * ID3 files are now recognized as MP3 format Austen Dicken - Tue Feb 26 23:28:27 PST 2008 diff --git a/music.c b/music.c index 2a37f605..34a4f959 100644 --- a/music.c +++ b/music.c @@ -242,6 +242,8 @@ static int music_halt_or_loop (void) /* Mixing function */ void music_mixer(void *udata, Uint8 *stream, int len) { + int left = 0; + if ( music_playing && music_active ) { /* Handle fading */ if ( music_playing->fading != MIX_NO_FADING ) { @@ -280,7 +282,7 @@ void music_mixer(void *udata, Uint8 *stream, int len) #endif #ifdef WAV_MUSIC case MUS_WAV: - WAVStream_PlaySome(stream, len); + left = WAVStream_PlaySome(stream, len); break; #endif #if defined(MOD_MUSIC) || defined(LIBMIKMOD_MUSIC) @@ -372,27 +374,22 @@ void music_mixer(void *udata, Uint8 *stream, int len) #ifdef OGG_MUSIC case MUS_OGG: - len = OGG_playAudio(music_playing->data.ogg, stream, len); - if (len > 0 && music_halt_or_loop()) - OGG_playAudio(music_playing->data.ogg, stream, len); - + left = OGG_playAudio(music_playing->data.ogg, stream, len); break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: - len = FLAC_playAudio(music_playing->data.flac, stream, len); - if (len > 0 && music_halt_or_loop()) - FLAC_playAudio(music_playing->data.flac, stream, len); + left = FLAC_playAudio(music_playing->data.flac, stream, len); break; #endif #ifdef MP3_MUSIC case MUS_MP3: - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len); + left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len)); break; #endif #ifdef MP3_MAD_MUSIC case MUS_MP3_MAD: - mad_getSamples(music_playing->data.mp3_mad, stream, len); + left = mad_getSamples(music_playing->data.mp3_mad, stream, len); break; #endif default: @@ -400,6 +397,11 @@ void music_mixer(void *udata, Uint8 *stream, int len) break; } } + + /* Handle seamless music looping */ + if (left > 0 && left < len && music_halt_or_loop()) { + music_mixer(udata, stream+(len-left), left); + } } /* Initialize the music players with a certain desired audio format */ diff --git a/music_mad.c b/music_mad.c index efd56d49..ff21e64b 100644 --- a/music_mad.c +++ b/music_mad.c @@ -233,7 +233,7 @@ decode_frame(mad_data *mp3_mad) { /*assert(mp3_mad->output_end <= MAD_OUTPUT_BUFFER_SIZE);*/ } -void +int mad_getSamples(mad_data *mp3_mad, Uint8 *stream, int len) { int bytes_remaining; int num_bytes; @@ -258,7 +258,7 @@ mad_getSamples(mad_data *mp3_mad, Uint8 *stream, int len) { end-of-file. Stop. */ memset(out, 0, bytes_remaining); mp3_mad->status &= ~MS_playing; - return; + return bytes_remaining; } } else { decode_frame(mp3_mad); @@ -289,6 +289,7 @@ mad_getSamples(mad_data *mp3_mad, Uint8 *stream, int len) { mp3_mad->output_begin += num_bytes; bytes_remaining -= num_bytes; } + return 0; } void diff --git a/music_mad.h b/music_mad.h index 133e8411..6abb0338 100644 --- a/music_mad.h +++ b/music_mad.h @@ -67,7 +67,7 @@ void mad_start(mad_data *mp3_mad); void mad_stop(mad_data *mp3_mad); int mad_isPlaying(mad_data *mp3_mad); -void mad_getSamples(mad_data *mp3_mad, Uint8 *stream, int len); +int mad_getSamples(mad_data *mp3_mad, Uint8 *stream, int len); void mad_seek(mad_data *mp3_mad, double position); void mad_setVolume(mad_data *mp3_mad, int volume); diff --git a/wavestream.c b/wavestream.c index 9c9fa023..13ffe7ba 100644 --- a/wavestream.c +++ b/wavestream.c @@ -174,9 +174,10 @@ void WAVStream_Start(WAVStream *wave) } /* Play some of a stream previously started with WAVStream_Start() */ -void WAVStream_PlaySome(Uint8 *stream, int len) +int WAVStream_PlaySome(Uint8 *stream, int len) { long pos; + int left = 0; if ( music && ((pos=SDL_RWtell(music->rw)) < music->stop) ) { if ( music->cvt.needed ) { @@ -196,7 +197,9 @@ void WAVStream_PlaySome(Uint8 *stream, int len) music->cvt.len = original_len; } if ( (music->stop - pos) < original_len ) { - original_len = (music->stop - pos); + left = (original_len - (music->stop - pos)); + original_len -= left; + left = (int)((double)left*music->cvt.len_ratio); } original_len = SDL_RWread(music->rw, music->cvt.buf,1,original_len); /* At least at the time of writing, SDL_ConvertAudio() @@ -214,7 +217,8 @@ void WAVStream_PlaySome(Uint8 *stream, int len) } else { Uint8 *data; if ( (music->stop - pos) < len ) { - len = (music->stop - pos); + left = (len - (music->stop - pos)); + len -= left; } data = SDL_stack_alloc(Uint8, len); if (data) @@ -225,6 +229,7 @@ void WAVStream_PlaySome(Uint8 *stream, int len) } } } + return left; } /* Stop playback of a stream previously started with WAVStream_Start() */ diff --git a/wavestream.h b/wavestream.h index 004e1005..d5337e43 100644 --- a/wavestream.h +++ b/wavestream.h @@ -52,7 +52,7 @@ extern WAVStream *WAVStream_LoadSong_RW(SDL_RWops *rw, const char *magic); extern void WAVStream_Start(WAVStream *wave); /* Play some of a stream previously started with WAVStream_Start() */ -extern void WAVStream_PlaySome(Uint8 *stream, int len); +extern int WAVStream_PlaySome(Uint8 *stream, int len); /* Stop playback of a stream previously started with WAVStream_Start() */ extern void WAVStream_Stop(void);