Hi,here is the patch for the directional sound and correct Doppler sound (and stereo sound) for the plib branch.
Please commit.
Maik
Index: sound/sample_openal.cxx =================================================================== RCS file: /var/cvs/SimGear-0.3/source/simgear/sound/sample_openal.cxx,v retrieving revision 1.26 diff -u -p -r1.26 sample_openal.cxx --- sound/sample_openal.cxx 8 Mar 2006 18:16:09 -0000 1.26 +++ sound/sample_openal.cxx 3 Jul 2007 21:00:29 -0000 @@ -75,12 +75,17 @@ SGSoundSample::SGSoundSample() : reference_dist(500.0), max_dist(3000.), loop(AL_FALSE), - playing(false) +#ifdef USE_SOFTWARE_DOPPLER + doppler_pitch_factor(1), + doppler_volume_factor(1), +#endif + playing(false), + no_Doppler_effect(true) { } // constructor -SGSoundSample::SGSoundSample( const char *path, const char *file) : +SGSoundSample::SGSoundSample( const char *path, const char *file , bool _no_Doppler_effect ) : buffer(0), source(0), pitch(1.0), @@ -88,8 +93,13 @@ SGSoundSample::SGSoundSample( const char reference_dist(500.0), max_dist(3000.), loop(AL_FALSE), - playing(false) -{ +#ifdef USE_SOFTWARE_DOPPLER + doppler_pitch_factor(1), + doppler_volume_factor(1), +#endif + playing(false), + no_Doppler_effect(_no_Doppler_effect) + { SGPath samplepath( path ); if ( strlen(file) ) { samplepath.append( file ); @@ -145,7 +155,7 @@ SGSoundSample::SGSoundSample( const char } // constructor -SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq ) : +SGSoundSample::SGSoundSample( unsigned char *_data, int len, int _freq , bool _no_Doppler_effect ) : buffer(0), source(0), pitch(1.0), @@ -153,7 +163,12 @@ SGSoundSample::SGSoundSample( unsigned c reference_dist(500.0), max_dist(3000.), loop(AL_FALSE), - playing(false) +#ifdef USE_SOFTWARE_DOPPLER + doppler_pitch_factor(1), + doppler_volume_factor(1), +#endif + playing(false), + no_Doppler_effect(_no_Doppler_effect) { SG_LOG( SG_GENERAL, SG_DEBUG, "In memory sounds sample" ); @@ -247,14 +262,23 @@ SGSoundSample::bind_source() { } alSourcei( source, AL_BUFFER, buffer ); +#ifndef USE_SOFTWARE_DOPPLER alSourcef( source, AL_PITCH, pitch ); alSourcef( source, AL_GAIN, volume ); +#else + print_openal_error("bind_sources return"); + alSourcef( source, AL_PITCH, pitch *doppler_pitch_factor ); + alGetError(); //ignore if the pitch is clamped by the driver + alSourcef( source, AL_GAIN, volume *doppler_volume_factor ); +#endif alSourcefv( source, AL_POSITION, source_pos ); alSourcefv( source, AL_DIRECTION, direction ); alSourcef( source, AL_CONE_INNER_ANGLE, inner ); alSourcef( source, AL_CONE_OUTER_ANGLE, outer ); alSourcef( source, AL_CONE_OUTER_GAIN, outergain); +#ifdef USE_OPEN_AL_DOPPLER alSourcefv( source, AL_VELOCITY, source_vel ); +#endif alSourcei( source, AL_LOOPING, loop ); alSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE ); @@ -273,8 +297,13 @@ SGSoundSample::set_pitch( double p ) { if ( p > 2.0 ) { p = 2.0; } pitch = p; if (playing) { +#ifndef USE_SOFTWARE_DOPPLER alSourcef( source, AL_PITCH, pitch ); print_openal_error("set_pitch"); +#else + alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor ); + alGetError(); //ignore if the pitch is clamped by the driver +#endif } } @@ -282,7 +311,11 @@ void SGSoundSample::set_volume( double v ) { volume = v; if (playing) { +#ifndef USE_SOFTWARE_DOPPLER alSourcef( source, AL_GAIN, volume ); +#else + alSourcef( source, AL_GAIN, volume * doppler_volume_factor ); +#endif print_openal_error("set_volume"); } } @@ -313,6 +346,7 @@ SGSoundSample::set_source_pos( ALfloat * sgAddVec3( final_pos, source_pos, offset_pos ); alSourcefv( source, AL_POSITION, final_pos ); + print_openal_error("set_source_pos"); } } @@ -327,6 +361,7 @@ SGSoundSample::set_offset_pos( ALfloat * sgAddVec3( final_pos, source_pos, offset_pos ); alSourcefv( source, AL_POSITION, final_pos ); + print_openal_error("set_offset_pos"); } } @@ -338,6 +373,9 @@ SGSoundSample::set_orientation( ALfloat inner = inner_angle; outer = outer_angle; outergain = outer_gain; + direction[0] = dir[0]; + direction[1] = dir[1]; + direction[2] = dir[2]; if (playing) { alSourcefv( source, AL_DIRECTION, dir); alSourcef( source, AL_CONE_INNER_ANGLE, inner ); @@ -347,13 +385,85 @@ SGSoundSample::set_orientation( ALfloat } void -SGSoundSample::set_source_vel( ALfloat *vel ) { - source_vel[0] = vel[0]; - source_vel[1] = vel[1]; - source_vel[2] = vel[2]; +SGSoundSample::set_source_vel( ALfloat *vel , ALfloat *listener_vel ) { + if (no_Doppler_effect) { + source_vel[0] = listener_vel[0]; + source_vel[1] = listener_vel[1]; + source_vel[2] = listener_vel[2]; + } else { + 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 ); } +#elif defined (USE_OPEN_AL_DOPPLER_WITH_FIXED_LISTENER) + if (playing) { + sgVec3 relative_vel; + sgSubVec3( relative_vel, source_vel, listener_vel ); + alSourcefv( source, AL_VELOCITY, relative_vel ); + } +#else + if (no_Doppler_effect) { + doppler_pitch_factor = 1; + doppler_volume_factor = 1; + return; + } + double doppler, mfp; + sgVec3 final_pos; + sgAddVec3( final_pos, source_pos, offset_pos ); + 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) { + if (doppler < 10) { + doppler_pitch_factor = doppler; + doppler_volume_factor = 1; + } + else { + doppler_pitch_factor = (doppler < 11) ? doppler : 11; + doppler_volume_factor = (doppler < 11) ? 11-doppler : 0; + } + } + else { + doppler_pitch_factor = 0.1; + doppler_volume_factor = (doppler > 0) ? doppler * 10 : 0; + } + if (playing) { + alSourcef( source, AL_GAIN, volume * doppler_volume_factor ); + print_openal_error("set_source_vel: volume"); + alSourcef( source, AL_PITCH, pitch * doppler_pitch_factor ); + alGetError(); //ignore if the pitch is clamped + } +#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 3 Jul 2007 21:00:30 -0000 @@ -52,6 +52,17 @@ # include <AL/alut.h> #endif +#ifndef HAVE_WINDOWS_H + #ifdef AL_VERSION_1_2 + #define USE_OPEN_AL_DOPPLER should work + #else + #define USE_OPEN_AL_DOPPLER_WITH_FIXED_LISTENER better than nothing + #endif +#else +//the Open_AL Doppler calculation seem to be buggy on windows + #define USE_SOFTWARE_DOPPLER seem to be necessary +#endif + SG_USING_STD(string); /** @@ -90,12 +101,17 @@ private: double pitch; double volume; +#ifdef USE_SOFTWARE_DOPPLER + double doppler_pitch_factor; + double doppler_volume_factor; +#endif double reference_dist; double max_dist; ALboolean loop; bool playing; bool bind_source(); + bool no_Doppler_effect; public: @@ -112,7 +128,7 @@ public: should usually be true unless you want to manipulate the data later.) */ - SGSoundSample( const char *path, const char *file ); + SGSoundSample( const char *path, const char *file , bool no_Doppler_effect = true ); /** * Constructor. @@ -123,7 +139,7 @@ public: should usually be true unless you want to manipulate the data later.) */ - SGSoundSample( unsigned char *_data, int len, int _freq ); + SGSoundSample( unsigned char *_data, int len, int _freq , bool no_Doppler_effect = true ); ~SGSoundSample(); @@ -208,7 +224,7 @@ public: /** * Set velocity of sound source (uses same coordinate system as opengl) */ - void set_source_vel( ALfloat *vel ); + void set_source_vel( ALfloat *vel , ALfloat *listener_vel ); /** 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 3 Jul 2007 21:00:31 -0000 @@ -345,6 +345,6 @@ 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 , listener_vel ); } } 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 3 Jul 2007 21:00:31 -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: sound/xmlsound.cxx =================================================================== RCS file: /var/cvs/SimGear-0.3/source/simgear/sound/xmlsound.cxx,v retrieving revision 1.19.2.1 diff -u -p -r1.19.2.1 xmlsound.cxx --- sound/xmlsound.cxx 23 Jun 2007 16:48:04 -0000 1.19.2.1 +++ sound/xmlsound.cxx 3 Jul 2007 21:00:33 -0000 @@ -237,7 +237,7 @@ SGXmlSound::init(SGPropertyNode *root, S SGPropertyNode_ptr pos = node->getChild("position"); if ( pos != NULL ) { offset_pos[0] = pos->getDoubleValue("x", 0.0); - offset_pos[1] = pos->getDoubleValue("y", 0.0); + offset_pos[1] = -pos->getDoubleValue("y", 0.0); offset_pos[2] = pos->getDoubleValue("z", 0.0); } @@ -252,7 +252,7 @@ SGXmlSound::init(SGPropertyNode *root, S pos = node->getChild("orientation"); if ( pos != NULL ) { dir[0] = pos->getDoubleValue("x", 0.0); - dir[1] = pos->getDoubleValue("y", 0.0); + dir[1] = -pos->getDoubleValue("y", 0.0); dir[2] = pos->getDoubleValue("z", 0.0); inner = pos->getDoubleValue("inner-angle", 360.0); outer = pos->getDoubleValue("outer-angle", 360.0); @@ -272,7 +272,8 @@ SGXmlSound::init(SGPropertyNode *root, S // "alSource". The semantics of what is going on here seems // confused and needs to be thought through more carefully. _sample = new SGSoundSample( path.c_str(), - node->getStringValue("path", "") ); + node->getStringValue("path", ""), + false ); _mgr->add( _sample, _name ); }
Index: Main/main.cxx =================================================================== RCS file: /var/cvs/FlightGear-0.9/source/src/Main/main.cxx,v retrieving revision 1.227.2.6 diff -u -p -r1.227.2.6 main.cxx --- Main/main.cxx 25 Jun 2007 19:57:15 -0000 1.227.2.6 +++ Main/main.cxx 3 Jul 2007 21:12:35 -0000 @@ -574,38 +574,111 @@ static void fgMainLoop( void ) { // aircraft is the source of all sounds and that all sounds are // positioned relative to the current view position. - static sgVec3 last_pos_offset; + static sgdVec3 last_visitor_pos = {0, 0, 0}; + static sgdVec3 last_model_pos = {0, 0, 0}; - // get the location data for the primary FDM (now hardcoded to ac model)... + //get the orientation + const sgVec4 *view = current_view->get_VIEW(); + + SGQuatd surf_or = SGQuatd::fromLonLatDeg( + current_view->getLongitude_deg(), current_view->getLatitude_deg()); + + SGQuatd model_or = SGQuatd::fromYawPitchRollDeg( + globals->get_aircraft_model()->get3DModel()->getHeadingDeg(), + globals->get_aircraft_model()->get3DModel()->getPitchDeg(), + globals->get_aircraft_model()->get3DModel()->getRollDeg()); + + //get the up and at vector in the aircraft base + sgVec3 sgv3_help; + sgSetVec3 ( sgv3_help, 0, 0, 1 ); //up + sgXformVec3( sgv3_help, view ); + SGVec3d sgv_up = model_or.rotateBack( + surf_or.rotateBack(SGVec3d(sgv3_help[0], sgv3_help[1], sgv3_help[2]))); + sgVec3 up; + sgSetVec3(up, sgv_up[0], sgv_up[1], sgv_up[2]); + + sgSetVec3 ( sgv3_help, 0, -1, 0 ); //at + sgXformVec3( sgv3_help, view ); + SGVec3d sgv_at = model_or.rotateBack( + surf_or.rotateBack(SGVec3d(sgv3_help[0], sgv3_help[1], sgv3_help[2]))); + sgVec3 at; + sgSetVec3(at, sgv_at[0], sgv_at[1], sgv_at[2]); + + // get the location data for the primary FDM (now hardcoded to ac model)... SGLocation *acmodel_loc = NULL; acmodel_loc = (SGLocation *)globals-> get_aircraft_model()->get3DModel()->getSGLocation(); + // calculate speed of visitor and model + sgVec3 listener_vel, model_vel; + SGVec3d SGV3d_help; + sgdVec3 sgdv3_help; + sgdVec3 sgdv3_null = {0, 0, 0}; + sgVec3 sgv3_null = {0, 0, 0}; + + sgdSubVec3( sgdv3_help, + last_visitor_pos, current_view->get_absolute_view_pos()); + sgdAddVec3( last_visitor_pos, sgdv3_null, current_view->get_absolute_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(delta_vel) > 1000) + sgSetVec3(listener_vel, model_vel[0], model_vel[1], model_vel[2] ); + 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, - view_location->get_absolute_view_pos(), + double * cvp = current_view->get_absolute_view_pos(); + sgdVec3 dsource_pos_offset = { cvp[0], cvp[1], cvp[2] }; + + sgdSubVec3( dsource_pos_offset,dsource_pos_offset, acmodel_loc->get_absolute_view_pos() ); - // cout << "pos all = " << source_pos_offset[0] << " " << source_pos_offset[1] << " " << source_pos_offset[2] << endl; + SGVec3d sgv_dsource_pos_offset = model_or.rotateBack( + surf_or.rotateBack(SGVec3d(dsource_pos_offset[0], + dsource_pos_offset[1], dsource_pos_offset[2]))); + sgVec3 source_pos_offset; - sgSetVec3(source_pos_offset, dsource_pos_offset); + sgSetVec3(source_pos_offset, sgv_dsource_pos_offset[0], + sgv_dsource_pos_offset[1], sgv_dsource_pos_offset[2]); globals->get_soundmgr()->set_source_pos_all( source_pos_offset ); - // set the velocity - sgVec3 source_vel; - sgSubVec3( source_vel, source_pos_offset, last_pos_offset ); + float orient[6]; + for (int i = 0; i < 3; i++) { + orient[i] = sgv_at[i]; + orient[i + 3] = sgv_up[i]; + } + globals->get_soundmgr()->set_listener_orientation( orient ); - 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 ); + // set the velocity + globals->get_soundmgr()->set_source_vel_all( model_vel ); - // Right now we make a simplifying assumption that the listener is - // always positioned at the origin. + // The listener is always positioned at the origin. sgVec3 listener_pos; sgSetVec3( listener_pos, 0.0, 0.0, 0.0 ); - // cout << "listener = " << listener_pos[0] << " " << listener_pos[1] << " " << listener_pos[2] << endl; globals->get_soundmgr()->set_listener_pos( listener_pos ); #endif Index: Main/viewer.cxx =================================================================== RCS file: /var/cvs/FlightGear-0.9/source/src/Main/viewer.cxx,v retrieving revision 1.23 diff -u -p -r1.23 viewer.cxx --- Main/viewer.cxx 27 Jul 2006 16:36:22 -0000 1.23 +++ Main/viewer.cxx 3 Jul 2007 21:12:38 -0000 @@ -629,6 +629,12 @@ FGViewer::recalcLookFrom () // add the offsets including rotations to the translation vector sgAddVec3( _view_pos, position_offset ); + sgdVec3 help; + help[0] = position_offset[0]; + help[1] = position_offset[1]; + help[2] = position_offset[2]; + sgdAddVec3(_absolute_view_pos,_absolute_view_pos,help); + // multiply the OFFSETS (for heading and pitch) into the VIEW sgPostMultMat4(VIEW, VIEW_OFFSET); @@ -709,6 +715,12 @@ FGViewer::recalcLookAt () // add the Position offsets from object to the eye position sgAddVec3( eye_pos, eye_pos, position_offset ); + sgdVec3 help; + help[0] = position_offset[0]; + help[1] = position_offset[1]; + help[2] = position_offset[2]; + sgdAddVec3(_absolute_view_pos,_absolute_view_pos,help); + // add target offsets to at_position... sgSetVec3(target_position_offset, _target_z_offset_m, _target_x_offset_m, _target_y_offset_m );
------------------------------------------------------------------------- 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