]> git.mxchange.org Git - simgear.git/blobdiff - simgear/sound/sample_group.cxx
scenery: Really, most people don't care for the noise.
[simgear.git] / simgear / sound / sample_group.cxx
index 99a5a0eb3689fa40b398e97d0fe3ad98f08d8b69..069f85df9dd557776171d3855c9fd77712a54b37 100644 (file)
@@ -94,18 +94,27 @@ void SGSampleGroup::update( double dt ) {
         ALint result = AL_STOPPED;
 
         if ( sample->is_valid_source() ) {
+            int source = sample->get_source();
+
+            alGetSourcei( source, AL_SOURCE_STATE, &result );
             if ( sample->is_looping() ) {
-                sample->no_valid_source();
-                _smgr->release_source( sample->get_source() );
+                if ( result != AL_STOPPED ) {
+                    alSourceStop( source );
+                    alGetSourcei( source, AL_SOURCE_STATE, &result );
+                }
+                if ( result == AL_STOPPED ) {
+                    sample->no_valid_source();
+                    _smgr->release_source( sample->get_source() );
+                }
             }
-            else
-                alGetSourcei( sample->get_source(), AL_SOURCE_STATE, &result );
         }
 
         if ( result == AL_STOPPED ) {
             sample->stop();
             if ( !sample->is_queue() ) {
                 ALuint buffer = sample->get_buffer();
+                // disconnect buffer from its source - otherwise it cannot be deleted
+                alSourceUnqueueBuffers(sample->get_source(), 1, &buffer);
                 alDeleteBuffers( 1, &buffer );
                 testForALError("buffer remove");
             }
@@ -134,42 +143,45 @@ void SGSampleGroup::update( double dt ) {
             ALuint source = _smgr->request_source();
             if (alIsSource(source) == AL_TRUE )
             {
+                ALboolean looping = sample->is_looping() ? AL_TRUE : AL_FALSE;
                 if ( sample->is_queue() )
                 {
                     sample->set_source( source );
                     update_sample_config( sample );
 
                     alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 );
-                    alSourcei( source, AL_LOOPING, AL_FALSE);
+                    alSourcei( source, AL_LOOPING, looping );
                     alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
                     alSourcePlay( source );
                     testForALError("sample play");
                 }
                 else
                 {
-                    if (_smgr->request_buffer(sample) == SGSoundMgr::NO_BUFFER)
+                    ALuint buffer = _smgr->request_buffer(sample);
+                    if (buffer == SGSoundMgr::FAILED_BUFFER ||
+                        buffer == SGSoundMgr::NO_BUFFER)
+                    {
+                        _smgr->release_source(source);
                         continue;
+                    }
 
                     // start playing the sample
-                    ALuint buffer = sample->get_buffer();
+                    buffer = sample->get_buffer();
                     if ( alIsBuffer(buffer) == AL_TRUE )
                     {
-                        ALboolean looping;
-
                         alSourcei( source, AL_BUFFER, buffer );
                         testForALError("assign buffer to source");
 
                         sample->set_source( source );
                         update_sample_config( sample );
 
-                        looping = sample->is_looping() ? AL_TRUE : AL_FALSE;
                         alSourcei( source, AL_LOOPING, looping );
                         alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 );
                         alSourcei( source, AL_SOURCE_RELATIVE, AL_FALSE );
                         alSourcePlay( source );
                         testForALError("sample play");
                     } else
-                        SG_LOG( SG_GENERAL, SG_ALERT, "No such buffer!\n");
+                        SG_LOG( SG_SOUND, SG_ALERT, "No such buffer!\n");
                 }
             }
 
@@ -275,7 +287,6 @@ SGSampleGroup::stop ()
             ALint source = sample->get_source();
             if ( sample->is_playing() ) {
                 alSourceStop( source );
-                alSourcei( source, AL_BUFFER, 0 );
             }
             _smgr->release_source( source );
             sample->no_valid_source();
@@ -395,6 +406,19 @@ void SGSampleGroup::update_pos_and_orientation() {
         sample->set_rotation( ec2body );
         sample->set_position( position );
         sample->set_velocity( velocity );
+
+        // Test if a sample is farther away than max distance, if so
+        // stop the sound playback and free it's source.
+        if (!_tied_to_listener) {
+            float max2 = sample->get_max_dist() * sample->get_max_dist();
+            float dist2 = position[0]*position[0]
+                          + position[1]*position[1] + position[2]*position[2];
+            if ((dist2 > max2) && !sample->test_out_of_range()) {
+                sample->set_out_of_range(true);
+            } else if ((dist2 < max2) && sample->test_out_of_range()) {
+                sample->set_out_of_range(false);
+            }
+        }
     }
 }
 
@@ -452,7 +476,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample ) {
 bool SGSampleGroup::testForError(void *p, string s)
 {
    if (p == NULL) {
-      SG_LOG( SG_GENERAL, SG_ALERT, "Error (sample group): " << s);
+      SG_LOG( SG_SOUND, SG_ALERT, "Error (sample group): " << s);
       return true;
    }
    return false;
@@ -462,7 +486,7 @@ bool SGSampleGroup::testForALError(string s)
 {
     ALenum error = alGetError();
     if (error != AL_NO_ERROR)  {
-       SG_LOG( SG_GENERAL, SG_ALERT, "AL Error (" << _refname << "): "
+       SG_LOG( SG_SOUND, SG_ALERT, "AL Error (" << _refname << "): "
                                       << alGetString(error) << " at " << s);
        return true;
     }