Queue up sfx instead of starting them immediately. Preparation for

threading the sfx manager.
This commit is contained in:
hiker 2014-09-18 11:43:26 +10:00
parent 64fc2dd968
commit c147dacbc2
7 changed files with 105 additions and 52 deletions

View File

@ -42,26 +42,24 @@ class Vec3;
class SFXBase : public NoCopy
{
public:
virtual ~SFXBase() {}
virtual ~SFXBase() {}
/** Late creation, if SFX was initially disabled */
virtual bool init() = 0;
virtual bool init() = 0;
virtual void position(const Vec3 &position) = 0;
virtual void setLoop(bool status) = 0;
virtual void play() = 0;
virtual void stop() = 0;
virtual void pause() = 0;
virtual void resume() = 0;
virtual void speed(float factor) = 0;
virtual void volume(float gain) = 0;
virtual void masterVolume(float gain) = 0;
virtual SFXManager::SFXStatus
getStatus() = 0;
virtual void onSoundEnabledBack() = 0;
virtual void setRolloff(float rolloff) = 0;
virtual const SFXBuffer* getBuffer() const = 0;
virtual void setLoop(bool status) = 0;
virtual void play() = 0;
virtual void reallyPlayNow() = 0;
virtual void stop() = 0;
virtual void pause() = 0;
virtual void resume() = 0;
virtual void speed(float factor) = 0;
virtual void volume(float gain) = 0;
virtual void setMasterVolume(float gain) = 0;
virtual void onSoundEnabledBack() = 0;
virtual void setRolloff(float rolloff) = 0;
virtual const SFXBuffer* getBuffer() const = 0;
virtual SFXManager::SFXStatus getStatus() = 0;
}; // SfxBase

View File

@ -18,8 +18,11 @@
#include "audio/dummy_sfx.hpp"
#include "audio/music_manager.hpp"
#include "audio/sfx_openal.hpp"
#include "audio/sfx_buffer.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "race/race_manager.hpp"
#include <stdexcept>
#include <algorithm>
@ -39,12 +42,6 @@
# endif
#endif
#include "audio/sfx_openal.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "race/race_manager.hpp"
#include "utils/constants.hpp"
SFXManager *SFXManager::m_sfx_manager;
// ----------------------------------------------------------------------------
@ -80,7 +77,9 @@ SFXManager::SFXManager()
loadSfx();
if (!sfxAllowed()) return;
setMasterSFXVolume( UserConfigParams::m_sfx_volume );
m_sfx_to_play.lock();
m_sfx_to_play.getData().clear();
m_sfx_to_play.unlock();
} // SoundManager
//-----------------------------------------------------------------------------
@ -122,6 +121,40 @@ SFXManager::~SFXManager()
} // ~SFXManager
//----------------------------------------------------------------------------
/** Adds a sound effect to the queue of sfx to be started by the sfx manager.
* Starting a sfx can sometimes cause a 5ms delay, so it is done in a
* separate thread.
* \param sfx The sound effect to be started.
*/
void SFXManager::queue(SFXBase *sfx)
{
// Don't add sfx that are either not working correctly (e.g. because sfx
// are disabled);
if(sfx->getStatus()==SFX_UNKNOWN ) return;
m_sfx_to_play.lock();
m_sfx_to_play.getData().push_back(sfx);
m_sfx_to_play.unlock();
} // playSFX
//----------------------------------------------------------------------------
/** Starts all sfx that are queues to be started. Called once per frame.
*/
void SFXManager::update()
{
m_sfx_to_play.lock();
while(!m_sfx_to_play.getData().empty())
{
SFXBase *sfx = m_sfx_to_play.getData().front();
m_sfx_to_play.getData().erase(m_sfx_to_play.getData().begin());
m_sfx_to_play.unlock();
sfx->reallyPlayNow();
m_sfx_to_play.lock();
} // while !empty
m_sfx_to_play.unlock();
} // update
//----------------------------------------------------------------------------
/** Called then sound is globally switched on or off. It either pauses or
* resumes all sound effects.
@ -327,7 +360,7 @@ SFXBase* SFXManager::createSoundSource(SFXBuffer* buffer,
SFXBase* sfx = new DummySFX(buffer, positional, buffer->getGain(), owns_buffer);
#endif
sfx->masterVolume(m_master_gain);
sfx->setMasterVolume(m_master_gain);
if (add_to_SFX_list) m_all_sfx.push_back(sfx);
@ -475,7 +508,7 @@ void SFXManager::setMasterSFXVolume(float gain)
for (std::vector<SFXBase*>::iterator i=m_all_sfx.begin();
i!=m_all_sfx.end(); i++)
{
(*i)->masterVolume(m_master_gain);
(*i)->setMasterVolume(m_master_gain);
} // for i in m_all_sfx
}
@ -484,7 +517,7 @@ void SFXManager::setMasterSFXVolume(float gain)
std::map<std::string, SFXBase*>::iterator i = m_quick_sounds.begin();
for (; i != m_quick_sounds.end(); i++)
{
(*i).second->masterVolume(m_master_gain);
(*i).second->setMasterVolume(m_master_gain);
}
}

View File

@ -19,10 +19,13 @@
#ifndef HEADER_SFX_MANAGER_HPP
#define HEADER_SFX_MANAGER_HPP
#include "utils/no_copy.hpp"
#include "utils/synchronised.hpp"
#include "utils/vec3.hpp"
#include <map>
#include <string>
#include <vector>
#include <map>
#if HAVE_OGGVORBIS
# ifdef __APPLE__
@ -31,11 +34,9 @@
# include <AL/al.h>
# endif
#else
typedef unsigned int ALuint;
typedef unsigned int ALuint;
#endif
#include "utils/no_copy.hpp"
#include "utils/vec3.hpp"
class SFXBase;
class SFXBuffer;
@ -94,6 +95,9 @@ private:
/** The actual instances (sound sources) */
std::vector<SFXBase*> m_all_sfx;
/** The list of sound effects to be played in the next update. */
Synchronised< std::vector<SFXBase*> > m_sfx_to_play;
/** To play non-positional sounds without having to create a new object for each */
std::map<std::string, SFXBase*> m_quick_sounds;
@ -113,6 +117,8 @@ private:
public:
static void create();
static void destroy();
void queue(SFXBase *sfx);
void update();
// ------------------------------------------------------------------------
/** Static function to get the singleton sfx manager. */
static SFXManager *get()

