Hi,

please use this .diff files (the simgear.diff is different, there was a bug for non-window systems).

Thanks to Melchior for pointing this out.

Maik

Maik Justus schrieb am 24.06.2007 16:34:
Hi,

here is a patch (only head/osg) which should fix all bugs listed below (on all OS). OpenAL has the doppler bug on my pc, therefore I can not test if the doppler calculation is correct e.g. on Linux.

Maik

Maik Justus schrieb am 24.06.2007 02:29:
Hi,

at the osg branch, the directional sound and doppler effects should work since two days.

It seems that (at least) on windows there is a bug within OpenAL calculating the Doppler effect. Either there is no Doppler Effect (like I have) or it is totally wrong (as aerotro has with the same executable than I have). Eventually it affects the performance of flightgear.

The enclosed patch switches of the Doppler calculation of OpenAL and adds a own Doppler calculation. The patch is not designed for cvs (now). I first need the feedback, if all windows builds or even other OS are affected.

With this patch Doppler effect should be ok at every OS. I hope, that the performance issue is solved with that, too (or is independent from the sound former sound patch).



Now that the Doppler effect works here I got aware of some bugs:
- the effect is wrong, if the aircraft changes its orientation (pitch and heading) - the sound is switched off for one frame if the fly-by view jumps to a new eyepoint (and often some 3d models are loaded at this time this frame can be noticeable long)
- the same happens, if you change the view
- if you move (rotate) the eye-point in an external view you hear Doppler effects

I will try to make a patch for this within the next days.

Maik


Index: sound/sample_openal.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/sound/sample_openal.cxx,v
retrieving revision 1.27
diff -u -p -r1.27 sample_openal.cxx
--- sound/sample_openal.cxx     21 Jun 2007 21:46:21 -0000      1.27
+++ sound/sample_openal.cxx     24 Jun 2007 14:56:32 -0000
@@ -75,6 +75,10 @@ SGSoundSample::SGSoundSample() :
     reference_dist(500.0),
     max_dist(3000.),
     loop(AL_FALSE),
+#ifndef USE_OPEN_AL_DOPPLER
+    doppler_pitch_factor(1),
+    doppler_volume_factor(1),
+#endif
     playing(false)
 {
 }
@@ -273,7 +277,11 @@ SGSoundSample::set_pitch( double p ) {
     if ( p > 2.0 ) { p = 2.0; }
     pitch = p;
     if (playing) {
+#ifdef USE_OPEN_AL_DOPPLER
         alSourcef( source, AL_PITCH, pitch );
+#else
+        alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
+#endif
         print_openal_error("set_pitch");
     }
 }
@@ -282,7 +290,11 @@ void
 SGSoundSample::set_volume( double v ) {
     volume = v;
     if (playing) {
+#ifdef USE_OPEN_AL_DOPPLER
         alSourcef( source, AL_GAIN, volume );
+#else
+        alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
+#endif
         print_openal_error("set_volume");
     }
 }
@@ -350,13 +362,66 @@ SGSoundSample::set_orientation( ALfloat 
 }
 
 void
-SGSoundSample::set_source_vel( ALfloat *vel ) {
+SGSoundSample::set_source_vel( ALfloat *vel 
+#ifndef USE_OPEN_AL_DOPPLER
+                              , ALfloat *listener_vel 
+#endif
+                              ) {
     source_vel[0] = vel[0];
     source_vel[1] = vel[1];
     source_vel[2] = vel[2];
+#ifdef USE_OPEN_AL_DOPPLER
     if (playing) {
         alSourcefv( source, AL_VELOCITY, source_vel );
     }
+#else
+    double doppler, msv, mfp, mlv;
+    sgVec3 final_pos;
+    sgAddVec3( final_pos, source_pos, offset_pos );
+    msv = sgLengthVec3(source_vel);
+    mlv = sgLengthVec3(listener_vel);
+    mfp = sgLengthVec3(final_pos);
+    if (mfp > 1e-6) {
+        double vls = - sgScalarProductVec3( listener_vel, final_pos ) / mfp;
+        double vss = - sgScalarProductVec3( source_vel, final_pos ) / mfp;
+        if (fabs(340 - vss) > 1e-6)
+        {
+            doppler = (340 - vls) / (340 - vss);
+            doppler = ( doppler > 0) ? ( ( doppler < 10) ? doppler : 10 ) : 0;
+        }
+        else
+            doppler = 0;
+    }
+    else
+        doppler = 1;
+    /* the OpenAL documentation of the Doppler calculation
+    SS: AL_SPEED_OF_SOUND = speed of sound (default value 343.3)
+    DF: AL_DOPPLER_FACTOR = Doppler factor (default 1.0)
+    vls: Listener velocity scalar (scalar, projected on source-to-listener 
vector)
+    vss: Source velocity scalar (scalar, projected on source-to-listener 
vector)
+    SL = source to listener vector
+    SV = Source Velocity vector
+    LV = Listener Velocity vector
+    vls = DotProduct(SL, LV) / Mag(SL)
+    vss = DotProduct(SL, SV) / Mag(SL)
+    Dopper Calculation:
+    vss = min(vss, SS/DF)
+    vls = min(vls, SS/DF)
+    f' = f * (SS - DF*vls) / (SS - DF*vss)
+    */
+    if (doppler > 0.1) {
+        doppler_pitch_factor = doppler;
+        doppler_volume_factor = 1;
+    }
+    else {
+        doppler_pitch_factor = 0.1;
+        doppler_volume_factor = (doppler > 0) ? doppler * 10 : 0;
+    }
+    if (playing) {
+        alSourcef( source, AL_GAIN, volume * doppler_volume_factor );
+        alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor );
+    }
+#endif
 }
 
 void
