Implement musicdef volume in new mixer

This commit is contained in:
Eidolon 2023-03-08 15:12:34 -06:00
parent 86990d47d2
commit 901ebdb5b0
5 changed files with 42 additions and 16 deletions

View file

@ -36,7 +36,7 @@ size_t Gain<C>::filter(tcb::span<Sample<C>> input_buffer, tcb::span<Sample<C>> b
template <size_t C>
void Gain<C>::gain(float new_gain)
{
new_gain_ = std::clamp(new_gain, 0.0f, 1.0f);
new_gain_ = std::max(new_gain, 0.f);
}
template <size_t C>

View file

@ -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);
/// ------------------------

View file

@ -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);
}
}

View file

@ -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);

View file

@ -57,7 +57,8 @@ static shared_ptr<Mixer<2>> mixer_sound_effects;
static shared_ptr<Mixer<2>> mixer_music;
static shared_ptr<MusicPlayer> music_player;
static shared_ptr<Gain<2>> gain_sound_effects;
static shared_ptr<Gain<2>> gain_music;
static shared_ptr<Gain<2>> gain_music_player;
static shared_ptr<Gain<2>> gain_music_channel;
static vector<shared_ptr<SoundEffectPlayer>> sound_effect_channels;
@ -187,12 +188,14 @@ void initialize_sound()
mixer_music = make_shared<Mixer<2>>();
music_player = make_shared<MusicPlayer>();
gain_sound_effects = make_shared<Gain<2>>();
gain_music = make_shared<Gain<2>>();
gain_music_player = make_shared<Gain<2>>();
gain_music_channel = make_shared<Gain<2>>();
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<size_t>(cv_numChannels.value); i++)
{
shared_ptr<SoundEffectPlayer> player = make_shared<SoundEffectPlayer>();
@ -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<float>(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<float>(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));
}
}