Positional sound: Limit volume when closer than 1 node

Change OpenAL distance model from AL_INVERSE_DISTANCE to
AL_INVERSE_DISTANCE_CLAMPED to avoid excessive volume when very close
to the sound location, for example MTG doors, and MTG fire sounds which
are combined at an average position and often located in air nodes.

Because AL_REFERENCE_DISTANCE has been reduced to 1 node (the distance
under which gain is clamped), multiply volume by the same factor to keep
sound gains the same as before, since the gain is calculated as:

gain = (AL_REFERENCE_DISTANCE / distance)
This commit is contained in:
paramat 2017-09-23 08:38:22 +01:00 committed by SmallJoker
parent 01b9da870b
commit 3a9d500396

@ -36,6 +36,7 @@ with this program; ifnot, write to the Free Software Foundation, Inc.,
#include <AL/alc.h> #include <AL/alc.h>
#include <AL/alext.h> #include <AL/alext.h>
#endif #endif
#include <cmath>
#include <vorbis/vorbisfile.h> #include <vorbis/vorbisfile.h>
#include <assert.h> #include <assert.h>
#include "log.h" #include "log.h"
@ -331,7 +332,7 @@ public:
return; return;
} }
alDistanceModel(AL_INVERSE_DISTANCE); alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
infostream<<"Audio: Initialized: OpenAL "<<alGetString(AL_VERSION) infostream<<"Audio: Initialized: OpenAL "<<alGetString(AL_VERSION)
<<", using "<<alcGetString(m_device, ALC_DEVICE_SPECIFIER) <<", using "<<alcGetString(m_device, ALC_DEVICE_SPECIFIER)
@ -407,7 +408,7 @@ public:
alSource3f(sound->source_id, AL_POSITION, 0, 0, 0); alSource3f(sound->source_id, AL_POSITION, 0, 0, 0);
alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0); alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0);
alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
volume = MYMAX(0.0, volume); volume = std::max(0.0f, volume);
alSourcef(sound->source_id, AL_GAIN, volume); alSourcef(sound->source_id, AL_GAIN, volume);
alSourcePlay(sound->source_id); alSourcePlay(sound->source_id);
warn_if_error(alGetError(), "createPlayingSound"); warn_if_error(alGetError(), "createPlayingSound");
@ -428,9 +429,14 @@ public:
alSourcei(sound->source_id, AL_SOURCE_RELATIVE, false); 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_POSITION, pos.X, pos.Y, pos.Z);
alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0); alSource3f(sound->source_id, AL_VELOCITY, 0, 0, 0);
alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 30.0); // Use alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED) and set reference
// distance to clamp gain at <1 node distance, to avoid excessive
// volume when closer
alSourcef(sound->source_id, AL_REFERENCE_DISTANCE, 10.0f);
alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); alSourcei(sound->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
volume = MYMAX(0.0, volume); // Multiply by 3 to compensate for reducing AL_REFERENCE_DISTANCE from
// the previous value of 30 to the new value of 10
volume = std::max(0.0f, volume * 3.0f);
alSourcef(sound->source_id, AL_GAIN, volume); alSourcef(sound->source_id, AL_GAIN, volume);
alSourcePlay(sound->source_id); alSourcePlay(sound->source_id);
warn_if_error(alGetError(), "createPlayingSoundAt"); warn_if_error(alGetError(), "createPlayingSoundAt");