Index: sound/sample_openal.hxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/sound/sample_openal.hxx,v
retrieving revision 1.17
diff -u -p -r1.17 sample_openal.hxx
--- sound/sample_openal.hxx     8 Mar 2006 18:16:09 -0000       1.17
+++ sound/sample_openal.hxx     24 Jun 2007 14:56:33 -0000
@@ -52,6 +52,11 @@
 # include <AL/alut.h>
 #endif
 
+#ifndef HAVE_WINDOWS_H
+#define USE_OPEN_AL_DOPPLER should work
+//the Open_AL Doppler calculation seem to be buggy on windows
+#endif
+
 SG_USING_STD(string);
 
 /**
@@ -90,6 +95,10 @@ private:
 
     double pitch;
     double volume;
+#ifndef USE_OPEN_AL_DOPPLER
+    double doppler_pitch_factor;
+    double doppler_volume_factor;
+#endif
     double reference_dist;
     double max_dist;
     ALboolean loop;
@@ -208,7 +217,11 @@ public:
     /**
      * Set velocity of sound source (uses same coordinate system as opengl)
      */
-    void set_source_vel( ALfloat *vel );
+    void set_source_vel( ALfloat *vel 
+#ifndef USE_OPEN_AL_DOPPLER
+                              , ALfloat *listener_vel 
+#endif
+        );
 
 
     /**
Index: sound/soundmgr_openal.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/sound/soundmgr_openal.cxx,v
retrieving revision 1.25
diff -u -p -r1.25 soundmgr_openal.cxx
--- sound/soundmgr_openal.cxx   22 Oct 2006 19:42:17 -0000      1.25
+++ sound/soundmgr_openal.cxx   24 Jun 2007 14:56:34 -0000
@@ -345,6 +345,10 @@ void SGSoundMgr::set_source_vel_all( ALf
     sample_map_iterator sample_end = samples.end();
     for ( ; sample_current != sample_end; ++sample_current ) {
        SGSoundSample *sample = sample_current->second;
-        sample->set_source_vel( vel );
+        sample->set_source_vel( vel 
+#ifndef USE_OPEN_AL_DOPPLER
+                              , listener_vel 
+#endif
+            );
     }
 }
Index: sound/soundmgr_openal.hxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/sound/soundmgr_openal.hxx,v
retrieving revision 1.8
diff -u -p -r1.8 soundmgr_openal.hxx
--- sound/soundmgr_openal.hxx   8 Mar 2006 18:16:09 -0000       1.8
+++ sound/soundmgr_openal.hxx   24 Jun 2007 14:56:35 -0000
@@ -206,7 +206,9 @@ public:
         listener_vel[0] = vel[0];
         listener_vel[1] = vel[1];
         listener_vel[2] = vel[2];
+#ifdef USE_OPEN_AL_DOPPLER
         alListenerfv( AL_VELOCITY, listener_vel );
+#endif
     }
 
     /**
Index: Main/main.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Main/main.cxx,v
retrieving revision 1.241
diff -u -p -r1.241 main.cxx
--- Main/main.cxx       22 Jun 2007 16:51:12 -0000      1.241
+++ Main/main.cxx       24 Jun 2007 14:22:55 -0000
@@ -549,7 +549,8 @@ static void fgMainLoop( void ) {
     // aircraft is the source of all sounds and that all sounds are
     // positioned in the aircraft base
 
-    static sgVec3 last_pos_offset = {0, 0, 0};
+    static sgdVec3 last_visitor_pos = {0, 0, 0};
+    static sgdVec3 last_model_pos = {0, 0, 0};
 
     //get the orientation
     const SGQuatd view_or = current_view->getViewOrientation();
@@ -575,6 +576,47 @@ static void fgMainLoop( void ) {
     acmodel_loc = (SGLocation *)globals->
         get_aircraft_model()->get3DModel()->getSGLocation();
 
+    // calcualte speed of visitor and model
+    sgVec3 listener_vel, model_vel;
+    SGVec3d SGV3d_help;
+    sgdVec3 sgdv3_help;
+    sgdVec3 sgdv3_null = { 0, 0, 0 };
+
+    sgdSubVec3( sgdv3_help,
+                last_visitor_pos, (double*) &current_view->get_view_pos());
+    sgdAddVec3( last_visitor_pos, sgdv3_null, (double*) 
&current_view->get_view_pos());
+    SGV3d_help = model_or.rotateBack(
+        surf_or.rotateBack(SGVec3d(sgdv3_help[0],
+        sgdv3_help[1], sgdv3_help[2])));
+    sgSetVec3( listener_vel, SGV3d_help[0], SGV3d_help[1], SGV3d_help[2]);
+
+    sgdSubVec3( sgdv3_help,
+                last_model_pos, acmodel_loc->get_absolute_view_pos());
+    sgdAddVec3( last_model_pos, sgdv3_null, 
acmodel_loc->get_absolute_view_pos());
+    SGV3d_help = model_or.rotateBack(
+        surf_or.rotateBack(SGVec3d(sgdv3_help[0],
+        sgdv3_help[1], sgdv3_help[2])));
+    sgSetVec3( model_vel, SGV3d_help[0],SGV3d_help[1],SGV3d_help[2]);
+
+    if (delta_time_sec > 0) {
+        sgScaleVec3( model_vel, 1 / delta_time_sec );
+        sgScaleVec3( listener_vel, 1 / delta_time_sec );
+    }
+
+    //checking, if the listener pos has moved suddenly
+    if (sgLengthVec3(listener_vel) > 1000)
+    {
+        //check if the relative speed model vs listener has moved suddenly, too
+        sgVec3 delta_vel;
+        sgSubVec3(delta_vel, listener_vel, model_vel );
+        if (sgLengthVec3(listener_vel) > 1000)
+            sgSetVec3(listener_vel, model_vel[0], model_vel[1], model_vel[2] 
); // a sane value
+        else
+            globals->get_soundmgr()->set_listener_vel( listener_vel );
+    }
+    else
+        globals->get_soundmgr()->set_listener_vel( listener_vel );
+
     // set positional offset for sources
     sgdVec3 dsource_pos_offset;
     sgdSubVec3( dsource_pos_offset,
@@ -584,7 +626,6 @@ static void fgMainLoop( void ) {
         surf_or.rotateBack(SGVec3d(dsource_pos_offset[0],
         dsource_pos_offset[1], dsource_pos_offset[2])));
 
-    //sgv_dsource_pos_offset = model_or.rotateBack(sgv_dsource_pos_offset);
     sgVec3 source_pos_offset;
     sgSetVec3(source_pos_offset, sgv_dsource_pos_offset[0],
         sgv_dsource_pos_offset[1], sgv_dsource_pos_offset[2]);
@@ -599,13 +640,8 @@ static void fgMainLoop( void ) {
     globals->get_soundmgr()->set_listener_orientation( orient );
 
     // set the velocity
-    sgVec3 source_vel;
-    sgSubVec3( source_vel, source_pos_offset, last_pos_offset );
-    if (delta_time_sec > 0)
-        sgScaleVec3( source_vel, 1 / delta_time_sec );
-    sgCopyVec3( last_pos_offset, source_pos_offset );
-    // cout << "vel = " << source_vel[0] << " " << source_vel[1] << " " << 
source_vel[2] << endl;
-    globals->get_soundmgr()->set_source_vel_all( source_vel );
+    // all souurces are defined to be in the model
+    globals->get_soundmgr()->set_source_vel_all( model_vel );
 
     // The listener is always positioned at the origin.
     sgVec3 listener_pos;
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to