#include <simgear/compiler.h>
-#if defined (__APPLE__)
-# ifdef __GNUC__
-# if ( __GNUC__ >= 3 ) && ( __GNUC_MINOR__ >= 3 )
-// # include <math.h>
-inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
-# else
- // any C++ header file undefines isinf and isnan
- // so this should be included before <iostream>
- // the functions are STILL in libm (libSystem on mac os x)
-extern "C" int isnan (double);
-extern "C" int isinf (double);
-# endif
-# else
-// inline int (isinf)(double r) { return isinf(r); }
-// inline int (isnan)(double r) { return isnan(r); }
-# endif
-#endif
-
-#if defined (__FreeBSD__)
-# if __FreeBSD_version < 500000
- extern "C" {
- inline int isnan(double r) { return !(r <= 0 || r >= 0); }
- }
-# endif
-#endif
-
-#if defined (__CYGWIN__)
-# include <ieeefp.h>
-#endif
-
-#if defined(__MINGW32__)
-# define isnan(x) _isnan(x)
-#endif
-
#include "soundmgr_openal.hxx"
#include "sample_group.hxx"
_smgr(NULL),
_refname(""),
_active(false),
+ _pause(false),
_tied_to_listener(false),
_velocity(SGVec3d::zeros()),
_orientation(SGQuatd::zeros()),
_smgr(smgr),
_refname(refname),
_active(false),
+ _pause(false),
_tied_to_listener(false),
_velocity(SGVec3d::zeros()),
_orientation(SGQuatd::zeros()),
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; 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();
for ( ; sample_current != sample_end; ++sample_current ) {
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.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 );
+ remove( sample->get_sample_name() );
}
}
testForALError("update");
}
// add a sound effect, return true if successful
-bool SGSampleGroup::add( SGSoundSample *sound, const string& refname ) {
+bool SGSampleGroup::add( SGSharedPtr<SGSoundSample> sound, const string& refname ) {
sample_map_iterator sample_it = _samples.find( refname );
if ( sample_it != _samples.end() ) {
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 ) {
}
}
testForALError("resume");
- _active = true;
+ _pause = false;
}
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() );
+ alSourcefv( source, AL_DIRECTION, _smgr->get_direction().data() );
} else {
alSourcefv( source, AL_POSITION, sample->get_position() );
- alSourcefv( source, AL_DIRECTION, sample->get_orientation() );
alSourcefv( source, AL_VELOCITY, sample->get_velocity() );
+ alSourcefv( source, AL_DIRECTION, sample->get_orientation() );
}
testForALError("position and orientation");