Skip to content

Commit

Permalink
Merge pull request #6512 from Goober5000/looping_sound_fixes
Browse files Browse the repository at this point in the history
fix volume updates for looping sounds
  • Loading branch information
Goober5000 authored Jan 12, 2025
2 parents 4dfaa85 + acfe6a1 commit 7cf7f0e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 50 deletions.
78 changes: 28 additions & 50 deletions code/sound/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,23 +98,21 @@ static auto VoiceVolumeOption __UNUSED = options::OptionBuilder<float>("Audio.Vo

unsigned int SND_ENV_DEFAULT = 0;

struct LoopingSoundInfo {
sound_handle m_dsHandle;
struct LoopingSoundInfo
{
float m_defaultVolume; //!< The default volume of this sound (from game_snd)
float m_dynamicVolume; //!< The dynamic volume before scripted volume adjustment is applied (is updated via snd_set_volume)

LoopingSoundInfo(sound_handle dsHandle, float defaultVolume, float dynamicVolume)
: m_dsHandle(dsHandle), m_defaultVolume(defaultVolume), m_dynamicVolume(dynamicVolume)
{
}
LoopingSoundInfo(float defaultVolume, float dynamicVolume)
: m_defaultVolume(defaultVolume), m_dynamicVolume(dynamicVolume)
{}

LoopingSoundInfo() : m_dsHandle(-1), m_defaultVolume(0.0f), m_dynamicVolume(0.0f)
{
}
LoopingSoundInfo() : m_defaultVolume(0.0f), m_dynamicVolume(0.0f)
{}
};

SCP_list<LoopingSoundInfo> currentlyLoopingSoundInfos;
SCP_list<LoopingSoundInfo> currentlyLooping3dSoundInfos;
SCP_unordered_map<sound_handle, LoopingSoundInfo, util::ID_Hash> currentlyLoopingSoundInfos;
SCP_unordered_map<sound_handle, LoopingSoundInfo, util::ID_Hash> currentlyLooping3dSoundInfos;

//For the adjust-audio-volume sexp
float aav_music_volume = 1.0f;
Expand Down Expand Up @@ -776,7 +774,7 @@ sound_handle snd_play_3d(game_snd* gs, const vec3d* source_pos, const vec3d* lis

if (handle.isValid()) {
if (looping) {
currentlyLooping3dSoundInfos.emplace_back(handle, default_volume, vol_scale);
currentlyLooping3dSoundInfos[handle] = { default_volume, vol_scale };
}

snd_set_pitch(handle, gs->pitch_range.next());
Expand Down Expand Up @@ -942,7 +940,7 @@ sound_handle snd_play_looping(game_snd* gs, float pan, int /*start_loop*/, int /

if (handle.isValid()) {
if (scriptingUpdateVolume) {
currentlyLoopingSoundInfos.emplace_back(handle, default_volume, vol_scale);
currentlyLoopingSoundInfos[handle] = { default_volume, vol_scale };
}

snd_set_pitch(handle, gs->pitch_range.next());
Expand All @@ -952,14 +950,6 @@ sound_handle snd_play_looping(game_snd* gs, float pan, int /*start_loop*/, int /
return handle;
}

void remove_looping_sound(SCP_list<LoopingSoundInfo> &looping_sounds, sound_handle sig)
{
// the cast to void avoids warnings about unused return value
(void)std::remove_if(looping_sounds.begin(), looping_sounds.end(), [sig](const LoopingSoundInfo &ls_info) -> bool {
return ls_info.m_dsHandle == sig;
});
}

/**
* Stop a sound from playing.
*
Expand All @@ -977,8 +967,8 @@ void snd_stop(sound_handle sig)
if ( channel == -1 )
return;

remove_looping_sound(currentlyLoopingSoundInfos, sig);
remove_looping_sound(currentlyLooping3dSoundInfos, sig);
currentlyLoopingSoundInfos.erase(sig);
currentlyLooping3dSoundInfos.erase(sig);

ds_stop_channel(channel);
}
Expand Down Expand Up @@ -1037,13 +1027,6 @@ void snd_stop_all()
ds_stop_channel_all();
}

SCP_list<LoopingSoundInfo>::iterator find_looping_sound(SCP_list<LoopingSoundInfo> &looping_sounds, sound_handle sig)
{
return std::find_if(looping_sounds.begin(), looping_sounds.end(), [sig](const LoopingSoundInfo &ls_info) -> bool {
return ls_info.m_dsHandle == sig;
});
}

/**
* Set the volume of a currently playing sound
*
Expand All @@ -1067,30 +1050,22 @@ void snd_set_volume(sound_handle sig, float volume, bool is_voice)
return;
}

bool isLoopingSound = false;


auto iter = find_looping_sound(currentlyLoopingSoundInfos, sig);
auto iter = currentlyLoopingSoundInfos.find(sig);
if (iter != currentlyLoopingSoundInfos.end()) {
iter->m_dynamicVolume = volume;
isLoopingSound = true;
iter->second.m_dynamicVolume = volume;
} else {
iter = find_looping_sound(currentlyLooping3dSoundInfos, sig);
iter = currentlyLooping3dSoundInfos.find(sig);
if (iter != currentlyLooping3dSoundInfos.end()) {
iter->m_dynamicVolume = volume;
isLoopingSound = true;
iter->second.m_dynamicVolume = volume;
}
}

//looping sound volumes are updated in snd_do_frame
if(!isLoopingSound) {
if (is_voice) {
new_volume = volume * (Master_voice_volume * aav_voice_volume);
} else {
new_volume = volume * (Master_sound_volume * aav_effect_volume);
}
ds_set_volume( channel, new_volume );
if (is_voice) {
new_volume = volume * (Master_voice_volume * aav_voice_volume);
} else {
new_volume = volume * (Master_sound_volume * aav_effect_volume);
}
ds_set_volume( channel, new_volume );
}

// ---------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1564,12 +1539,15 @@ void snd_do_frame()
ds_do_frame();
}

void update_looping_sound_volumes(SCP_list<LoopingSoundInfo> &looping_sounds)
void update_looping_sound_volumes(SCP_unordered_map<sound_handle, LoopingSoundInfo, util::ID_Hash> &looping_sounds)
{
for (auto &looping_sound : looping_sounds) {
for (const auto &looping_sound_pair : looping_sounds) {
const auto& dsHandle = looping_sound_pair.first;
const auto& looping_sound = looping_sound_pair.second;

const float new_volume =
looping_sound.m_defaultVolume * looping_sound.m_dynamicVolume * (Master_sound_volume * aav_effect_volume);
ds_set_volume(ds_get_channel(looping_sound.m_dsHandle), new_volume);
ds_set_volume(ds_get_channel(dsHandle), new_volume);
}
}

Expand Down
9 changes: 9 additions & 0 deletions code/utils/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,13 @@ class ID
Impl m_val;
};

struct ID_Hash
{
template <class Tag, class Impl, Impl default_value>
size_t operator()(const ID<Tag, Impl, default_value> &id) const
{
return std::hash<Impl>{}(id.value());
}
};

}

0 comments on commit 7cf7f0e

Please sign in to comment.