]> git.mxchange.org Git - flightgear.git/blob - src/Sound/soundmanager.cxx
use flite+hts for metar
[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 #if defined(ENABLE_FLITE)
27 #include "VoiceSynthesizer.hxx"
28 #endif
29 #include "soundmanager.hxx"
30 #include "Main/globals.hxx"
31 #include "Main/fg_props.hxx"
32
33 #include <vector>
34 #include <string>
35
36 #ifdef ENABLE_AUDIO_SUPPORT
37 /**
38  * Listener class that monitors the sim state.
39  */
40 class Listener : public SGPropertyChangeListener
41 {
42 public:
43     Listener(FGSoundManager *wrapper) : _wrapper(wrapper) {}
44     virtual void valueChanged (SGPropertyNode * node);
45
46 private:
47     FGSoundManager* _wrapper;
48 };
49
50 void Listener::valueChanged(SGPropertyNode * node)
51 {
52     _wrapper->activate(node->getBoolValue());
53 }
54
55 FGSoundManager::FGSoundManager()
56   : _is_initialized(false),
57     _enabled(false),
58     _listener(new Listener(this))
59 {
60 }
61
62 FGSoundManager::~FGSoundManager()
63 {
64 }
65
66 void FGSoundManager::init()
67 {
68     _sound_working = fgGetNode("/sim/sound/working");
69     _sound_enabled = fgGetNode("/sim/sound/enabled");
70     _volume        = fgGetNode("/sim/sound/volume");
71     _device_name   = fgGetNode("/sim/sound/device-name");
72
73     _currentView   = fgGetNode("sim/current-view");
74     _viewPosLon    = fgGetNode("sim/current-view/viewer-lon-deg");
75     _viewPosLat    = fgGetNode("sim/current-view/viewer-lat-deg");
76     _viewPosElev   = fgGetNode("sim/current-view/viewer-elev-ft");
77   
78     _velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true);
79     _velocityEastFPS  = fgGetNode("velocities/speed-east-fps", true);
80     _velocityDownFPS  = fgGetNode("velocities/speed-down-fps", true);
81   
82     _viewXoffset      = _currentView->getNode("x-offset-m", true);
83     _viewYoffset      = _currentView->getNode("y-offset-m", true);
84     _viewZoffset      = _currentView->getNode("z-offset-m", true);
85
86     SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
87     scenery_loaded->addChangeListener(_listener.get());
88
89     reinit();
90 }
91
92 void FGSoundManager::shutdown()
93 {
94     SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
95     scenery_loaded->removeChangeListener(_listener.get());
96     
97     stop();
98     
99     SGSoundMgr::shutdown();
100 }
101
102 void FGSoundManager::reinit()
103 {
104     _is_initialized = false;
105
106     if (_is_initialized && !_sound_working->getBoolValue())
107     {
108         // shutdown sound support
109         stop();
110         return;
111     }
112
113     if (!_sound_working->getBoolValue())
114     {
115         return;
116     }
117
118     update_device_list();
119
120     select_device(_device_name->getStringValue());
121     SGSoundMgr::reinit();
122     _is_initialized = true;
123
124     activate(fgGetBool("sim/sceneryloaded", true));
125 }
126
127 void FGSoundManager::activate(bool State)
128 {
129     if (_is_initialized)
130     {
131         if (State)
132         {
133             SGSoundMgr::activate();
134         }
135     }
136 }
137
138 void FGSoundManager::update_device_list()
139 {
140     std::vector <const char*>devices = get_available_devices();
141     for (unsigned int i=0; i<devices.size(); i++) {
142         SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true);
143         p->setStringValue(devices[i]);
144     }
145     devices.clear();
146 }
147
148 bool FGSoundManager::stationaryView() const
149 {
150   // this is an ugly hack to decide if the *viewer* is stationary,
151   // since we don't model the viewer velocity directly.
152   return (_viewXoffset->getDoubleValue() == 0.0) &&
153          (_viewYoffset->getDoubleValue() == 0.0) &&
154          (_viewZoffset->getDoubleValue() == 0.0);
155 }
156
157 // Update sound manager and propagate property values,
158 // since the sound manager doesn't read any properties itself.
159 // Actual sound update is triggered by the subsystem manager.
160 void FGSoundManager::update(double dt)
161 {
162     if (_is_initialized && _sound_working->getBoolValue())
163     {
164         bool enabled = _sound_enabled->getBoolValue();
165         if (enabled != _enabled)
166         {
167             if (enabled)
168                 resume();
169             else
170                 suspend();
171             _enabled = enabled;
172         }
173         if (enabled)
174         {
175             SGGeod viewPosGeod(SGGeod::fromDegFt(_viewPosLon->getDoubleValue(),
176                                                  _viewPosLat->getDoubleValue(),
177                                                  _viewPosElev->getDoubleValue()));
178             SGVec3d cartPos = SGVec3d::fromGeod(viewPosGeod);
179
180             set_position(cartPos, viewPosGeod);
181
182             SGQuatd viewOrientation;
183             for (int i=0; i<4; ++i) {
184               viewOrientation[i] = _currentView->getChild("raw-orientation", i, true)->getDoubleValue();
185             }
186
187             set_orientation( viewOrientation );
188
189             SGVec3d velocity(SGVec3d::zeros());
190             if (!stationaryView()) {
191               velocity = SGVec3d(_velocityNorthFPS->getDoubleValue(),
192                                  _velocityEastFPS->getDoubleValue(),
193                                  _velocityDownFPS->getDoubleValue() );
194             }
195
196             set_velocity( velocity );
197
198             set_volume(_volume->getFloatValue());
199             SGSoundMgr::update(dt);
200         }
201     }
202 }
203
204 #if defined(ENABLE_FLITE)
205 VoiceSynthesizer * FGSoundManager::getSynthesizer( const std::string & voice )
206 {
207   std::map<std::string,VoiceSynthesizer*>::iterator it = _synthesizers.find(voice);
208   if( it == _synthesizers.end() ) {
209     VoiceSynthesizer * synthesizer = new FLITEVoiceSynthesizer( voice );
210     _synthesizers[voice] = synthesizer;
211     return synthesizer;
212   }
213   return it->second;
214 }
215 #endif
216 #endif // ENABLE_AUDIO_SUPPORT