mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-29 19:06:41 +00:00
Apply reverb and a low-pass filter when underwater
This replaces the pitch-shift effect when available.
This commit is contained in:
parent
27eeaf90d0
commit
edfba68eb5
2 changed files with 93 additions and 12 deletions
|
@ -698,7 +698,7 @@ void OpenAL_Output::init(const std::string &devname)
|
||||||
{
|
{
|
||||||
std::cout<< "Low-pass filter supported" <<std::endl;
|
std::cout<< "Low-pass filter supported" <<std::endl;
|
||||||
alFilterf(mWaterFilter, AL_LOWPASS_GAIN, 0.9f);
|
alFilterf(mWaterFilter, AL_LOWPASS_GAIN, 0.9f);
|
||||||
alFilterf(mWaterFilter, AL_LOWPASS_GAINHF, 0.01f);
|
alFilterf(mWaterFilter, AL_LOWPASS_GAINHF, 0.125f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -709,18 +709,34 @@ void OpenAL_Output::init(const std::string &devname)
|
||||||
}
|
}
|
||||||
|
|
||||||
alGenAuxiliaryEffectSlots(1, &mEffectSlot);
|
alGenAuxiliaryEffectSlots(1, &mEffectSlot);
|
||||||
alGenEffects(1, &mWaterEffect);
|
alGetError();
|
||||||
|
|
||||||
|
alGenEffects(1, &mDefaultEffect);
|
||||||
if(alGetError() == AL_NO_ERROR)
|
if(alGetError() == AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
alEffecti(mDefaultEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||||
if(alGetError() == AL_NO_ERROR)
|
if(alGetError() == AL_NO_ERROR)
|
||||||
std::cout<< "EAX Reverb supported" <<std::endl;
|
std::cout<< "EAX Reverb supported" <<std::endl;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
alEffecti(mDefaultEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||||
if(alGetError() == AL_NO_ERROR)
|
if(alGetError() == AL_NO_ERROR)
|
||||||
std::cout<< "Standard Reverb supported" <<std::endl;
|
std::cout<< "Standard Reverb supported" <<std::endl;
|
||||||
}
|
}
|
||||||
|
EFXEAXREVERBPROPERTIES props = EFX_REVERB_PRESET_GENERIC;
|
||||||
|
props.flGain = 0.0f;
|
||||||
|
LoadEffect(mDefaultEffect, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
alGenEffects(1, &mWaterEffect);
|
||||||
|
if(alGetError() == AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||||
|
if(alGetError() != AL_NO_ERROR)
|
||||||
|
{
|
||||||
|
alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||||
|
alGetError();
|
||||||
|
}
|
||||||
LoadEffect(mWaterEffect, EFX_REVERB_PRESET_UNDERWATER);
|
LoadEffect(mWaterEffect, EFX_REVERB_PRESET_UNDERWATER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,6 +761,9 @@ void OpenAL_Output::deinit()
|
||||||
if(mEffectSlot)
|
if(mEffectSlot)
|
||||||
alDeleteAuxiliaryEffectSlots(1, &mEffectSlot);
|
alDeleteAuxiliaryEffectSlots(1, &mEffectSlot);
|
||||||
mEffectSlot = 0;
|
mEffectSlot = 0;
|
||||||
|
if(mDefaultEffect)
|
||||||
|
alDeleteEffects(1, &mDefaultEffect);
|
||||||
|
mDefaultEffect = 0;
|
||||||
if(mWaterEffect)
|
if(mWaterEffect)
|
||||||
alDeleteEffects(1, &mWaterEffect);
|
alDeleteEffects(1, &mWaterEffect);
|
||||||
mWaterEffect = 0;
|
mWaterEffect = 0;
|
||||||
|
@ -954,10 +973,26 @@ void OpenAL_Output::initCommon2D(ALuint source, const osg::Vec3f &pos, ALfloat g
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
|
alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||||
alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
|
alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
|
||||||
|
|
||||||
if(useenv && mListenerEnv == Env_Underwater)
|
if(useenv)
|
||||||
{
|
{
|
||||||
gain *= 0.9f;
|
if(mWaterFilter)
|
||||||
pitch *= 0.7f;
|
alSourcei(source, AL_DIRECT_FILTER,
|
||||||
|
(mListenerEnv == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL
|
||||||
|
);
|
||||||
|
else if(mListenerEnv == Env_Underwater)
|
||||||
|
{
|
||||||
|
gain *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
|
if(mEffectSlot)
|
||||||
|
alSource3i(source, AL_AUXILIARY_SEND_FILTER, mEffectSlot, 0, AL_FILTER_NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mWaterFilter)
|
||||||
|
alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||||
|
if(mEffectSlot)
|
||||||
|
alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourcef(source, AL_GAIN, gain);
|
alSourcef(source, AL_GAIN, gain);
|
||||||
|
@ -977,10 +1012,26 @@ void OpenAL_Output::initCommon3D(ALuint source, const osg::Vec3f &pos, ALfloat m
|
||||||
|
|
||||||
if((pos - mListenerPos).length2() > maxdist*maxdist)
|
if((pos - mListenerPos).length2() > maxdist*maxdist)
|
||||||
gain = 0.0f;
|
gain = 0.0f;
|
||||||
if(useenv && mListenerEnv == Env_Underwater)
|
if(useenv)
|
||||||
{
|
{
|
||||||
gain *= 0.9f;
|
if(mWaterFilter)
|
||||||
pitch *= 0.7f;
|
alSourcei(source, AL_DIRECT_FILTER,
|
||||||
|
(mListenerEnv == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL
|
||||||
|
);
|
||||||
|
else if(mListenerEnv == Env_Underwater)
|
||||||
|
{
|
||||||
|
gain *= 0.9f;
|
||||||
|
pitch *= 0.7f;
|
||||||
|
}
|
||||||
|
if(mEffectSlot)
|
||||||
|
alSource3i(source, AL_AUXILIARY_SEND_FILTER, mEffectSlot, 0, AL_FILTER_NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mWaterFilter)
|
||||||
|
alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||||
|
if(mEffectSlot)
|
||||||
|
alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourcef(source, AL_GAIN, gain);
|
alSourcef(source, AL_GAIN, gain);
|
||||||
|
@ -997,7 +1048,7 @@ void OpenAL_Output::updateCommon(ALuint source, const osg::Vec3f& pos, ALfloat m
|
||||||
if((pos - mListenerPos).length2() > maxdist*maxdist)
|
if((pos - mListenerPos).length2() > maxdist*maxdist)
|
||||||
gain = 0.0f;
|
gain = 0.0f;
|
||||||
}
|
}
|
||||||
if(useenv && mListenerEnv == Env_Underwater)
|
if(useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
|
||||||
{
|
{
|
||||||
gain *= 0.9f;
|
gain *= 0.9f;
|
||||||
pitch *= 0.7f;
|
pitch *= 0.7f;
|
||||||
|
@ -1256,10 +1307,39 @@ void OpenAL_Output::updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdi
|
||||||
};
|
};
|
||||||
alListenerfv(AL_POSITION, pos.ptr());
|
alListenerfv(AL_POSITION, pos.ptr());
|
||||||
alListenerfv(AL_ORIENTATION, orient);
|
alListenerfv(AL_ORIENTATION, orient);
|
||||||
|
|
||||||
if(env != mListenerEnv)
|
if(env != mListenerEnv)
|
||||||
{
|
{
|
||||||
// Speed of sound in water is 1484m/s, and in air is 343.3m/s (roughly)
|
// Speed of sound in water is 1484m/s, and in air is 343.3m/s (roughly)
|
||||||
alSpeedOfSound(((env == Env_Underwater) ? 1484.0f : 343.3f) * UnitsPerMeter);
|
alSpeedOfSound(((env == Env_Underwater) ? 1484.0f : 343.3f) * UnitsPerMeter);
|
||||||
|
|
||||||
|
// Update active sources with the environment's direct filter
|
||||||
|
if(mWaterFilter)
|
||||||
|
{
|
||||||
|
ALuint filter = (env == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL;
|
||||||
|
std::for_each(mActiveSounds.cbegin(), mActiveSounds.cend(),
|
||||||
|
[filter](const SoundVec::value_type &item) -> void
|
||||||
|
{
|
||||||
|
if(item->getUseEnv())
|
||||||
|
alSourcei(GET_PTRID(item->mHandle), AL_DIRECT_FILTER, filter);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
std::for_each(mActiveStreams.cbegin(), mActiveStreams.cend(),
|
||||||
|
[filter](const StreamVec::value_type &item) -> void
|
||||||
|
{
|
||||||
|
if(item->getUseEnv())
|
||||||
|
alSourcei(
|
||||||
|
reinterpret_cast<OpenAL_SoundStream*>(item->mHandle)->mSource,
|
||||||
|
AL_DIRECT_FILTER, filter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Update the environment effect
|
||||||
|
if(mEffectSlot)
|
||||||
|
alAuxiliaryEffectSloti(mEffectSlot, AL_EFFECTSLOT_EFFECT,
|
||||||
|
(env == Env_Underwater) ? mWaterEffect : mDefaultEffect
|
||||||
|
);
|
||||||
}
|
}
|
||||||
throwALerror();
|
throwALerror();
|
||||||
}
|
}
|
||||||
|
@ -1323,7 +1403,7 @@ void OpenAL_Output::resumeSounds(int types)
|
||||||
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
||||||
: Sound_Output(mgr), mDevice(0), mContext(0)
|
: Sound_Output(mgr), mDevice(0), mContext(0)
|
||||||
, mListenerPos(0.0f, 0.0f, 0.0f), mListenerEnv(Env_Normal)
|
, mListenerPos(0.0f, 0.0f, 0.0f), mListenerEnv(Env_Normal)
|
||||||
, mWaterFilter(0), mWaterEffect(0), mEffectSlot(0)
|
, mWaterFilter(0), mWaterEffect(0), mDefaultEffect(0), mEffectSlot(0)
|
||||||
, mStreamThread(new StreamThread)
|
, mStreamThread(new StreamThread)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace MWSound
|
||||||
|
|
||||||
ALuint mWaterFilter;
|
ALuint mWaterFilter;
|
||||||
ALuint mWaterEffect;
|
ALuint mWaterEffect;
|
||||||
|
ALuint mDefaultEffect;
|
||||||
ALuint mEffectSlot;
|
ALuint mEffectSlot;
|
||||||
|
|
||||||
struct StreamThread;
|
struct StreamThread;
|
||||||
|
|
Loading…
Reference in a new issue