// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <simgear/sound/soundmgr_openal.hxx>
+#if defined(ENABLE_FLITE)
+#include "VoiceSynthesizer.hxx"
+#endif
#include "soundmanager.hxx"
#include "Main/globals.hxx"
#include "Main/fg_props.hxx"
virtual void valueChanged (SGPropertyNode * node);
private:
- FGSoundManager * _wrapper;
+ FGSoundManager* _wrapper;
};
void Listener::valueChanged(SGPropertyNode * node)
FGSoundManager::FGSoundManager()
: _is_initialized(false),
+ _enabled(false),
_listener(new Listener(this))
{
- SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
- scenery_loaded->addChangeListener(_listener);
}
FGSoundManager::~FGSoundManager()
{
}
-
-void FGSoundManager::setNewSoundDevice(const char *device)
+void FGSoundManager::init()
{
- SGSoundMgr *smgr = globals->get_soundmgr();
- smgr->suspend();
- smgr->stop();
- smgr->init(device);
- smgr->resume();
+ _sound_working = fgGetNode("/sim/sound/working");
+ _sound_enabled = fgGetNode("/sim/sound/enabled");
+ _volume = fgGetNode("/sim/sound/volume");
+ _device_name = fgGetNode("/sim/sound/device-name");
+
+ _currentView = fgGetNode("sim/current-view");
+
+ _viewX = _currentView->getNode("viewer-x-m", true);
+ _viewY = _currentView->getNode("viewer-y-m", true);
+ _viewZ = _currentView->getNode("viewer-z-m", true);
+
+ _velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true);
+ _velocityEastFPS = fgGetNode("velocities/speed-east-fps", true);
+ _velocityDownFPS = fgGetNode("velocities/speed-down-fps", true);
+
+ _viewXoffset = _currentView->getNode("x-offset-m", true);
+ _viewYoffset = _currentView->getNode("y-offset-m", true);
+ _viewZoffset = _currentView->getNode("z-offset-m", true);
+
+ SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
+ scenery_loaded->addChangeListener(_listener.get());
+
+ reinit();
}
-void FGSoundManager::init()
+void FGSoundManager::shutdown()
{
- globals->get_props()->tie("/sim/sound/devices/name",
- SGRawValueFunctions<const char *>(0, FGSoundManager::setNewSoundDevice), false);
+ SGPropertyNode_ptr scenery_loaded = fgGetNode("sim/sceneryloaded", true);
+ scenery_loaded->removeChangeListener(_listener.get());
+
+ stop();
+
+ SGSoundMgr::shutdown();
}
-void FGSoundManager::bind()
+void FGSoundManager::reinit()
{
- _sound_working = fgGetNode("/sim/sound/working");
- _sound_enabled = fgGetNode("/sim/sound/enabled");
- _volume = fgGetNode("/sim/sound/volume");
+ _is_initialized = false;
- // we intentionally do _not_ call SGSoundMgr::bind here, we'll do this later
+ if (_is_initialized && !_sound_working->getBoolValue())
+ {
+ // shutdown sound support
+ stop();
+ return;
+ }
+
+ if (!_sound_working->getBoolValue())
+ {
+ return;
+ }
+
+ update_device_list();
+
+ select_device(_device_name->getStringValue());
+ SGSoundMgr::reinit();
+ _is_initialized = true;
+
+ activate(fgGetBool("sim/sceneryloaded", true));
}
void FGSoundManager::activate(bool State)
{
- if (_is_initialized &&
- fgGetBool("/sim/sound/working"))
+ if (_is_initialized)
{
if (State)
+ {
SGSoundMgr::activate();
+ }
}
}
-void FGSoundManager::runtime_init()
+void FGSoundManager::update_device_list()
{
- SGSoundMgr::bind();
- SGSoundMgr::init(fgGetString("/sim/sound/device-name", NULL));
-
std::vector <const char*>devices = get_available_devices();
for (unsigned int i=0; i<devices.size(); i++) {
SGPropertyNode *p = fgGetNode("/sim/sound/devices/device", i, true);
devices.clear();
}
+bool FGSoundManager::stationaryView() const
+{
+ // this is an ugly hack to decide if the *viewer* is stationary,
+ // since we don't model the viewer velocity directly.
+ return (_viewXoffset->getDoubleValue() == 0.0) &&
+ (_viewYoffset->getDoubleValue() == 0.0) &&
+ (_viewZoffset->getDoubleValue() == 0.0);
+}
+
// Update sound manager and propagate property values,
// since the sound manager doesn't read any properties itself.
// Actual sound update is triggered by the subsystem manager.
void FGSoundManager::update(double dt)
{
- if (!_is_initialized) {
- if (_sound_working->getBoolValue()) {
- runtime_init();
- _is_initialized = true;
- }
- } else {
- if (!_sound_working->getBoolValue()) { // request to reinit
- SGSoundMgr::reinit();
- _sound_working->setBoolValue(true);
+ if (_is_initialized && _sound_working->getBoolValue())
+ {
+ bool enabled = _sound_enabled->getBoolValue();
+ if (enabled != _enabled)
+ {
+ if (enabled)
+ resume();
+ else
+ suspend();
+ _enabled = enabled;
}
+ if (enabled)
+ {
+ SGVec3d cartPos(_viewX->getDoubleValue(),
+ _viewY->getDoubleValue(),
+ _viewZ->getDoubleValue());
+ SGGeod geodPos = SGGeod::fromCart(cartPos);
+
+ set_position(cartPos, geodPos);
+
+ SGQuatd viewOrientation;
+ for (int i=0; i<4; ++i) {
+ viewOrientation[i] = _currentView->getChild("raw-orientation", i, true)->getDoubleValue();
+ }
+
+ set_orientation( viewOrientation );
+
+ SGVec3d velocity(SGVec3d::zeros());
+ if (!stationaryView()) {
+ velocity = SGVec3d(_velocityNorthFPS->getDoubleValue(),
+ _velocityEastFPS->getDoubleValue(),
+ _velocityDownFPS->getDoubleValue() );
+ }
+
+ set_velocity( velocity );
- if (_sound_enabled->getBoolValue()) {
set_volume(_volume->getFloatValue());
SGSoundMgr::update(dt);
}
}
}
+#if defined(ENABLE_FLITE)
+VoiceSynthesizer * FGSoundManager::getSynthesizer( const std::string & voice )
+{
+ std::map<std::string,VoiceSynthesizer*>::iterator it = _synthesizers.find(voice);
+ if( it == _synthesizers.end() ) {
+ VoiceSynthesizer * synthesizer = new FLITEVoiceSynthesizer( voice );
+ _synthesizers[voice] = synthesizer;
+ return synthesizer;
+ }
+ return it->second;
+}
+#endif
#endif // ENABLE_AUDIO_SUPPORT