Moved all remaining music commands to be handled by sfx thread.
This commit is contained in:
parent
6aa9ff86a4
commit
eb37092643
@ -76,6 +76,30 @@ private:
|
||||
// The constructor is private so that the
|
||||
// static create function must be used.
|
||||
MusicInformation (const XMLNode *root, const std::string &filename);
|
||||
|
||||
// Declare the following functions private, but allow the SFXManager
|
||||
// and music manager to access them. This makes sure that only the sfx thread calls
|
||||
// openal/vorbis etc, and so makes it all thread safe.
|
||||
private:
|
||||
friend class SFXManager;
|
||||
friend class MusicManager;
|
||||
void update(float dt);
|
||||
void startMusic();
|
||||
void stopMusic();
|
||||
void pauseMusic();
|
||||
void resumeMusic();
|
||||
void volumeMusic(float gain);
|
||||
void switchToFastMusic();
|
||||
void setTemporaryVolume(float gain);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Resets a temporary volume change. */
|
||||
void resetTemporaryVolume() { volumeMusic(m_adjusted_gain); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the music to be waiting, i.e. startMusic still needs to be
|
||||
* called. Used to pre-load track music during track loading time. */
|
||||
void setMusicWaiting() { m_music_waiting = true; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
|
||||
@ -85,14 +109,6 @@ public:
|
||||
~MusicInformation ();
|
||||
static MusicInformation *create(const std::string &filename);
|
||||
void addMusicToTracks();
|
||||
void update(float dt);
|
||||
void startMusic();
|
||||
void stopMusic();
|
||||
void pauseMusic();
|
||||
void resumeMusic();
|
||||
void volumeMusic(float gain);
|
||||
void setTemporaryVolume(float gain);
|
||||
void switchToFastMusic();
|
||||
bool isPlaying() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -109,13 +125,6 @@ public:
|
||||
const std::string& getFastFilename() const { return m_fast_filename; }
|
||||
// ------------------------------------------------------------------------
|
||||
float getMaxPitch() const { return m_max_pitch; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets the music to be waiting, i.e. startMusic still needs to be
|
||||
* called. Used to pre-load track music during track loading time. */
|
||||
void setMusicWaiting () {m_music_waiting = true;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Resets a temporary volume change. */
|
||||
void resetTemporaryVolume() { volumeMusic(m_adjusted_gain); }
|
||||
|
||||
}; // MusicInformation
|
||||
#endif
|
||||
|
@ -159,6 +159,16 @@ void MusicManager::addMusicToTracks()
|
||||
}
|
||||
} // addMusicToTracks
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Special shortcut vor overworld (which skips other phases where the music
|
||||
* would normally be started.
|
||||
*/
|
||||
void MusicManager::startMusic()
|
||||
{
|
||||
if (m_current_music)
|
||||
SFXManager::get()->queue(SFXManager::SFX_MUSIC_START, m_current_music);
|
||||
} // startMusic
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Schedules the indicated music to be played next.
|
||||
* \param mi Music information of the music to be played.
|
||||
@ -182,7 +192,7 @@ void MusicManager::startMusic(MusicInformation* mi, bool start_right_now)
|
||||
|
||||
if(!mi || !UserConfigParams::m_music || !m_initialized) return;
|
||||
|
||||
mi->volumeMusic(m_masterGain);
|
||||
mi->volumeMusic(m_master_gain);
|
||||
SFXManager::get()->queue(start_right_now ? SFXManager::SFX_MUSIC_START
|
||||
: SFXManager::SFX_MUSIC_WAITING,
|
||||
mi);
|
||||
@ -198,6 +208,59 @@ void MusicManager::stopMusic()
|
||||
} // stopMusic
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Insert a command into the sfx queue to pause the current music.
|
||||
*/
|
||||
void MusicManager::pauseMusic()
|
||||
{
|
||||
if (m_current_music)
|
||||
SFXManager::get()->queue(SFXManager::SFX_MUSIC_PAUSE, m_current_music);
|
||||
} // pauseMusic
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Inserts a resume current music event into the queue.
|
||||
*/
|
||||
void MusicManager::resumeMusic()
|
||||
{
|
||||
if (m_current_music)
|
||||
SFXManager::get()->queue(SFXManager::SFX_MUSIC_RESUME, m_current_music);
|
||||
} // resumeMusic
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Switches to fast (last lap ) music (if defined for the current music).
|
||||
*/
|
||||
void MusicManager::switchToFastMusic()
|
||||
{
|
||||
if (m_current_music)
|
||||
SFXManager::get()->queue(SFXManager::SFX_MUSIC_SWITCH_FAST,
|
||||
m_current_music);
|
||||
} // switchToFastMusic
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Queues a command to temporarily change the volume. This is used to make
|
||||
* the music a bit quieter while the 'last lap fanfare' is being played.
|
||||
* \param gain The temporary volume value.
|
||||
*/
|
||||
void MusicManager::setTemporaryVolume(float gain)
|
||||
{
|
||||
if (m_current_music)
|
||||
SFXManager::get()->queue(SFXManager::SFX_MUSIC_SET_TMP_VOLUME,
|
||||
m_current_music, gain);
|
||||
} // setTemporaryVolume
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Queues a command for the sfx manager to reset a temporary volume change.
|
||||
*/
|
||||
void MusicManager::resetTemporaryVolume()
|
||||
{
|
||||
if (m_current_music)
|
||||
SFXManager::get()->queue(SFXManager::SFX_MUSIC_RESET_TMP_VOLUME,
|
||||
m_current_music);
|
||||
} // resetTemporaryVolume
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sets the master music volume.
|
||||
* \param gain The volume.
|
||||
*/
|
||||
void MusicManager::setMasterMusicVolume(float gain)
|
||||
{
|
||||
if(gain > 1.0)
|
||||
@ -205,15 +268,15 @@ void MusicManager::setMasterMusicVolume(float gain)
|
||||
if(gain < 0.0f)
|
||||
gain = 0.0f;
|
||||
|
||||
m_masterGain = gain;
|
||||
if(m_current_music) m_current_music->volumeMusic(m_masterGain);
|
||||
m_master_gain = gain;
|
||||
if(m_current_music) m_current_music->volumeMusic(m_master_gain);
|
||||
|
||||
UserConfigParams::m_music_volume = m_masterGain;
|
||||
UserConfigParams::m_music_volume = m_master_gain;
|
||||
} // setMasterMusicVolume
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
*/
|
||||
/** @throw runtime_error if the music file could not be found/opened
|
||||
*/
|
||||
MusicInformation* MusicManager::getMusicInformation(const std::string& filename)
|
||||
{
|
||||
if(filename=="")
|
||||
@ -229,7 +292,7 @@ MusicInformation* MusicManager::getMusicInformation(const std::string& filename)
|
||||
MusicInformation *mi = MusicInformation::create(filename);
|
||||
if(mi)
|
||||
{
|
||||
mi->volumeMusic(m_masterGain);
|
||||
mi->volumeMusic(m_master_gain);
|
||||
m_all_music[basename] = mi;
|
||||
}
|
||||
return mi;
|
||||
|
@ -42,42 +42,44 @@ private:
|
||||
/** If the sound could not be initialized, e.g. if the player doesn't has
|
||||
* a sound card, we want to avoid anything sound related so we crash the
|
||||
* game. */
|
||||
bool m_initialized;
|
||||
std::map<std::string, MusicInformation*>
|
||||
m_all_music;
|
||||
bool m_initialized;
|
||||
|
||||
void loadMusicInformation();
|
||||
float m_masterGain;
|
||||
/** Stores all music information files (read from the .music files). */
|
||||
std::map<std::string, MusicInformation*>
|
||||
m_all_music;
|
||||
float m_master_gain;
|
||||
|
||||
void loadMusicInformation();
|
||||
void loadMusicFromOneDir(const std::string& dir);
|
||||
|
||||
public:
|
||||
MusicManager();
|
||||
virtual ~MusicManager();
|
||||
MusicManager();
|
||||
virtual ~MusicManager();
|
||||
MusicInformation* getMusicInformation(const std::string& filename);
|
||||
void addMusicToTracks();
|
||||
|
||||
void startMusic(MusicInformation* mi,
|
||||
bool start_right_now=true);
|
||||
void stopMusic();
|
||||
bool initialized() const { return m_initialized; }
|
||||
void pauseMusic() {if(m_current_music)
|
||||
m_current_music->pauseMusic(); }
|
||||
void resumeMusic() {if(m_current_music)
|
||||
m_current_music->resumeMusic(); }
|
||||
void switchToFastMusic() {if(m_current_music)
|
||||
m_current_music->switchToFastMusic();}
|
||||
|
||||
void setMasterMusicVolume(float gain);
|
||||
float getMasterMusicVolume() const { return m_masterGain; }
|
||||
|
||||
MusicInformation *getCurrentMusic() {return m_current_music; }
|
||||
|
||||
/**
|
||||
* @throw runtime_error if the music file could not be found/opened
|
||||
*/
|
||||
MusicInformation *getMusicInformation(const std::string& filename);
|
||||
|
||||
void loadMusicFromOneDir(const std::string& dir);
|
||||
void addMusicToTracks();
|
||||
|
||||
void clearCurrentMusic() { m_current_music = NULL; }
|
||||
void startMusic();
|
||||
void startMusic(MusicInformation* mi,
|
||||
bool start_right_now=true);
|
||||
void stopMusic();
|
||||
void pauseMusic();
|
||||
void resumeMusic();
|
||||
void switchToFastMusic();
|
||||
void setMasterMusicVolume(float gain);
|
||||
void resetTemporaryVolume();
|
||||
void setTemporaryVolume(float gain);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the master volume. */
|
||||
float getMasterMusicVolume() const { return m_master_gain; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns if the music system is initialised. */
|
||||
bool initialized() const { return m_initialized; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the information object of the current music. */
|
||||
MusicInformation* getCurrentMusic() { return m_current_music; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Stops and removes the current music. */
|
||||
void clearCurrentMusic() { m_current_music = NULL; }
|
||||
};
|
||||
|
||||
extern MusicManager* music_manager;
|
||||
|
@ -202,11 +202,25 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p)
|
||||
} // queue (Vec3)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Queues a command for the music manager.
|
||||
* \param mi The music for which the command is.
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, MusicInformation *mi)
|
||||
{
|
||||
SFXCommand *sfx_command = new SFXCommand(command, mi);
|
||||
queueCommand(sfx_command);
|
||||
} // queue(MusicInformation)
|
||||
//----------------------------------------------------------------------------
|
||||
/** Queues a command for the music manager that takes a floating point value
|
||||
* (e.g. setTemporaryVolume).
|
||||
* \param mi The music for which the command is.
|
||||
* \param f The floating point parameter.
|
||||
*/
|
||||
void SFXManager::queue(SFXCommands command, MusicInformation *mi, float f)
|
||||
{
|
||||
SFXCommand *sfx_command = new SFXCommand(command, mi, f);
|
||||
queueCommand(sfx_command);
|
||||
} // queue(MusicInformation)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Enqueues a command to the sfx queue threadsafe. Then signal the
|
||||
@ -286,40 +300,57 @@ void* SFXManager::mainLoop(void *obj)
|
||||
break;
|
||||
}
|
||||
me->m_sfx_commands.unlock();
|
||||
switch(current->m_command)
|
||||
switch (current->m_command)
|
||||
{
|
||||
case SFX_PLAY: current->m_sfx->reallyPlayNow(); 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;
|
||||
case SFX_PLAY: current->m_sfx->reallyPlayNow(); 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;
|
||||
case SFX_SPEED: current->m_sfx->reallySetSpeed(
|
||||
current->m_parameter.getX()); break;
|
||||
current->m_parameter.getX()); break;
|
||||
case SFX_POSITION: current->m_sfx->reallySetPosition(
|
||||
current->m_parameter); break;
|
||||
current->m_parameter); break;
|
||||
case SFX_VOLUME: current->m_sfx->reallySetVolume(
|
||||
current->m_parameter.getX()); break;
|
||||
current->m_parameter.getX()); break;
|
||||
case SFX_MASTER_VOLUME:
|
||||
current->m_sfx->reallySetMasterVolumeNow(
|
||||
current->m_parameter.getX()); break;
|
||||
current->m_sfx->reallySetMasterVolumeNow(
|
||||
current->m_parameter.getX()); break;
|
||||
case SFX_LOOP: current->m_sfx->reallySetLoop(
|
||||
current->m_parameter.getX()!=0); break;
|
||||
case SFX_DELETE: {
|
||||
me->deleteSFX(current->m_sfx); break;
|
||||
}
|
||||
case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break;
|
||||
case SFX_RESUME_ALL: me->reallyResumeAllNow(); break;
|
||||
case SFX_LISTENER: me->reallyPositionListenerNow(); break;
|
||||
case SFX_UPDATE: me->reallyUpdateNow(current); break;
|
||||
current->m_parameter.getX() != 0); break;
|
||||
case SFX_DELETE: me->deleteSFX(current->m_sfx); break;
|
||||
case SFX_PAUSE_ALL: me->reallyPauseAllNow(); break;
|
||||
case SFX_RESUME_ALL: me->reallyResumeAllNow(); break;
|
||||
case SFX_LISTENER: me->reallyPositionListenerNow(); break;
|
||||
case SFX_UPDATE: me->reallyUpdateNow(current); break;
|
||||
case SFX_MUSIC_START:
|
||||
current->m_music_information->startMusic(); break;
|
||||
current->m_music_information->startMusic(); break;
|
||||
case SFX_MUSIC_STOP:
|
||||
current->m_music_information->stopMusic(); break;
|
||||
current->m_music_information->stopMusic(); break;
|
||||
case SFX_MUSIC_PAUSE:
|
||||
current->m_music_information->pauseMusic(); break;
|
||||
case SFX_MUSIC_RESUME:
|
||||
current->m_music_information->resumeMusic(); break;
|
||||
case SFX_MUSIC_SWITCH_FAST:
|
||||
current->m_music_information->switchToFastMusic(); break;
|
||||
case SFX_MUSIC_SET_TMP_VOLUME:
|
||||
{
|
||||
MusicInformation *mi = current->m_music_information;
|
||||
mi->setTemporaryVolume(current->m_parameter.getX()); break;
|
||||
}
|
||||
case SFX_MUSIC_RESET_TMP_VOLUME:
|
||||
{
|
||||
MusicInformation *mi = current->m_music_information;
|
||||
mi->resetTemporaryVolume(); break;
|
||||
}
|
||||
case SFX_MUSIC_WAITING:
|
||||
current->m_music_information->setMusicWaiting(); break;
|
||||
current->m_music_information->setMusicWaiting(); break;
|
||||
default: assert("Not yet supported.");
|
||||
}
|
||||
delete current;
|
||||
current = NULL;
|
||||
static SFXCommand *prev = NULL;
|
||||
delete prev;
|
||||
prev = current;
|
||||
//delete current;
|
||||
//current = NULL;
|
||||
me->m_sfx_commands.lock();
|
||||
|
||||
} // while
|
||||
@ -622,7 +653,7 @@ void SFXManager::deleteSFXMapping(const std::string &name)
|
||||
*/
|
||||
void SFXManager::update(float dt)
|
||||
{
|
||||
queue(SFX_UPDATE, NULL, dt);
|
||||
queue(SFX_UPDATE, (SFXBase*)NULL, dt);
|
||||
// Wake up the sfx thread to handle all queued up audio commands.
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
} // update
|
||||
|
@ -79,7 +79,11 @@ public:
|
||||
SFX_UPDATE,
|
||||
SFX_MUSIC_START,
|
||||
SFX_MUSIC_STOP,
|
||||
SFX_MUSIC_UPDATE,
|
||||
SFX_MUSIC_PAUSE,
|
||||
SFX_MUSIC_RESUME,
|
||||
SFX_MUSIC_SWITCH_FAST,
|
||||
SFX_MUSIC_SET_TMP_VOLUME,
|
||||
SFX_MUSIC_RESET_TMP_VOLUME,
|
||||
SFX_MUSIC_WAITING,
|
||||
SFX_EXIT,
|
||||
}; // SFXCommands
|
||||
@ -135,7 +139,16 @@ private:
|
||||
{
|
||||
m_command = command;
|
||||
m_music_information = mi;
|
||||
} // SFXCommnd
|
||||
} // SFXCommnd(MusicInformation*)
|
||||
// --------------------------------------------------------------------
|
||||
/** Constructor for music information commands that take a floating
|
||||
* point parameter (which is stored in the X value of m_parameter). */
|
||||
SFXCommand(SFXCommands command, MusicInformation *mi, float f)
|
||||
{
|
||||
m_command = command;
|
||||
m_parameter.setX(f);
|
||||
m_music_information = mi;
|
||||
} // SFXCommnd(MusicInformation *, float)
|
||||
// --------------------------------------------------------------------
|
||||
SFXCommand(SFXCommands command, SFXBase *base, float parameter)
|
||||
{
|
||||
@ -205,6 +218,7 @@ public:
|
||||
void queue(SFXCommands command, SFXBase *sfx, float f);
|
||||
void queue(SFXCommands command, SFXBase *sfx, const Vec3 &p);
|
||||
void queue(SFXCommands command, MusicInformation *mi);
|
||||
void queue(SFXCommands command, MusicInformation *mi, float f);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Static function to get the singleton sfx manager. */
|
||||
static SFXManager *get()
|
||||
|
@ -1516,7 +1516,8 @@ static void cleanSuperTuxKart()
|
||||
SFXManager::destroy();
|
||||
|
||||
// Music manager can not be deleted before the sfx thread is stopped
|
||||
// (since sfx commands can contain music information).
|
||||
// (since sfx commands can contain music information, which are
|
||||
// deleted by the music manager).
|
||||
delete music_manager;
|
||||
|
||||
// The addons manager might still be called from a currenty running request
|
||||
|
@ -157,8 +157,7 @@ void LinearWorld::update(float dt)
|
||||
if (m_last_lap_sfx_playing &&
|
||||
m_last_lap_sfx->getStatus() != SFXBase::SFX_PLAYING)
|
||||
{
|
||||
if(music_manager->getCurrentMusic())
|
||||
music_manager->getCurrentMusic()->resetTemporaryVolume();
|
||||
music_manager->resetTemporaryVolume();
|
||||
m_last_lap_sfx_playing = false;
|
||||
}
|
||||
|
||||
@ -288,7 +287,7 @@ void LinearWorld::newLap(unsigned int kart_index)
|
||||
if(music_manager->getCurrentMusic() &&
|
||||
music_manager->getMasterMusicVolume() > 0.2f)
|
||||
{
|
||||
music_manager->getCurrentMusic()->setTemporaryVolume(0.2f);
|
||||
music_manager->setTemporaryVolume(0.2f);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -114,9 +114,8 @@ void OverWorld::update(float dt)
|
||||
// so we have to start music 'manually', since we skip all phases.
|
||||
World::getWorld()->getTrack()->startMusic();
|
||||
|
||||
if (music_manager->getCurrentMusic() != NULL &&
|
||||
UserConfigParams::m_music)
|
||||
music_manager->getCurrentMusic()->startMusic();
|
||||
if (UserConfigParams::m_music)
|
||||
music_manager->startMusic();
|
||||
m_karts[0]->startEngineSFX();
|
||||
}
|
||||
WorldWithRank::update(dt);
|
||||
|
Loading…
Reference in New Issue
Block a user