From feba9024eb791f3fca56405bdff728cd103ace28 Mon Sep 17 00:00:00 2001 From: ehofman Date: Tue, 20 Oct 2009 11:31:00 +0000 Subject: [PATCH] Fix a pause situation where more code was executed than expected. Unbind an OpenAL buffer from an OpenAL source when requested to stop playing. --- simgear/sound/sample_group.cxx | 31 ++++++++++++++++++++++++------ simgear/sound/sample_group.hxx | 6 +++++- simgear/sound/soundmgr_openal.cxx | 32 ++++++++++++++++++------------- simgear/sound/soundmgr_openal.hxx | 4 ++-- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/simgear/sound/sample_group.cxx b/simgear/sound/sample_group.cxx index 815fb460..5d460be1 100644 --- a/simgear/sound/sample_group.cxx +++ b/simgear/sound/sample_group.cxx @@ -67,6 +67,7 @@ SGSampleGroup::SGSampleGroup () : _smgr(NULL), _refname(""), _active(false), + _pause(false), _tied_to_listener(false), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), @@ -79,6 +80,7 @@ SGSampleGroup::SGSampleGroup ( SGSoundMgr *smgr, const string &refname ) : _smgr(smgr), _refname(refname), _active(false), + _pause(false), _tied_to_listener(false), _velocity(SGVec3d::zeros()), _orientation(SGQuatd::zeros()), @@ -109,10 +111,28 @@ SGSampleGroup::~SGSampleGroup () void SGSampleGroup::update( double dt ) { - if ( !_active ) return; + if ( !_active || _pause ) return; testForALError("start of update!!\n"); + // Delete any OpenAL buffers that might still be in use. + unsigned int size = _removed_samples.size(); + for (unsigned int i=0; iget_source(), AL_SOURCE_STATE, &result ); + if ( result == AL_STOPPED ) { + ALuint buffer = sample->get_buffer(); + alDeleteBuffers( 1, &buffer ); + testForALError("buffer remove"); + _removed_samples.erase( _removed_samples.begin()+i ); + size--; + continue; + } + i++; + } + sample_map_iterator sample_current = _samples.begin(); sample_map_iterator sample_end = _samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { @@ -203,9 +223,8 @@ bool SGSampleGroup::remove( const string &refname ) { return false; } - // remove the sources buffer - _smgr->release_buffer( sample_it->second ); - _samples.erase( refname ); + _removed_samples.push_back( sample_it->second ); + _samples.erase( sample_it ); return true; } @@ -240,7 +259,7 @@ SGSoundSample *SGSampleGroup::find( const string &refname ) { void SGSampleGroup::suspend () { - _active = false; + _pause = true; sample_map_iterator sample_current = _samples.begin(); sample_map_iterator sample_end = _samples.end(); for ( ; sample_current != sample_end; ++sample_current ) { @@ -267,7 +286,7 @@ SGSampleGroup::resume () } } testForALError("resume"); - _active = true; + _pause = false; } diff --git a/simgear/sound/sample_group.hxx b/simgear/sound/sample_group.hxx index 88f86bcd..7a3dff70 100644 --- a/simgear/sound/sample_group.hxx +++ b/simgear/sound/sample_group.hxx @@ -42,6 +42,7 @@ #endif #include +#include #include #include @@ -55,7 +56,8 @@ using std::map; using std::string; -typedef map < string, SGSharedPtr > sample_map; +typedef SGSharedPtr SGSoundSample_ptr; +typedef map < string, SGSoundSample_ptr > sample_map; typedef sample_map::iterator sample_map_iterator; typedef sample_map::const_iterator const_sample_map_iterator; @@ -214,6 +216,7 @@ protected: bool _active; private: + bool _pause; float _volume; bool _tied_to_listener; @@ -222,6 +225,7 @@ private: SGGeod _position; sample_map _samples; + std::vector _removed_samples; bool testForALError(string s); bool testForError(void *p, string s); diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index eb0a76e4..ee5320da 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -154,12 +154,17 @@ void SGSoundMgr::init() { if (_free_sources.size() == 0) { SG_LOG(SG_GENERAL, SG_ALERT, "Unable to grab any OpenAL sources!"); } +} - 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 ) { - SGSampleGroup *sgrp = sample_grp_current->second; - sgrp->activate(); +void SGSoundMgr::activate() { + if ( _working ) { + _active = true; + 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 ) { + SGSampleGroup *sgrp = sample_grp_current->second; + sgrp->activate(); + } } } @@ -187,7 +192,7 @@ void SGSoundMgr::stop() { } void SGSoundMgr::suspend() { - if (_active) { + if (_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 ) { @@ -199,7 +204,7 @@ void SGSoundMgr::suspend() { } void SGSoundMgr::resume() { - if (!_active) { + if (_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 ) { @@ -225,7 +230,7 @@ void SGSoundMgr::unbind () // delete free sources for (unsigned int i=0; i<_free_sources.size(); i++) { - ALuint source = _free_sources.at( i ); + ALuint source = _free_sources[i]; alDeleteSources( 1 , &source ); } @@ -264,7 +269,7 @@ bool SGSoundMgr::add( SGSampleGroup *sgrp, const string& refname ) return false; } - if (_working) sgrp->activate(); + if (_active) sgrp->activate(); _sample_groups[refname] = sgrp; return true; @@ -280,7 +285,7 @@ bool SGSoundMgr::remove( const string &refname ) return false; } - _sample_groups.erase( refname ); + _sample_groups.erase( sample_grp_it ); return true; } @@ -386,8 +391,9 @@ void SGSoundMgr::release_source( unsigned int source ) alSourceStop( source ); testForALError("release source"); - _free_sources.push_back(source); - _sources_in_use.erase(it, it+1); + alSourcei( source, AL_BUFFER, 0 ); + _free_sources.push_back( source ); + _sources_in_use.erase( it ); } } @@ -465,8 +471,8 @@ void SGSoundMgr::release_buffer(SGSoundSample *sample) buffer_it->second.refctr--; if (buffer_it->second.refctr == 0) { ALuint buffer = buffer_it->second.id; - _buffers.erase( sample_name ); alDeleteBuffers(1, &buffer); + _buffers.erase( buffer_it ); testForALError("release buffer"); } } diff --git a/simgear/sound/soundmgr_openal.hxx b/simgear/sound/soundmgr_openal.hxx index ac94788f..5d86c6be 100644 --- a/simgear/sound/soundmgr_openal.hxx +++ b/simgear/sound/soundmgr_openal.hxx @@ -116,13 +116,13 @@ public: /** * Set the sound manager to a working condition. */ - inline void activate() { _active = true; } + void activate(); /** * Test is the sound manager is in an active and working condition. * @return true is the sound manager is active */ - inline bool is_active() const { return (_working && _active); } + inline bool is_active() const { return _active; } /** * Register a sample group to the sound manager. -- 2.39.5