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 + + Comment + Controls the distance-based dropoff of audio volume when camera is submerged (fraction or multiple of default audio rolloff) + Persist + 1 + Type + F32 + Value + 4.0 + AudioLevelSFX Comment diff --git a/indra/newview/llpanelaudioprefs.cpp b/indra/newview/llpanelaudioprefs.cpp index 0d78a44ae..d58635c85 100644 --- a/indra/newview/llpanelaudioprefs.cpp +++ b/indra/newview/llpanelaudioprefs.cpp @@ -105,6 +105,7 @@ void LLPanelAudioPrefs::refreshValues() mPreviousMediaVolume = gSavedSettings.getF32("AudioLevelMedia"); mPreviousDoppler = gSavedSettings.getF32("AudioLevelDoppler"); mPreviousRolloff = gSavedSettings.getF32("AudioLevelRolloff"); + mPreviousUnderwaterRolloff = gSavedSettings.getF32("AudioLevelUnderwaterRolloff"); mPreviousMoneyThreshold = gSavedSettings.getF32("UISndMoneyChangeThreshold"); mPreviousHealthThreshold = gSavedSettings.getF32("UISndHealthReductionThreshold"); @@ -126,6 +127,7 @@ void LLPanelAudioPrefs::cancel() gSavedSettings.setF32("AudioLevelMedia", mPreviousMediaVolume); gSavedSettings.setF32("AudioLevelDoppler", mPreviousDoppler ); gSavedSettings.setF32("AudioLevelRolloff", mPreviousRolloff ); + gSavedSettings.setF32("AudioLevelUnderwaterRolloff", mPreviousUnderwaterRolloff ); gSavedSettings.setF32("UISndMoneyChangeThreshold", mPreviousMoneyThreshold ); gSavedSettings.setF32("UISndHealthReductionThreshold", mPreviousHealthThreshold ); diff --git a/indra/newview/llpanelaudioprefs.h b/indra/newview/llpanelaudioprefs.h index 08009c9e6..45b6de83e 100644 --- a/indra/newview/llpanelaudioprefs.h +++ b/indra/newview/llpanelaudioprefs.h @@ -67,6 +67,7 @@ private: F32 mPreviousDoppler; F32 mPreviousDistance; F32 mPreviousRolloff; + F32 mPreviousUnderwaterRolloff; S32 mPreviousBitrate; diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index e46058591..9538262c1 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -134,6 +134,7 @@ void audio_update_volume(bool force_update) static const LLCachedControl mute_when_minimized("MuteWhenMinimized",true); static const LLCachedControl audio_level_doppler("AudioLevelDoppler",1.0); static const LLCachedControl audio_level_rolloff("AudioLevelRolloff",1.0); + static const LLCachedControl audio_level_underwater_rolloff("AudioLevelUnderwaterRolloff",3.0); BOOL mute_audio = _mute_audio; if (!gViewerWindow->getActive() && mute_when_minimized) { @@ -147,7 +148,11 @@ void audio_update_volume(bool force_update) gAudiop->setMasterGain ( master_volume ); gAudiop->setDopplerFactor(audio_level_doppler); - gAudiop->setRolloffFactor(audio_level_rolloff); + if(!LLViewerCamera::getInstance()->cameraUnderWater()) + gAudiop->setRolloffFactor( audio_level_rolloff ); + else + gAudiop->setRolloffFactor( audio_level_underwater_rolloff ); + gAudiop->setMuted(mute_audio); if (force_update) @@ -215,32 +220,8 @@ void audio_update_listener() void audio_update_wind(bool force_update) { #ifdef kAUDIO_ENABLE_WIND - // - // Extract height above water to modulate filter by whether above/below water - // - LLViewerRegion* region = gAgent.getRegion(); - if (region) + if(gAgent.getRegion()) { - static F32 last_camera_water_height = -1000.f; - LLVector3 camera_pos = gAgentCamera.getCameraPositionAgent(); - F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight(); - - // - // Don't update rolloff factor unless water surface has been crossed - // - if (force_update || (last_camera_water_height * camera_water_height) < 0.f) - { - static const LLCachedControl audio_level_rolloff("AudioLevelRolloff",1); - if (camera_water_height < 0.f) - { - gAudiop->setRolloffFactor(audio_level_rolloff * LL_ROLLOFF_MULTIPLIER_UNDER_WATER); - } - else - { - gAudiop->setRolloffFactor(audio_level_rolloff); - } - } - // Scale down the contribution of weather-simulation wind to the // ambient wind noise. Wind velocity averages 3.5 m/s, with gusts to 7 m/s // whereas steady-state avatar walk velocity is only 3.2 m/s. @@ -289,8 +270,7 @@ void audio_update_wind(bool force_update) gAudiop->mMaxWindGain = llmax(gAudiop->mMaxWindGain - volume_delta, 0.f); } - last_camera_water_height = camera_water_height; - gAudiop->updateWind(gRelativeWindVec, camera_water_height); + gAudiop->updateWind(gRelativeWindVec, gAgentCamera.getCameraPositionAgent()[VZ] - gAgent.getRegion()->getWaterHeight()); } #endif } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 6440652ef..1ba3f1d9e 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -690,6 +690,7 @@ void settings_setup_listeners() gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); + gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _2)); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_audio.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_audio.xml index 2ca59db4b..27c4ca7e6 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_audio.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_audio.xml @@ -9,8 +9,9 @@ - - - + + + +