diff --git a/simgear/sound/soundmgr.hxx b/simgear/sound/soundmgr.hxx index 983c3f75..33fc9e2c 100644 --- a/simgear/sound/soundmgr.hxx +++ b/simgear/sound/soundmgr.hxx @@ -39,6 +39,10 @@ #include #include + +// Speed of sound in meters per second +#define SPEED_OF_SOUND 340.3f + // forward decls class SGSampleGroup; class SGSoundSample; @@ -193,6 +197,13 @@ public: */ inline float get_volume() { return _volume; } + /** + * Set the speed of sound. + * + * @param vel Sound velocity + */ + void set_sound_velocity( float vel ) { _sound_velocity = vel; } + /** * Get a free OpenAL source-id * @@ -332,19 +343,21 @@ private: std::unique_ptr d; bool _block_support; - bool _active; - bool _changed; - float _volume; + bool _active = false; + bool _changed = true; + float _volume = 0.0f; + + float _sound_velocity = SPEED_OF_SOUND; // Position of the listener. SGGeod _geod_pos; // Velocity of the listener. - SGVec3d _velocity; + SGVec3d _velocity = SGVec3d::zeros(); - bool _bad_doppler; - std::string _renderer; - std::string _vendor; + bool _bad_doppler = false; + std::string _renderer = "unknown"; + std::string _vendor = "unknown"; std::string _device_name; bool testForALCError(std::string s); diff --git a/simgear/sound/soundmgr_aeonwave.cxx b/simgear/sound/soundmgr_aeonwave.cxx index d282355c..ae0ef3d0 100644 --- a/simgear/sound/soundmgr_aeonwave.cxx +++ b/simgear/sound/soundmgr_aeonwave.cxx @@ -93,6 +93,8 @@ public: SGVec3d _base_pos = SGVec3d::zeros(); SGQuatd _orientation = SGQuatd::zeros(); + float _sound_velocity = SPEED_OF_SOUND; + unsigned int _buffer_id = 0; buffer_map _buffers; aax::Buffer nullBuffer; @@ -122,15 +124,7 @@ public: // // constructor -SGSoundMgr::SGSoundMgr() : - _active(false), - _changed(true), - _volume(0.0), - _velocity(SGVec3d::zeros()), - _bad_doppler(false), - _renderer("unknown"), - _vendor("unknown") -{ +SGSoundMgr::SGSoundMgr() { d.reset(new SoundManagerPrivate); d->_base_pos = SGVec3d::fromGeod(_geod_pos); } @@ -189,7 +183,7 @@ void SGSoundMgr::init() dsp = aax::dsp(d->_aax, AAX_VELOCITY_EFFECT); TRY( dsp.set(AAX_DOPPLER_FACTOR, 1.0f) ); - TRY( dsp.set(AAX_SOUND_VELOCITY, 340.3f) ); + TRY( dsp.set(AAX_SOUND_VELOCITY, _sound_velocity) ); TRY( d->_aax.set(dsp) ); testForError("scenery setup"); @@ -308,6 +302,14 @@ void SGSoundMgr::update( double dt ) aax::Vector vel( toVec3f(velocity).data() ); TRY( d->_aax.sensor_velocity(vel) ); + if (fabsf(_sound_velocity - d->_sound_velocity) > 10.0f) { + d->_sound_velocity = _sound_velocity; + + dsp = aax::dsp(d->_aax, AAX_VELOCITY_EFFECT); + TRY( dsp.set(AAX_SOUND_VELOCITY, _sound_velocity) ); + TRY( d->_aax.set(dsp) ); + } + testForError("update"); _changed = false; } diff --git a/simgear/sound/soundmgr_openal.cxx b/simgear/sound/soundmgr_openal.cxx index f00cfaab..a9b43408 100644 --- a/simgear/sound/soundmgr_openal.cxx +++ b/simgear/sound/soundmgr_openal.cxx @@ -67,16 +67,7 @@ using std::vector; class SGSoundMgr::SoundManagerPrivate { public: - SoundManagerPrivate() : - _device(nullptr), - _context(nullptr), - _absolute_pos(SGVec3d::zeros()), - _base_pos(SGVec3d::zeros()), - _orientation(SGQuatd::zeros()) - { - - - } + SoundManagerPrivate() = default; void init() { @@ -109,15 +100,15 @@ public: _absolute_pos = _base_pos; } - ALCdevice *_device; - ALCcontext *_context; + ALCdevice *_device = nullptr; + ALCcontext *_context = nullptr; std::vector _free_sources; std::vector _sources_in_use; - SGVec3d _absolute_pos; - SGVec3d _base_pos; - SGQuatd _orientation; + SGVec3d _absolute_pos = SGVec3d::zeros(); + SGVec3d _base_pos = SGVec3d::zeros(); + SGQuatd _orientation = SGQuatd::zeros(); // Orientation of the listener. // first 3 elements are "at" vector, second 3 are "up" vector ALfloat _at_up_vec[6]; @@ -132,15 +123,7 @@ public: // // constructor -SGSoundMgr::SGSoundMgr() : - _active(false), - _changed(true), - _volume(0.0), - _velocity(SGVec3d::zeros()), - _bad_doppler(false), - _renderer("unknown"), - _vendor("unknown") -{ +SGSoundMgr::SGSoundMgr() { d.reset(new SoundManagerPrivate); d->_base_pos = SGVec3d::fromGeod(_geod_pos); @@ -219,7 +202,7 @@ void SGSoundMgr::init() alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() ); alDopplerFactor(1.0); - alDopplerVelocity(340.3); // speed of sound in meters per second. + alDopplerVelocity(_sound_velocity); // gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE + // AL_ROLLOFF_FACTOR * (distance - AL_REFERENCE_DISTANCE)); @@ -392,14 +375,20 @@ if (isNaN(toVec3f(_velocity).data())) printf("NaN in listener velocity\n"); SGVec3d velocity = SGVec3d::zeros(); if ( _velocity[0] || _velocity[1] || _velocity[2] ) { velocity = hlOr.backTransform(_velocity*SG_FEET_TO_METER); - } - if ( _bad_doppler ) { - velocity *= 100.0f; + if ( _bad_doppler ) { + double fact = 100.0; + double mag = length( velocity*fact ); + + if (mag > _sound_velocity) { + fact *= _sound_velocity / mag; + } + velocity *= fact; + } } alListenerfv( AL_VELOCITY, toVec3f(velocity).data() ); - // alDopplerVelocity(340.3); // TODO: altitude dependent + alDopplerVelocity(_sound_velocity); testForError("update"); _changed = false; }