Skip to content

Commit 5bda361

Browse files
authoredAug 19, 2020
Clean up sound_fade (#10119)
Add proper documentation and correct gain reduction calculations. Co-authored-by: hecktest <>
1 parent 649211b commit 5bda361

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed
 

Diff for: ‎doc/lua_api.txt

+5-2
Original file line numberDiff line numberDiff line change
@@ -5238,9 +5238,12 @@ Sounds
52385238
* `minetest.sound_fade(handle, step, gain)`
52395239
* `handle` is a handle returned by `minetest.sound_play`
52405240
* `step` determines how fast a sound will fade.
5241-
Negative step will lower the sound volume, positive step will increase
5242-
the sound volume.
5241+
The gain will change by this much per second,
5242+
until it reaches the target gain.
5243+
Note: Older versions used a signed step. This is deprecated, but old
5244+
code will still work. (the client uses abs(step) to correct it)
52435245
* `gain` the target gain for the fade.
5246+
Fading to zero will delete the sound.
52445247

52455248
Timing
52465249
------

Diff for: ‎src/client/sound_openal.cpp

+30-25
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,12 @@ class OpenALSoundManager: public ISoundManager
337337
};
338338

339339
std::unordered_map<int, FadeState> m_sounds_fading;
340-
float m_fade_delay;
341340
public:
342341
OpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher):
343342
m_fetcher(fetcher),
344343
m_device(smg->m_device.get()),
345344
m_context(smg->m_context.get()),
346-
m_next_id(1),
347-
m_fade_delay(0)
345+
m_next_id(1)
348346
{
349347
infostream << "Audio: Initialized: OpenAL " << std::endl;
350348
}
@@ -616,38 +614,45 @@ class OpenALSoundManager: public ISoundManager
616614

617615
void fadeSound(int soundid, float step, float gain)
618616
{
619-
m_sounds_fading[soundid] = FadeState(step, getSoundGain(soundid), gain);
617+
// Ignore the command if step isn't valid.
618+
if (step == 0)
619+
return;
620+
float current_gain = getSoundGain(soundid);
621+
step = gain - current_gain > 0 ? abs(step) : -abs(step);
622+
if (m_sounds_fading.find(soundid) != m_sounds_fading.end()) {
623+
auto current_fade = m_sounds_fading[soundid];
624+
// Do not replace the fade if it's equivalent.
625+
if (current_fade.target_gain == gain && current_fade.step == step)
626+
return;
627+
m_sounds_fading.erase(soundid);
628+
}
629+
gain = rangelim(gain, 0, 1);
630+
m_sounds_fading[soundid] = FadeState(step, current_gain, gain);
620631
}
621632

622633
void doFades(float dtime)
623634
{
624-
m_fade_delay += dtime;
625-
626-
if (m_fade_delay < 0.1f)
627-
return;
635+
for (auto i = m_sounds_fading.begin(); i != m_sounds_fading.end();) {
636+
FadeState& fade = i->second;
637+
assert(fade.step != 0);
638+
fade.current_gain += (fade.step * dtime);
628639

629-
float chkGain = 0;
630-
for (auto i = m_sounds_fading.begin();
631-
i != m_sounds_fading.end();) {
632-
if (i->second.step < 0.f)
633-
chkGain = -(i->second.current_gain);
640+
if (fade.step < 0.f)
641+
fade.current_gain = std::max(fade.current_gain, fade.target_gain);
634642
else
635-
chkGain = i->second.current_gain;
643+
fade.current_gain = std::min(fade.current_gain, fade.target_gain);
636644

637-
if (chkGain < i->second.target_gain) {
638-
i->second.current_gain += (i->second.step * m_fade_delay);
639-
i->second.current_gain = rangelim(i->second.current_gain, 0, 1);
640-
641-
updateSoundGain(i->first, i->second.current_gain);
642-
++i;
643-
} else {
644-
if (i->second.target_gain <= 0.f)
645-
stopSound(i->first);
645+
if (fade.current_gain <= 0.f)
646+
stopSound(i->first);
647+
else
648+
updateSoundGain(i->first, fade.current_gain);
646649

650+
// The increment must happen during the erase call, or else it'll segfault.
651+
if (fade.current_gain == fade.target_gain)
647652
m_sounds_fading.erase(i++);
648-
}
653+
else
654+
i++;
649655
}
650-
m_fade_delay = 0;
651656
}
652657

653658
bool soundExists(int sound)

0 commit comments

Comments
 (0)
Please sign in to comment.