Set the sound properties at initialization

This commit is contained in:
Chris Robinson 2012-12-17 23:35:20 -08:00
parent 20321c4552
commit dd3e568a00
5 changed files with 80 additions and 113 deletions

View file

@ -128,13 +128,15 @@ class OpenAL_SoundStream : public Sound
volatile bool mIsFinished; volatile bool mIsFinished;
void updateAll(bool local);
OpenAL_SoundStream(const OpenAL_SoundStream &rhs); OpenAL_SoundStream(const OpenAL_SoundStream &rhs);
OpenAL_SoundStream& operator=(const OpenAL_SoundStream &rhs); OpenAL_SoundStream& operator=(const OpenAL_SoundStream &rhs);
friend class OpenAL_Output; friend class OpenAL_Output;
public: public:
OpenAL_SoundStream(OpenAL_Output &output, ALuint src, DecoderPtr decoder); OpenAL_SoundStream(OpenAL_Output &output, ALuint src, DecoderPtr decoder, float basevol, float pitch, int flags);
virtual ~OpenAL_SoundStream(); virtual ~OpenAL_SoundStream();
virtual void stop(); virtual void stop();
@ -215,8 +217,9 @@ private:
}; };
OpenAL_SoundStream::OpenAL_SoundStream(OpenAL_Output &output, ALuint src, DecoderPtr decoder) OpenAL_SoundStream::OpenAL_SoundStream(OpenAL_Output &output, ALuint src, DecoderPtr decoder, float basevol, float pitch, int flags)
: mOutput(output), mSource(src), mSamplesQueued(0), mDecoder(decoder), mIsFinished(true) : Sound(Ogre::Vector3(0.0f), 1.0f, basevol, pitch, 1.0f, 1000.0f, flags)
, mOutput(output), mSource(src), mSamplesQueued(0), mDecoder(decoder), mIsFinished(true)
{ {
throwALerror(); throwALerror();
@ -324,6 +327,25 @@ double OpenAL_SoundStream::getTimeOffset()
return t; return t;
} }
void OpenAL_SoundStream::updateAll(bool local)
{
alSourcef(mSource, AL_REFERENCE_DISTANCE, mMinDistance);
alSourcef(mSource, AL_MAX_DISTANCE, mMaxDistance);
if(local)
{
alSourcef(mSource, AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(mSource, AL_SOURCE_RELATIVE, AL_TRUE);
}
else
{
alSourcef(mSource, AL_ROLLOFF_FACTOR, 1.0f);
alSourcei(mSource, AL_SOURCE_RELATIVE, AL_FALSE);
}
alSourcei(mSource, AL_LOOPING, AL_FALSE);
update();
}
void OpenAL_SoundStream::update() void OpenAL_SoundStream::update()
{ {
ALfloat gain = mVolume*mBaseVolume; ALfloat gain = mVolume*mBaseVolume;
@ -411,12 +433,14 @@ protected:
friend class OpenAL_Output; friend class OpenAL_Output;
void updateAll(bool local);
private: private:
OpenAL_Sound(const OpenAL_Sound &rhs); OpenAL_Sound(const OpenAL_Sound &rhs);
OpenAL_Sound& operator=(const OpenAL_Sound &rhs); OpenAL_Sound& operator=(const OpenAL_Sound &rhs);
public: public:
OpenAL_Sound(OpenAL_Output &output, ALuint src, ALuint buf); OpenAL_Sound(OpenAL_Output &output, ALuint src, ALuint buf, const Ogre::Vector3& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags);
virtual ~OpenAL_Sound(); virtual ~OpenAL_Sound();
virtual void stop(); virtual void stop();
@ -434,15 +458,16 @@ class OpenAL_Sound3D : public OpenAL_Sound
OpenAL_Sound3D& operator=(const OpenAL_Sound &rhs); OpenAL_Sound3D& operator=(const OpenAL_Sound &rhs);
public: public:
OpenAL_Sound3D(OpenAL_Output &output, ALuint src, ALuint buf) OpenAL_Sound3D(OpenAL_Output &output, ALuint src, ALuint buf, const Ogre::Vector3& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
: OpenAL_Sound(output, src, buf) : OpenAL_Sound(output, src, buf, pos, vol, basevol, pitch, mindist, maxdist, flags)
{ } { }
virtual void update(); virtual void update();
}; };
OpenAL_Sound::OpenAL_Sound(OpenAL_Output &output, ALuint src, ALuint buf) OpenAL_Sound::OpenAL_Sound(OpenAL_Output &output, ALuint src, ALuint buf, const Ogre::Vector3& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
: mOutput(output), mSource(src), mBuffer(buf) : Sound(pos, vol, basevol, pitch, mindist, maxdist, flags)
, mOutput(output), mSource(src), mBuffer(buf)
{ {
mOutput.mActiveSounds.push_back(this); mOutput.mActiveSounds.push_back(this);
} }
@ -484,10 +509,30 @@ double OpenAL_Sound::getTimeOffset()
return t; return t;
} }
void OpenAL_Sound::updateAll(bool local)
{
alSourcef(mSource, AL_REFERENCE_DISTANCE, mMinDistance);
alSourcef(mSource, AL_MAX_DISTANCE, mMaxDistance);
if(local)
{
alSourcef(mSource, AL_ROLLOFF_FACTOR, 0.0f);
alSourcei(mSource, AL_SOURCE_RELATIVE, AL_TRUE);
}
else
{
alSourcef(mSource, AL_ROLLOFF_FACTOR, 1.0f);
alSourcei(mSource, AL_SOURCE_RELATIVE, AL_FALSE);
}
alSourcei(mSource, AL_LOOPING, (mFlags&MWBase::SoundManager::Play_Loop) ? AL_TRUE : AL_FALSE);
update();
}
void OpenAL_Sound::update() void OpenAL_Sound::update()
{ {
ALfloat gain = mVolume*mBaseVolume; ALfloat gain = mVolume*mBaseVolume;
ALfloat pitch = mPitch; ALfloat pitch = mPitch;
if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater)
{ {
gain *= 0.9f; gain *= 0.9f;
@ -731,7 +776,7 @@ void OpenAL_Output::bufferFinished(ALuint buf)
} }
MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, int flags) MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float vol, float basevol, float pitch, int flags)
{ {
boost::shared_ptr<OpenAL_Sound> sound; boost::shared_ptr<OpenAL_Sound> sound;
ALuint src=0, buf=0; ALuint src=0, buf=0;
@ -744,7 +789,7 @@ MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume
try try
{ {
buf = getBuffer(fname); buf = getBuffer(fname);
sound.reset(new OpenAL_Sound(*this, src, buf)); sound.reset(new OpenAL_Sound(*this, src, buf, Ogre::Vector3(0.0f), vol, basevol, pitch, 1.0f, 1000.0f, flags));
} }
catch(std::exception &e) catch(std::exception &e)
{ {
@ -755,25 +800,7 @@ MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume
throw; throw;
} }
alSource3f(src, AL_POSITION, 0.0f, 0.0f, 0.0f); sound->updateAll(true);
alSource3f(src, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSource3f(src, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSourcef(src, AL_REFERENCE_DISTANCE, 1.0f);
alSourcef(src, AL_MAX_DISTANCE, 1000.0f);
alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);
if(!(flags&MWBase::SoundManager::Play_NoEnv) && mLastEnvironment == Env_Underwater)
{
volume *= 0.9f;
pitch *= 0.7f;
}
alSourcef(src, AL_GAIN, volume);
alSourcef(src, AL_PITCH, pitch);
alSourcei(src, AL_SOURCE_RELATIVE, AL_TRUE);
alSourcei(src, AL_LOOPING, (flags&MWBase::SoundManager::Play_Loop) ? AL_TRUE : AL_FALSE);
throwALerror();
alSourcei(src, AL_BUFFER, buf); alSourcei(src, AL_BUFFER, buf);
alSourcePlay(src); alSourcePlay(src);
@ -782,7 +809,7 @@ MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume
return sound; return sound;
} }
MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float vol, float basevol, float pitch,
float min, float max, int flags) float min, float max, int flags)
{ {
boost::shared_ptr<OpenAL_Sound> sound; boost::shared_ptr<OpenAL_Sound> sound;
@ -796,7 +823,7 @@ MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre
try try
{ {
buf = getBuffer(fname); buf = getBuffer(fname);
sound.reset(new OpenAL_Sound3D(*this, src, buf)); sound.reset(new OpenAL_Sound3D(*this, src, buf, pos, vol, basevol, pitch, min, max, flags));
} }
catch(std::exception &e) catch(std::exception &e)
{ {
@ -807,26 +834,7 @@ MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre
throw; throw;
} }
alSource3f(src, AL_POSITION, pos.x, pos.z, -pos.y); sound->updateAll(false);
alSource3f(src, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSource3f(src, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSourcef(src, AL_REFERENCE_DISTANCE, min);
alSourcef(src, AL_MAX_DISTANCE, max);
alSourcef(src, AL_ROLLOFF_FACTOR, 1.0f);
if(!(flags&MWBase::SoundManager::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);
alSourcei(src, AL_SOURCE_RELATIVE, AL_FALSE);
alSourcei(src, AL_LOOPING, (flags&MWBase::SoundManager::Play_Loop) ? AL_TRUE : AL_FALSE);
throwALerror();
alSourcei(src, AL_BUFFER, buf); alSourcei(src, AL_BUFFER, buf);
alSourcePlay(src); alSourcePlay(src);
@ -850,7 +858,7 @@ MWBase::SoundPtr OpenAL_Output::streamSound(DecoderPtr decoder, float volume, fl
std::cout <<"Warning: cannot loop stream \""<<decoder->getName()<<"\""<< std::endl; std::cout <<"Warning: cannot loop stream \""<<decoder->getName()<<"\""<< std::endl;
try try
{ {
sound.reset(new OpenAL_SoundStream(*this, src, decoder)); sound.reset(new OpenAL_SoundStream(*this, src, decoder, volume, pitch, flags));
} }
catch(std::exception &e) catch(std::exception &e)
{ {
@ -858,25 +866,7 @@ MWBase::SoundPtr OpenAL_Output::streamSound(DecoderPtr decoder, float volume, fl
throw; throw;
} }
alSource3f(src, AL_POSITION, 0.0f, 0.0f, 0.0f); sound->updateAll(true);
alSource3f(src, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
alSource3f(src, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
alSourcef(src, AL_REFERENCE_DISTANCE, 1.0f);
alSourcef(src, AL_MAX_DISTANCE, 1000.0f);
alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f);
if(!(flags&MWBase::SoundManager::Play_NoEnv) && mLastEnvironment == Env_Underwater)
{
volume *= 0.9f;
pitch *= 0.7f;
}
alSourcef(src, AL_GAIN, volume);
alSourcef(src, AL_PITCH, pitch);
alSourcei(src, AL_SOURCE_RELATIVE, AL_TRUE);
alSourcei(src, AL_LOOPING, AL_FALSE);
throwALerror();
sound->play(); sound->play();
return sound; return sound;

View file

@ -48,9 +48,9 @@ namespace MWSound
virtual void init(const std::string &devname=""); virtual void init(const std::string &devname="");
virtual void deinit(); virtual void deinit();
virtual MWBase::SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags); virtual MWBase::SoundPtr playSound(const std::string &fname, float vol, float basevol, float pitch, int flags);
virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
float volume, float pitch, float min, float max, int flags); float vol, float basevol, float pitch, float min, float max, int flags);
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags); virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags);
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env); virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env);

View file

@ -30,13 +30,14 @@ namespace MWSound
void setPosition(const Ogre::Vector3 &pos) { mPos = pos; } void setPosition(const Ogre::Vector3 &pos) { mPos = pos; }
void setVolume(float volume) { mVolume = volume; } void setVolume(float volume) { mVolume = volume; }
Sound() : mPos(0.0f, 0.0f, 0.0f) Sound(const Ogre::Vector3& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
, mVolume(1.0f) : mPos(pos)
, mBaseVolume(1.0f) , mVolume(vol)
, mPitch(1.0f) , mBaseVolume(basevol)
, mMinDistance(20.0f) /* 1 * min_range_scale */ , mPitch(pitch)
, mMaxDistance(12750.0f) /* 255 * max_range_scale */ , mMinDistance(mindist)
, mFlags(MWBase::SoundManager::Play_Normal) , mMaxDistance(maxdist)
, mFlags(flags)
{ } { }
virtual ~Sound() { } virtual ~Sound() { }

View file

@ -24,9 +24,9 @@ namespace MWSound
virtual void init(const std::string &devname="") = 0; virtual void init(const std::string &devname="") = 0;
virtual void deinit() = 0; virtual void deinit() = 0;
virtual MWBase::SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags) = 0; virtual MWBase::SoundPtr playSound(const std::string &fname, float vol, float basevol, float pitch, int flags) = 0;
virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos,
float volume, float pitch, float min, float max, int flags) = 0; float vol, float basevol, float pitch, float min, float max, int flags) = 0;
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags) = 0; virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags) = 0;
virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) = 0; virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) = 0;

