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 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 b2c015afe..fa7044e67 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ b/indra/llaudio/llstreamingaudio_fmodex.cpp @@ -70,9 +70,7 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) : mCurrentInternetStreamp(NULL), mFMODInternetStreamChannelp(NULL), mGain(1.0f), - mMetaData(NULL), - mStarvedProgress(0), - mStarvedNoProgressFrames(0) + mMetaData(NULL) { // Number of milliseconds of audio to buffer for the audio card. // Must be larger than the usual Second Life frame stutter time. @@ -252,27 +250,10 @@ void LLStreamingAudio_FMODEX::update() llinfos << " (diskbusy="<setMute(true); - mStarvedProgress = progress; - mStarvedNoProgressFrames = 0; - } - else if(mStarvedProgress == progress) - { - if(++mStarvedNoProgressFrames >= 10) - { - //we got 10 consecutive updates of 0 progress made on the stream buffer. It probably stalled. - llinfos << "Stream unable to recover from starvation. Halting." << llendl; - stop(); - return; - } - } - else - { - mStarvedNoProgressFrames = 0; - mStarvedProgress = progress; } mLastStarved.start(); } - else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 5.f) + else if(mLastStarved.getStarted() && mLastStarved.getElapsedTimeF32() > 1.f) { mLastStarved.stop(); mFMODInternetStreamChannelp->setMute(false); diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h index 46c0ea553..1b5211485 100644 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ b/indra/llaudio/llstreamingaudio_fmodex.h @@ -80,8 +80,6 @@ private: F32 mGain; LLTimer mLastStarved; - unsigned int mStarvedProgress; - unsigned int mStarvedNoProgressFrames; LLSD *mMetaData; }; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 45121a899..54f1e1402 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1801,6 +1801,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 b6c442c6e..a58bd2c5d 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -700,6 +700,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..ca04f8b84 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,27 +39,28 @@ Shaders: - + + - Terrain Scale: + Terrain Scale: Low Medium High Ultra - Shadows: + Shadows: Disabled Sun/Moon Sun/Moon + Projectors - Water Reflections: + Water Reflections: Minimal Terrain and trees @@ -68,7 +69,7 @@ Everything - + Off m