From 8fa968c7bc829b463ac056472eabd89ed3c3ab07 Mon Sep 17 00:00:00 2001 From: Erik Hofman Date: Tue, 31 May 2016 13:40:46 +0200 Subject: [PATCH] Add the option to define volume and pitch using an expression --- simgear/sound/xmlsound.cxx | 50 ++++++++++++++++++++++++++++++++------ simgear/sound/xmlsound.hxx | 6 ++++- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/simgear/sound/xmlsound.cxx b/simgear/sound/xmlsound.cxx index 36907f5b..2becb55a 100644 --- a/simgear/sound/xmlsound.cxx +++ b/simgear/sound/xmlsound.cxx @@ -140,7 +140,12 @@ SGXmlSound::init( SGPropertyNode *root, float v = 0.0; std::vector kids = node->getChildren("volume"); for (i = 0; (i < kids.size()) && (i < SGXmlSound::MAXPROP); i++) { - _snd_prop volume = {NULL, NULL, NULL, 1.0, 0.0, 0.0, 0.0, false}; + _snd_prop volume = {NULL, NULL, NULL, NULL, 1.0, 0.0, 0.0, 0.0, false}; + + SGPropertyNode *n = kids[i]->getChild("expression"); + if (n != NULL) { + volume.expr = SGReadDoubleExpression(root, n->getChild(0)); + } propval = kids[i]->getStringValue("property", ""); if ( propval != "" ) @@ -198,7 +203,12 @@ SGXmlSound::init( SGPropertyNode *root, float p = 0.0; kids = node->getChildren("pitch"); for (i = 0; (i < kids.size()) && (i < SGXmlSound::MAXPROP); i++) { - _snd_prop pitch = {NULL, NULL, NULL, 1.0, 1.0, 0.0, 0.0, false}; + _snd_prop pitch = {NULL, NULL, NULL, NULL, 1.0, 1.0, 0.0, 0.0, false}; + + SGPropertyNode *n = kids[i]->getChild("expression"); + if (n != NULL) { + pitch.expr = SGReadDoubleExpression(root, n->getChild(0)); + } propval = kids[i]->getStringValue("property", ""); if (propval != "") @@ -401,15 +411,27 @@ SGXmlSound::update (double dt) int max = _volume.size(); double volume = 1.0; double volume_offset = 0.0; + bool expr = false; for(i = 0; i < max; i++) { double v = 1.0; - if (_volume[i].prop) - v = _volume[i].prop->getDoubleValue(); + if (_volume[i].expr) { + v = _volume[i].expr->getValue(NULL); + expr = true; + continue; + } - else if (_volume[i].intern) + if (_volume[i].prop) { + // do not process if there was an expression defined + if (expr) continue; + + v = _volume[i].prop->getDoubleValue(); + } + else if (_volume[i].intern) { + // intern sections always get processed. v = *_volume[i].intern; + } if (_volume[i].fn) v = _volume[i].fn(v); @@ -438,14 +460,26 @@ SGXmlSound::update (double dt) double pitch = 1.0; double pitch_offset = 0.0; + expr = false; for(i = 0; i < max; i++) { double p = 1.0; - if (_pitch[i].prop) - p = _pitch[i].prop->getDoubleValue(); + if (_volume[i].expr) { + p = _pitch[i].expr->getValue(NULL); + expr = true; + continue; + } - else if (_pitch[i].intern) + if (_pitch[i].prop) { + // do not process if there was an expression defined + if (expr) continue; + + p = _pitch[i].prop->getDoubleValue(); + } + else if (_pitch[i].intern) { + // intern sections always get processed. p = *_pitch[i].intern; + } if (_pitch[i].fn) p = _pitch[i].fn(p); diff --git a/simgear/sound/xmlsound.hxx b/simgear/sound/xmlsound.hxx index 576ead7b..53f9adcb 100644 --- a/simgear/sound/xmlsound.hxx +++ b/simgear/sound/xmlsound.hxx @@ -33,6 +33,7 @@ #include #include +#include // forward decls class SGSampleGroup; @@ -126,8 +127,9 @@ protected: enum { ONCE=0, LOOPED, IN_TRANSIT }; enum { LEVEL=0, INVERTED, FLIPFLOP }; - // SGXmlSound properties + // SGXmlSound properties for typedef struct { + SGSharedPtr expr; // sound system version 2.0 SGPropertyNode_ptr prop; double (*fn)(double); double *intern; @@ -147,6 +149,7 @@ private: SGPropertyNode_ptr _property; bool _active; + float _version; std::string _name; int _mode; double _prev_value; @@ -157,6 +160,7 @@ private: // This is useful for lost packets in in-transit mode. bool _initialized; + // sound system version 1.0 std::vector<_snd_prop> _volume; std::vector<_snd_prop> _pitch; }; -- 2.39.5