View file

@ -221,11 +221,8 @@ namespace MWSound
const ESM::Position &pos = ptr.getRefData().getPosition(); const ESM::Position &pos = ptr.getRefData().getPosition();
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, basevol, 1.0f, MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, 1.0f, basevol, 1.0f,
20.0f, 12750.0f, Play_Normal); 20.0f, 12750.0f, Play_Normal);
sound->mPos = objpos;
sound->mBaseVolume = basevol;
mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound")); mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound"));
} }
catch(std::exception &e) catch(std::exception &e)
@ -243,9 +240,7 @@ namespace MWSound
float basevol = mMasterVolume * mVoiceVolume; float basevol = mMasterVolume * mVoiceVolume;
std::string filePath = "Sound/"+filename; std::string filePath = "Sound/"+filename;
MWBase::SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal); MWBase::SoundPtr sound = mOutput->playSound(filePath, 1.0f, basevol, 1.0f, Play_Normal);
sound->mBaseVolume = basevol;
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound")); mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound"));
} }
catch(std::exception &e) catch(std::exception &e)
@ -282,11 +277,7 @@ namespace MWSound
return track; return track;
try try
{ {
float basevol = mMasterVolume; track = mOutput->streamSound(decoder, mMasterVolume, 1.0f, Play_NoEnv);
track = mOutput->streamSound(decoder, basevol, 1.0f, Play_NoEnv);
track->mBaseVolume = basevol;
track->mFlags = Play_NoEnv;
} }
catch(std::exception &e) catch(std::exception &e)
{ {
@ -307,14 +298,7 @@ namespace MWSound
float min, max; float min, max;
std::string file = lookup(soundId, basevol, min, max); std::string file = lookup(soundId, basevol, min, max);
sound = mOutput->playSound(file, volume*basevol, pitch, mode); sound = mOutput->playSound(file, volume, basevol, pitch, mode);
sound->mVolume = volume;
sound->mBaseVolume = basevol;
sound->mPitch = pitch;
sound->mMinDistance = min;
sound->mMaxDistance = max;
sound->mFlags = mode;
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId); mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
} }
catch(std::exception &e) catch(std::exception &e)
@ -339,15 +323,7 @@ namespace MWSound
const ESM::Position &pos = ptr.getRefData().getPosition();; const ESM::Position &pos = ptr.getRefData().getPosition();;
const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]);
sound = mOutput->playSound3D(file, objpos, volume*basevol, pitch, min, max, mode); sound = mOutput->playSound3D(file, objpos, volume, basevol, pitch, min, max, mode);
sound->mPos = objpos;
sound->mVolume = volume;
sound->mBaseVolume = basevol;
sound->mPitch = pitch;
sound->mMinDistance = min;
sound->mMaxDistance = max;
sound->mFlags = mode;
if((mode&Play_NoTrack)) if((mode&Play_NoTrack))
mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId); mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId);
else else