Limit the velocity to the sound velocity after multiplying it by a foctor of 100 to compensate for bad Doppler calculations. Also add the option to set the sound velocity for the sound manager from within FlightGear (not yet used).

This commit is contained in:
Erik Hofman 2020-04-11 09:48:49 +02:00
parent c62c080a4b
commit b3bdf8636a
3 changed files with 50 additions and 46 deletions

View File

@ -39,6 +39,10 @@
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
// Speed of sound in meters per second
#define SPEED_OF_SOUND 340.3f
// forward decls // forward decls
class SGSampleGroup; class SGSampleGroup;
class SGSoundSample; class SGSoundSample;
@ -193,6 +197,13 @@ public:
*/ */
inline float get_volume() { return _volume; } 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 * Get a free OpenAL source-id
* *
@ -332,19 +343,21 @@ private:
std::unique_ptr<SoundManagerPrivate> d; std::unique_ptr<SoundManagerPrivate> d;
bool _block_support; bool _block_support;
bool _active; bool _active = false;
bool _changed; bool _changed = true;
float _volume; float _volume = 0.0f;
float _sound_velocity = SPEED_OF_SOUND;
// Position of the listener. // Position of the listener.
SGGeod _geod_pos; SGGeod _geod_pos;
// Velocity of the listener. // Velocity of the listener.
SGVec3d _velocity; SGVec3d _velocity = SGVec3d::zeros();
bool _bad_doppler; bool _bad_doppler = false;
std::string _renderer; std::string _renderer = "unknown";
std::string _vendor; std::string _vendor = "unknown";
std::string _device_name; std::string _device_name;
bool testForALCError(std::string s); bool testForALCError(std::string s);

View File

@ -93,6 +93,8 @@ public:
SGVec3d _base_pos = SGVec3d::zeros(); SGVec3d _base_pos = SGVec3d::zeros();
SGQuatd _orientation = SGQuatd::zeros(); SGQuatd _orientation = SGQuatd::zeros();
float _sound_velocity = SPEED_OF_SOUND;
unsigned int _buffer_id = 0; unsigned int _buffer_id = 0;
buffer_map _buffers; buffer_map _buffers;
aax::Buffer nullBuffer; aax::Buffer nullBuffer;
@ -122,15 +124,7 @@ public:
// //
// constructor // constructor
SGSoundMgr::SGSoundMgr() : SGSoundMgr::SGSoundMgr() {
_active(false),
_changed(true),
_volume(0.0),
_velocity(SGVec3d::zeros()),
_bad_doppler(false),
_renderer("unknown"),
_vendor("unknown")
{
d.reset(new SoundManagerPrivate); d.reset(new SoundManagerPrivate);
d->_base_pos = SGVec3d::fromGeod(_geod_pos); d->_base_pos = SGVec3d::fromGeod(_geod_pos);
} }
@ -189,7 +183,7 @@ void SGSoundMgr::init()
dsp = aax::dsp(d->_aax, AAX_VELOCITY_EFFECT); dsp = aax::dsp(d->_aax, AAX_VELOCITY_EFFECT);
TRY( dsp.set(AAX_DOPPLER_FACTOR, 1.0f) ); 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) ); TRY( d->_aax.set(dsp) );
testForError("scenery setup"); testForError("scenery setup");
@ -308,6 +302,14 @@ void SGSoundMgr::update( double dt )
aax::Vector vel( toVec3f(velocity).data() ); aax::Vector vel( toVec3f(velocity).data() );
TRY( d->_aax.sensor_velocity(vel) ); 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"); testForError("update");
_changed = false; _changed = false;
} }

View File

@ -67,16 +67,7 @@ using std::vector;
class SGSoundMgr::SoundManagerPrivate class SGSoundMgr::SoundManagerPrivate
{ {
public: public:
SoundManagerPrivate() : SoundManagerPrivate() = default;
_device(nullptr),
_context(nullptr),
_absolute_pos(SGVec3d::zeros()),
_base_pos(SGVec3d::zeros()),
_orientation(SGQuatd::zeros())
{
}
void init() void init()
{ {
@ -109,15 +100,15 @@ public:
_absolute_pos = _base_pos; _absolute_pos = _base_pos;
} }
ALCdevice *_device; ALCdevice *_device = nullptr;
ALCcontext *_context; ALCcontext *_context = nullptr;
std::vector<ALuint> _free_sources; std::vector<ALuint> _free_sources;
std::vector<ALuint> _sources_in_use; std::vector<ALuint> _sources_in_use;
SGVec3d _absolute_pos; SGVec3d _absolute_pos = SGVec3d::zeros();
SGVec3d _base_pos; SGVec3d _base_pos = SGVec3d::zeros();
SGQuatd _orientation; SGQuatd _orientation = SGQuatd::zeros();
// Orientation of the listener. // Orientation of the listener.
// first 3 elements are "at" vector, second 3 are "up" vector // first 3 elements are "at" vector, second 3 are "up" vector
ALfloat _at_up_vec[6]; ALfloat _at_up_vec[6];
@ -132,15 +123,7 @@ public:
// //
// constructor // constructor
SGSoundMgr::SGSoundMgr() : SGSoundMgr::SGSoundMgr() {
_active(false),
_changed(true),
_volume(0.0),
_velocity(SGVec3d::zeros()),
_bad_doppler(false),
_renderer("unknown"),
_vendor("unknown")
{
d.reset(new SoundManagerPrivate); d.reset(new SoundManagerPrivate);
d->_base_pos = SGVec3d::fromGeod(_geod_pos); d->_base_pos = SGVec3d::fromGeod(_geod_pos);
@ -219,7 +202,7 @@ void SGSoundMgr::init()
alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() ); alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() );
alDopplerFactor(1.0); alDopplerFactor(1.0);
alDopplerVelocity(340.3); // speed of sound in meters per second. alDopplerVelocity(_sound_velocity);
// gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE + // gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +
// AL_ROLLOFF_FACTOR * (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(); SGVec3d velocity = SGVec3d::zeros();
if ( _velocity[0] || _velocity[1] || _velocity[2] ) { if ( _velocity[0] || _velocity[1] || _velocity[2] ) {
velocity = hlOr.backTransform(_velocity*SG_FEET_TO_METER); velocity = hlOr.backTransform(_velocity*SG_FEET_TO_METER);
}
if ( _bad_doppler ) { if ( _bad_doppler ) {
velocity *= 100.0f; 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() ); alListenerfv( AL_VELOCITY, toVec3f(velocity).data() );
// alDopplerVelocity(340.3); // TODO: altitude dependent alDopplerVelocity(_sound_velocity);
testForError("update"); testForError("update");
_changed = false; _changed = false;
} }