Additional functionality added to the FlightGear sound fx manager.
Create a queue of one-off wav files. Calling layer can request the system to play any wav file. The request is thrown at the end of a play queue. The queue is serviced sequentially so that queued wav files will no longer overlap. When a sample is finished playing. It is removed from the queue and deleted from memory. The next remaining request in the queue is then played.
This commit is contained in:
parent
0e16419f0d
commit
4132b41470
2 changed files with 92 additions and 16 deletions
|
@ -49,7 +49,16 @@ FGFX::FGFX () :
|
||||||
|
|
||||||
FGFX::~FGFX ()
|
FGFX::~FGFX ()
|
||||||
{
|
{
|
||||||
|
unsigned int i;
|
||||||
|
for ( i = 0; i < _sound.size(); i++ ) {
|
||||||
|
delete _sound[i];
|
||||||
|
}
|
||||||
_sound.clear();
|
_sound.clear();
|
||||||
|
|
||||||
|
while ( _samplequeue.size() > 0 ) {
|
||||||
|
delete _samplequeue.front();
|
||||||
|
_samplequeue.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -109,20 +118,43 @@ FGFX::unbind ()
|
||||||
void
|
void
|
||||||
FGFX::update (double dt)
|
FGFX::update (double dt)
|
||||||
{
|
{
|
||||||
|
SGSoundMgr *smgr = globals->get_soundmgr();
|
||||||
|
|
||||||
// command sound manger
|
// command sound manger
|
||||||
bool pause = _pause->getBoolValue();
|
bool pause = _pause->getBoolValue();
|
||||||
if ( pause != last_pause ) {
|
if ( pause != last_pause ) {
|
||||||
if ( pause ) {
|
if ( pause ) {
|
||||||
globals->get_soundmgr()->pause();
|
smgr->pause();
|
||||||
} else {
|
} else {
|
||||||
globals->get_soundmgr()->resume();
|
smgr->resume();
|
||||||
}
|
}
|
||||||
last_pause = pause;
|
last_pause = pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process mesage queue
|
||||||
|
const string msgid = "Sequential Audio Message";
|
||||||
|
bool is_playing = false;
|
||||||
|
if ( smgr->exists( msgid ) ) {
|
||||||
|
if ( smgr->is_playing( msgid ) ) {
|
||||||
|
// still playing, do nothing
|
||||||
|
is_playing = true;
|
||||||
|
} else {
|
||||||
|
// current message finished, remove
|
||||||
|
smgr->remove( msgid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !is_playing ) {
|
||||||
|
// message queue idle, add next sound if we have one
|
||||||
|
if ( _samplequeue.size() > 0 ) {
|
||||||
|
smgr->add( _samplequeue.front(), msgid );
|
||||||
|
_samplequeue.pop();
|
||||||
|
smgr->play_once( msgid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double volume = _volume->getDoubleValue();
|
double volume = _volume->getDoubleValue();
|
||||||
if ( volume != last_volume ) {
|
if ( volume != last_volume ) {
|
||||||
globals->get_soundmgr()->set_volume( volume );
|
smgr->set_volume( volume );
|
||||||
last_volume = volume;
|
last_volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,4 +166,22 @@ FGFX::update (double dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a sound sample to the message queue which is played sequentially
|
||||||
|
* in order.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
FGFX::play_message( SGSoundSample *_sample )
|
||||||
|
{
|
||||||
|
_samplequeue.push( _sample );
|
||||||
|
}
|
||||||
|
void
|
||||||
|
FGFX::play_message( const string path, const string fname )
|
||||||
|
{
|
||||||
|
SGSoundSample *sample;
|
||||||
|
sample = new SGSoundSample( path.c_str(), fname.c_str() );
|
||||||
|
play_message( sample );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// end of fg_fx.cxx
|
// end of fg_fx.cxx
|
||||||
|
|
|
@ -24,8 +24,17 @@
|
||||||
#ifndef __FGFX_HXX
|
#ifndef __FGFX_HXX
|
||||||
#define __FGFX_HXX 1
|
#define __FGFX_HXX 1
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <simgear/sound/sample_openal.hxx>
|
||||||
#include <simgear/structure/subsystem_mgr.hxx>
|
#include <simgear/structure/subsystem_mgr.hxx>
|
||||||
|
|
||||||
|
SG_USING_STD(queue);
|
||||||
|
SG_USING_STD(vector);
|
||||||
|
|
||||||
class SGXmlSound;
|
class SGXmlSound;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +43,15 @@ class SGXmlSound;
|
||||||
* This module uses FGSoundMgr to generate sound effects based
|
* This module uses FGSoundMgr to generate sound effects based
|
||||||
* on current flight conditions. The sound manager must be initialized
|
* on current flight conditions. The sound manager must be initialized
|
||||||
* before this object is.
|
* before this object is.
|
||||||
|
*
|
||||||
|
* Note: this module supports two separate sound mechanisms concurrently.
|
||||||
|
*
|
||||||
|
* 1. This module will load and play a set of sound effects defined in an
|
||||||
|
* xml file and tie them to various property states.
|
||||||
|
* 2. This modules also maintains a queue of 'message' audio files. These
|
||||||
|
* are played sequentially with no overlap until the queue is finished.
|
||||||
|
* This second mechanims is useful for things like tutorial messages or
|
||||||
|
* background atc chatter.
|
||||||
*/
|
*/
|
||||||
class FGFX : public SGSubsystem
|
class FGFX : public SGSubsystem
|
||||||
{
|
{
|
||||||
|
@ -49,9 +67,17 @@ public:
|
||||||
virtual void unbind ();
|
virtual void unbind ();
|
||||||
virtual void update (double dt);
|
virtual void update (double dt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add a sound sample to the message queue which is played sequentially
|
||||||
|
* in order.
|
||||||
|
*/
|
||||||
|
void play_message( SGSoundSample *_sample );
|
||||||
|
void play_message( const string path, const string fname );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
vector<SGXmlSound *> _sound;
|
vector<SGXmlSound *> _sound;
|
||||||
|
queue<SGSoundSample *> _samplequeue;
|
||||||
|
|
||||||
bool last_pause;
|
bool last_pause;
|
||||||
double last_volume;
|
double last_volume;
|
||||||
|
|
Loading…
Add table
Reference in a new issue