Avoid calling querying the openal status in getStatus (which causes
a slowdown of sfx).
This commit is contained in:
parent
d753fab7db
commit
22633aa363
@ -589,6 +589,7 @@ void SFXManager::resumeAll()
|
||||
/** Returns whether or not an openal error has occurred. If so, an error
|
||||
* message is printed containing the given context.
|
||||
* \param context Context to specify in the error message.
|
||||
* \return True if no error happened.
|
||||
*/
|
||||
bool SFXManager::checkError(const std::string &context)
|
||||
{
|
||||
|
@ -23,8 +23,7 @@
|
||||
|
||||
#include "audio/sfx_buffer.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "modes/world.hpp"
|
||||
#include "utils/vs.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
@ -38,18 +37,19 @@
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBuffer) : SFXBase()
|
||||
SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool owns_buffer) : SFXBase()
|
||||
{
|
||||
m_sound_buffer = buffer;
|
||||
m_sound_source = 0;
|
||||
m_ok = false;
|
||||
m_status = SFX_UNKNOWN;
|
||||
m_is_playing = false;
|
||||
m_positional = positional;
|
||||
m_defaultGain = gain;
|
||||
m_loop = false;
|
||||
m_gain = -1.0f;
|
||||
m_master_gain = 1.0f;
|
||||
m_owns_buffer = ownsBuffer;
|
||||
m_owns_buffer = owns_buffer;
|
||||
m_end_time = -1.0f;
|
||||
|
||||
// Don't initialise anything else if the sfx manager was not correctly
|
||||
// initialised. First of all the initialisation will not work, and it
|
||||
@ -61,15 +61,16 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float gain, bool ownsBu
|
||||
} // SFXOpenAL
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** Deletes the sfx source, and if it owns the buffer, also deletes the sound
|
||||
* buffer. */
|
||||
SFXOpenAL::~SFXOpenAL()
|
||||
{
|
||||
if (m_ok)
|
||||
if (m_status!=SFX_UNKNOWN)
|
||||
{
|
||||
alDeleteSources(1, &m_sound_source);
|
||||
}
|
||||
|
||||
if (m_owns_buffer && m_sound_buffer != NULL)
|
||||
if (m_owns_buffer && m_sound_buffer)
|
||||
{
|
||||
m_sound_buffer->unload();
|
||||
delete m_sound_buffer;
|
||||
@ -86,9 +87,6 @@ bool SFXOpenAL::init()
|
||||
assert( alIsBuffer(m_sound_buffer->getBufferID()) );
|
||||
assert( alIsSource(m_sound_source) );
|
||||
|
||||
//Log::info("SFXOpenAL", "Setting a source with buffer, %p, rolloff %f, gain = %f, position = %s",
|
||||
// m_sound_buffer, rolloff, m_defaultGain, positional ? "true" : "false");
|
||||
|
||||
alSourcei (m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID());
|
||||
|
||||
if (!SFXManager::checkError("attaching the buffer to the source"))
|
||||
@ -115,18 +113,35 @@ bool SFXOpenAL::init()
|
||||
|
||||
alSourcei(m_sound_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE);
|
||||
|
||||
m_ok = SFXManager::checkError("setting up the source");
|
||||
if(SFXManager::checkError("setting up the source"))
|
||||
m_status = SFX_INITIAL;
|
||||
|
||||
return m_ok;
|
||||
return m_status==SFX_INITIAL;
|
||||
} // init
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the status of this sfx. */
|
||||
SFXBase::SFXStatus SFXOpenAL::getStatus()
|
||||
{
|
||||
if(m_status==SFX_PLAYING)
|
||||
{
|
||||
if(m_loop) return SFX_PLAYING;
|
||||
if(World::getWorld() && World::getWorld()->getTime() > m_end_time)
|
||||
{
|
||||
m_status = SFX_STOPPED;
|
||||
return m_status;
|
||||
}
|
||||
}
|
||||
return m_status;
|
||||
} // getStatus;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Changes the pitch of a sound effect.
|
||||
* \param factor Speedup/slowdown between 0.5 and 2.0
|
||||
*/
|
||||
void SFXOpenAL::speed(float factor)
|
||||
{
|
||||
if(!m_ok || isnan(factor)) return;
|
||||
if(m_status==SFX_UNKNOWN || isnan(factor)) return;
|
||||
|
||||
//OpenAL only accepts pitches in the range of 0.5 to 2.0
|
||||
if(factor > 2.0f)
|
||||
@ -149,7 +164,7 @@ void SFXOpenAL::volume(float gain)
|
||||
{
|
||||
m_gain = m_defaultGain * gain;
|
||||
|
||||
if(!m_ok) return;
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
|
||||
alSourcef(m_sound_source, AL_GAIN, m_gain * m_master_gain);
|
||||
SFXManager::checkError("setting volume");
|
||||
@ -161,7 +176,7 @@ void SFXOpenAL::setMasterVolume(float gain)
|
||||
{
|
||||
m_master_gain = gain;
|
||||
|
||||
if(!m_ok) return;
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
|
||||
alSourcef(m_sound_source, AL_GAIN,
|
||||
(m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
|
||||
@ -175,7 +190,7 @@ void SFXOpenAL::setLoop(bool status)
|
||||
{
|
||||
m_loop = status;
|
||||
|
||||
if(!m_ok) return;
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
|
||||
alSourcei(m_sound_source, AL_LOOPING, status ? AL_TRUE : AL_FALSE);
|
||||
SFXManager::checkError("looping");
|
||||
@ -193,9 +208,10 @@ void SFXOpenAL::stop()
|
||||
*/
|
||||
void SFXOpenAL::reallyStopNow()
|
||||
{
|
||||
if(!m_ok) return;
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
|
||||
m_is_playing = false;
|
||||
m_status = SFX_STOPPED;
|
||||
m_loop = false;
|
||||
alSourcei(m_sound_source, AL_LOOPING, AL_FALSE);
|
||||
alSourceStop(m_sound_source);
|
||||
@ -216,7 +232,8 @@ void SFXOpenAL::pause()
|
||||
*/
|
||||
void SFXOpenAL::reallyPauseNow()
|
||||
{
|
||||
if(!m_ok) return;
|
||||
if(m_status==SFX_UNKNOWN) return;
|
||||
m_status = SFX_PAUSED;
|
||||
alSourcePause(m_sound_source);
|
||||
SFXManager::checkError("pausing");
|
||||
} // reallyPauseNow
|
||||
@ -234,18 +251,21 @@ void SFXOpenAL::resume()
|
||||
*/
|
||||
void SFXOpenAL::reallyResumeNow()
|
||||
{
|
||||
if (!m_ok)
|
||||
if (m_status==SFX_UNKNOWN)
|
||||
{
|
||||
// lazily create OpenAL source when needed
|
||||
init();
|
||||
|
||||
// creation of OpenAL source failed, giving up
|
||||
if (!m_ok) return;
|
||||
if (m_status==SFX_UNKNOWN) return;
|
||||
}
|
||||
|
||||
if(getStatus()==SFX_PAUSED)
|
||||
if(m_status==SFX_PAUSED)
|
||||
{
|
||||
alSourcePlay(m_sound_source);
|
||||
SFXManager::checkError("resuming");
|
||||
SFXManager::checkError("resuming");
|
||||
m_status = SFX_PLAYING;
|
||||
}
|
||||
} // reallyResumeNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -277,17 +297,24 @@ void SFXOpenAL::play()
|
||||
void SFXOpenAL::reallyPlayNow()
|
||||
{
|
||||
if (!SFXManager::get()->sfxAllowed()) return;
|
||||
if (!m_ok)
|
||||
if (m_status==SFX_UNKNOWN)
|
||||
{
|
||||
// lazily create OpenAL source when needed
|
||||
init();
|
||||
|
||||
// creation of OpenAL source failed, giving up
|
||||
if (!m_ok) return;
|
||||
if (m_status==SFX_UNKNOWN) return;
|
||||
}
|
||||
|
||||
alSourcePlay(m_sound_source);
|
||||
m_status = SFX_PLAYING;
|
||||
SFXManager::checkError("playing");
|
||||
|
||||
// At non-race time the end time is not important
|
||||
if(World::getWorld())
|
||||
m_end_time = World::getWorld()->getTime()+m_sound_buffer->getDuration();
|
||||
else
|
||||
m_end_time = 1.0f;
|
||||
} // reallyPlayNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -306,9 +333,10 @@ void SFXOpenAL::position(const Vec3 &position)
|
||||
{
|
||||
if(!UserConfigParams::m_sfx)
|
||||
return;
|
||||
if (!m_ok)
|
||||
if (m_status==SFX_UNKNOWN)
|
||||
{
|
||||
Log::warn("SFX", "Position called on non-ok SFX <%s>", m_sound_buffer->getFileName().c_str());
|
||||
Log::warn("SFX", "Position called on non-ok SFX <%s>",
|
||||
m_sound_buffer->getFileName().c_str());
|
||||
return;
|
||||
}
|
||||
if (!m_positional)
|
||||
@ -338,33 +366,14 @@ void SFXOpenAL::position(const Vec3 &position)
|
||||
SFXManager::checkError("positioning");
|
||||
} // position
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the status of this sound effect.
|
||||
*/
|
||||
SFXBase::SFXStatus SFXOpenAL::getStatus()
|
||||
{
|
||||
if(!m_ok) return SFX_UNKNOWN;
|
||||
|
||||
int state = 0;
|
||||
alGetSourcei(m_sound_source, AL_SOURCE_STATE, &state);
|
||||
switch(state)
|
||||
{
|
||||
case AL_STOPPED: return SFX_STOPPED;
|
||||
case AL_PLAYING: return SFX_PLAYING;
|
||||
case AL_PAUSED: return SFX_PAUSED;
|
||||
case AL_INITIAL: return SFX_INITIAL;
|
||||
default: return SFX_UNKNOWN;
|
||||
}
|
||||
} // getStatus
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXOpenAL::onSoundEnabledBack()
|
||||
{
|
||||
if (m_loop)
|
||||
{
|
||||
if (!m_ok) init();
|
||||
if (m_ok)
|
||||
if (m_status==SFX_UNKNOWN) init();
|
||||
if (m_status!=SFX_UNKNOWN)
|
||||
{
|
||||
alSourcef(m_sound_source, AL_GAIN, 0);
|
||||
play();
|
||||
@ -372,7 +381,7 @@ void SFXOpenAL::onSoundEnabledBack()
|
||||
alSourcef(m_sound_source, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // onSoundEnabledBack
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -37,13 +37,17 @@
|
||||
class SFXOpenAL : public SFXBase
|
||||
{
|
||||
private:
|
||||
LEAK_CHECK()
|
||||
|
||||
/** Buffers hold sound data. */
|
||||
SFXBuffer* m_sound_buffer;
|
||||
|
||||
/** Sources are points emitting sound. */
|
||||
ALuint m_sound_source;
|
||||
|
||||
bool m_ok;
|
||||
/** The status of this SFX. */
|
||||
SFXStatus m_status;
|
||||
|
||||
bool m_positional;
|
||||
float m_defaultGain;
|
||||
|
||||
@ -65,39 +69,42 @@ private:
|
||||
/** The master gain set in user preferences */
|
||||
float m_master_gain;
|
||||
|
||||
/** If this sfx should also free the sound buffer. */
|
||||
bool m_owns_buffer;
|
||||
|
||||
/** Time at which a sfx ends playing. Used to avoid frequently getting
|
||||
* the openl status (which can slow down stk). */
|
||||
float m_end_time;
|
||||
|
||||
public:
|
||||
SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
|
||||
bool owns_buffer = false);
|
||||
virtual ~SFXOpenAL();
|
||||
SFXOpenAL(SFXBuffer* buffer, bool positional, float gain,
|
||||
bool owns_buffer = false);
|
||||
virtual ~SFXOpenAL();
|
||||
|
||||
/** Late creation, if SFX was initially disabled */
|
||||
virtual bool init();
|
||||
|
||||
virtual void play();
|
||||
virtual void reallyPlayNow();
|
||||
virtual void setLoop(bool status);
|
||||
virtual bool isPlaying();
|
||||
virtual void stop();
|
||||
virtual void reallyStopNow();
|
||||
virtual void pause();
|
||||
virtual void reallyPauseNow();
|
||||
virtual void resume();
|
||||
virtual void reallyResumeNow();
|
||||
virtual void deleteSFX();
|
||||
virtual void speed(float factor);
|
||||
virtual void position(const Vec3 &position);
|
||||
virtual void volume(float gain);
|
||||
virtual void setMasterVolume(float gain);
|
||||
virtual SFXStatus getStatus();
|
||||
virtual void onSoundEnabledBack();
|
||||
virtual void setRolloff(float rolloff);
|
||||
virtual bool init();
|
||||
virtual void play();
|
||||
virtual void reallyPlayNow();
|
||||
virtual void setLoop(bool status);
|
||||
virtual bool isPlaying();
|
||||
virtual void stop();
|
||||
virtual void reallyStopNow();
|
||||
virtual void pause();
|
||||
virtual void reallyPauseNow();
|
||||
virtual void resume();
|
||||
virtual void reallyResumeNow();
|
||||
virtual void deleteSFX();
|
||||
virtual void speed(float factor);
|
||||
virtual void position(const Vec3 &position);
|
||||
virtual void volume(float gain);
|
||||
virtual void setMasterVolume(float gain);
|
||||
virtual void onSoundEnabledBack();
|
||||
virtual void setRolloff(float rolloff);
|
||||
virtual SFXStatus getStatus();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the buffer associated with this sfx. */
|
||||
virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; }
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
}; // SFXOpenAL
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user