forked from mirror/openmw-tes3mp
Add a method to stream sounds in 3D
This commit is contained in:
parent
f1a1dc8408
commit
eee6a19e31
3 changed files with 73 additions and 3 deletions
|
@ -158,9 +158,12 @@ class OpenAL_SoundStream : public Sound
|
|||
static const ALuint sNumBuffers = 6;
|
||||
static const ALfloat sBufferLength;
|
||||
|
||||
protected:
|
||||
OpenAL_Output &mOutput;
|
||||
|
||||
ALuint mSource;
|
||||
|
||||
private:
|
||||
ALuint mBuffers[sNumBuffers];
|
||||
ALint mCurrentBufIdx;
|
||||
|
||||
|
@ -194,9 +197,22 @@ public:
|
|||
bool process();
|
||||
ALint refillQueue();
|
||||
};
|
||||
|
||||
const ALfloat OpenAL_SoundStream::sBufferLength = 0.125f;
|
||||
|
||||
class OpenAL_SoundStream3D : public OpenAL_SoundStream
|
||||
{
|
||||
OpenAL_SoundStream3D(const OpenAL_SoundStream3D &rhs);
|
||||
OpenAL_SoundStream3D& operator=(const OpenAL_SoundStream3D &rhs);
|
||||
|
||||
public:
|
||||
OpenAL_SoundStream3D(OpenAL_Output &output, ALuint src, DecoderPtr decoder, const osg::Vec3f& pos, float vol, float basevol, float pitch, float mindist, float maxdist, int flags)
|
||||
: OpenAL_SoundStream(output, src, decoder, pos, vol, basevol, pitch, mindist, maxdist, flags)
|
||||
{ }
|
||||
|
||||
virtual void update();
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// A background streaming thread (keeps active streams processed)
|
||||
//
|
||||
|
@ -481,6 +497,26 @@ ALint OpenAL_SoundStream::refillQueue()
|
|||
return queued;
|
||||
}
|
||||
|
||||
void OpenAL_SoundStream3D::update()
|
||||
{
|
||||
ALfloat gain = mVolume*mBaseVolume;
|
||||
ALfloat pitch = mPitch;
|
||||
if((mPos - mOutput.mPos).length2() > mMaxDistance*mMaxDistance)
|
||||
gain = 0.0f;
|
||||
else if(!(mFlags&MWBase::SoundManager::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[1], mPos[2]);
|
||||
alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
throwALerror();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// A regular 2D OpenAL sound
|
||||
|
@ -917,6 +953,35 @@ MWBase::SoundPtr OpenAL_Output::streamSound(DecoderPtr decoder, float basevol, f
|
|||
}
|
||||
|
||||
|
||||
MWBase::SoundPtr OpenAL_Output::streamSound3D(DecoderPtr decoder, const osg::Vec3f &pos, float volume, float basevol, float pitch, float min, float max, int flags)
|
||||
{
|
||||
boost::shared_ptr<OpenAL_SoundStream> sound;
|
||||
ALuint src;
|
||||
|
||||
if(mFreeSources.empty())
|
||||
fail("No free sources");
|
||||
src = mFreeSources.front();
|
||||
mFreeSources.pop_front();
|
||||
|
||||
if((flags&MWBase::SoundManager::Play_Loop))
|
||||
std::cout <<"Warning: cannot loop stream \""<<decoder->getName()<<"\""<< std::endl;
|
||||
try
|
||||
{
|
||||
sound.reset(new OpenAL_SoundStream3D(*this, src, decoder, pos, volume, basevol, pitch, min, max, flags));
|
||||
}
|
||||
catch(std::exception&)
|
||||
{
|
||||
mFreeSources.push_back(src);
|
||||
throw;
|
||||
}
|
||||
|
||||
sound->updateAll(true);
|
||||
|
||||
sound->play();
|
||||
return sound;
|
||||
}
|
||||
|
||||
|
||||
void OpenAL_Output::updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env)
|
||||
{
|
||||
mPos = pos;
|
||||
|
|
|
@ -47,7 +47,9 @@ namespace MWSound
|
|||
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
||||
virtual MWBase::SoundPtr playSound3D(Sound_Handle data, const osg::Vec3f &pos,
|
||||
float vol, float basevol, float pitch, float min, float max, int flags, float offset);
|
||||
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags);
|
||||
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float basevol, float pitch, int flags);
|
||||
virtual MWBase::SoundPtr streamSound3D(DecoderPtr decoder, const osg::Vec3f &pos,
|
||||
float vol, float basevol, float pitch, float min, float max, int flags);
|
||||
|
||||
virtual void updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env);
|
||||
|
||||
|
@ -66,6 +68,7 @@ namespace MWSound
|
|||
friend class OpenAL_Sound;
|
||||
friend class OpenAL_Sound3D;
|
||||
friend class OpenAL_SoundStream;
|
||||
friend class OpenAL_SoundStream3D;
|
||||
friend class SoundManager;
|
||||
};
|
||||
#ifndef DEFAULT_OUTPUT
|
||||
|
|
|
@ -35,7 +35,9 @@ namespace MWSound
|
|||
/// @param offset Value from [0,1] meaning from which fraction the sound the playback starts.
|
||||
virtual MWBase::SoundPtr playSound3D(Sound_Handle data, const osg::Vec3f &pos,
|
||||
float vol, float basevol, float pitch, float min, float max, int flags, float offset) = 0;
|
||||
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float volume, float pitch, int flags) = 0;
|
||||
virtual MWBase::SoundPtr streamSound(DecoderPtr decoder, float basevol, float pitch, int flags) = 0;
|
||||
virtual MWBase::SoundPtr streamSound3D(DecoderPtr decoder, const osg::Vec3f &pos,
|
||||
float vol, float basevol, float pitch, float min, float max, int flags) = 0;
|
||||
|
||||
virtual void updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env) = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue