]> git.mxchange.org Git - simgear.git/blobdiff - simgear/sound/sample_group.cxx
Fixes for headless mode.
[simgear.git] / simgear / sound / sample_group.cxx
index f76d98b97ba76eb461fbc830bbf8ca18be37ca71..1610d088fbfabb3871d290ad5670866ee36e81fa 100644 (file)
@@ -39,6 +39,7 @@ SGSampleGroup::SGSampleGroup () :
     _active(false),
     _changed(false),
     _pause(false),
+    _volume(1.0),
     _tied_to_listener(false),
     _velocity(SGVec3d::zeros()),
     _orientation(SGQuatd::zeros())
@@ -52,6 +53,7 @@ SGSampleGroup::SGSampleGroup ( SGSoundMgr *smgr, const string &refname ) :
     _active(false), 
     _changed(false),
     _pause(false),
+    _volume(1.0),
     _tied_to_listener(false),
     _velocity(SGVec3d::zeros()),
     _orientation(SGQuatd::zeros())
@@ -101,9 +103,12 @@ void SGSampleGroup::update( double dt ) {
         }
 
         if ( result == AL_STOPPED ) {
-            ALuint buffer = sample->get_buffer();
-            alDeleteBuffers( 1, &buffer );
-            testForALError("buffer remove");
+            sample->stop();
+            if ( !sample->is_queue() ) {
+                ALuint buffer = sample->get_buffer();
+                alDeleteBuffers( 1, &buffer );
+                testForALError("buffer remove");
+            }
             _removed_samples.erase( _removed_samples.begin()+i );
             size--;
             continue;
@@ -126,44 +131,44 @@ void SGSampleGroup::update( double dt ) {
             //
             // a request to start playing a sound has been filed.
             //
-            if ( _smgr->request_buffer(sample) == SGSoundMgr::NO_BUFFER )
-                continue;
-
-            // start playing the sample
-            ALuint buffer = sample->get_buffer();
             ALuint source = _smgr->request_source();
-            if (alIsSource(source) == AL_TRUE && alIsBuffer(buffer) == AL_TRUE)
+            if (alIsSource(source) == AL_TRUE )
             {
-                sample->set_source( source );
-                
-                alSourcei( source, AL_BUFFER, buffer );
-                testForALError("assign buffer to source");
-
-                sample->set_source( source );
-                update_sample_config( sample );
-
                 ALboolean looping = sample->is_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 (alIsBuffer(buffer) == AL_FALSE) 
-                   SG_LOG( SG_GENERAL, SG_ALERT, "No such buffer!\n");
-                // sample->no_valid_source();
-                // sadly, no free source available at this time
-            }
-
-        } else if ( sample->is_valid_source() && sample->has_changed() ) {
-            if ( !sample->is_playing() ) {
-                // a request to stop playing the sound has been filed.
-
-                sample->stop();
-                sample->no_valid_source();
-                _smgr->release_source( sample->get_source() );
-            } else if ( _smgr->has_changed() ) {
-                update_sample_config( sample );
+                if ( sample->is_queue() )
+                {
+                    sample->set_source( source );
+                    update_sample_config( sample );
+
+                    alSourcef( source, AL_ROLLOFF_FACTOR, 0.3 );
+                    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)
+                        continue;
+
+                    // start playing the sample
+                    ALuint buffer = sample->get_buffer();
+                    if ( alIsBuffer(buffer) == AL_TRUE )
+                    {
+                        alSourcei( source, AL_BUFFER, buffer );
+                        testForALError("assign buffer to source");
+
+                        sample->set_source( source );
+                        update_sample_config( sample );
+
+                        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");
+                }
             }
 
         } else if ( sample->is_valid_source() ) {
@@ -181,6 +186,18 @@ void SGSampleGroup::update( double dt ) {
                 _smgr->release_buffer( sample );
                 remove( sample->get_sample_name() );
             }
+            else
+            if ( sample->has_changed() ) {
+                if ( !sample->is_playing() ) {
+                    // a request to stop playing the sound has been filed.
+                    sample->stop();
+                    sample->no_valid_source();
+                    _smgr->release_source( sample->get_source() );
+                } else if ( _smgr->has_changed() ) {
+                    update_sample_config( sample );
+                }
+            }
+
         }
         testForALError("update");
     }
