diff --git a/src/audio/gain.cpp b/src/audio/gain.cpp index 8db17d4e8..9f907d961 100644 --- a/src/audio/gain.cpp +++ b/src/audio/gain.cpp @@ -36,7 +36,7 @@ size_t Gain::filter(tcb::span> input_buffer, tcb::span> b template void Gain::gain(float new_gain) { - new_gain_ = std::clamp(new_gain, 0.0f, 1.0f); + new_gain_ = std::max(new_gain, 0.f); } template diff --git a/src/i_sound.h b/src/i_sound.h index 7df4b5346..7bca60cc1 100644 --- a/src/i_sound.h +++ b/src/i_sound.h @@ -214,7 +214,8 @@ void I_PauseSong(void); */ void I_ResumeSong(void); -/** \brief The I_SetMusicVolume function +/** \brief Sets the volume of the Music mixing channel. Distinguished from the song's individual volume. The scale of + the volume is determined by the interface implementation. \param volume volume to set at @@ -222,6 +223,13 @@ void I_ResumeSong(void); */ void I_SetMusicVolume(int volume); +/** \brief Sets the current song's volume, independent of the overall music channel volume. The volume scale is 0-100, + * as a linear gain multiplier. This is distinguished from SetMusicVolume which may or may not be linear. +*/ +void I_SetCurrentSongVolume(int volume); + +// TODO refactor fades to control Song Volume exclusively in tandem with RR musicdef volume multiplier. + boolean I_SetSongTrack(INT32 track); /// ------------------------ diff --git a/src/s_sound.c b/src/s_sound.c index b45215c73..0a2ddb983 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1360,7 +1360,6 @@ static tic_t pause_starttic; musicdef_t *musicdefstart = NULL; struct cursongcredit cursongcredit; // Currently displayed song credit info -int musicdef_volume; // // S_FindMusicDef @@ -2249,14 +2248,12 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 music_flags = mflags; music_looping = looping; - musicdef_volume = DEFAULT_MUSICDEF_VOLUME; - { musicdef_t *def = S_FindMusicDef(music_name); if (def) { - musicdef_volume = def->volume; + I_SetCurrentSongVolume(def->volume); } } diff --git a/src/s_sound.h b/src/s_sound.h index 5e29e960f..5905458aa 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -38,7 +38,7 @@ extern openmpt_module *openmpt_mhandle; #define SOUND_VOLUME_RANGE 256 #define MAX_SOUND_VOLUME 255 -#define DEFAULT_MUSICDEF_VOLUME ( 100 / VOLUME_DIVIDER ) +#define DEFAULT_MUSICDEF_VOLUME 100 extern consvar_t stereoreverse; extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume; @@ -197,7 +197,6 @@ extern struct cursongcredit } cursongcredit; extern musicdef_t *musicdefstart; -extern int musicdef_volume; void S_LoadMusicDefs(UINT16 wadnum); void S_InitMusicDefs(void); diff --git a/src/sdl/new_sound.cpp b/src/sdl/new_sound.cpp index 80f549508..050b30539 100644 --- a/src/sdl/new_sound.cpp +++ b/src/sdl/new_sound.cpp @@ -57,7 +57,8 @@ static shared_ptr> mixer_sound_effects; static shared_ptr> mixer_music; static shared_ptr music_player; static shared_ptr> gain_sound_effects; -static shared_ptr> gain_music; +static shared_ptr> gain_music_player; +static shared_ptr> gain_music_channel; static vector> sound_effect_channels; @@ -187,12 +188,14 @@ void initialize_sound() mixer_music = make_shared>(); music_player = make_shared(); gain_sound_effects = make_shared>(); - gain_music = make_shared>(); + gain_music_player = make_shared>(); + gain_music_channel = make_shared>(); gain_sound_effects->bind(mixer_sound_effects); - gain_music->bind(mixer_music); + gain_music_player->bind(music_player); + gain_music_channel->bind(mixer_music); master->add_source(gain_sound_effects); - master->add_source(gain_music); - mixer_music->add_source(music_player); + master->add_source(gain_music_channel); + mixer_music->add_source(gain_music_player); for (size_t i = 0; i < static_cast(cv_numChannels.value); i++) { shared_ptr player = make_shared(); @@ -356,7 +359,7 @@ void I_SetSfxVolume(int volume) if (gain_sound_effects) { - gain_sound_effects->gain(vol * vol * vol); + gain_sound_effects->gain(std::clamp(vol * vol * vol, 0.f, 1.f)); } } @@ -597,6 +600,12 @@ boolean I_LoadSong(char* data, size_t len) return false; } + if (gain_music_player) + { + // Reset song volume to 1.0 for newly loaded songs. + gain_music_player->gain(1.0); + } + return true; } @@ -663,9 +672,22 @@ void I_SetMusicVolume(int volume) { float vol = static_cast(volume) / 100.f; - if (gain_music) + if (gain_music_channel) { - gain_music->gain(vol * vol * vol); + // Music channel volume is interpreted as logarithmic rather than linear. + // We approximate by cubing the gain level so vol 50 roughly sounds half as loud. + gain_music_channel->gain(std::clamp(vol * vol * vol, 0.f, 1.f)); + } +} + +void I_SetCurrentSongVolume(int volume) +{ + float vol = static_cast(volume) / 100.f; + + if (gain_music_player) + { + // However, different from music channel volume, musicdef volumes are explicitly linear. + gain_music_player->gain(std::max(vol, 0.f)); } }