diff --git a/simgear/sound/openal_test4.cxx b/simgear/sound/openal_test4.cxx index 320b6e6f..1b595eff 100644 --- a/simgear/sound/openal_test4.cxx +++ b/simgear/sound/openal_test4.cxx @@ -21,7 +21,8 @@ int main( int argc, char *argv[] ) { smgr = new SGSoundMgr; smgr->bind(); - smgr->init("OSS Default"); + smgr->select_device("OSS Default"); + smgr->init(); sgr = smgr->find("default", true); smgr->set_volume(0.9); smgr->activate(); diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index 385e918f..53f1fe3d 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -43,7 +43,9 @@ using std::string; using std::vector; +#if 0 extern bool isNaN(float *v); +#endif #define MAX_SOURCES 128 @@ -58,7 +60,6 @@ extern bool isNaN(float *v); // constructor SGSoundMgr::SGSoundMgr() : - _working(false), _active(false), _changed(true), _volume(0.0), @@ -80,23 +81,44 @@ SGSoundMgr::SGSoundMgr() : SGSoundMgr::~SGSoundMgr() { - stop(); + if (is_working()) + stop(); + _sample_groups.clear(); } // initialize the sound manager -void SGSoundMgr::init(const char *devname) { +void SGSoundMgr::init() { + + if (is_working()) + { + SG_LOG( SG_SOUND, SG_ALERT, "Oops, OpenAL sound manager is already initialized." ); + return; + } SG_LOG( SG_SOUND, SG_INFO, "Initializing OpenAL sound manager" ); - ALCdevice *device = alcOpenDevice(devname); - if ( testForError(device, "Audio device not available, trying default") ) { + _free_sources.clear(); + _free_sources.reserve( MAX_SOURCES ); + _sources_in_use.clear(); + _sources_in_use.reserve( MAX_SOURCES ); + + ALCdevice *device = NULL; + const char* devname = _device_name.c_str(); + if (_device_name == "") + devname = NULL; // use default device + else + { + // try non-default device + device = alcOpenDevice(devname); + } + + if ((!devname)||(testForError(device, "Audio device not available, trying default.")) ) { device = alcOpenDevice(NULL); - if (testForError(device, "Default Audio device not available.") ) { + if (testForError(device, "Default audio device not available.") ) { return; } } - _device = device; ALCcontext *context = alcCreateContext(device, NULL); testForALCError("context creation."); if ( testForError(context, "Unable to create a valid context.") ) { @@ -112,9 +134,11 @@ void SGSoundMgr::init(const char *devname) { } if (_context != NULL) + { SG_LOG(SG_SOUND, SG_ALERT, "context is already assigned"); + } _context = context; - _working = true; + _device = device; _at_up_vec[0] = 0.0; _at_up_vec[1] = 0.0; _at_up_vec[2] = -1.0; _at_up_vec[3] = 0.0; _at_up_vec[4] = 1.0; _at_up_vec[5] = 0.0; @@ -163,8 +187,24 @@ void SGSoundMgr::init(const char *devname) { } } +void SGSoundMgr::reinit() +{ + bool was_active = _active; + + if (was_active) + { + suspend(); + } + + SGSoundMgr::stop(); + SGSoundMgr::init(); + + if (was_active) + resume(); +} + void SGSoundMgr::activate() { - if ( _working ) { + if ( is_working() ) { _active = true; sample_group_map_iterator sample_grp_current = _sample_groups.begin(); sample_group_map_iterator sample_grp_end = _sample_groups.end(); @@ -204,15 +244,14 @@ void SGSoundMgr::stop() { testForALError("SGSoundMgr::stop: delete buffers"); } _buffers.clear(); + _sources_in_use.clear(); - if (_working) { - _working = false; + if (is_working()) { _active = false; - _context = alcGetCurrentContext(); - _device = alcGetContextsDevice(_context); alcDestroyContext(_context); alcCloseDevice(_device); _context = NULL; + _device = NULL; _renderer = "unknown"; _vendor = "unknown"; @@ -220,7 +259,7 @@ void SGSoundMgr::stop() { } void SGSoundMgr::suspend() { - if (_working) { + if (is_working()) { sample_group_map_iterator sample_grp_current = _sample_groups.begin(); sample_group_map_iterator sample_grp_end = _sample_groups.end(); for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { @@ -232,7 +271,7 @@ void SGSoundMgr::suspend() { } void SGSoundMgr::resume() { - if (_working) { + if (is_working()) { sample_group_map_iterator sample_grp_current = _sample_groups.begin(); sample_group_map_iterator sample_grp_end = _sample_groups.end(); for ( ; sample_grp_current != sample_grp_end; ++sample_grp_current ) { @@ -243,30 +282,6 @@ void SGSoundMgr::resume() { } } -void SGSoundMgr::bind () -{ - _free_sources.clear(); - _free_sources.reserve( MAX_SOURCES ); - _sources_in_use.clear(); - _sources_in_use.reserve( MAX_SOURCES ); -} - - -void SGSoundMgr::unbind () -{ - _sample_groups.clear(); - - // delete free sources - for (unsigned int i=0; i<_free_sources.size(); i++) { - ALuint source = _free_sources[i]; - alDeleteSources( 1 , &source ); - testForALError("SGSoundMgr::unbind: delete sources"); - } - - _free_sources.clear(); - _sources_in_use.clear(); -} - // run the audio scheduler void SGSoundMgr::update( double dt ) { if (_active) { @@ -543,7 +558,8 @@ void SGSoundMgr::update_pos_and_orientation() { bool SGSoundMgr::load(const string &samplepath, void **dbuf, int *fmt, size_t *sz, int *frq ) { - if ( !_working ) return false; + if ( !is_working() ) + return false; ALenum format; ALsizei size; diff --git a/simgear/sound/soundmgr_openal.hxx b/simgear/sound/soundmgr_openal.hxx index 34ca6427..84d93baa 100644 --- a/simgear/sound/soundmgr_openal.hxx +++ b/simgear/sound/soundmgr_openal.hxx @@ -83,22 +83,26 @@ public: SGSoundMgr(); ~SGSoundMgr(); - void init(const char *devname = NULL); - void bind(); - void unbind(); + void init(); void update(double dt); void suspend(); void resume(); void stop(); - inline void reinit() { stop(); init(); } + void reinit(); + + /** + * Select a specific sound device. + * Requires a init/reinit call before sound is actually switched. + */ + inline void select_device(const char* devname) {_device_name = devname;} /** * Test is the sound manager is in a working condition. * @return true is the sound manager is working */ - inline bool is_working() const { return _working; } + inline bool is_working() const { return (_device != NULL); } /** * Set the sound manager to a working condition. @@ -282,7 +286,6 @@ public: private: - bool _working; bool _active; bool _changed; float _volume; @@ -313,6 +316,7 @@ private: bool _bad_doppler; std::string _renderer; std::string _vendor; + std::string _device_name; bool testForALError(std::string s); bool testForALCError(std::string s);