Significantly reduced number of audio sfx commands: instead of sending

7 commands for each kart (when only engine is actually playing),
now there is only one command being sent: positions of sfx that are
not playing are not sent anymore, a duplication engine position was
removed, and speed and position are combined into one event.
This commit is contained in:
hiker 2015-06-29 08:09:42 +10:00
parent f992b864e1
commit 11a213fa8d
8 changed files with 123 additions and 19 deletions

View File

@ -42,8 +42,14 @@ public:
virtual void reallySetLoop(bool status) {}
virtual void setPosition(const Vec3 &p) {}
virtual void reallySetPosition(const Vec3 &p) {}
virtual void setSpeedPosition(float factor,
const Vec3 &p) {}
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 stop() {}
virtual void reallyStopNow() {}
virtual void pause() {}

View File

@ -57,10 +57,16 @@ public:
virtual void updatePlayingSFX(float dt) = 0;
virtual void setPosition(const Vec3 &p) = 0;
virtual void reallySetPosition(const Vec3 &p) = 0;
virtual void setSpeedPosition(float factor,
const Vec3 &p) = 0;
virtual void reallySetSpeedPosition(float f,
const Vec3 &p)= 0;
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 stop() = 0;
virtual void reallyStopNow() = 0;
virtual void pause() = 0;

View File

@ -207,6 +207,22 @@ void SFXManager::queue(SFXCommands command, SFXBase *sfx, const Vec3 &p)
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
* is done in a separate thread.
* \param command The command to execute.
* \param sfx The sound effect to be started.
* \param f A float parameter for the command.
* \param p A Vec3 parameter for the command.
*/
void SFXManager::queue(SFXCommands command, SFXBase *sfx, float f,
const Vec3 &p)
{
SFXCommand *sfx_command = new SFXCommand(command, sfx, f, p);
queueCommand(sfx_command);
} // queue(float, Vec3)
//----------------------------------------------------------------------------
/** Queues a command for the music manager.
* \param mi The music for which the command is.
@ -310,20 +326,26 @@ void* SFXManager::mainLoop(void *obj)
switch (current->m_command)
{
case SFX_PLAY: current->m_sfx->reallyPlayNow(); break;
case SFX_PLAY_POSITION:
current->m_sfx->reallyPlayNow(current->m_parameter); 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_SPEED_POSITION: current->m_sfx->reallySetSpeedPosition(
// Extract float from W component
current->m_parameter.getW(),
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_parameter.getX()); break;
case SFX_LOOP: current->m_sfx->reallySetLoop(
current->m_parameter.getX() != 0); 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;

View File

@ -64,6 +64,7 @@ public:
enum SFXCommands
{
SFX_PLAY = 1,
SFX_PLAY_POSITION,
SFX_STOP,
SFX_PAUSE,
SFX_PAUSE_ALL,
@ -72,6 +73,7 @@ public:
SFX_DELETE,
SFX_SPEED,
SFX_POSITION,
SFX_SPEED_POSITION,
SFX_VOLUME,
SFX_MASTER_VOLUME,
SFX_LOOP,
@ -163,6 +165,18 @@ private:
m_sfx = base;
m_parameter = parameter;
} // SFXCommand(Vec3)
// --------------------------------------------------------------------
/** Store a float and vec3 parameter. The float is stored as W
* component of the vector. A bit hacky, but this class is used
* very frequently, so should remain as small as possible). */
SFXCommand(SFXCommands command, SFXBase *base, float f,
const Vec3 &parameter)
{
m_command = command;
m_sfx = base;
m_parameter = parameter;
m_parameter.setW(f);
} // SFXCommand(Vec3)
}; // SFXCommand
// ========================================================================
@ -220,8 +234,9 @@ public:
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, MusicInformation *mi, float f);
// ------------------------------------------------------------------------
/** Static function to get the singleton sfx manager. */
static SFXManager *get()

View File

