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/math/SGMath.hxx>
// 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<SoundManagerPrivate> 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);

View File

@ -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;
}

View File

@ -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<ALuint> _free_sources;
std::vector<ALuint> _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;
}