]> git.mxchange.org Git - flightgear.git/blob - src/Sound/scenefx.cxx
Rename EnvironmentFX to SceneFX and rethink the aircraft model specific properties...
[flightgear.git] / src / Sound / scenefx.cxx
1 // scenefx.cxx -- Scenery sound effect management implementation
2 //
3 // Started by Erik Hofman, November 2015
4 //
5 // Copyright (C) 2015  Erik Hofman <erik@ehofman.com>
6 //
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.
11 //
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.
16 //
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.
20 //
21 // $Id$
22
23 #ifdef _MSC_VER
24 #pragma warning (disable: 4786)
25 #endif
26
27 #ifdef HAVE_CONFIG_H
28 #  include <config.h>
29 #endif
30
31 #include <stdio.h>
32
33 #include "scenefx.hxx"
34
35 #include <Main/fg_props.hxx>
36 #include <Main/globals.hxx>
37
38 #include <simgear/misc/sg_path.hxx>
39 #include <simgear/sound/soundmgr_openal.hxx>
40 #include <simgear/nasal/cppbind/Ghost.hxx>
41
42 #include <boost/shared_ptr.hpp>
43 #include <boost/weak_ptr.hpp>
44
45
46 static std::string _refname = "SceneFX";
47 typedef boost::shared_ptr<SGSampleGroup> SGSampleGroupRef;
48 typedef boost::shared_ptr<FGSceneFX> FGSceneFXRef;
49
50
51 FGSceneFX::FGSceneFX()
52 {
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);
57
58     nasal::Ghost<FGSceneFXRef>::init("soundfx.scene")
59       .bases<SGSampleGroupRef>()
60       .method("load", &FGSceneFX::load)
61       .method("damping", &FGSceneFX::model_damping);
62 }
63
64 FGSceneFX::~FGSceneFX()
65 {
66 }
67
68 void FGSceneFX::unbind()
69 {
70     if (_smgr) {
71         _smgr->remove(_refname);
72     }
73 }
74
75 void FGSceneFX::init()
76 {
77     if (!_smgr) {
78         return;
79     }
80 }
81
82 void FGSceneFX::reinit()
83 {
84     init();
85 }
86
87 void FGSceneFX::update (double dt)
88 {
89     if (!_smgr) {
90         return;
91     }
92
93     if (_enabled->getBoolValue())
94     {
95         float fact = 1.0f - _damping->getFloatValue();
96         set_volume(_volume->getFloatValue() * fact);
97         resume();
98
99         SGSampleGroup::update(dt);
100     }
101     else {
102         suspend();
103     }
104 }
105
106 /* Sets the scene properties from the models point of view      */
107 void FGSceneFX::model_damping(float damping)
108 {
109     _damping->setFloatValue(damping);
110 }
111
112 /* (Over)load the sound file for a particular ref. name         */
113 bool FGSceneFX::load(const std::string& refname, const std::string& path_str)
114 {
115     if (!_smgr) {
116         return false;
117     }
118
119     SGPath path = globals->resolve_resource_path(path_str);
120     if (!path.isNull() && path.exists())
121     {
122         SGSoundSample* sample;
123         unsigned int i = 0;
124         do
125         {
126             sample = find(refname, i);
127             if (sample) {
128                 sample->set_sample_name(path_str);
129             }
130         }
131         while(sample);
132
133         return true;
134     }
135
136     throw sg_io_exception("SceneFX: couldn't find file: '" + path.str() + "'");
137
138     return false;
139 }
140
141 /* Control the sounds from the generating side.                 */
142 size_t FGSceneFX::add(const std::string& refname)
143 {
144     if (!_smgr) {
145         return false;
146     }
147
148     unsigned int num = 0;
149     std::string name;
150     do {
151         name = full_name(refname, num++);
152     } while(SGSampleGroup::exists(name));
153
154     SGSharedPtr<SGSoundSample> sample;
155     sample = new SGSoundSample();
156     SGSampleGroup::add(sample, name);
157
158     return num;
159 }
160
161 bool FGSceneFX::remove(const std::string& refname, size_t num)
162 {
163     std::string name = full_name(refname, num);
164     return SGSampleGroup::remove(name);
165 }
166
167 void FGSceneFX::position(const std::string& refname, size_t num, double lon, double lat, double elevation)
168 {
169     SGSoundSample* sample = find(refname, num);
170     if (sample)
171     {
172         SGGeod pos = SGGeod::fromDegFt(lon, lat, elevation);
173         sample->set_position(SGVec3d::fromGeod(pos));
174     }
175 }
176
177 void FGSceneFX::pitch(const std::string& refname, size_t num, float pitch)
178 {
179     SGSoundSample* sample = find(refname, num);
180     if (sample) {
181         sample->set_pitch(pitch);
182     }
183 }
184
185 void FGSceneFX::volume(const std::string& refname, size_t num, float volume)
186 {
187     SGSoundSample* sample = find(refname, num);
188     if (sample)
189     {
190         sample->set_volume(volume);
191     }
192 }
193
194 void FGSceneFX::properties(const std::string& refname, size_t num, float reference_dist, float maximum_dist)
195 {
196     SGSoundSample* sample = find(refname, num);
197     if (sample)
198     {
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);
203         }
204     }
205 }
206
207 void FGSceneFX::play(const std::string& refname, size_t num, bool looping)
208 {
209     SGSampleGroup::play(full_name(refname, num), looping);
210 }
211
212 void FGSceneFX::stop(const std::string& refname, size_t num)
213 {
214     SGSampleGroup::stop(full_name(refname, num));
215 }
216
217 const char* FGSceneFX::full_name(const std::string& refname, size_t num)
218 {
219     static char nstr[128];
220     snprintf(nstr, 127, "%s_%4zu", refname.c_str(), num);
221     return nstr;
222 }
223
224 SGSoundSample *FGSceneFX::find(const std::string& refname, size_t num)
225 {
226     return SGSampleGroup::find( full_name(refname, num) );
227 }
228
229 // end of scenefx.cxx