diff options
author | ShadowNinja <shadowninja@minetest.net> | 2017-06-03 14:55:10 -0400 |
---|---|---|
committer | ShadowNinja <shadowninja@minetest.net> | 2017-06-03 14:55:10 -0400 |
commit | caecdb681c428c1aab9c0f7eec2570c0460f995c (patch) | |
tree | e5115982ea59bbf2343ba9b35bc4a0cfbb56f407 /src/sound_openal.cpp | |
parent | 81d56b94919dceb7b2e51d70b21a7ca22f852bd5 (diff) | |
parent | 80dc961d24e1964e25d57039ddb2ba639f9f4d22 (diff) | |
download | minetest-caecdb681c428c1aab9c0f7eec2570c0460f995c.tar.gz minetest-caecdb681c428c1aab9c0f7eec2570c0460f995c.tar.bz2 minetest-caecdb681c428c1aab9c0f7eec2570c0460f995c.zip |
Merge 0.4.16 into stable-0.4
Diffstat (limited to 'src/sound_openal.cpp')
-rw-r--r-- | src/sound_openal.cpp | 97 |
1 files changed, 93 insertions, 4 deletions
diff --git a/src/sound_openal.cpp b/src/sound_openal.cpp index 317667f52..a425af827 100644 --- a/src/sound_openal.cpp +++ b/src/sound_openal.cpp @@ -274,6 +274,19 @@ private: UNORDERED_MAP<std::string, std::vector<SoundBuffer*> > m_buffers; UNORDERED_MAP<int, PlayingSound*> m_sounds_playing; v3f m_listener_pos; + struct FadeState { + FadeState() {} + FadeState(float step, float current_gain, float target_gain): + step(step), + current_gain(current_gain), + target_gain(target_gain) {} + float step; + float current_gain; + float target_gain; + }; + + UNORDERED_MAP<int, FadeState> m_sounds_fading; + float m_fade_delay; public: bool m_is_initialized; OpenALSoundManager(OnDemandSoundFetcher *fetcher): @@ -281,6 +294,7 @@ public: m_device(NULL), m_context(NULL), m_next_id(1), + m_fade_delay(0), m_is_initialized(false) { ALCenum error = ALC_NO_ERROR; @@ -317,7 +331,7 @@ public: return; } - alDistanceModel(AL_EXPONENT_DISTANCE); + alDistanceModel(AL_INVERSE_DISTANCE); infostream<<"Audio: Initialized: OpenAL "<<alGetString(AL_VERSION) <<", using "<<alcGetString(m_device, ALC_DEVICE_SPECIFIER) @@ -349,6 +363,11 @@ public: infostream<<"Audio: Deinitialized."<<std::endl; } + void step(float dtime) + { + doFades(dtime); + } + void addBuffer(const std::string &name, SoundBuffer *buf) { UNORDERED_MAP<std::string, std::vector<SoundBuffer*> >::iterator i = @@ -409,7 +428,6 @@ public: alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false); alSource3f(sound->source_id, AL_POSITION, pos.X, pos.Y, pos.Z); alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0); - //alSourcef(sound->source_id, AL_ROLLOFF_FACTOR, 0.7); alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 30.0); alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); volume = MYMAX(0.0, volume); @@ -516,6 +534,7 @@ public: addBuffer(name, buf); return false; } + bool loadSoundData(const std::string &name, const std::string &filedata) { @@ -542,7 +561,7 @@ public: alListenerf(AL_GAIN, gain); } - int playSound(const std::string &name, bool loop, float volume) + int playSound(const std::string &name, bool loop, float volume, float fade) { maintain(); if(name == "") @@ -553,8 +572,16 @@ public: <<std::endl; return -1; } - return playSoundRaw(buf, loop, volume); + int handle = -1; + if (fade > 0) { + handle = playSoundRaw(buf, loop, 0); + fadeSound(handle, fade, volume); + } else { + handle = playSoundRaw(buf, loop, volume); + } + return handle; } + int playSoundAt(const std::string &name, bool loop, float volume, v3f pos) { maintain(); @@ -568,16 +595,55 @@ public: } return playSoundRawAt(buf, loop, volume, pos); } + void stopSound(int sound) { maintain(); deleteSound(sound); } + + void fadeSound(int soundid, float step, float gain) + { + m_sounds_fading[soundid] = FadeState(step, getSoundGain(soundid), gain); + } + + void doFades(float dtime) + { + m_fade_delay += dtime; + + if (m_fade_delay < 0.1f) + return; + + float chkGain = 0; + for (UNORDERED_MAP<int, FadeState>::iterator i = m_sounds_fading.begin(); + i != m_sounds_fading.end();) { + if (i->second.step < 0.f) + chkGain = -(i->second.current_gain); + else + chkGain = i->second.current_gain; + + if (chkGain < i->second.target_gain) { + i->second.current_gain += (i->second.step * m_fade_delay); + i->second.current_gain = rangelim(i->second.current_gain, 0, 1); + + updateSoundGain(i->first, i->second.current_gain); + ++i; + } else { + if (i->second.target_gain <= 0.f) + stopSound(i->first); + + m_sounds_fading.erase(i++); + } + } + m_fade_delay = 0; + } + bool soundExists(int sound) { maintain(); return (m_sounds_playing.count(sound) != 0); } + void updateSoundPosition(int id, v3f pos) { UNORDERED_MAP<int, PlayingSound*>::iterator i = m_sounds_playing.find(id); @@ -590,6 +656,29 @@ public: alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0); alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 30.0); } + + bool updateSoundGain(int id, float gain) + { + UNORDERED_MAP<int, PlayingSound*>::iterator i = m_sounds_playing.find(id); + if (i == m_sounds_playing.end()) + return false; + + PlayingSound *sound = i->second; + alSourcef(sound->source_id, AL_GAIN, gain); + return true; + } + + float getSoundGain(int id) + { + UNORDERED_MAP<int, PlayingSound*>::iterator i = m_sounds_playing.find(id); + if (i == m_sounds_playing.end()) + return 0; + + PlayingSound *sound = i->second; + ALfloat gain; + alGetSourcef(sound->source_id, AL_GAIN, &gain); + return gain; + } }; ISoundManager *createOpenALSoundManager(OnDemandSoundFetcher *fetcher) |