The SFX manager and SFXOpenAL would check if SFXs are enabled before pausing (looping) sound effects, so disabling SFXs in the options would fail to stop looping SFxs.

Furthermore, 'OnSoundEnabledBack' would pause all looping SFXs. This commit checks for the pause status of the World (if applicable) to decide if the looping SFXs should be immediately resumed (networking) or not (real pause).

Also clean some comments and move some code around.

This patch doesn't address sound resuming when going from the pause menu to the options in networked mode, whereas it doesn't in a normal race. This is what caused the bug to trigger in the first place, but it's very minor by itself and the design of the SFX code could have triggered other future issues too.
This commit is contained in:
Alayan 2024-05-08 17:21:39 +02:00
parent 8dbf0a9922
commit 99868d5897
No known key found for this signature in database
5 changed files with 35 additions and 28 deletions

View File

@ -64,7 +64,7 @@ public:
virtual void setMasterVolume(float gain) OVERRIDE {}
virtual void reallySetMasterVolumeNow(float gain) OVERRIDE {}
virtual SFXStatus getStatus() OVERRIDE { return SFX_STOPPED; }
virtual void onSoundEnabledBack() OVERRIDE {}
virtual void onSoundEnabledBack(bool resume_later) OVERRIDE {}
virtual void setRolloff(float rolloff) OVERRIDE {}
virtual SFXBuffer* getBuffer() const OVERRIDE { return NULL; }

View File

@ -80,7 +80,7 @@ public:
virtual void reallySetVolume(float gain) = 0;
virtual void setMasterVolume(float gain) = 0;
virtual void reallySetMasterVolumeNow(float gain) = 0;
virtual void onSoundEnabledBack() = 0;
virtual void onSoundEnabledBack(bool resume_later)= 0;
virtual void setRolloff(float rolloff) = 0;
virtual SFXBuffer* getBuffer() const = 0;
virtual SFXStatus getStatus() = 0;

View File

