forked from Mirrorlandia_minetest/minetest
Clean up sound_fade (#10119)
Add proper documentation and correct gain reduction calculations. Co-authored-by: hecktest <>
This commit is contained in:
parent
649211bf27
commit
5bda36143f
@ -5238,9 +5238,12 @@ Sounds
|
|||||||
* `minetest.sound_fade(handle, step, gain)`
|
* `minetest.sound_fade(handle, step, gain)`
|
||||||
* `handle` is a handle returned by `minetest.sound_play`
|
* `handle` is a handle returned by `minetest.sound_play`
|
||||||
* `step` determines how fast a sound will fade.
|
* `step` determines how fast a sound will fade.
|
||||||
Negative step will lower the sound volume, positive step will increase
|
The gain will change by this much per second,
|
||||||
the sound volume.
|
until it reaches the target gain.
|
||||||
|
Note: Older versions used a signed step. This is deprecated, but old
|
||||||
|
code will still work. (the client uses abs(step) to correct it)
|
||||||
* `gain` the target gain for the fade.
|
* `gain` the target gain for the fade.
|
||||||
|
Fading to zero will delete the sound.
|
||||||
|
|
||||||
Timing
|
Timing
|
||||||
------
|
------
|
||||||
|
@ -337,14 +337,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::unordered_map<int, FadeState> m_sounds_fading;
|
std::unordered_map<int, FadeState> m_sounds_fading;
|
||||||
float m_fade_delay;
|
|
||||||
public:
|
public:
|
||||||
OpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher):
|
OpenALSoundManager(SoundManagerSingleton *smg, OnDemandSoundFetcher *fetcher):
|
||||||
m_fetcher(fetcher),
|
m_fetcher(fetcher),
|
||||||
m_device(smg->m_device.get()),
|
m_device(smg->m_device.get()),
|
||||||
m_context(smg->m_context.get()),
|
m_context(smg->m_context.get()),
|
||||||
m_next_id(1),
|
m_next_id(1)
|
||||||
m_fade_delay(0)
|
|
||||||
{
|
{
|
||||||
infostream << "Audio: Initialized: OpenAL " << std::endl;
|
infostream << "Audio: Initialized: OpenAL " << std::endl;
|
||||||
}
|
}
|
||||||
@ -616,38 +614,45 @@ public:
|
|||||||
|
|
||||||
void fadeSound(int soundid, float step, float gain)
|
void fadeSound(int soundid, float step, float gain)
|
||||||
{
|
{
|
||||||
m_sounds_fading[soundid] = FadeState(step, getSoundGain(soundid), gain);
|
// Ignore the command if step isn't valid.
|
||||||
|
if (step == 0)
|
||||||
|
return;
|
||||||
|
float current_gain = getSoundGain(soundid);
|
||||||
|
step = gain - current_gain > 0 ? abs(step) : -abs(step);
|
||||||
|
if (m_sounds_fading.find(soundid) != m_sounds_fading.end()) {
|
||||||
|
auto current_fade = m_sounds_fading[soundid];
|
||||||
|
// Do not replace the fade if it's equivalent.
|
||||||
|
if (current_fade.target_gain == gain && current_fade.step == step)
|
||||||
|
return;
|
||||||
|
m_sounds_fading.erase(soundid);
|
||||||
|
}
|
||||||
|
gain = rangelim(gain, 0, 1);
|
||||||
|
m_sounds_fading[soundid] = FadeState(step, current_gain, gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doFades(float dtime)
|
void doFades(float dtime)
|
||||||
{
|
{
|
||||||
m_fade_delay += dtime;
|
for (auto i = m_sounds_fading.begin(); i != m_sounds_fading.end();) {
|
||||||
|
FadeState& fade = i->second;
|
||||||
|
assert(fade.step != 0);
|
||||||
|
fade.current_gain += (fade.step * dtime);
|
||||||
|
|
||||||
if (m_fade_delay < 0.1f)
|
if (fade.step < 0.f)
|
||||||
return;
|
fade.current_gain = std::max(fade.current_gain, fade.target_gain);
|
||||||
|
|
||||||
float chkGain = 0;
|
|
||||||
for (auto i = m_sounds_fading.begin();
|
|
||||||
i != m_sounds_fading.end();) {
|
|
||||||
if (i->second.step < 0.f)
|
|
||||||
chkGain = -(i->second.current_gain);
|
|
||||||
else
|
else
|
||||||
chkGain = i->second.current_gain;
|
fade.current_gain = std::min(fade.current_gain, fade.target_gain);
|
||||||
|
|
||||||
if (chkGain < i->second.target_gain) {
|
if (fade.current_gain <= 0.f)
|
||||||
i->second.current_gain += (i->second.step * m_fade_delay);
|
stopSound(i->first);
|
||||||
i->second.current_gain = rangelim(i->second.current_gain, 0, 1);
|
else
|
||||||
|
updateSoundGain(i->first, fade.current_gain);
|
||||||
updateSoundGain(i->first, i->second.current_gain);
|
|
||||||
++i;
|
|
||||||
} else {
|
|
||||||
if (i->second.target_gain <= 0.f)
|
|
||||||
stopSound(i->first);
|
|
||||||
|
|
||||||
|
// The increment must happen during the erase call, or else it'll segfault.
|
||||||
|
if (fade.current_gain == fade.target_gain)
|
||||||
m_sounds_fading.erase(i++);
|
m_sounds_fading.erase(i++);
|
||||||
}
|
else
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
m_fade_delay = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool soundExists(int sound)
|
bool soundExists(int sound)
|
||||||
|
Loading…
Reference in New Issue
Block a user