1 // scenefx.cxx -- Scenery sound effect management implementation
3 // Started by Erik Hofman, November 2015
5 // Copyright (C) 2015 Erik Hofman <erik@ehofman.com>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #pragma warning (disable: 4786)
33 #include "scenefx.hxx"
35 #include <Main/fg_props.hxx>
36 #include <Main/globals.hxx>
38 #include <simgear/misc/sg_path.hxx>
39 #include <simgear/sound/soundmgr_openal.hxx>
40 #include <simgear/nasal/cppbind/Ghost.hxx>
42 #include <boost/shared_ptr.hpp>
43 #include <boost/weak_ptr.hpp>
46 static std::string _refname = "SceneFX";
47 typedef boost::shared_ptr<SGSampleGroup> SGSampleGroupRef;
48 typedef boost::shared_ptr<FGSceneFX> FGSceneFXRef;
51 FGSceneFX::FGSceneFX()
53 _enabled = fgGetNode("/sim/sound/scene/enabled", true);
54 _volume = fgGetNode("/sim/sound/scene/volume", true);
55 _damping = fgGetNode("/sim/sound/model-damping", true);
56 _smgr->add(this, _refname);
58 nasal::Ghost<FGSceneFXRef>::init("soundfx.scene")
59 .bases<SGSampleGroupRef>()
60 .method("load", &FGSceneFX::load)
61 .method("damping", &FGSceneFX::model_damping);
64 FGSceneFX::~FGSceneFX()
68 void FGSceneFX::unbind()
71 _smgr->remove(_refname);
75 void FGSceneFX::init()
82 void FGSceneFX::reinit()
87 void FGSceneFX::update (double dt)
93 if (_enabled->getBoolValue())
95 float fact = 1.0f - _damping->getFloatValue();
96 set_volume(_volume->getFloatValue() * fact);
99 SGSampleGroup::update(dt);
106 /* Sets the scene properties from the models point of view */
107 void FGSceneFX::model_damping(float damping)
109 _damping->setFloatValue(damping);
112 /* (Over)load the sound file for a particular ref. name */
113 bool FGSceneFX::load(const std::string& refname, const std::string& path_str)
119 SGPath path = globals->resolve_resource_path(path_str);
120 if (!path.isNull() && path.exists())
122 SGSoundSample* sample;
126 sample = find(refname, i);
128 sample->set_sample_name(path_str);
136 throw sg_io_exception("SceneFX: couldn't find file: '" + path.str() + "'");
141 /* Control the sounds from the generating side. */
142 size_t FGSceneFX::add(const std::string& refname)
148 unsigned int num = 0;
151 name = full_name(refname, num++);
152 } while(SGSampleGroup::exists(name));
154 SGSharedPtr<SGSoundSample> sample;
155 sample = new SGSoundSample();
156 SGSampleGroup::add(sample, name);
161 bool FGSceneFX::remove(const std::string& refname, size_t num)
163 std::string name = full_name(refname, num);
164 return SGSampleGroup::remove(name);
167 void FGSceneFX::position(const std::string& refname, size_t num, double lon, double lat, double elevation)
169 SGSoundSample* sample = find(refname, num);
172 SGGeod pos = SGGeod::fromDegFt(lon, lat, elevation);
173 sample->set_position(SGVec3d::fromGeod(pos));
177 void FGSceneFX::pitch(const std::string& refname, size_t num, float pitch)
179 SGSoundSample* sample = find(refname, num);
181 sample->set_pitch(pitch);
185 void FGSceneFX::volume(const std::string& refname, size_t num, float volume)
187 SGSoundSample* sample = find(refname, num);
190 sample->set_volume(volume);
194 void FGSceneFX::properties(const std::string& refname, size_t num, float reference_dist, float maximum_dist)
196 SGSoundSample* sample = find(refname, num);
199 float fact = 1.0f - _damping->getFloatValue();
200 sample->set_reference_dist(reference_dist * fact);
201 if (maximum_dist > 0) {
202 sample->set_max_dist(maximum_dist * fact);
207 void FGSceneFX::play(const std::string& refname, size_t num, bool looping)
209 SGSampleGroup::play(full_name(refname, num), looping);
212 void FGSceneFX::stop(const std::string& refname, size_t num)
214 SGSampleGroup::stop(full_name(refname, num));
217 const char* FGSceneFX::full_name(const std::string& refname, size_t num)
219 static char nstr[128];
220 snprintf(nstr, 127, "%s_%4zu", refname.c_str(), num);
224 SGSoundSample *FGSceneFX::find(const std::string& refname, size_t num)
226 return SGSampleGroup::find( full_name(refname, num) );
229 // end of scenefx.cxx