View File

@ -85,28 +85,30 @@ bool SFXOpenAL::init()
assert( alIsBuffer(m_soundBuffer->getBufferID()) );
assert( alIsSource(m_soundSource) );
//std::cout << "Setting a source with buffer " << m_soundBuffer << ", rolloff " << rolloff
// << ", gain=" << m_defaultGain << ", positional=" << (positional ? "true" : "false") << std::endl;
//std::cout << "Setting a source with buffer " << m_soundBuffer
// << ", rolloff " << rolloff
// << ", gain=" << m_defaultGain << ", positional="
// << (positional ? "true" : "false") << std::endl;
alSourcei (m_soundSource, AL_BUFFER, m_soundBuffer->getBufferID());
alSourcei (m_soundSource, AL_BUFFER, m_soundBuffer->getBufferID());
if (!SFXManager::checkError("attaching the buffer to the source")) return false;
if (!SFXManager::checkError("attaching the buffer to the source"))
return false;
alSource3f(m_soundSource, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_VELOCITY, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_DIRECTION, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_VELOCITY, 0.0, 0.0, 0.0);
alSource3f(m_soundSource, AL_DIRECTION, 0.0, 0.0, 0.0);
alSourcef (m_soundSource, AL_ROLLOFF_FACTOR, m_soundBuffer->getRolloff());
alSourcef (m_soundSource, AL_MAX_DISTANCE, m_soundBuffer->getMaxDist());
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 * m_master_gain);
alSourcef (m_soundSource, AL_GAIN, m_defaultGain * m_master_gain);
}
else
{
alSourcef (m_soundSource, AL_GAIN, m_gain * m_master_gain);
alSourcef (m_soundSource, AL_GAIN, m_gain * m_master_gain);
}
if (m_positional) alSourcei (m_soundSource, AL_SOURCE_RELATIVE, AL_FALSE);
@ -117,7 +119,7 @@ bool SFXOpenAL::init()
m_ok = SFXManager::checkError("setting up the source");
return m_ok;
}
} // init
//-----------------------------------------------------------------------------
/** Changes the pitch of a sound effect.
@ -156,15 +158,16 @@ void SFXOpenAL::volume(float gain)
//-----------------------------------------------------------------------------
void SFXOpenAL::masterVolume(float gain)
void SFXOpenAL::setMasterVolume(float gain)
{
m_master_gain = gain;
if(!m_ok) return;
alSourcef(m_soundSource, AL_GAIN, (m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
alSourcef(m_soundSource, AL_GAIN,
(m_gain < 0.0f ? m_defaultGain : m_gain) * m_master_gain);
SFXManager::checkError("setting volume");
}
} //setMasterVolume
//-----------------------------------------------------------------------------
/** Loops this sound effect.
@ -222,9 +225,18 @@ void SFXOpenAL::resume()
} // resume
//-----------------------------------------------------------------------------
/** Plays this sound effect.
/** This actually queues up the sfx in the sfx manager. It will be started
* from a separate thread later (in this frame).
*/
void SFXOpenAL::play()
{
SFXManager::get()->queue(this);
} // play
//-----------------------------------------------------------------------------
/** Plays this sound effect.
*/
void SFXOpenAL::reallyPlayNow()
{
if (!SFXManager::get()->sfxAllowed()) return;
if (!m_ok)
@ -238,7 +250,7 @@ void SFXOpenAL::play()
alSourcePlay(m_soundSource);
SFXManager::checkError("playing");
} // play
} // reallyPlayNow
//-----------------------------------------------------------------------------
/** Sets the position where this sound effects is played.

View File

@ -70,6 +70,7 @@ public:
virtual bool init();
virtual void play();
virtual void reallyPlayNow();
virtual void setLoop(bool status);
virtual void stop();
virtual void pause();
@ -77,7 +78,7 @@ public:
virtual void speed(float factor);
virtual void position(const Vec3 &position);
virtual void volume(float gain);
virtual void masterVolume(float gain);
virtual void setMasterVolume(float gain);
virtual SFXManager::SFXStatus getStatus();
virtual void onSoundEnabledBack();
virtual void setRolloff(float rolloff);

View File

@ -67,5 +67,7 @@ void HitSFX::setPlayerKartHit()
*/
bool HitSFX::updateAndDelete(float dt)
{
return m_sfx->getStatus() != SFXManager::SFX_PLAYING;
SFXManager::SFXStatus status = m_sfx->getStatus();
if(status==SFXManager::SFX_INITIAL) return false;
return status!= SFXManager::SFX_PLAYING;
} // updateAndDelete

View File

@ -22,6 +22,7 @@
#include <assert.h>
#include "audio/music_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp"
@ -139,7 +140,7 @@ void MainLoop::run()
{
PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00);
music_manager->update(dt);
SFXManager::get()->update();
input_manager->update(dt);
#ifdef ENABLE_WIIUSE