diff --git a/docs-mini/README.xmlsound b/docs-mini/README.xmlsound index 4b9632340..c8ed950cf 100644 --- a/docs-mini/README.xmlsound +++ b/docs-mini/README.xmlsound @@ -155,7 +155,17 @@ Configuration description: Defins which property supplies the value for the calculation. + Either a or an should be defined. The value is treatened as a floating point number. + + + Defins which internal variable should be used for the calculation. + The value is treatened as a floating point number. + The following internals are available at this time: + + dt_play: the number of seconds since the sound started playing. + + dt_stop: the number of seconds after the sound has stopped. Defines the function that should be used upon the property diff --git a/src/Sound/fg_sound.cxx b/src/Sound/fg_sound.cxx index 4de3ed0e4..728a3a1aa 100644 --- a/src/Sound/fg_sound.cxx +++ b/src/Sound/fg_sound.cxx @@ -65,6 +65,8 @@ FGSound::FGSound() : _sample(NULL), _condition(NULL), _property(NULL), + _dt_play(0.0), + _dt_stop(0.0), _prev_value(0), _name(""), _mode(FGSound::ONCE) @@ -73,7 +75,12 @@ FGSound::FGSound() FGSound::~FGSound() { - delete _condition; + if (_property) + delete _property; + + if (_condition) + delete _condition; + delete _sample; } @@ -118,22 +125,23 @@ FGSound::init(SGPropertyNode *node) float v = 0.0; vector kids = node->getChildren("volume"); for (i = 0; (i < kids.size()) && (i < FGSound::MAXPROP); i++) { - _snd_prop volume; + _snd_prop volume = {NULL, NULL, NULL, 1.0, 0.0, 0.0, 0.0, false}; - volume.prop = fgGetNode(kids[i]->getStringValue("property"), true); + if (strcmp(kids[i]->getStringValue("property"), "")) + volume.prop = fgGetNode(kids[i]->getStringValue("property"), true); - if ((volume.factor = kids[i]->getDoubleValue("factor")) == 0.0) - volume.factor = 1.0; + const char *intern_str = kids[i]->getStringValue("internal"); + if (!strcmp(intern_str, "dt_play")) + volume.intern = &_dt_play; + else if (!strcmp(intern_str, "dt_stop")) + volume.intern = &_dt_stop; - else + if ((volume.factor = kids[i]->getDoubleValue("factor")) != 0.0) if (volume.factor < 0.0) { volume.factor = -volume.factor; volume.subtract = true; + } - } else - volume.subtract = false; - - volume.fn = NULL; const char *type_str = kids[i]->getStringValue("type"); if ( strcmp(type_str, "") ) { @@ -150,21 +158,15 @@ FGSound::init(SGPropertyNode *node) volume.offset = kids[i]->getDoubleValue("offset"); - if ((volume.min = kids[i]->getDoubleValue("min")) < 0.0) { + if ((volume.min = kids[i]->getDoubleValue("min")) < 0.0) SG_LOG( SG_GENERAL, SG_WARN, "Volume minimum value below 0. Forced to 0."); - volume.min = 0.0; - } - volume.max = kids[i]->getDoubleValue("max"); - if (volume.max && (volume.max < volume.min) ) { + if (volume.max && (volume.max < volume.min) ) SG_LOG(SG_GENERAL,SG_ALERT, " Volume maximum below minimum. Neglected."); - volume.max = 0.0; - } - _volume.push_back(volume); v += volume.offset; @@ -177,22 +179,23 @@ FGSound::init(SGPropertyNode *node) float p = 0.0; kids = node->getChildren("pitch"); for (i = 0; (i < kids.size()) && (i < FGSound::MAXPROP); i++) { - _snd_prop pitch; + _snd_prop pitch = {NULL, NULL, NULL, 1.0, 1.0, 0.0, 0.0, false}; - pitch.prop = fgGetNode(kids[i]->getStringValue("property"), true); + if (strcmp(kids[i]->getStringValue("property"), "")) + pitch.prop = fgGetNode(kids[i]->getStringValue("property"), true); - if ((pitch.factor = kids[i]->getDoubleValue("factor")) == 0.0) - pitch.factor = 1.0; + const char *intern_str = kids[i]->getStringValue("internal"); + if (!strcmp(intern_str, "dt_play")) + pitch.intern = &_dt_play; + else if (!strcmp(intern_str, "dt_stop")) + pitch.intern = &_dt_stop; - else + if ((pitch.factor = kids[i]->getDoubleValue("factor")) != 0.0) if (pitch.factor < 0.0) { pitch.factor = -pitch.factor; pitch.subtract = true; + } - } else - pitch.subtract = false; - - pitch.fn = NULL; const char *type_str = kids[i]->getStringValue("type"); if ( strcmp(type_str, "") ) { @@ -207,24 +210,17 @@ FGSound::init(SGPropertyNode *node) " Unknown pitch type, default to 'lin'"); } - if ((pitch.offset = kids[i]->getDoubleValue("offset")) == 0.0) - pitch.offset = 1.0; + pitch.offset = kids[i]->getDoubleValue("offset"); - if ((pitch.min = kids[i]->getDoubleValue("min")) < 0.0) { + if ((pitch.min = kids[i]->getDoubleValue("min")) < 0.0) SG_LOG(SG_GENERAL,SG_WARN, " Pitch minimum value below 0. Forced to 0."); - pitch.min = 0.0; - } - pitch.max = kids[i]->getDoubleValue("max"); - if (pitch.max && (pitch.max < pitch.min) ) { + if (pitch.max && (pitch.max < pitch.min) ) SG_LOG(SG_GENERAL,SG_ALERT, " Pitch maximum below minimum. Neglected"); - pitch.max = 0.0; - } - _pitch.push_back(pitch); p += pitch.offset; } @@ -272,10 +268,12 @@ FGSound::update (double dt) ) { - _active = false; + _dt_stop += dt; if (_sample->is_playing()) { - SG_LOG(SG_GENERAL, SG_INFO, "Stopping sound: " << _name); + SG_LOG(SG_GENERAL, SG_INFO, "Stopping audio after " << _dt_play + << " sec: " << _name ); _sample->stop( _mgr->get_scheduler() ); + _dt_play = 0.0; } return; @@ -286,13 +284,14 @@ FGSound::update (double dt) // If the mode is ONCE and the sound is still playing, // we have nothing to do anymore. // - if (_active && (_mode == FGSound::ONCE)) + if (_dt_play && (_mode == FGSound::ONCE)) return; // - // Cache current value; + // Cache current value and Update playing time // _prev_value = curr_value; + _dt_play += dt; // // Update the volume @@ -303,7 +302,13 @@ FGSound::update (double dt) double volume_offset = 0.0; for(i = 0; i < max; i++) { - double v = _volume[i].prop->getDoubleValue(); + double v; + + if (_volume[i].prop) + v = _volume[i].prop->getDoubleValue(); + + else if (_volume[i].intern) + v = *_volume[i].intern; if (_volume[i].fn) v = _volume[i].fn(v); @@ -333,7 +338,13 @@ FGSound::update (double dt) double pitch_offset = 0.0; for(i = 0; i < max; i++) { - double p = _pitch[i].prop->getDoubleValue(); + double p; + + if (_pitch[i].prop) + p = _pitch[i].prop->getDoubleValue(); + + else if (_pitch[i].intern) + p = *_pitch[i].intern; if (_pitch[i].fn) p = _pitch[i].fn(p); @@ -365,9 +376,10 @@ FGSound::update (double dt) // // Do we need to start playing the sample? // - if (!_active) { + if (_dt_stop) { + + _dt_stop = 0.0; - _active = true; if (_mode == FGSound::ONCE) _sample->play(_mgr->get_scheduler(), false); diff --git a/src/Sound/fg_sound.hxx b/src/Sound/fg_sound.hxx index 8774562b2..6681dc261 100644 --- a/src/Sound/fg_sound.hxx +++ b/src/Sound/fg_sound.hxx @@ -61,6 +61,7 @@ protected: typedef struct { SGPropertyNode * prop; double (*fn)(double); + double *intern; double factor; double offset; double min; @@ -72,14 +73,15 @@ private: FGSoundMgr * _mgr; FGSimpleSound * _sample; + FGCondition * _condition; - SGPropertyNode * _property; - double _prev_value; - bool _active; string _name; int _mode; + double _prev_value; + double _dt_play; + double _dt_stop; vector<_snd_prop> _volume; vector<_snd_prop> _pitch;