@ -146,7 +146,7 @@ void SFXOpenAL::updatePlayingSFX(float dt)
*/
void SFXOpenAL::setSpeed(float factor)
{
if(m_status==SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return;
//if(m_status!=SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return;
assert(!isnan(factor));
SFXManager::get()->queue(SFXManager::SFX_SPEED, this, factor);
} // setSpeed
@ -377,13 +377,44 @@ void SFXOpenAL::reallyPlayNow()
SFXManager::checkError("playing");
} // 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)
{
if (m_status == SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return;
if(m_status==SFX_STOPPED)
m_play_time = 0.0f;
// Technically the sfx is only playing after the sfx thread starts it,
// but it is important to set this here since stk might decide to
// delete a sfx if it has finished playing (i.e. is in stopped state)
// - 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);
} // play(Vec3)
//-----------------------------------------------------------------------------
/** Plays this sound effect.
*/
void SFXOpenAL::reallyPlayNow(const Vec3 &position)
{
reallySetPosition(position);
reallyPlayNow();
} // reallyPlayNow(Vec3)
//-----------------------------------------------------------------------------
/** Sets the position where this sound effects is played.
* \param position Position of the sound effect.
*/
void SFXOpenAL::setPosition(const Vec3 &position)
{
if (m_status == SFX_UNKNOWN || !SFXManager::get()->sfxAllowed()) return;
// Don't send a position command to the thread if the sound is not playing
// (or sfx disabled or the sound was not initialised correctly)
// if (m_status != SFX_PLAYING|| !SFXManager::get()->sfxAllowed()) return;
SFXManager::get()->queue(SFXManager::SFX_POSITION, this, position);
} // setPosition
@ -430,6 +461,25 @@ void SFXOpenAL::reallySetPosition(const Vec3 &position)
SFXManager::checkError("positioning");
} // reallySetPosition
// ----------------------------------------------------------------------------
/** Shortcut that plays at a specified position. */
void SFXOpenAL::setSpeedPosition(float factor, const Vec3 &position)
{
if (m_status != SFX_PLAYING || !SFXManager::get()->sfxAllowed()) return;
SFXManager::get()->queue(SFXManager::SFX_SPEED_POSITION, this,
factor, position);
} // play(vec3)
//-----------------------------------------------------------------------------
/** Set speed and position of a sound effect.
* \param f Speed.
* \param position Position of the sfx.
*/
void SFXOpenAL::reallySetSpeedPosition(float f, const Vec3 &position)
{
reallySetSpeed(f);
reallySetPosition(position);
} // reallySetSpeedPosition
//-----------------------------------------------------------------------------
/** Queues up a delete request for this object. This is necessary to avoid
* a crash if the sfx manager thread might be delayed and access this object

View File

@ -84,6 +84,8 @@ public:
virtual bool init();
virtual void play();
virtual void reallyPlayNow();
virtual void play(const Vec3 &xyz);
virtual void reallyPlayNow(const Vec3 &xyz);
virtual void setLoop(bool status);
virtual void reallySetLoop(bool status);
virtual void stop();
@ -97,6 +99,8 @@ public:
virtual void reallySetSpeed(float factor);
virtual void setPosition(const Vec3 &position);
virtual void reallySetPosition(const Vec3 &p);
virtual void setSpeedPosition(float factor, const Vec3 &p);
virtual void reallySetSpeedPosition(float f,const Vec3 &p);
virtual void setVolume(float volume);
virtual void reallySetVolume(float volume);
virtual void setMasterVolume(float volume);

View File

@ -27,14 +27,13 @@ HitSFX::HitSFX(const Vec3& coord, const char* explosion_sound)
: HitEffect()
{
m_sfx = SFXManager::get()->createSoundSource( explosion_sound );
m_sfx->setPosition(coord);
// in multiplayer mode, sounds are NOT positional (because we have
// multiple listeners) so the sounds of all AIs are constantly heard.
// Therefore reduce volume of sounds.
float vol = race_manager->getNumLocalPlayers() > 1 ? 0.5f : 1.0f;
m_sfx->setVolume(vol);
m_sfx->play();
m_sfx->play(coord);
} // HitSFX
//-----------------------------------------------------------------------------

View File

@ -1218,7 +1218,6 @@ void Kart::update(float dt)
*/
m_beep_sound->setPosition ( getXYZ() );
m_engine_sound->setPosition ( getXYZ() );
m_crash_sound->setPosition ( getXYZ() );
m_skid_sound->setPosition ( getXYZ() );
m_boing_sound->setPosition ( getXYZ() );
@ -1961,12 +1960,14 @@ void Kart::playCrashSFX(const Material* m, AbstractKart *k)
if (isShielded() || (k != NULL && k->isShielded()))
{
if (m_boing_sound->getStatus() != SFXBase::SFX_PLAYING)
m_boing_sound->play();
m_boing_sound->play(getXYZ());
}
else
{
if(m_crash_sound->getStatus() != SFXBase::SFX_PLAYING)
m_crash_sound->play();
if (m_crash_sound->getStatus() != SFXBase::SFX_PLAYING)
{
m_crash_sound->play(getXYZ());
}
}
} // if lin_vel > 0.555
} // if m_bounce_back_time <= 0
@ -1979,7 +1980,9 @@ void Kart::beep()
{
// If the custom horn can't play (isn't defined) then play the default one
if (!playCustomSFX(SFXManager::CUSTOM_HORN))
m_beep_sound->play();
{
m_beep_sound->play(getXYZ());
}
} // beep
@ -2085,7 +2088,7 @@ void Kart::updatePhysics(float dt)
m_skidding->getGraphicalJumpOffset()==0)
{
if(m_skid_sound->getStatus()!=SFXBase::SFX_PLAYING && !isWheeless())
m_skid_sound->play();
m_skid_sound->play(getXYZ());
}
else if(m_skid_sound->getStatus()==SFXBase::SFX_PLAYING)
{
@ -2192,15 +2195,14 @@ void Kart::updateEngineSFX()
float gears = 3.0f * fmod(f, 0.333334f);
assert(!isnan(f));
m_engine_sound->setSpeed(0.6f + (f + gears) * 0.35f);
m_engine_sound->setSpeedPosition(0.6f + (f + gears) * 0.35f, getXYZ());
}
else
{
// When flying, fixed value but not too high pitch
// This gives some variation (vs previous "on wheels" one)
m_engine_sound->setSpeed(0.9f);
m_engine_sound->setSpeedPosition(0.9f, getXYZ());
}
m_engine_sound->setPosition(getXYZ());
} // updateEngineSFX
//-----------------------------------------------------------------------------