]> git.mxchange.org Git - flightgear.git/commitdiff
Additional functionality added to the FlightGear sound fx manager.
authorcurt <curt>
Mon, 9 Jan 2006 02:21:04 +0000 (02:21 +0000)
committercurt <curt>
Mon, 9 Jan 2006 02:21:04 +0000 (02:21 +0000)
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.

src/Sound/fg_fx.cxx
src/Sound/fg_fx.hxx

index 97223c951d76233bff7669711fb600a1153eeb74..b2196b7a5c0f4bfb8a3243bc9b0da201aff14a27 100644 (file)
@@ -49,7 +49,16 @@ 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
@@ -109,20 +118,43 @@ FGFX::unbind ()
 void
 FGFX::update (double dt)
 {
+    SGSoundMgr *smgr = globals->get_soundmgr();
+
     // command sound manger
     bool pause = _pause->getBoolValue();
     if ( pause != last_pause ) {
         if ( pause ) {
-            globals->get_soundmgr()->pause();
+            smgr->pause();
         } else {
-            globals->get_soundmgr()->resume();
+            smgr->resume();
         }
         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();
     if ( volume != last_volume ) {
-        globals->get_soundmgr()->set_volume( volume );        
+        smgr->set_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
index 2c80d1c04bf112e6174a5b81793d4d5ac5ec900e..61aee36ec7d4e3fd6c4ea85c6efff65289ea2691 100644 (file)
 #ifndef __FGFX_HXX
 #define __FGFX_HXX 1
 
+#include <simgear/compiler.h>
+
+#include <queue>
+#include <vector>
+
+#include <simgear/sound/sample_openal.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 
+SG_USING_STD(queue);
+SG_USING_STD(vector);
+
 class SGXmlSound;
 
 /**
@@ -34,30 +43,47 @@ class SGXmlSound;
  * This module uses FGSoundMgr to generate sound effects based
  * on current flight conditions.  The sound manager must be initialized
  * 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
 {
 
 public:
 
-  FGFX ();
-  virtual ~FGFX ();
+    FGFX ();
+    virtual ~FGFX ();
+
+    virtual void init ();
+    virtual void reinit ();
+    virtual void bind ();
+    virtual void unbind ();
+    virtual void update (double dt);
 
-  virtual void init ();
-  virtual void reinit ();
-  virtual void bind ();
-  virtual void unbind ();
-  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:
 
-  vector<SGXmlSound *> _sound;
+    vector<SGXmlSound *> _sound;
+    queue<SGSoundSample *> _samplequeue;
 
-  bool last_pause;
-  double last_volume;
+    bool last_pause;
+    double last_volume;
 
-  SGPropertyNode *_pause;
-  SGPropertyNode *_volume;
+    SGPropertyNode *_pause;
+    SGPropertyNode *_volume;
 
 };