diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 2d54073ee..77c7fd6d7 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -48,7 +48,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 d57ef7f3a..520154fb8 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; @@ -159,7 +161,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; @@ -604,6 +612,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/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp index fa7044e67..33fd30fee 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ b/indra/llaudio/llstreamingaudio_fmodex.cpp @@ -172,7 +172,6 @@ void LLStreamingAudio_FMODEX::update() if(mFMODInternetStreamChannelp) { - //llinfos << "progress = " << progress << llendl; if(!mMetaData) mMetaData = new LLSD; @@ -484,4 +483,4 @@ void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuf settings.cbsize=sizeof(settings); settings.defaultDecodeBufferSize = decodebuffertime;//ms mSystem->setAdvancedSettings(&settings); -} \ No newline at end of file +} 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/llpaneldisplay.cpp b/indra/newview/llpaneldisplay.cpp index fdb1a0035..b9cf32442 100644 --- a/indra/newview/llpaneldisplay.cpp +++ b/indra/newview/llpaneldisplay.cpp @@ -224,6 +224,9 @@ BOOL LLPanelDisplay::postBuild() mGraphicsBorder = getChild("GraphicsBorder"); + // Enable Transparent Water + mCtrlTransparentWater = getChild("TransparentWater"); + //---------------------------------------------------------------------------- // Enable Bump/Shiny mCtrlBumpShiny = getChild("BumpShiny"); @@ -414,6 +417,7 @@ void LLPanelDisplay::refresh() mQualityPerformance = gSavedSettings.getU32("RenderQualityPerformance"); mCustomSettings = gSavedSettings.getBOOL("RenderCustomSettings"); + mTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater"); // shader settings mBumpShiny = gSavedSettings.getBOOL("RenderObjectBump"); mShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); @@ -678,6 +682,7 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) llassert(mSkyFactorText != NULL); llassert(mPostProcessText != NULL); + llassert(mCtrlTransparentWater != NULL); llassert(mCtrlBumpShiny != NULL); llassert(mCtrlWindLight != NULL); llassert(mCtrlAvatarVP != NULL); @@ -730,6 +735,7 @@ void LLPanelDisplay::setHiddenGraphicsState(bool isHidden) mSkyFactorText->setVisible(!isHidden); mPostProcessText->setVisible(!isHidden); + mCtrlTransparentWater->setVisible(!isHidden); mCtrlBumpShiny->setVisible(!isHidden); mCtrlWindLight->setVisible(!isHidden); mCtrlAvatarVP->setVisible(!isHidden); @@ -777,6 +783,7 @@ void LLPanelDisplay::cancel() gSavedSettings.setBOOL("RenderCustomSettings", mCustomSettings); + gSavedSettings.setBOOL("RenderTransparentWater", mTransparentWater); gSavedSettings.setBOOL("RenderObjectBump", mBumpShiny); gSavedSettings.setBOOL("VertexShaderEnable", mShaderEnable); gSavedSettings.setBOOL("WindLightUseAtmosShaders", mWindLight); diff --git a/indra/newview/llpaneldisplay.h b/indra/newview/llpaneldisplay.h index a2cbc3549..234c785b6 100644 --- a/indra/newview/llpaneldisplay.h +++ b/indra/newview/llpaneldisplay.h @@ -107,6 +107,7 @@ protected: LLSliderCtrl *mCtrlPostProcess; // Max Particle LLSliderCtrl *mCtrlNonImpostors; // Max non-impostors + LLCheckBoxCtrl *mCtrlTransparentWater; LLCheckBoxCtrl *mCtrlBumpShiny; LLCheckBoxCtrl *mCtrlWindLight; LLCheckBoxCtrl *mCtrlAvatarVP; @@ -155,6 +156,7 @@ protected: S32 mQualityPerformance; BOOL mCustomSettings; + BOOL mTransparentWater; BOOL mBumpShiny; BOOL mShaderEnable; BOOL mWindLight; 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 755e97e1c..148526dad 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -698,6 +698,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 d9b7c2ff2..c46212512 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 @@ - - - + + + + diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml index 9e66ad8b7..cdc4ecddd 100644 --- a/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml @@ -39,7 +39,8 @@ Shaders: - + + @@ -47,20 +48,20 @@ Terrain Scale: - + Low Medium High Ultra Shadows: - + Disabled Sun/Moon Sun/Moon + Projectors Water Reflections: - + Minimal Terrain and trees All static objects @@ -99,7 +100,7 @@ Low High -