Manually implement muting sounds when too far since OpenAL doesn't seem to have that feature, and use it to finally make the spaceship sound in the intro work

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11422 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2012-07-22 20:05:38 +00:00
parent 9f909b4c26
commit 65d897915a
7 changed files with 46 additions and 8 deletions

View File

@ -39,12 +39,14 @@
SFXBuffer::SFXBuffer(const std::string& file,
bool positional,
float rolloff,
float max_width,
float gain)
{
m_buffer = 0;
m_gain = 1.0f;
m_rolloff = 0.1f;
m_loaded = false;
m_max_dist = max_width;
m_file = file;
m_rolloff = rolloff;
@ -60,6 +62,7 @@ SFXBuffer::SFXBuffer(const std::string& file,
m_buffer = 0;
m_gain = 1.0f;
m_rolloff = 0.1f;
m_max_dist = 300.0f;
m_positional = false;
m_loaded = false;
m_file = file;
@ -67,6 +70,7 @@ SFXBuffer::SFXBuffer(const std::string& file,
node->get("rolloff", &m_rolloff );
node->get("positional", &m_positional );
node->get("volume", &m_gain );
node->get("max_dist", &m_max_dist );
}
//----------------------------------------------------------------------------

View File

@ -55,6 +55,7 @@ private:
bool m_positional;
float m_rolloff;
float m_gain;
float m_max_dist;
bool loadVorbisBuffer(const std::string &name, ALuint buffer);
@ -63,6 +64,7 @@ public:
SFXBuffer(const std::string& file,
bool positional,
float rolloff,
float max_width,
float gain);
SFXBuffer(const std::string& file,
@ -95,6 +97,7 @@ public:
bool isPositional() const { return m_positional; }
float getRolloff() const { return m_rolloff; }
float getGain() const { return m_gain; }
float getMaxDist() const { return m_max_dist; }
std::string getFileName() const { return m_file; }
void setPositional(bool positional) { m_positional = positional; }

View File

@ -185,10 +185,11 @@ SFXBuffer* SFXManager::addSingleSfx(const std::string &sfx_name,
const std::string &sfx_file,
bool positional,
float rolloff,
float max_width,
float gain)
{
SFXBuffer* buffer = new SFXBuffer(sfx_file, positional, rolloff, gain);
SFXBuffer* buffer = new SFXBuffer(sfx_file, positional, rolloff, max_width, gain);
m_all_sfx_types[sfx_name] = buffer;
@ -250,6 +251,7 @@ SFXBuffer* SFXManager::loadSingleSfx(const XMLNode* node,
return addSingleSfx(sfx_name, full_path,
tmpbuffer.isPositional(),
tmpbuffer.getRolloff(),
tmpbuffer.getMaxDist(),
tmpbuffer.getGain());
} // loadSingleSfx
@ -478,6 +480,8 @@ void SFXManager::positionListener(const Vec3 &position, const Vec3 &front)
#if HAVE_OGGVORBIS
if (!UserConfigParams::m_sfx || !m_initialized) return;
m_position = position;
//forward vector
m_listenerVec[0] = front.getX();
m_listenerVec[1] = front.getY();

View File

@ -80,6 +80,9 @@ public:
private:
/** Listener position */
Vec3 m_position;
/** The buffers and info for all sound effects. These are shared among all
* instances of SFXOpenal. */
std::map<std::string, SFXBuffer*> m_all_sfx_types;
@ -110,6 +113,7 @@ public:
const std::string &filename,
bool positional,
float rolloff,
float max_width,
float gain);
SFXBase* createSoundSource(SFXBuffer* info,
@ -137,6 +141,8 @@ public:
/** Prints the list of currently loaded sounds to stdout. Useful to debug audio leaks */
void dump();
Vec3 getListenerPos() const { return m_position; }
};
extern SFXManager* sfx_manager;

View File

@ -87,6 +87,8 @@ bool SFXOpenAL::init()
alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, m_soundBuffer->getRolloff());
alSourcef (m_soundSource, AL_MAX_DISTANCE, m_soundBuffer->getMaxDist());
if (m_gain < 0.0f)
{
alSourcef (m_soundSource, AL_GAIN, m_defaultGain);
@ -242,6 +244,16 @@ void SFXOpenAL::position(const Vec3 &position)
alSource3f(m_soundSource, AL_POSITION,
(float)position.getX(), (float)position.getY(), (float)position.getZ());
if (sfx_manager->getListenerPos().distance(position) > m_soundBuffer->getMaxDist())
{
alSourcef(m_soundSource, AL_GAIN, 0);
}
else
{
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain));
}
SFXManager::checkError("positioning");
} // position

View File

@ -187,8 +187,8 @@ void CutsceneWorld::update(float dt)
rot2.setPitch(rot2.getPitch() + 90.0f);
m_camera->setRotation(rot2.toIrrVector());
sfx_manager->positionListener(curr->getNode()->getPosition(),
m_camera->getTarget() - curr->getNode()->getPosition());
sfx_manager->positionListener(m_camera->getAbsolutePosition(),
m_camera->getTarget() - m_camera->getAbsolutePosition());
break;
//printf("Camera %f %f %f\n", curr->getNode()->getPosition().X, curr->getNode()->getPosition().Y, curr->getNode()->getPosition().Z);

View File

@ -135,8 +135,8 @@ TrackObject::TrackObject(const XMLNode &xml_node)
xml_node.get("conditions", &m_trigger_condition);
float rolloff_distance = 10.0f;
xml_node.get("distance", &rolloff_distance );
float max_dist = 390.0f;
xml_node.get("max_dist", &max_dist );
// first try track dir, then global dir
std::string soundfile = file_manager->getModelFile(sound);
@ -148,6 +148,7 @@ TrackObject::TrackObject(const XMLNode &xml_node)
SFXBuffer* buffer = new SFXBuffer(soundfile,
true /* positional */,
rolloff,
max_dist,
volume);
buffer->load();
@ -420,6 +421,14 @@ void TrackObject::OnAnimationEnd(scene::IAnimatedMeshSceneNode* node)
// ----------------------------------------------------------------------------
void TrackObject::update(float dt)
{
if (m_sound != NULL)
{
// muting when too far is implemented manually since not supported by OpenAL
// so need to call this every frame to update the muting state if listener
// moved
m_sound->position(m_init_xyz);
}
} // update
// ----------------------------------------------------------------------------