From 26f1d12ad79c19c0e68820d18a1a0a5a12e4f831 Mon Sep 17 00:00:00 2001 From: Erik Hofman Date: Thu, 5 Nov 2015 15:31:52 +0100 Subject: [PATCH] Rename EnvironmentFX to SceneFX and rethink the aircraft model specific properties: use a samping factor which applies to both volume and reference_distance and max_distance --- src/Sound/CMakeLists.txt | 4 +- src/Sound/environment_fx.cxx | 185 ---------------------------- src/Sound/environment_fx.hxx | 68 ----------- src/Sound/scenefx.cxx | 229 +++++++++++++++++++++++++++++++++++ src/Sound/scenefx.hxx | 88 ++++++++++++++ 5 files changed, 319 insertions(+), 255 deletions(-) delete mode 100644 src/Sound/environment_fx.cxx delete mode 100644 src/Sound/environment_fx.hxx create mode 100644 src/Sound/scenefx.cxx create mode 100644 src/Sound/scenefx.hxx diff --git a/src/Sound/CMakeLists.txt b/src/Sound/CMakeLists.txt index b2492b010..3e0fcab16 100644 --- a/src/Sound/CMakeLists.txt +++ b/src/Sound/CMakeLists.txt @@ -5,7 +5,7 @@ set(SOURCES soundgenerator.cxx beacon.cxx fg_fx.cxx - environment_fx.cxx + scenefx.cxx morse.cxx sample_queue.cxx voice.cxx @@ -18,7 +18,7 @@ set(HEADERS soundgenerator.hxx beacon.hxx fg_fx.hxx - environment_fx.hxx + scenefx.hxx morse.hxx sample_queue.hxx voice.hxx diff --git a/src/Sound/environment_fx.cxx b/src/Sound/environment_fx.cxx deleted file mode 100644 index 964fd3b98..000000000 --- a/src/Sound/environment_fx.cxx +++ /dev/null @@ -1,185 +0,0 @@ -// fg_environmentfx.cxx -- Sound effect management class implementation -// -// Started by David Megginson, October 2001 -// (Reuses some code from main.cxx, probably by Curtis Olson) -// -// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// $Id$ - -#ifdef _MSC_VER -#pragma warning (disable: 4786) -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "environment_fx.hxx" - -#include
-#include
- -#include -#include -#include - -#include -#include - - -static std::string _refname = "EnvironmentFX"; -typedef boost::shared_ptr SGSampleGroupRef; -typedef boost::shared_ptr FGEnvironmentFXRef; - - -FGEnvironmentFX::FGEnvironmentFX() -{ - _enabled = fgGetNode("/sim/sound/environment/enabled", true); - _volume = fgGetNode("/sim/sound/environment/volume", true); - _smgr->add(this, _refname); - - nasal::Ghost::init("sound") - .bases() - .method("add", &FGEnvironmentFX::add) - .method("position", &FGEnvironmentFX::position) - .method("pitch", &FGEnvironmentFX::pitch) - .method("volume", &FGEnvironmentFX::volume) - .method("properties", &FGEnvironmentFX::properties) - .method("play", &FGEnvironmentFX::play) - .method("stop", &FGEnvironmentFX::stop); -} - -FGEnvironmentFX::~FGEnvironmentFX() -{ -} - -void FGEnvironmentFX::unbind() -{ - if (_smgr) { - _smgr->remove(_refname); - } -} - -void FGEnvironmentFX::init() -{ - if (!_smgr) { - return; - } -} - -void FGEnvironmentFX::reinit() -{ - init(); -} - -void FGEnvironmentFX::update (double dt) -{ - if (!_smgr) { - return; - } - - if ( _enabled->getBoolValue() ) { - set_volume( _volume->getDoubleValue() ); - resume(); - - SGSampleGroup::update(dt); - } - else { - suspend(); - } -} - -bool FGEnvironmentFX::add(const std::string& path_str, const std::string& refname) -{ - if (!_smgr) { - return false; - } - - SGPath path = globals->resolve_resource_path(path_str); - if (path.isNull()) - { - SG_LOG(SG_SOUND, SG_ALERT, "File not found: '" << path_str); - return false; - } - SG_LOG(SG_SOUND, SG_INFO, "Reading sound from " << path.str()); - - SGSharedPtr sample; - sample = new SGSoundSample("", path); - if (sample->file_path().exists()) { - SGSampleGroup::add( sample, refname ); - } - else - { - throw sg_io_exception("Environment FX: couldn't find file: '" + path.str() + "'"); - delete sample; - return false; - } - return true; -} - -void FGEnvironmentFX::position(const std::string& refname, double lon, double lat, double elevation) -{ - SGSoundSample* sample = SGSampleGroup::find(refname); - if (sample) - { - SGGeod pos = SGGeod::fromDegFt(lon, lat, elevation); - sample->set_position( SGVec3d::fromGeod(pos) ); - } -} - -void FGEnvironmentFX::pitch(const std::string& refname, float pitch) -{ - SGSoundSample* sample = SGSampleGroup::find(refname); - if (sample) - { - sample->set_volume( pitch ); - } -} - -void FGEnvironmentFX::volume(const std::string& refname, float volume) -{ - SGSoundSample* sample = SGSampleGroup::find(refname); - if (sample) - { - sample->set_volume( volume ); - } -} - -void FGEnvironmentFX::properties(const std::string& refname, float reference_dist, float max_dist ) -{ - SGSoundSample* sample = SGSampleGroup::find(refname); - if (sample) - { - sample->set_reference_dist( reference_dist ); - if (max_dist > 0) { - sample->set_max_dist( max_dist ); - } - } -} - -void FGEnvironmentFX::play(const std::string& refname, bool looping) -{ - SGSampleGroup::play( refname, looping ); -} - -void FGEnvironmentFX::stop(const std::string& refname) -{ - SGSampleGroup::stop( refname ); -} - -// end of fg_environmentfx.cxx diff --git a/src/Sound/environment_fx.hxx b/src/Sound/environment_fx.hxx deleted file mode 100644 index 3be2d4897..000000000 --- a/src/Sound/environment_fx.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// fg_environmentfx.hxx -- Sound effect management class -// -// Started by David Megginson, October 2001 -// (Reuses some code from main.cxx, probably by Curtis Olson) -// -// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// $Id$ - -#ifndef __FGENVIRONMENTFX_HXX -#define __FGENVIRONMENTFX_HXX 1 - -#include - -#include -#include -#include -#include - - - -/** - * Container for FlightGear envirnonmetal sound effects. - */ -class FGEnvironmentFX : public SGSampleGroup -{ - -public: - - FGEnvironmentFX(); - virtual ~FGEnvironmentFX(); - - void init (); - void reinit(); - void update (double dt); - void unbind(); - - bool add(const std::string& path_str, const std::string& refname); - void position(const std::string& refname, double lon, double lat, double elevation = 0.0); - void pitch(const std::string& refname, float pitch); - void volume(const std::string& refname, float volume); - void properties(const std::string& refname, float reference_dist, float max_dist = -1 ); - void play(const std::string& refname, bool looping = false); - void stop(const std::string& refname); - -private: - SGPropertyNode_ptr _enabled; - SGPropertyNode_ptr _volume; -}; - - -#endif - -// end of fg_environmentfx.hxx diff --git a/src/Sound/scenefx.cxx b/src/Sound/scenefx.cxx new file mode 100644 index 000000000..2a1fbfbc2 --- /dev/null +++ b/src/Sound/scenefx.cxx @@ -0,0 +1,229 @@ +// scenefx.cxx -- Scenery sound effect management implementation +// +// Started by Erik Hofman, November 2015 +// +// Copyright (C) 2015 Erik Hofman +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#ifdef _MSC_VER +#pragma warning (disable: 4786) +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "scenefx.hxx" + +#include
+#include
+ +#include +#include +#include + +#include +#include + + +static std::string _refname = "SceneFX"; +typedef boost::shared_ptr SGSampleGroupRef; +typedef boost::shared_ptr FGSceneFXRef; + + +FGSceneFX::FGSceneFX() +{ + _enabled = fgGetNode("/sim/sound/scene/enabled", true); + _volume = fgGetNode("/sim/sound/scene/volume", true); + _damping = fgGetNode("/sim/sound/model-damping", true); + _smgr->add(this, _refname); + + nasal::Ghost::init("soundfx.scene") + .bases() + .method("load", &FGSceneFX::load) + .method("damping", &FGSceneFX::model_damping); +} + +FGSceneFX::~FGSceneFX() +{ +} + +void FGSceneFX::unbind() +{ + if (_smgr) { + _smgr->remove(_refname); + } +} + +void FGSceneFX::init() +{ + if (!_smgr) { + return; + } +} + +void FGSceneFX::reinit() +{ + init(); +} + +void FGSceneFX::update (double dt) +{ + if (!_smgr) { + return; + } + + if (_enabled->getBoolValue()) + { + float fact = 1.0f - _damping->getFloatValue(); + set_volume(_volume->getFloatValue() * fact); + resume(); + + SGSampleGroup::update(dt); + } + else { + suspend(); + } +} + +/* Sets the scene properties from the models point of view */ +void FGSceneFX::model_damping(float damping) +{ + _damping->setFloatValue(damping); +} + +/* (Over)load the sound file for a particular ref. name */ +bool FGSceneFX::load(const std::string& refname, const std::string& path_str) +{ + if (!_smgr) { + return false; + } + + SGPath path = globals->resolve_resource_path(path_str); + if (!path.isNull() && path.exists()) + { + SGSoundSample* sample; + unsigned int i = 0; + do + { + sample = find(refname, i); + if (sample) { + sample->set_sample_name(path_str); + } + } + while(sample); + + return true; + } + + throw sg_io_exception("SceneFX: couldn't find file: '" + path.str() + "'"); + + return false; +} + +/* Control the sounds from the generating side. */ +size_t FGSceneFX::add(const std::string& refname) +{ + if (!_smgr) { + return false; + } + + unsigned int num = 0; + std::string name; + do { + name = full_name(refname, num++); + } while(SGSampleGroup::exists(name)); + + SGSharedPtr sample; + sample = new SGSoundSample(); + SGSampleGroup::add(sample, name); + + return num; +} + +bool FGSceneFX::remove(const std::string& refname, size_t num) +{ + std::string name = full_name(refname, num); + return SGSampleGroup::remove(name); +} + +void FGSceneFX::position(const std::string& refname, size_t num, double lon, double lat, double elevation) +{ + SGSoundSample* sample = find(refname, num); + if (sample) + { + SGGeod pos = SGGeod::fromDegFt(lon, lat, elevation); + sample->set_position(SGVec3d::fromGeod(pos)); + } +} + +void FGSceneFX::pitch(const std::string& refname, size_t num, float pitch) +{ + SGSoundSample* sample = find(refname, num); + if (sample) { + sample->set_pitch(pitch); + } +} + +void FGSceneFX::volume(const std::string& refname, size_t num, float volume) +{ + SGSoundSample* sample = find(refname, num); + if (sample) + { + sample->set_volume(volume); + } +} + +void FGSceneFX::properties(const std::string& refname, size_t num, float reference_dist, float maximum_dist) +{ + SGSoundSample* sample = find(refname, num); + if (sample) + { + float fact = 1.0f - _damping->getFloatValue(); + sample->set_reference_dist(reference_dist * fact); + if (maximum_dist > 0) { + sample->set_max_dist(maximum_dist * fact); + } + } +} + +void FGSceneFX::play(const std::string& refname, size_t num, bool looping) +{ + SGSampleGroup::play(full_name(refname, num), looping); +} + +void FGSceneFX::stop(const std::string& refname, size_t num) +{ + SGSampleGroup::stop(full_name(refname, num)); +} + +const char* FGSceneFX::full_name(const std::string& refname, size_t num) +{ + static char nstr[128]; + snprintf(nstr, 127, "%s_%4zu", refname.c_str(), num); + return nstr; +} + +SGSoundSample *FGSceneFX::find(const std::string& refname, size_t num) +{ + return SGSampleGroup::find( full_name(refname, num) ); +} + +// end of scenefx.cxx diff --git a/src/Sound/scenefx.hxx b/src/Sound/scenefx.hxx new file mode 100644 index 000000000..310ecb178 --- /dev/null +++ b/src/Sound/scenefx.hxx @@ -0,0 +1,88 @@ +// scenefx.hxx -- Scene sound effect management class +// +// Started by Erik Hofman, November 2015 +// +// Copyright (C) 2015 Erik Hofman +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// $Id$ + +#ifndef __FGSCENEFX_HXX +#define __FGSCENEFX_HXX 1 + +#include + +#include +#include +#include +#include + +#define _DEFAULT_MAX_DISTANCE 100000.0 + +/** + * Container for FlightGear envirnonmetal sound effects. + */ +class FGSceneFX : public SGSampleGroup +{ + +public: + + FGSceneFX(); + virtual ~FGSceneFX(); + + void init (); + void reinit(); + void update (double dt); + void unbind(); + + /* Adjust volume and distance properties for the aircraft model */ + /* These work on all active sounds */ + void model_damping(float damping); + + /* (Over)load the sound file for a particular ref. name */ + bool load(const std::string& refname, const std::string& path_str); + + + /* Control the sounds from the generating side. + * + * Every sound has a reference name and an instance number: + * A reference name would be for instance 'thunder' or 'rain'. + * The number indicates the exact instance in case multiple + * variants are active simultaniously. + */ + size_t add(const std::string& refname); + bool remove(const std::string& refname, size_t num); + + void position(const std::string& refname, size_t num, double lon, double lat, double elevation = 0.0); + void pitch(const std::string& refname, size_t num, float pitch); + void volume(const std::string& refname, size_t num, float volume); + void properties(const std::string& refname, size_t num, float reference_dist, float max_dist = -1 ); + void play(const std::string& refname, size_t num, bool looping = false); + void stop(const std::string& refname, size_t num); + +private: + SGPropertyNode_ptr _enabled; + SGPropertyNode_ptr _volume; + SGPropertyNode_ptr _damping; // model sound damping + + const char* full_name(const std::string& refname, size_t num); + SGSoundSample *find(const std::string& refname, size_t num); +}; + + +#endif + +// end of scenefx.hxx -- 2.39.5