]> git.mxchange.org Git - flightgear.git/commitdiff
This patch creates a sample manager next to the sound manager. The
authorcurt <curt>
Mon, 4 Mar 2002 16:03:11 +0000 (16:03 +0000)
committercurt <curt>
Mon, 4 Mar 2002 16:03:11 +0000 (16:03 +0000)
difference between the two is this: A sample is file related and sound
is a authonomus entity. This means you can have several sounds pointing
to a single sample. In that case, just one sample is loaded into memory.
The advantage is you can play the same sample with different pitch or
volume, but with just one  sample loaded into memory.

To fully support this there is a new fucntion call:

    FGSimpleSound *sample = new FGSimpleSound("filename");
    mgr->add(sample, "name");

should be replaced by:

    FGSimpleSound *sample = mgr->add("name", "filename");

But the old behaviour is still supported with one minor change, sounds
with the same name aren't supported anymore.

Erik

src/Sound/fg_sound.cxx
src/Sound/soundmgr.cxx
src/Sound/soundmgr.hxx

index c8bb87eed9941f49ebd995eb109aaa9ee8996de5..1cbbd242d0e99cae240b0b186cce136891762b0c 100644 (file)
 
 FGSound::FGSound(const SGPropertyNode * node)
   : _name(""),
+    _sample(0),
     _factor(1.0),
     _active(false),
     _mode(FGSound::ONCE),
-    _type(FGSound::LEVEL)
+    _type(FGSound::LEVEL),
+    _node(node)
 {
-   _node = node;
 }
 
 FGSound::~FGSound()
@@ -53,7 +54,6 @@ FGSound::~FGSound()
 void
 FGSound::init()
 {
-   FGSoundMgr * mgr = globals->get_soundmgr();
    vector<const SGPropertyNode *> kids;
    float p = 0.0;
    float v = 0.0;
@@ -204,12 +204,10 @@ FGSound::init()
    //
    // Initialize the sample
    //
-   _sample = new FGSimpleSound(_node->getStringValue("path"));
+   FGSoundMgr * mgr = globals->get_soundmgr();
+   _sample = mgr->add(_name, _node->getStringValue("path"));
    _sample->set_volume(v);
    _sample->set_pitch(p);
-
-   if (!mgr->exists(_name))
-      mgr->add(_sample, _name);
 }
 
 void
@@ -235,12 +233,22 @@ FGSound::update (int dt)
    // if (!_property)
    //   return;
 
