]> git.mxchange.org Git - flightgear.git/blob - src/Sound/soundmanager.cxx
httpd: update mongoose and websockets
[flightgear.git] / src / Sound / soundmanager.cxx
1 // soundmanager.cxx -- Wraps the SimGear OpenAl sound manager class
2 //
3 // Copyright (C) 2001  Curtis L. Olson - http://www.flightgear.org/~curt
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 //
19
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif
23
24 #include <simgear/sound/soundmgr_openal.hxx>
25
26 #include "soundmanager.hxx"
27 #include "Main/globals.hxx"
28 #include "Main/fg_props.hxx"
29
30 #include <vector>
31 #include <string>
32
33 #ifdef ENABLE_AUDIO_SUPPORT
34 /**
35  * Listener class that monitors the sim state.
36  */
37 class Listener : public SGPropertyChangeListener
38 {
39 public:
40     Listener(FGSoundManager *wrapper) : _wrapper(wrapper) {}
41     virtual void valueChanged (SGPropertyNode * node);
42
43 private:
44     FGSoundManager* _wrapper;
45 };
46
47 void Listener::valueChanged(SGPropertyNode * node)
48 {
49     _wrapper->activate(node->getBoolValue());
50 }
51
52 FGSoundManager::FGSoundManager()
53   : _is_initialized(false),
54     _enabled(false),
55     _listener(new Listener(this))
56 {
57 }
58
59 FGSoundManager::~FGSoundManager()
60 {
61 }
62
63 void FGSoundManager::init()
64 {
65     _sound_working = fgGetNode("/sim/sound/working");
66     _sound_enabled = fgGetNode("/sim/sound/enabled");
67     _volume        = fgGetNode("/sim/sound/volume");
68     _device_name   = fgGetNode("/sim/sound/device-name");
69
70     _currentView   = fgGetNode("sim/current-view");
71     _viewPosLon    = fgGetNode("sim/current-view/viewer-lon-deg");
72     _viewPosLat    = fgGetNode("sim/current-view/viewer-lat-deg");
73     _viewPosElev   = fgGetNode("sim/current-view/viewer-elev-ft");
74   
75     _velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true);
76     _velocityEastFPS  = fgGetNode("velocities/speed-east-fps", true);
77     _velocityDownFPS  = fgGetNode("velocities/speed-down-fps", true);
78   
79     _viewXoffset      = _currentView->getNode("x-offset-m", true);
80     _viewYoffset      = _currentView->getNode("y-offset-m", true);
81     _viewZoffset      = _currentView->getNode("z-offset-m", true);
82
83     SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
84     scenery_loaded->addChangeListener(_listener.get());
85
86     reinit();
87 }
88
89 void FGSoundManager::shutdown()
90 {
91     SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
92     scenery_loaded->removeChangeListener(_listener.get());
93     
94     stop();
95     
96     SGSoundMgr::shutdown();
97 }
98
99 void FGSoundManager::reinit()
100 {
101     _is_initialized = false;
102
103     if (_is_initialized && !_sound_working->getBoolValue())
104     {
105         // shutdown sound support
106         stop();
107         return;
108     }
109
110     if (!_sound_working->getBoolValue())
111     {
112         return;
113     }
114
115     update_device_list();
116
117     select_device(_device_name->getStringValue());
118     SGSoundMgr::reinit();
119     _is_initialized = true;
120
121     activate(fgGetBool("sim/sceneryloaded", true));
122 }
123
124 void FGSoundManager::activate(bool State)
125 {
126     if (_is_initialized)
127     {
128         if (State)
129         {
130             SGSoundMgr::activate();
131         }
132     }
133 }
134
135 void FGSoundManager::update_device_list()
136 {
137     std::vector <const char*>devices = get_available_devices();
138     for (unsigned int i=0; i<devices.size(); i++) {
139         SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true);
140         p->setStringValue(devices[i]);
141     }
142     devices.clear();
143 }
144
145 bool FGSoundManager::stationaryView() const
146 {
147   // this is an ugly hack to decide if the *viewer* is stationary,
148   // since we don't model the viewer velocity directly.
149   return (_viewXoffset->getDoubleValue() == 0.0) &&
150          (_viewYoffset->getDoubleValue() == 0.0) &&
151          (_viewZoffset->getDoubleValue() == 0.0);
152 }
153
154 // Update sound manager and propagate property values,
155 // since the sound manager doesn't read any properties itself.
156 // Actual sound update is triggered by the subsystem manager.
157 void FGSoundManager::update(double dt)
158 {
159     if (_is_initialized && _sound_working->getBoolValue())
160     {
161         bool enabled = _sound_enabled->getBoolValue();
162         if (enabled != _enabled)
163         {
164             if (enabled)
165                 resume();
166             else
167                 suspend();
168             _enabled = enabled;
169         }
170         if (enabled)
171         {
172             SGGeod viewPosGeod(SGGeod::fromDegFt(_viewPosLon->getDoubleValue(),
173                                                  _viewPosLat->getDoubleValue(),
174                                                  _viewPosElev->getDoubleValue()));
175             SGVec3d cartPos = SGVec3d::fromGeod(viewPosGeod);
176
177             set_position(cartPos, viewPosGeod);
178
179             SGQuatd viewOrientation;
180             for (int i=0; i<4; ++i) {
181               viewOrientation[i] = _currentView->getChild("raw-orientation", i, true)->getDoubleValue();
182             }
183
184             set_orientation( viewOrientation );
185
186             SGVec3d velocity(SGVec3d::zeros());
187             if (!stationaryView()) {
188               velocity = SGVec3d(_velocityNorthFPS->getDoubleValue(),
189                                  _velocityEastFPS->getDoubleValue(),
190                                  _velocityDownFPS->getDoubleValue() );
191             }
192
193             set_velocity( velocity );
194
195             set_volume(_volume->getFloatValue());
196             SGSoundMgr::update(dt);
197         }
198     }
199 }
200
201 #endif // ENABLE_AUDIO_SUPPORT