1
0
Fork 0

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:
curt 2006-01-09 02:21:04 +00:00
parent 0e16419f0d
commit 4132b41470
2 changed files with 92 additions and 16 deletions

View file

@ -49,7 +49,16 @@ FGFX::FGFX () :
FGFX::~FGFX () FGFX::~FGFX ()
{ {
_sound.clear(); unsigned int i;
for ( i = 0; i < _sound.size(); i++ ) {
delete _sound[i];
}
_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

View file

@ -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,30 +43,47 @@ 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
{ {
public: public:
FGFX (); FGFX ();
virtual ~FGFX (); virtual ~FGFX ();
virtual void init (); virtual void init ();
virtual void reinit (); virtual void reinit ();
virtual void bind (); virtual void bind ();
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;
SGPropertyNode *_pause; SGPropertyNode *_pause;
SGPropertyNode *_volume; SGPropertyNode *_volume;
}; };