@@ -211,6 +228,7 @@ bool SGSampleGroup::remove( const string &refname ) {
 
     if ( sample_it->second->is_valid_buffer() )
         _removed_samples.push_back( sample_it->second );
+
     _samples.erase( sample_it );
 
     return true;
@@ -242,9 +260,8 @@ SGSoundSample *SGSampleGroup::find( const string &refname ) {
 }
 
 
-// stop playing all associated samples
 void
-SGSampleGroup::suspend ()
+SGSampleGroup::stop ()
 {
     _pause = true;
     sample_map_iterator sample_current = _samples.begin();
@@ -252,28 +269,59 @@ SGSampleGroup::suspend ()
     for ( ; sample_current != sample_end; ++sample_current ) {
         SGSoundSample *sample = sample_current->second;
 
-        if ( sample->is_valid_source() && sample->is_playing() ) {
-            alSourcePause( sample->get_source() );
+        if ( sample->is_valid_source() ) {
+            ALint source = sample->get_source();
+            if ( sample->is_playing() ) {
+                alSourceStop( source );
+            }
+            _smgr->release_source( source );
+            sample->no_valid_source();
+        }
+
+        if ( sample->is_valid_buffer() ) {
+            _smgr->release_buffer( sample );
+            sample->no_valid_buffer();
+        }
+    }
+    testForALError("stop");
+}
+
+// stop playing all associated samples
+void
+SGSampleGroup::suspend ()
+{
+    if (_active && _pause == 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() ) {
+                alSourcePause( sample->get_source() );
+            }
         }
+        testForALError("suspend");
     }
-    testForALError("suspend");
 }
 
 // resume playing all associated samples
 void
 SGSampleGroup::resume ()
 {
-    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() ) {
-            alSourcePlay( sample->get_source() );
+    if (_active && _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() ) {
+                alSourcePlay( sample->get_source() );
+            }
         }
+        testForALError("resume");
+        _pause = false;
     }
-    testForALError("resume");
-    _pause = false;
 }
 
 
@@ -315,41 +363,35 @@ bool SGSampleGroup::stop( const string& refname ) {
 
 void SGSampleGroup::set_volume( float vol )
 {
-    _volume = vol;
-    if (_volume < 0.0) _volume = 0.0;
-    if (_volume > 1.0) _volume = 1.0;
-
-    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;
-        sample->set_master_volume( _volume );
+    if (vol > _volume*1.01 || vol < _volume*0.99) {
+        _volume = vol;
+        if (_volume < 0.0) _volume = 0.0;
+        if (_volume > 1.0) _volume = 1.0;
+        _changed = true;
     }
 }
 
 // set the source position and orientation of all managed sounds
 void SGSampleGroup::update_pos_and_orientation() {
  
-    static const SGQuatd q(-0.5, -0.5, 0.5, 0.5);
-
     SGVec3d position = SGVec3d::fromGeod(_base_pos) - _smgr->get_position();
-
     SGQuatd hlOr = SGQuatd::fromLonLat(_base_pos);
-    SGQuatd ec2gl = hlOr*_orientation*q;
+    SGQuatd ec2body = hlOr*_orientation;
 
     SGVec3f velocity = SGVec3f::zeros();
     if ( _velocity[0] || _velocity[1] || _velocity[2] ) {
-       velocity = toVec3f( (hlOr*q).backTransform(_velocity) );
+       velocity = toVec3f( hlOr.backTransform(_velocity*SG_FEET_TO_METER) );
     }
 
     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;
+        sample->set_master_volume( _volume );
+        sample->set_orientation( _orientation );
+        sample->set_rotation( ec2body );
         sample->set_position( position );
         sample->set_velocity( velocity );
-        sample->set_orientation( _orientation );
-        sample->set_rotation( ec2gl );
     }
 }
 
@@ -368,9 +410,14 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample ) {
         velocity = sample->get_velocity();
     }
 
+    if (_smgr->bad_doppler_effect()) {
+        velocity *= 100.0f;
+    }
+
 #if 0
     if (length(position) > 20000)
-        printf("source and listener distance greater than 20km!\n");
+        printf("%s source and listener distance greater than 20km!\n",
+               _refname.c_str());
     if (isNaN(toVec3f(position).data())) printf("NaN in source position\n");
     if (isNaN(orientation.data())) printf("NaN in source orientation\n");
     if (isNaN(velocity.data())) printf("NaN in source velocity\n");