@ -22,6 +22,7 @@
#include "audio/sfx_buffer.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "modes/world.hpp"
#include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/stk_process.hpp"
@ -336,7 +337,7 @@ void SFXManager::stopThread()
} // stopThread
//----------------------------------------------------------------------------
/** This loops runs in a different threads, and starts sfx to be played.
/** This loops runs in a different thread, and starts playing sfx.
* This can sometimes take up to 5 ms, so it needs to be handled in a thread
* in order to avoid rendering delays.
* \param obj A pointer to the SFX singleton.
@ -513,25 +514,18 @@ void SFXManager::toggleSound(const bool on)
reallyResumeAllNow();
m_all_sfx.lock();
const int sfx_amount = (int)m_all_sfx.getData().size();
bool resume_later = false;
if (World::getWorld() != NULL)
resume_later = (World::getWorld()->getPhase() == World::IN_GAME_MENU_PHASE);
for (int n=0; n<sfx_amount; n++)
{
m_all_sfx.getData()[n]->onSoundEnabledBack();
// This also pauses sound effects
m_all_sfx.getData()[n]->onSoundEnabledBack(resume_later);
}
m_all_sfx.unlock();
}
else
{
// First stop all sfx that are not looped
const int sfx_amount = (int)m_all_sfx.getData().size();
m_all_sfx.lock();
for (int i=0; i<sfx_amount; i++)
{
if(!m_all_sfx.getData()[i]->isLooped())
{
m_all_sfx.getData()[i]->reallyStopNow();
}
}
m_all_sfx.unlock();
pauseAll();
}
} // toggleSound
@ -898,20 +892,29 @@ void SFXManager::deleteSFX(SFXBase *sfx)
} // deleteSFX
//----------------------------------------------------------------------------
/** Pauses all looping SFXs. Non-looping SFX will be finished, since it's
* otherwise not possible to determine which SFX must be resumed (i.e. were
* actually playing at the time pause was called).
/** Request the pausing of all SFXs. Non-looping SFXs are finished,
* since it's otherwise not possible to determine which SFXs must be resumed
* (i.e. were actually playing at the time pause was called).
*/
void SFXManager::pauseAll()
{
if (!sfxAllowed()) return;
// First stop all sfx that are not looped
const int sfx_amount = (int)m_all_sfx.getData().size();
m_all_sfx.lock();
for (int i=0; i<sfx_amount; i++)
{
if(!m_all_sfx.getData()[i]->isLooped())
{
m_all_sfx.getData()[i]->reallyStopNow();
}
}
m_all_sfx.unlock();
queue(SFX_PAUSE_ALL);
} // pauseAll
//----------------------------------------------------------------------------
/** Pauses all looping SFXs. Non-looping SFX will be finished, since it's
* otherwise not possible to determine which SFX must be resumed (i.e. were
* actually playing at the time pause was called.
/** Actually pauses the SFXs.
*/
void SFXManager::reallyPauseAllNow()
{
@ -922,7 +925,7 @@ void SFXManager::reallyPauseAllNow()
(*i)->reallyPauseNow();
} // for i in m_all_sfx
m_all_sfx.unlock();
} // pauseAll
} // reallyPauseAllNow
//----------------------------------------------------------------------------
/** Resumes all paused SFXs. If sound is disabled, does nothing.
@ -950,7 +953,7 @@ void SFXManager::reallyResumeAllNow()
(*i)->reallyResumeNow();
} // for i in m_all_sfx
m_all_sfx.unlock();
} // resumeAll
} // reallyResumeAllNow
//-----------------------------------------------------------------------------
/** Returns whether or not an openal error has occurred. If so, an error

View File

@ -262,10 +262,11 @@ void SFXOpenAL::reallySetLoop(bool status)
//-----------------------------------------------------------------------------
/** Queues a stop for this effect to the sound manager.
* Stopping MUST be allowed when SFX are disabled
*/
void SFXOpenAL::stop()
{
if (m_status == SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return;
if (m_status == SFX_UNKNOWN) return;
SFXManager::get()->queue(SFXManager::SFX_STOP, this);
} // stop
@ -295,12 +296,13 @@ void SFXOpenAL::pause()
//-----------------------------------------------------------------------------
/** Pauses a SFX that's currently played. Nothing happens it the effect is
* currently not being played.
* Pausing MUST be allowed when SFX are disabled
*/
void SFXOpenAL::reallyPauseNow()
{
// Need to be tested again here, since this function can be called
// from pauseAll, and we have to make sure to only pause playing sfx.
if (m_status != SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return;
if (m_status != SFX_PLAYING) return;
m_status = SFX_PAUSED;
alSourcePause(m_sound_source);
SFXManager::checkError("pausing");
@ -513,7 +515,7 @@ void SFXOpenAL::deleteSFX()
//-----------------------------------------------------------------------------
void SFXOpenAL::onSoundEnabledBack()
void SFXOpenAL::onSoundEnabledBack(bool resume_later)
{
if (m_loop)
{
@ -525,6 +527,8 @@ void SFXOpenAL::onSoundEnabledBack()
pause();
alSourcef(m_sound_source, AL_GAIN,
(m_gain < 0.0f ? m_default_gain : m_gain) * m_master_gain);
if (!resume_later)
play();
}
}
} // onSoundEnabledBack

View File

@ -103,7 +103,7 @@ public:
virtual void reallySetVolume(float volume) OVERRIDE;
virtual void setMasterVolume(float volume) OVERRIDE;
virtual void reallySetMasterVolumeNow(float volue) OVERRIDE;
virtual void onSoundEnabledBack() OVERRIDE;
virtual void onSoundEnabledBack(bool resume_later) OVERRIDE;
virtual void setRolloff(float rolloff) OVERRIDE;
// ------------------------------------------------------------------------
/** Returns if this sfx is looped or not. */