+// sample_group.cxx -- Manage a group of samples relative to a base position
+//
+// Written for the new SoundSystem by Erik Hofman, October 2009
+//
+// Copyright (C) 2009 Erik Hofman <erik@ehofman.com>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+// $Id$
+
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
_smgr(NULL),
_refname(""),
_active(false),
+ _pause(false),
_tied_to_listener(false),
_velocity(SGVec3d::zeros()),
- _position(SGGeod()),
- _orientation(SGQuatd::zeros())
+ _orientation(SGQuatd::zeros()),
+ _position(SGGeod())
{
_samples.clear();
}
_smgr(smgr),
_refname(refname),
_active(false),
+ _pause(false),
_tied_to_listener(false),
_velocity(SGVec3d::zeros()),
- _position(SGGeod()),
- _orientation(SGQuatd::zeros())
+ _orientation(SGQuatd::zeros()),
+ _position(SGGeod())
{
_smgr->add(this, refname);
_samples.clear();
void SGSampleGroup::update( double dt ) {
- if ( !_active ) return;
+ if ( !_active || _pause ) return;
+
+ testForALError("start of update!!\n");
- // 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; i<size; ) {
+ SGSoundSample *sample = _removed_samples[i];
+ ALint result;
+
+ alGetSourcei( sample->get_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();
continue;
// start playing the sample
- ALboolean looping = sample->get_looping() ? AL_TRUE : AL_FALSE;
ALuint buffer = sample->get_buffer();
ALuint source = _smgr->request_source();
if (alIsSource(source) == AL_TRUE && alIsBuffer(buffer) == AL_TRUE)
sample->set_source( source );
update_sample_config( sample );
- alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
+ ALboolean looping = sample->get_looping() ? AL_TRUE : AL_FALSE;
alSourcei( source, AL_LOOPING, looping );
- alSourcef( source, AL_ROLLOFF_FACTOR, 1.2 );
+ alSourcef( source, AL_ROLLOFF_FACTOR, 1.0 );
+ alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
alSourcePlay( source );
testForALError("sample play");
} else {
if ( !sample->is_playing() ) {
// a request to stop playing the sound has been filed.
- sample->no_valid_source();
sample->stop();
+ sample->no_valid_source();
_smgr->release_source( sample->get_source() );
} else {
update_sample_config( sample );
alGetSourcei( source, AL_SOURCE_STATE, &result );
if ( result == AL_STOPPED ) {
// sample is stoped because it wasn't looping
- sample->no_valid_source();
sample->stop();
+ sample->no_valid_source();
_smgr->release_source( source );
+ _smgr->release_buffer( sample );
}
}
testForALError("update");
return false;
}
- // remove the sources buffer
- _smgr->release_buffer( sample_it->second );
- _samples.erase( refname );
+ if ( sample_it->second->is_valid_buffer() )
+ _removed_samples.push_back( sample_it->second );
+ _samples.erase( sample_it );
return true;
}
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 ) {
SGSoundSample *sample = sample_current->second;
if ( sample->is_valid_source() && sample->is_playing() ) {
- unsigned int source = sample->get_source();
- alSourcePause( source );
+ alSourcePause( sample->get_source() );
}
}
testForALError("suspend");
SGSoundSample *sample = sample_current->second;
if ( sample->is_valid_source() && sample->is_playing() ) {
- unsigned int source = sample->get_source();
- alSourcePlay( source );
+ alSourcePlay( sample->get_source() );
}
}
testForALError("resume");
- _active = true;
+ _pause = false;
}
}
// set source velocity of all managed sounds
-void SGSampleGroup::set_velocity( SGVec3d &vel ) {
+void SGSampleGroup::set_velocity( const SGVec3d &vel ) {
if ( isnan(vel[0]) || isnan(vel[1]) || isnan(vel[2]) )
{
SG_LOG( SG_GENERAL, SG_ALERT, "NAN's found in SampleGroup velocity");
}
}
-// ste the source orientation of all managed sounds
-void SGSampleGroup::set_position( SGGeod pos ) {
+// set the source position of all managed sounds
+void SGSampleGroup::set_position( const SGGeod& pos ) {
sample_map_iterator sample_current = _samples.begin();
sample_map_iterator sample_end = _samples.end();
}
-// ste the source orientation of all managed sounds
-void SGSampleGroup::set_orientation( SGQuatd ori ) {
+// set the source orientation of all managed sounds
+void SGSampleGroup::set_orientation( const SGQuatd& ori ) {
if (_orientation != ori) {
sample_map_iterator sample_current = _samples.begin();
if ( sample->is_valid_source() ) {
unsigned int source = sample->get_source();
+#if 0
if ( _tied_to_listener && _smgr->has_changed() ) {
alSourcefv( source, AL_POSITION, _smgr->get_position().data() );
alSourcefv( source, AL_DIRECTION, _smgr->get_direction().data() );
alSourcefv( source, AL_VELOCITY, _smgr->get_velocity().data() );
} else {
- alSourcefv( source, AL_POSITION, sample->get_position());
+ alSourcefv( source, AL_POSITION, sample->get_position() );
alSourcefv( source, AL_DIRECTION, sample->get_orientation() );
alSourcefv( source, AL_VELOCITY, sample->get_velocity() );
}
+#else
+ alSourcefv( source, AL_POSITION, SGVec3f::zeros().data() );
+ alSourcefv( source, AL_DIRECTION, SGVec3f::zeros().data() );
+ alSourcefv( source, AL_VELOCITY, SGVec3f::zeros().data() );
+#endif
testForALError("position and orientation");
alSourcef( source, AL_PITCH, sample->get_pitch() );
testForALError("pitch and gain");
if ( sample->has_static_data_changed() ) {
+#if 0
alSourcef( source, AL_CONE_INNER_ANGLE, sample->get_innerangle() );
alSourcef( source, AL_CONE_OUTER_ANGLE, sample->get_outerangle() );
alSourcef( source, AL_CONE_OUTER_GAIN, sample->get_outergain() );
+#endif
testForALError("audio cone");
alSourcef( source, AL_MAX_DISTANCE, sample->get_max_dist() );