1 // soundmanager.cxx -- Wraps the SimGear OpenAl sound manager class
3 // Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
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.
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.
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.
24 #include <simgear/sound/soundmgr_openal.hxx>
26 #if defined(ENABLE_FLITE)
27 #include "VoiceSynthesizer.hxx"
29 #include "soundmanager.hxx"
30 #include "Main/globals.hxx"
31 #include "Main/fg_props.hxx"
36 #ifdef ENABLE_AUDIO_SUPPORT
38 * Listener class that monitors the sim state.
40 class Listener : public SGPropertyChangeListener
43 Listener(FGSoundManager *wrapper) : _wrapper(wrapper) {}
44 virtual void valueChanged (SGPropertyNode * node);
47 FGSoundManager* _wrapper;
50 void Listener::valueChanged(SGPropertyNode * node)
52 _wrapper->activate(node->getBoolValue());
55 FGSoundManager::FGSoundManager()
56 : _is_initialized(false),
58 _listener(new Listener(this))
62 FGSoundManager::~FGSoundManager()
66 void FGSoundManager::init()
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");
73 _currentView = fgGetNode("sim/current-view");
75 _viewX = _currentView->getNode("viewer-x-m", true);
76 _viewY = _currentView->getNode("viewer-y-m", true);
77 _viewZ = _currentView->getNode("viewer-z-m", true);
79 _velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true);
80 _velocityEastFPS = fgGetNode("velocities/speed-east-fps", true);
81 _velocityDownFPS = fgGetNode("velocities/speed-down-fps", true);
83 _viewXoffset = _currentView->getNode("x-offset-m", true);
84 _viewYoffset = _currentView->getNode("y-offset-m", true);
85 _viewZoffset = _currentView->getNode("z-offset-m", true);
87 SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
88 scenery_loaded->addChangeListener(_listener.get());
93 void FGSoundManager::shutdown()
95 SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
96 scenery_loaded->removeChangeListener(_listener.get());
100 SGSoundMgr::shutdown();
103 void FGSoundManager::reinit()
105 _is_initialized = false;
107 if (_is_initialized && !_sound_working->getBoolValue())
109 // shutdown sound support
114 if (!_sound_working->getBoolValue())
119 update_device_list();
121 select_device(_device_name->getStringValue());
122 SGSoundMgr::reinit();
123 _is_initialized = true;
125 activate(fgGetBool("sim/sceneryloaded", true));
128 void FGSoundManager::activate(bool State)
134 SGSoundMgr::activate();
139 void FGSoundManager::update_device_list()
141 std::vector <const char*>devices = get_available_devices();
142 for (unsigned int i=0; i<devices.size(); i++) {
143 SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true);
144 p->setStringValue(devices[i]);
149 bool FGSoundManager::stationaryView() const
151 // this is an ugly hack to decide if the *viewer* is stationary,
152 // since we don't model the viewer velocity directly.
153 return (_viewXoffset->getDoubleValue() == 0.0) &&
154 (_viewYoffset->getDoubleValue() == 0.0) &&
155 (_viewZoffset->getDoubleValue() == 0.0);
158 // Update sound manager and propagate property values,
159 // since the sound manager doesn't read any properties itself.
160 // Actual sound update is triggered by the subsystem manager.
161 void FGSoundManager::update(double dt)
163 if (_is_initialized && _sound_working->getBoolValue())
165 bool enabled = _sound_enabled->getBoolValue();
166 if (enabled != _enabled)
176 SGVec3d cartPos(_viewX->getDoubleValue(),
177 _viewY->getDoubleValue(),
178 _viewZ->getDoubleValue());
179 SGGeod geodPos = SGGeod::fromCart(cartPos);
181 set_position(cartPos, geodPos);
183 SGQuatd viewOrientation;
184 for (int i=0; i<4; ++i) {
185 viewOrientation[i] = _currentView->getChild("raw-orientation", i, true)->getDoubleValue();
188 set_orientation( viewOrientation );
190 SGVec3d velocity(SGVec3d::zeros());
191 if (!stationaryView()) {
192 velocity = SGVec3d(_velocityNorthFPS->getDoubleValue(),
193 _velocityEastFPS->getDoubleValue(),
194 _velocityDownFPS->getDoubleValue() );
197 set_velocity( velocity );
199 set_volume(_volume->getFloatValue());
200 SGSoundMgr::update(dt);
205 #if defined(ENABLE_FLITE)
206 VoiceSynthesizer * FGSoundManager::getSynthesizer( const std::string & voice )
208 std::map<std::string,VoiceSynthesizer*>::iterator it = _synthesizers.find(voice);
209 if( it == _synthesizers.end() ) {
210 VoiceSynthesizer * synthesizer = new FLITEVoiceSynthesizer( voice );
211 _synthesizers[voice] = synthesizer;
217 #endif // ENABLE_AUDIO_SUPPORT