Add the option to define volume and pitch using an expression

This commit is contained in:
Erik Hofman
2016-05-31 13:40:46 +02:00
parent 976c85ff57
commit ce0cdcdcb0
2 changed files with 47 additions and 9 deletions

View File

@@ -140,7 +140,12 @@ SGXmlSound::init( SGPropertyNode *root,
float v = 0.0;
std::vector<SGPropertyNode_ptr> 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);

View File

@@ -33,6 +33,7 @@
#include <simgear/props/propsfwd.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/SGExpression.hxx>
// 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<SGExpressiond> 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;
};