diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index ddf4df7057..6c7fff973a 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -260,7 +260,16 @@ bool OpenAL_SoundStream::isPlaying() void OpenAL_SoundStream::update() { - alSourcef(mSource, AL_GAIN, mVolume*mBaseVolume); + ALfloat gain = mVolume*mBaseVolume; + ALfloat pitch = 1.0f; + if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) + { + gain *= 0.9f; + pitch *= 0.7f; + } + + alSourcef(mSource, AL_GAIN, gain); + alSourcef(mSource, AL_PITCH, pitch); alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]); alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f); alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f); @@ -388,7 +397,16 @@ bool OpenAL_Sound::isPlaying() void OpenAL_Sound::update() { - alSourcef(mSource, AL_GAIN, mVolume*mBaseVolume); + ALfloat gain = mVolume*mBaseVolume; + ALfloat pitch = 1.0f; + if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) + { + gain *= 0.9f; + pitch *= 0.7f; + } + + alSourcef(mSource, AL_GAIN, gain); + alSourcef(mSource, AL_PITCH, pitch); alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]); alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f); alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f); @@ -397,10 +415,18 @@ void OpenAL_Sound::update() void OpenAL_Sound3D::update() { + ALfloat gain = mVolume*mBaseVolume; + ALfloat pitch = 1.0f; if(mPos.squaredDistance(mOutput.mPos) > mMaxDistance*mMaxDistance) - alSourcef(mSource, AL_GAIN, 0.0f); - else - alSourcef(mSource, AL_GAIN, mVolume*mBaseVolume); + gain = 0.0f; + else if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) + { + gain *= 0.9f; + pitch *= 0.7f; + } + + alSourcef(mSource, AL_GAIN, gain); + alSourcef(mSource, AL_PITCH, pitch); alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]); alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f); alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f); @@ -638,6 +664,11 @@ SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float alSourcef(src, AL_MAX_DISTANCE, 1000.0f); alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f); + if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater) + { + volume *= 0.9f; + pitch *= 0.7f; + } alSourcef(src, AL_GAIN, volume); alSourcef(src, AL_PITCH, pitch); @@ -685,6 +716,11 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector alSourcef(src, AL_MAX_DISTANCE, max); alSourcef(src, AL_ROLLOFF_FACTOR, 1.0f); + if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater) + { + volume *= 0.9f; + pitch *= 0.7f; + } alSourcef(src, AL_GAIN, (pos.squaredDistance(mPos) > max*max) ? 0.0f : volume); alSourcef(src, AL_PITCH, pitch); @@ -701,7 +737,7 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector } -SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch) +SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch, int flags) { boost::shared_ptr sound; ALuint src; @@ -713,6 +749,8 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa try { + if((flags&Play_Loop)) + std::cout <<"Warning: cannot loop stream "<open(fname); sound.reset(new OpenAL_SoundStream(*this, src, decoder)); @@ -731,6 +769,11 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa alSourcef(src, AL_MAX_DISTANCE, 1000.0f); alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f); + if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater) + { + volume *= 0.9f; + pitch *= 0.7f; + } alSourcef(src, AL_GAIN, volume); alSourcef(src, AL_PITCH, pitch); @@ -743,9 +786,10 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa } -void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir) +void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) { mPos = pos; + mLastEnvironment = env; if(mContext) { @@ -762,7 +806,7 @@ void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 OpenAL_Output::OpenAL_Output(SoundManager &mgr) : Sound_Output(mgr), mDevice(0), mContext(0), mBufferCacheMemSize(0), - mStreamThread(new StreamThread) + mLastEnvironment(Env_Normal), mStreamThread(new StreamThread) { } diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index a709576bae..d62d20286a 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -36,6 +36,8 @@ namespace MWSound ALuint getBuffer(const std::string &fname); void bufferFinished(ALuint buffer); + Environment mLastEnvironment; + virtual std::vector enumerate(); virtual void init(const std::string &devname=""); virtual void deinit(); @@ -43,9 +45,9 @@ namespace MWSound virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags); virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, float min, float max, int flags); - virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch); + virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags); - virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir); + virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env); OpenAL_Output& operator=(const OpenAL_Output &rhs); OpenAL_Output(const OpenAL_Output &rhs); diff --git a/apps/openmw/mwsound/sound_output.hpp b/apps/openmw/mwsound/sound_output.hpp index 1507e18472..774e42efa3 100644 --- a/apps/openmw/mwsound/sound_output.hpp +++ b/apps/openmw/mwsound/sound_output.hpp @@ -27,9 +27,9 @@ namespace MWSound virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags) = 0; virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, float min, float max, int flags) = 0; - virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch) = 0; + virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags) = 0; - virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir) = 0; + virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) = 0; Sound_Output& operator=(const Sound_Output &rhs); Sound_Output(const Sound_Output &rhs); diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 2c2e6e9f91..aaeef80ff5 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -137,8 +137,9 @@ namespace MWSound { if(mMusic) mMusic->stop(); - mMusic = mOutput->streamSound(filename, 0.4f, 1.0f); + mMusic = mOutput->streamSound(filename, 0.4f, 1.0f, Play_NoEnv); mMusic->mBaseVolume = 0.4f; + mMusic->mFlags = Play_NoEnv; } catch(std::exception &e) { @@ -408,19 +409,25 @@ namespace MWSound if(!isMusicPlaying()) startRandomTitle(); + MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell(); Ogre::Camera *cam = mEnvironment.mWorld->getPlayer().getRenderer()->getCamera(); Ogre::Vector3 nPos, nDir, nUp; nPos = cam->getRealPosition(); nDir = cam->getRealDirection(); nUp = cam->getRealUp(); + Environment env = Env_Normal; + if(nPos.y < current->cell->water) + env = Env_Underwater; + // The output handler is expecting vectors oriented like the game // (that is, -Z goes down, +Y goes forward), but that's not what we // get from Ogre's camera, so we have to convert. const Ogre::Vector3 pos(nPos[0], -nPos[2], nPos[1]); const Ogre::Vector3 at(nDir[0], -nDir[2], nDir[1]); const Ogre::Vector3 up(nUp[0], -nUp[2], nUp[1]); - mOutput->updateListener(pos, at, up); + + mOutput->updateListener(pos, at, up, env); // Check if any sounds are finished playing, and trash them SoundMap::iterator snditer = mActiveSounds.begin(); diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index de5cca839c..cad5f61871 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -43,6 +43,11 @@ namespace MWSound static inline int operator&(const PlayMode &a, const PlayMode &b) { return (int)a & (int)b; } + enum Environment { + Env_Normal, + Env_Underwater, + }; + class SoundManager { Ogre::ResourceGroupManager& mResourceMgr;