diff --git a/src/audio/dummy_sfx.hpp b/src/audio/dummy_sfx.hpp index 63f9893e9..32eb1116d 100644 --- a/src/audio/dummy_sfx.hpp +++ b/src/audio/dummy_sfx.hpp @@ -47,9 +47,9 @@ public: virtual void reallySetSpeedPosition(float f, const Vec3 &p) {} virtual void play() {} - virtual void reallyPlayNow() {} - virtual void play(const Vec3 &xyz) {} - virtual void reallyPlayNow(const Vec3 &xyz) {} + virtual void reallyPlayNow(SFXBuffer* buffer = NULL) {} + virtual void play(const Vec3 &xyz, SFXBuffer* buffer = NULL) {} + virtual void reallyPlayNow(const Vec3 &xyz, SFXBuffer* buffer = NULL) {} virtual void stop() {} virtual void reallyStopNow() {} virtual void pause() {} diff --git a/src/audio/sfx_base.hpp b/src/audio/sfx_base.hpp index e0fff346d..da601bbf1 100644 --- a/src/audio/sfx_base.hpp +++ b/src/audio/sfx_base.hpp @@ -64,9 +64,9 @@ public: virtual void setLoop(bool status) = 0; virtual void reallySetLoop(bool status) = 0; virtual void play() = 0; - virtual void reallyPlayNow() = 0; - virtual void play(const Vec3 &xyz) = 0; - virtual void reallyPlayNow(const Vec3 &xyz) = 0; + virtual void reallyPlayNow(SFXBuffer* buffer = NULL) = 0; + virtual void play(const Vec3 &xyz, SFXBuffer* buffer = NULL) = 0; + virtual void reallyPlayNow(const Vec3 &xyz, SFXBuffer* buffer = NULL) = 0; virtual void stop() = 0; virtual void reallyStopNow() = 0; virtual void pause() = 0; @@ -83,7 +83,6 @@ public: virtual void onSoundEnabledBack() = 0; virtual void setRolloff(float rolloff) = 0; virtual const SFXBuffer* getBuffer() const = 0; - virtual void setBuffer(SFXBuffer* buffer, bool owns_buffer) = 0; virtual SFXStatus getStatus() = 0; }; // SFXBase diff --git a/src/audio/sfx_manager.cpp b/src/audio/sfx_manager.cpp index 12b24ba5d..9cecda9dc 100644 --- a/src/audio/sfx_manager.cpp +++ b/src/audio/sfx_manager.cpp @@ -217,6 +217,15 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p) queueCommand(sfx_command); } // queue (Vec3) +//---------------------------------------------------------------------------- + +void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p, SFXBuffer* buffer) +{ + SFXCommand *sfx_command = new SFXCommand(command, sfx, p); + sfx_command->m_buffer = buffer; + queueCommand(sfx_command); +} // queue (Vec3) + //---------------------------------------------------------------------------- /** Adds a sound effect command with a float and a Vec3 parameter to the queue * of the sfx manager. Openal commands can sometimes cause a 5ms delay, so it @@ -340,7 +349,7 @@ void* SFXManager::mainLoop(void *obj) { case SFX_PLAY: current->m_sfx->reallyPlayNow(); break; case SFX_PLAY_POSITION: - current->m_sfx->reallyPlayNow(current->m_parameter); break; + current->m_sfx->reallyPlayNow(current->m_parameter, current->m_buffer); break; case SFX_STOP: current->m_sfx->reallyStopNow(); break; case SFX_PAUSE: current->m_sfx->reallyPauseNow(); break; case SFX_RESUME: current->m_sfx->reallyResumeNow(); break; diff --git a/src/audio/sfx_manager.hpp b/src/audio/sfx_manager.hpp index 8e0c701cc..beb476395 100644 --- a/src/audio/sfx_manager.hpp +++ b/src/audio/sfx_manager.hpp @@ -122,6 +122,9 @@ private: /** The sound effect for which the command should be executed. */ SFXBase *m_sfx; + /** The sound buffer to play (null = no change) */ + SFXBuffer *m_buffer = NULL; + /** Stores music information for music commands. */ MusicInformation *m_music_information; @@ -232,12 +235,14 @@ private: public: static void create(); static void destroy(); - void queue(SFXCommands command, SFXBase *sfx=NULL); - void queue(SFXCommands command, SFXBase *sfx, float f); - void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p); - void queue(SFXCommands command, SFXBase *sfx, float f, const Vec3 &p); - void queue(SFXCommands command, MusicInformation *mi); - void queue(SFXCommands command, MusicInformation *mi, float f); + void queue(SFXCommands command, SFXBase *sfx=NULL); + void queue(SFXCommands command, SFXBase *sfx, float f); + void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p); + void queue(SFXCommands command, SFXBase *sfx, float f, const Vec3 &p); + void queue(SFXCommands command, MusicInformation *mi); + void queue(SFXCommands command, MusicInformation *mi, float f); + void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p, SFXBuffer* buffer); + // ------------------------------------------------------------------------ /** Static function to get the singleton sfx manager. */ static SFXManager *get() diff --git a/src/audio/sfx_openal.cpp b/src/audio/sfx_openal.cpp index 61456e5a3..21368e1b5 100644 --- a/src/audio/sfx_openal.cpp +++ b/src/audio/sfx_openal.cpp @@ -52,7 +52,6 @@ SFXOpenAL::SFXOpenAL(SFXBuffer* buffer, bool positional, float volume, m_master_gain = 1.0f; m_owns_buffer = owns_buffer; m_play_time = 0.0f; - m_sound_buffer_changed = false; // Don't initialise anything else if the sfx manager was not correctly // initialised. First of all the initialisation will not work, and it @@ -366,7 +365,7 @@ void SFXOpenAL::play() //----------------------------------------------------------------------------- /** Plays this sound effect. */ -void SFXOpenAL::reallyPlayNow() +void SFXOpenAL::reallyPlayNow(SFXBuffer* buffer) { if (!SFXManager::get()->sfxAllowed()) return; if (m_status==SFX_NOT_INITIALISED) @@ -378,13 +377,13 @@ void SFXOpenAL::reallyPlayNow() if (m_status==SFX_UNKNOWN) return; } - if (m_sound_buffer_changed) + if (buffer != NULL) { if (m_status == SFX_PLAYING || m_status == SFX_PAUSED) reallyStopNow(); + m_sound_buffer = buffer; alSourcei(m_sound_source, AL_BUFFER, m_sound_buffer->getBufferID()); - m_sound_buffer_changed = false; if (!SFXManager::checkError("attaching the buffer to the source")) return; @@ -405,8 +404,11 @@ void SFXOpenAL::reallyPlayNow() /** 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(const Vec3 &position) +void SFXOpenAL::play(const Vec3 &position, SFXBuffer* buffer) { + if (m_owns_buffer && buffer != NULL) + assert(false); // sources that own a buffer cannot play any other buffer + if (m_status == SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return; if(m_status==SFX_STOPPED || m_status==SFX_NOT_INITIALISED) @@ -418,16 +420,15 @@ void SFXOpenAL::play(const Vec3 &position) // - which can happen if the sfx thread had no time to actually start // it yet. m_status = SFX_PLAYING; - SFXManager::get()->queue(SFXManager::SFX_PLAY_POSITION, this, position); + SFXManager::get()->queue(SFXManager::SFX_PLAY_POSITION, this, position, buffer); } // play(Vec3) - //----------------------------------------------------------------------------- /** Plays this sound effect. */ -void SFXOpenAL::reallyPlayNow(const Vec3 &position) +void SFXOpenAL::reallyPlayNow(const Vec3 &position, SFXBuffer* buffer) { reallySetPosition(position); - reallyPlayNow(); + reallyPlayNow(buffer); } // reallyPlayNow(Vec3) //----------------------------------------------------------------------------- @@ -543,18 +544,4 @@ void SFXOpenAL::setRolloff(float rolloff) //----------------------------------------------------------------------------- -// TODO: make this thread-safe -void SFXOpenAL::setBuffer(SFXBuffer* buffer, bool owns_buffer) -{ - if (m_owns_buffer && m_sound_buffer) - { - m_sound_buffer->unload(); - delete m_sound_buffer; - } - - m_sound_buffer = buffer; - m_owns_buffer = owns_buffer; - m_sound_buffer_changed = true; -} - #endif //if HAVE_OGGVORBIS diff --git a/src/audio/sfx_openal.hpp b/src/audio/sfx_openal.hpp index cd2d095b4..0d491b097 100644 --- a/src/audio/sfx_openal.hpp +++ b/src/audio/sfx_openal.hpp @@ -29,6 +29,7 @@ #endif #include "audio/sfx_base.hpp" #include "utils/leak_check.hpp" +#include "utils/cpp2011.hpp" /** * \brief OpenAL implementation of the abstract SFXBase interface @@ -75,19 +76,17 @@ private: /** How long the sfx has been playing. */ float m_play_time; - bool m_sound_buffer_changed; - public: SFXOpenAL(SFXBuffer* buffer, bool positional, float volume, bool owns_buffer = false); virtual ~SFXOpenAL(); virtual void updatePlayingSFX(float dt); - virtual bool init(); - virtual void play(); - virtual void reallyPlayNow(); - virtual void play(const Vec3 &xyz); - virtual void reallyPlayNow(const Vec3 &xyz); + virtual bool init() OVERRIDE; + virtual void play() OVERRIDE; + virtual void reallyPlayNow(SFXBuffer* buffer = NULL) OVERRIDE; + virtual void play(const Vec3 &xyz, SFXBuffer* buffer = NULL) OVERRIDE; + virtual void reallyPlayNow(const Vec3 &xyz, SFXBuffer* buffer = NULL) OVERRIDE; virtual void setLoop(bool status); virtual void reallySetLoop(bool status); virtual void stop(); @@ -119,8 +118,6 @@ public: // ------------------------------------------------------------------------ /** Returns the buffer associated with this sfx. */ virtual const SFXBuffer* getBuffer() const { return m_sound_buffer; } - // ------------------------------------------------------------------------ - virtual void setBuffer(SFXBuffer* buffer, bool owns_buffer); }; // SFXOpenAL diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 28a1c0855..5e20d8a67 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -170,6 +170,13 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id, } }*/ + m_horn_sound = SFXManager::get()->getBuffer("horn"); + m_crash_sound = SFXManager::get()->getBuffer("crash"); + m_crash_sound2 = SFXManager::get()->getBuffer("crash2"); + m_crash_sound3 = SFXManager::get()->getBuffer("crash3"); + m_goo_sound = SFXManager::get()->getBuffer("goo"); + m_boing_sound = SFXManager::get()->getBuffer("boing"); + m_engine_sound = SFXManager::get()->createSoundSource(m_kart_properties->getEngineSfxType()); m_emitter_1 = SFXManager::get()->createSoundSource("crash"); m_emitter_2 = SFXManager::get()->createSoundSource("crash"); @@ -1020,11 +1027,8 @@ void Kart::collectedItem(Item *item, int add_info) m_kart_properties->getBubblegumSpeedFraction() , m_kart_properties->getBubblegumFadeInTime(), m_bubblegum_time); - { - SFXBase* emitter = getNextEmitter(); - emitter->setBuffer(SFXManager::get()->getBuffer("goo"), false); - emitter->play(getXYZ()); - } + getNextEmitter()->play(getXYZ(), m_goo_sound); + // Play appropriate custom character sound playCustomSFX(SFXManager::CUSTOM_GOO); break; @@ -2158,22 +2162,20 @@ void Kart::playCrashSFX(const Material* m, AbstractKart *k) // it's not already playing. if (isShielded() || (k != NULL && k->isShielded())) { - SFXBase* emitter = getNextEmitter(); - emitter->setBuffer(SFXManager::get()->getBuffer("boing"), false); - emitter->play(getXYZ()); + getNextEmitter()->play(getXYZ(), m_boing_sound); } else { int idx = rand() % 3; - - SFXBase* emitter = getNextEmitter(); + SFXBuffer* buffer; if (idx == 0) - emitter->setBuffer(SFXManager::get()->getBuffer("crash"), false); + buffer = m_crash_sound; else if (idx == 1) - emitter->setBuffer(SFXManager::get()->getBuffer("crash2"), false); + buffer = m_crash_sound2; else - emitter->setBuffer(SFXManager::get()->getBuffer("crash3"), false); - emitter->play(getXYZ()); + buffer = m_crash_sound3; + + getNextEmitter()->play(getXYZ(), buffer); } } // if lin_vel > 0.555 } // if m_bounce_back_time <= 0 @@ -2187,9 +2189,7 @@ void Kart::beep() // If the custom horn can't play (isn't defined) then play the default one if (!playCustomSFX(SFXManager::CUSTOM_HORN)) { - SFXBase* emitter = getNextEmitter(); - emitter->setBuffer(SFXManager::get()->getBuffer("horn"), false); - emitter->play(getXYZ()); + getNextEmitter()->play(getXYZ(), m_horn_sound); } } // beep diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp index 3e2f7a307..6d364bd01 100644 --- a/src/karts/kart.hpp +++ b/src/karts/kart.hpp @@ -210,19 +210,19 @@ protected: SFXBase *m_emitter_1; SFXBase *m_emitter_2; SFXBase *m_emitter_3; - //SFXBase *m_beep_sound; SFXBase *m_engine_sound; - //SFXBase *m_crash_sound; - //SFXBase *m_crash_sound2; - //SFXBase *m_crash_sound3; SFXBase *m_terrain_sound; SFXBase *m_nitro_sound; /** A pointer to the previous terrain sound needs to be saved so that an * 'older' sfx can be finished and an abrupt end of the sfx is avoided. */ SFXBase *m_previous_terrain_sound; SFXBase *m_skid_sound; - //SFXBase *m_goo_sound; - //SFXBase *m_boing_sound; + SFXBuffer *m_horn_sound; + SFXBuffer *m_crash_sound; + SFXBuffer *m_crash_sound2; + SFXBuffer *m_crash_sound3; + SFXBuffer *m_goo_sound; + SFXBuffer *m_boing_sound; float m_time_last_crash; RaceManager::KartType m_type;