From 27a604bd5657f53412fa1d7e95e557cad591bc8f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 9 Nov 2003 20:11:30 +0000 Subject: [PATCH] (Courtesy of Jerome Zago on the SDL mailing list...) +++++ Synopsis: Mix_FadeInMusic(Music, 0, chunksize) following Mix_VolumeMusic(0) doesn't take into account the latter for low values of "chunksize" when "Music" is a mod. +++++ How to reproduce the problem: ##### $ cat testmusic.c #include #include #include int main (int argc, char **argv) { if (argc != 4) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } if (SDL_Init(SDL_INIT_AUDIO) >= 0) { if (Mix_OpenAudio(44100, AUDIO_S16, 1, atoi(argv[2])) >= 0) { Mix_Music* Music = Mix_LoadMUS(argv[1]); if (Music) { Mix_VolumeMusic(0); Mix_FadeInMusic(Music, 0, atoi(argv[3])); printf("Now playing\n"); SDL_Delay(2000); Mix_FreeMusic(Music); } } } SDL_Quit(); return 0; }; $ cc -g -O2 -Wall -I/usr/include/SDL -D_REENTRANT -L/usr/lib -lSDL \ -lpthread -lSDL_mixer testmusic.c -o testmusic $ ./testmusic /usr/local/share/heroes/mod/heroes01.xm 512 10 Now playing [ I hear the music => BAD ] $ ./testmusic /usr/local/share/heroes/mod/heroes01.xm 512 11 Now playing [ I don't hear the music => GOOD ] $ ./testmusic /usr/local/share/heroes/mod/heroes01.xm 1024 22 Now playing [ I hear the music => BAD ] $ ./testmusic /usr/local/share/heroes/mod/heroes01.xm 1024 23 Now playing [ I don't hear the music => GOOD ] $ ./testmusic /usr/local/share/heroes/mod/heroes01.xm 2048 45 Now playing [ I hear the music => BAD ] $ ./testmusic /usr/local/share/heroes/mod/heroes01.xm 2048 46 Now playing [ I don't hear the music => GOOD ] ##### +++++ Comments heroes01.xm comes from http://prdownloads.sourceforge.net/heroes/heroes-sound-tracks-1.0.tar.bz2. All the other modules I've tested show the same behaviour. +++++ Analysis (using SDL_mixer source code): It appears that the lowest value of chunksize for which the volume is taken into account is equal to ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq) [file music.c, function open_music()]. This also means that music->fade_steps [function Mix_FadeInMusicPos()] = 0 when and only when the volume isn't taken into account. In this case, note that music_internal_volume() is never called from music_mixer(), since (music_playing->fade_step++ < music_playing->fade_steps) is never verified. This might explain the bug. +++++ Testing environment: - Mandrake Linux 9.1 i386 - SDL_mixer 1.2.4 (Mandrake package), 1.2.5 or CVS (both built from scratch) - Athlon XP 1500+ - SB Live! More details upon request. Thanks for your time. -------- This is related to my previous message: [SDL] Strange behaviour of Mix_FadeInMusic (1.2.5) on mods http://www.libsdl.org/pipermail/sdl/2003-November/057749.html +++++ Analysis (continued): It appears that calling mikmod's Player_SetVolume() does nothing when called before Player_Start() since pf [global variable initialized in mplayer.c] is NULL then. This API seems a bit strange to me but well... --- music.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/music.c b/music.c index 0a202971..b77b010a 100644 --- a/music.c +++ b/music.c @@ -135,6 +135,7 @@ static int native_midi_ok; static int ms_per_step; /* Local low-level functions prototypes */ +static void music_internal_initialize_volume(void); static void music_internal_volume(int volume); static int music_internal_play(Mix_Music *music, double position); static int music_internal_position(double position); @@ -620,10 +621,8 @@ static int music_internal_play(Mix_Music *music, double position) music_playing = music; /* Set the initial volume */ - if ( music->fading == MIX_FADING_IN ) { - music_internal_volume(0); - } else { - music_internal_volume(music_volume); + if ( music->type != MUS_MOD ) { + music_internal_initialize_volume(); } /* Set up for playback */ @@ -641,6 +640,8 @@ static int music_internal_play(Mix_Music *music, double position) #ifdef MOD_MUSIC case MUS_MOD: Player_Start(music->data.module); + /* Player_SetVolume() does nothing before Player_Start() */ + music_internal_initialize_volume(); break; #endif #ifdef MID_MUSIC @@ -788,6 +789,16 @@ int Mix_SetMusicPosition(double position) return(retval); } +/* Set the music's initial volume */ +static void music_internal_initialize_volume(void) +{ + if ( music_playing->fading == MIX_FADING_IN ) { + music_internal_volume(0); + } else { + music_internal_volume(music_volume); + } +} + /* Set the music volume */ static void music_internal_volume(int volume) {