-   i = _property->getFloatValue() * _factor;
-   if (_type == FGSound::INVERTED)
-      i = !i;
    if ((_type == FGSound::LEVEL)  || (_type == FGSound::INVERTED)) {
-      if (i == 0) {
+
+      //
+      // If the sound is already playing we have nothing to do.
+      //
+      if (_active && (_mode == FGSound::ONCE))
+         return;
+
+      int check = _property->getFloatValue() * _factor;
+      if (_type == FGSound::INVERTED)
+         check = !check;
+
+      //
+      // If the state changes to false, stop playing.
+      //
+      if (check == 0) {
          _active = false;
          if (mgr->is_playing(_name)) {
             SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name);
@@ -250,12 +258,10 @@ FGSound::update (int dt)
          return;
       }
 
-      if (_active && (_mode == FGSound::ONCE))
-         return;
-
    } else {            // FGSound::FLIPFLOP
 
-      if ((bool)i == _active)
+      bool check = _property->getFloatValue() * _factor;
+      if (check == _active)
          return;
 
       //
@@ -272,6 +278,7 @@ FGSound::update (int dt)
    // Update the volume
    //
    int max = _volume.size();
+
    double volume = 1.0, volume_offset = 0.0;
    for(i = 0; i < max; i++) {
       double v = _volume[i].prop->getDoubleValue();
index 834632fbac75c3dd628929d2fe4eeb7941e28b4a..aa4b6f4f0d8c4acc846c2006850dfa164823e2f8 100644 (file)
@@ -81,12 +81,26 @@ FGSoundMgr::FGSoundMgr() {
 // destructor
 
 FGSoundMgr::~FGSoundMgr() {
-    sound_map_iterator current = sounds.begin();
-    sound_map_iterator end = sounds.end();
-    for ( ; current != end; ++current ) {
-       FGSimpleSound *s = current->second;
-       delete s->get_sample();
-       delete s;
+
+    //
+    // Remove the samples from the sample manager.
+    //
+    sample_map_iterator sample_current = samples.begin();
+    sample_map_iterator sample_end = samples.end();
+    for ( ; sample_current != sample_end; ++sample_current ) {
+       sample_ref *sr = sample_current->second;
+       delete sr->sample;
+       delete sr;
+    }
+
+    //
+    // Remove the sounds from the sound manager.
+    //
+    sound_map_iterator sound_current = sounds.begin();
+    sound_map_iterator sound_end = sounds.end();
+    for ( ; sound_current != sound_end; ++sound_current ) {
+        FGSimpleSound *s = sound_current->second;
+        delete s;
     }
 
     delete audio_sched;
@@ -102,10 +116,26 @@ void FGSoundMgr::init() {
     // audio_mixer -> setMasterVolume ( 80 ) ;  /* 80% of max volume. */
     audio_sched -> setSafetyMargin ( FG_SOUND_SAFETY_MULT * safety ) ;
 
-    sound_map_iterator current = sounds.begin();
-    sound_map_iterator end = sounds.end();
-    for ( ; current != end; ++current ) {
-       FGSimpleSound *s = current->second;
+
+    //
+    // Remove the samples from the sample manager.
+    //
+    sample_map_iterator sample_current = samples.begin();
+    sample_map_iterator sample_end = samples.end();
+    for ( ; sample_current != sample_end; ++sample_current ) {
+        sample_ref *sr = sample_current->second;
+        delete sr->sample;
+        delete sr;
+    }
+    samples.clear();
+    //
+    // Remove the sounds from the sound manager.
+    //
+    sound_map_iterator sound_current = sounds.begin();
+    sound_map_iterator sound_end = sounds.end();
+    for ( ; sound_current != sound_end; ++sound_current ) {
+       FGSimpleSound *s = sound_current->second;
        delete s->get_sample();
        delete s;
     }
@@ -149,12 +179,53 @@ void FGSoundMgr::update(int dt) {
 
 
 // add a sound effect, return true if successful
-bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname  ) {
+bool FGSoundMgr::add( FGSimpleSound *sound, const string& refname ) {
+
+    sample_map_iterator it = samples.find(refname);
+    if (it != samples.end())
+       return false;
+
+    sample_ref *sr = new sample_ref;
+
+    sr->n=1;
+    sr->sample = sound->get_sample();
+    samples[refname] = sr;
+
     sounds[refname] = sound;
 
     return true;
 }
 
+// add a sound from a file, return the sample if successful, else return NULL
+FGSimpleSound *FGSoundMgr::add( const string& refname, const string &file ) {
+     FGSimpleSound *sound;
+
+    if (file == (string)"")
+       return NULL;
+
+    sample_map_iterator it = samples.find(file);
+    if (it == samples.end()) {
+       sound = new FGSimpleSound(file);
+       sounds[refname] = sound;
+
+       sample_ref *sr = new sample_ref;
+
+       sr->n=1;
+       sr->sample = sound->get_sample();
+       samples[file] = sr;
+
+    } else {
+       sample_ref *sr = it->second;
+
+       sr->n++;
+       sound =
+           new FGSimpleSound(sr->sample->getBuffer(), sr->sample->getLength());
+       sounds[refname] = sound;
+
+    }
+
+    return sound;
+}
 
 // remove a sound effect, return true if successful
 bool FGSoundMgr::remove( const string& refname ) {
@@ -182,7 +253,12 @@ bool FGSoundMgr::remove( const string& refname ) {
        // cout << "Still playing " << sample->get_sample()->getPlayCount()
        //      << " instances!" << endl;
 
-       delete sample;
+        //
+        // FIXME:
+        // Due to the change in the sound manager, samples live
+       // until the sound manager gets removed.
+        //
+       // delete sample;
         sounds.erase( it );
 
        return true;
index c8809d0020c0a85ff12b42941403123f1830cf13..2c756390528eb2312d9abe80e822be7130b8ccb5 100644 (file)
@@ -79,6 +79,16 @@ public:
 };
 
 
+typedef struct {
+       int n;
+       slSample *sample;
+} sample_ref;
+
+typedef map < string, sample_ref * > sample_map;
+typedef sample_map::iterator sample_map_iterator;
+typedef sample_map::const_iterator const_sample_map_iterator;
+
+
 typedef map < string, FGSimpleSound * > sound_map;
 typedef sound_map::iterator sound_map_iterator;
 typedef sound_map::const_iterator const_sound_map_iterator;
@@ -89,7 +99,9 @@ class FGSoundMgr : public FGSubsystem
 
     slScheduler *audio_sched;
     smMixer *audio_mixer;
+
     sound_map sounds;
+    sample_map samples;
 
     SGTimeStamp last;
     double safety;
@@ -128,7 +140,10 @@ public:
     inline bool is_working() const { return !audio_sched->notWorking(); }
 
     // add a sound effect, return true if successful
-    bool add( FGSimpleSound *sound, const string& refname );
+    bool add( FGSimpleSound *sound, const string& refname);
+
+    // add a sound file, return the sample if successful, else return NULL
+    FGSimpleSound *add( const string& refname, const string& file = "" );
 
     // remove a sound effect, return true if successful
     bool remove( const string& refname );