diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index c80b71688..a4dcaa2b1 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -47,7 +47,6 @@
#include "lllistener.h"
const F32 LL_WIND_UPDATE_INTERVAL = 0.1f;
-const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water
const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f;
diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp
index c745dbcd1..3f90f9cb2 100644
--- a/indra/llaudio/llaudioengine_fmodex.cpp
+++ b/indra/llaudio/llaudioengine_fmodex.cpp
@@ -72,6 +72,8 @@ bool attemptDelayLoad()
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels);
+FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
+
LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler)
{
mInited = false;
@@ -207,7 +209,13 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
U32 fmod_flags = FMOD_INIT_NORMAL;
if(mEnableProfiler)
+ {
fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
+ mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
+ mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
+ mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
+ mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
+ }
#if LL_LINUX
bool audio_ok = false;
@@ -639,6 +647,9 @@ void LLAudioChannelFMODEX::play()
Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause");
getSource()->setPlayedOnce(true);
+
+ if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()])
+ mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]);
}
diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h
index f6f920e10..6b780128f 100644
--- a/indra/llaudio/llaudioengine_fmodex.h
+++ b/indra/llaudio/llaudioengine_fmodex.h
@@ -44,6 +44,7 @@ namespace FMOD
{
class System;
class Channel;
+ class ChannelGroup;
class Sound;
class DSP;
}
@@ -83,6 +84,9 @@ protected:
FMOD::DSP *mWindDSP;
FMOD::System *mSystem;
bool mEnableProfiler;
+
+public:
+ static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT];
};
diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp
index 43749e6b1..e70dc7c60 100644
--- a/indra/llaudio/lllistener_fmodex.cpp
+++ b/indra/llaudio/lllistener_fmodex.cpp
@@ -106,6 +106,15 @@ void LLListener_FMODEX::commitDeferredChanges()
void LLListener_FMODEX::setRolloffFactor(F32 factor)
{
+ //An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment.
+ //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
+ //In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call.
+ if(mRolloffFactor != factor)
+ {
+ LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f);
+ mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
+ mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL);
+ }
mRolloffFactor = factor;
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5dc30d0c3..a6a95d8a8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1725,6 +1725,17 @@
Value
1.0
+ AudioLevelUnderwaterRolloff
+
AudioLevelSFX