From 918976bdccabf59802570bcc802afbbffe54c81b Mon Sep 17 00:00:00 2001 From: mazmazz <mar.marcoz@outlook.com> Date: Sun, 19 Aug 2018 16:19:48 -0400 Subject: [PATCH] S_FadeMusic[FromLevel] and S_StopFadingMusic implementation --- src/i_sound.h | 6 ++++ src/s_sound.c | 10 ++++++ src/s_sound.h | 4 +++ src/sdl/mixer_sound.c | 81 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/src/i_sound.h b/src/i_sound.h index 4e6a253333..50b9653254 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -249,6 +249,12 @@ boolean I_SetSongTrack(INT32 track); void I_SetInternalMusicVolume(UINT8 volume); +void I_StopFadingMusic(void); + +boolean I_FadeMusicFromLevel(UINT8 target_volume, INT16 source_volume, UINT32 ms); + +#define I_FadeMusic(a, b) I_FadeMusicFromLevel(a, -1, b) + /** \brief The I_StartDigSong function \param musicname music lump name diff --git a/src/s_sound.c b/src/s_sound.c index 2d4de70b1c..d7321a6186 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1481,6 +1481,16 @@ void S_SetInternalMusicVolume(INT32 volume) I_SetInternalMusicVolume(min(max(volume, 0), 100)); } +void S_StopFadingMusic(void) +{ + I_StopFadingMusic(); +} + +boolean S_FadeMusicFromLevel(UINT8 target_volume, INT16 source_volume, UINT32 ms) +{ + return I_FadeMusicFromLevel(target_volume, source_volume, ms); +} + void S_SetDigMusicVolume(INT32 volume) { if (volume < 0 || volume > 31) diff --git a/src/s_sound.h b/src/s_sound.h index 19b616ab24..20a0f81e07 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -173,6 +173,10 @@ const char *S_MusicName(void); // Checks if music name exists boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi); +void S_StopFadingMusic(void); +boolean S_FadeMusicFromLevel(UINT8 target_volume, INT16 source_volume, UINT32 ms); +#define S_FadeMusic(a, b) S_FadeMusicFromLevel(a, -1, b) + // // Updates music & sounds // diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5de1831ce8..485ecec16f 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -72,6 +72,8 @@ static UINT32 music_bytes; static boolean is_looping; static boolean is_fading; static UINT8 fading_target; +static UINT32 fading_steps; +static INT16 fading_volume_step; static INT32 fading_id; #ifdef HAVE_LIBGME @@ -82,7 +84,8 @@ static INT32 current_track; static void varcleanup(void) { loop_point = music_length =\ - music_bytes = 0; + music_bytes = fading_target =\ + fading_steps = fading_volume_step = 0; songpaused = is_looping =\ is_fading = midimode = false; @@ -103,7 +106,7 @@ void I_StartupSound(void) // EE inits audio first so we're following along. if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO) - CONS_Printf("SDL Audio already started\n"); + CONS_Debug(DBG_BASIC, "SDL Audio already started\n"); else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); @@ -507,18 +510,28 @@ static void music_loop(void) static UINT32 music_fade(UINT32 interval, void *param) { - if (!is_fading || internal_volume == fading_target) + if (!is_fading || + internal_volume == fading_target || + fading_steps == 0 || + fading_volume_step == 0) + { + I_StopFadingMusic(); return 0; - else if (internal_volume > fading_target) // fading out + } + else if ( + (internal_volume > fading_target && internal_volume + fading_volume_step <= fading_target) || // finish fade out + (internal_volume < fading_target && internal_volume + fading_volume_step >= fading_target)) // finish fade in { - CONS_Printf("Fading out\n"); + internal_volume = fading_target; + Mix_VolumeMusic(get_real_volume(midimode ? midi_volume : music_volume)); + return 0; } - else //if (internval_volume < fading_target) // fading in + else { - CONS_Printf("Fading in\n"); + internal_volume += fading_volume_step; + Mix_VolumeMusic(get_real_volume(midimode ? midi_volume : music_volume)); + return interval; } - - return interval; } #ifdef HAVE_LIBGME @@ -1168,26 +1181,64 @@ void I_SetInternalMusicVolume(UINT8 volume) Mix_VolumeMusic(get_real_volume(midimode ? midi_volume : music_volume)); } -void I_StopFadingMusic() +void I_StopFadingMusic(void) { if (fading_id) SDL_RemoveTimer(fading_id); is_fading = false; - fading_target = fading_id = 0; + fading_target = fading_steps = fading_volume_step = fading_id = 0; } -void I_FadeMusic(UINT8 fading_target_in) +boolean I_FadeMusicFromLevel(UINT8 target_volume, INT16 source_volume, UINT32 ms) { + UINT32 target_steps, ms_per_step; + INT16 target_volume_step, volume_delta; + + source_volume = min(source_volume, 100); + volume_delta = (INT16)(target_volume - (source_volume < 0 ? internal_volume : source_volume)); + I_StopFadingMusic(); - if (!is_fading || fading_target != fading_target_in) + + if (!ms) + { + I_SetInternalMusicVolume(target_volume); + return true; + } + else if (!volume_delta) + return true; + + // Round MS to nearest 10 + // If n - lower > higher - n, then round up + ms = (ms - ((ms / 10) * 10) > (((ms / 10) * 10) + 10) - ms) ? + (((ms / 10) * 10) + 10) // higher + : ((ms / 10) * 10); // lower + + ms_per_step = max(10, ms / abs(volume_delta)); + // 10ms is the usual minimum timer granularity, but platform-dependent + target_steps = ms/ms_per_step; + target_volume_step = volume_delta / (INT16)target_steps; + + if (!target_steps || !target_volume_step) + I_SetInternalMusicVolume(target_volume); + else if (source_volume != target_volume) { - fading_id = SDL_AddTimer(1, music_fade, NULL); + fading_id = SDL_AddTimer(ms_per_step, music_fade, NULL); if (fading_id) { is_fading = true; - fading_target = fading_target_in; + fading_target = target_volume; + fading_steps = target_steps; + fading_volume_step = target_volume_step; + + if (source_volume >= 0 && internal_volume != source_volume) + I_SetInternalMusicVolume(source_volume); } } + + CONS_Printf("Target %d> Source %d> MS %d> Steps %d> MSPer %d> VolPer %d> Fading %d\n", + target_volume, internal_volume, ms, target_steps, ms_per_step, target_volume_step, is_fading); + + return is_fading; } // -- GitLab