Switch from doing the calculations ourselves in case of a bad_doppler implementation to using alDopplerFactor

This commit is contained in:
Erik Hofman 2020-04-12 14:50:12 +02:00
parent b3bdf8636a
commit 695616a8f2
6 changed files with 71 additions and 139 deletions

View File

@ -24,7 +24,6 @@ if (USE_AEONWAVE)
else() else()
set(SOURCES ${SOURCES} set(SOURCES ${SOURCES}
soundmgr_openal.cxx soundmgr_openal.cxx
soundmgr_openal_private.hxx
) )
endif() endif()

View File

@ -49,7 +49,7 @@ SGSampleGroup::~SGSampleGroup ()
{ {
_active = false; _active = false;
stop(); stop();
_smgr = 0; _smgr = nullptr;
} }
#include <stdio.h> #include <stdio.h>
@ -121,8 +121,8 @@ void SGSampleGroup::update( double dt ) {
_changed = false; _changed = false;
} }
for (auto current =_samples.begin(); current !=_samples.end(); ++current) { for (auto current : _samples) {
SGSoundSample *sample = current->second; SGSoundSample *sample = current.second;
if ( !sample->is_valid_source() && sample->is_playing() && !sample->test_out_of_range()) { if ( !sample->is_valid_source() && sample->is_playing() && !sample->test_out_of_range()) {
start_playing_sample(sample); start_playing_sample(sample);
@ -196,9 +196,8 @@ void
SGSampleGroup::stop () SGSampleGroup::stop ()
{ {
_pause = true; _pause = true;
for (auto current =_samples.begin(); current !=_samples.end(); ++current) { for (auto current : _samples) {
SGSoundSample *sample = current->second; _smgr->sample_destroy( current.second );
_smgr->sample_destroy( sample );
} }
} }
@ -208,12 +207,11 @@ SGSampleGroup::suspend ()
{ {
if (_active && _pause == false) { if (_active && _pause == false) {
_pause = true; _pause = true;
for (auto current =_samples.begin(); current !=_samples.end(); ++current) {
#ifdef ENABLE_SOUND #ifdef ENABLE_SOUND
SGSoundSample *sample = current->second; for (auto current : _samples) {
_smgr->sample_suspend( sample ); _smgr->sample_suspend( current.second );
#endif
} }
#endif
testForMgrError("suspend"); testForMgrError("suspend");
} }
} }
@ -224,9 +222,8 @@ SGSampleGroup::resume ()
{ {
if (_active && _pause == true) { if (_active && _pause == true) {
#ifdef ENABLE_SOUND #ifdef ENABLE_SOUND
for (auto current =_samples.begin(); current !=_samples.end(); ++current) { for (auto current : _samples) {
SGSoundSample *sample = current->second; _smgr->sample_resume( current.second );
_smgr->sample_resume( sample );
} }
testForMgrError("resume"); testForMgrError("resume");
#endif #endif
@ -295,8 +292,8 @@ void SGSampleGroup::update_pos_and_orientation() {
velocity = toVec3f( hlOr.backTransform(_velocity*SG_FEET_TO_METER) ); velocity = toVec3f( hlOr.backTransform(_velocity*SG_FEET_TO_METER) );
} }
for (auto current =_samples.begin(); current !=_samples.end(); ++current ) { for (auto current : _samples ) {
SGSoundSample *sample = current->second; SGSoundSample *sample = current.second;
sample->set_master_volume( _volume ); sample->set_master_volume( _volume );
sample->set_orientation( _orientation ); sample->set_orientation( _orientation );
sample->set_rotation( ec2body ); sample->set_rotation( ec2body );
@ -338,10 +335,6 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample )
velocity = sample->get_velocity(); velocity = sample->get_velocity();
} }
if (_smgr->bad_doppler_effect()) {
velocity *= 100.0f;
}
#if 0 #if 0
if (length(position) > 20000) if (length(position) > 20000)
printf("%s source and listener distance greater than 20km!\n", printf("%s source and listener distance greater than 20km!\n",

View File

@ -41,7 +41,7 @@
// Speed of sound in meters per second // Speed of sound in meters per second
#define SPEED_OF_SOUND 340.3f #define SPEED_OF_SOUND 340.3
// forward decls // forward decls
class SGSampleGroup; class SGSampleGroup;
@ -202,7 +202,7 @@ public:
* *
* @param vel Sound velocity * @param vel Sound velocity
*/ */
void set_sound_velocity( float vel ) { _sound_velocity = vel; } void set_sound_velocity( double vel ) { _sound_velocity = vel; }
/** /**
* Get a free OpenAL source-id * Get a free OpenAL source-id
@ -299,14 +299,6 @@ public:
*/ */
inline bool has_changed() { return _changed; } inline bool has_changed() { return _changed; }
/**
* Some implementations seem to need the velocity multiplied by a
* factor of 100 to make them distinct. I've not found if this is
* a problem in the implementation or in out code. Until then
* this function is used to detect the problematic implementations.
*/
inline bool bad_doppler_effect() { return _bad_doppler; }
/** /**
* Load a sample file and return it's configuration and data. * Load a sample file and return it's configuration and data.
* *
@ -347,7 +339,7 @@ private:
bool _changed = true; bool _changed = true;
float _volume = 0.0f; float _volume = 0.0f;
float _sound_velocity = SPEED_OF_SOUND; double _sound_velocity = SPEED_OF_SOUND;
// Position of the listener. // Position of the listener.
SGGeod _geod_pos; SGGeod _geod_pos;
@ -355,7 +347,6 @@ private:
// Velocity of the listener. // Velocity of the listener.
SGVec3d _velocity = SGVec3d::zeros(); SGVec3d _velocity = SGVec3d::zeros();
bool _bad_doppler = false;
std::string _renderer = "unknown"; std::string _renderer = "unknown";
std::string _vendor = "unknown"; std::string _vendor = "unknown";
std::string _device_name; std::string _device_name;

View File

@ -298,6 +298,7 @@ void SGSoundMgr::update( double dt )
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);
printf("lst vel: %f\n", length(velocity));
} }
aax::Vector vel( toVec3f(velocity).data() ); aax::Vector vel( toVec3f(velocity).data() );
TRY( d->_aax.sensor_velocity(vel) ); TRY( d->_aax.sensor_velocity(vel) );
@ -619,6 +620,7 @@ void SGSoundMgr::update_sample_config( SGSoundSample *sample, SGVec3d& position,
aax::Vector64 pos = position.data(); aax::Vector64 pos = position.data();
aax::Vector ori = orientation.data(); aax::Vector ori = orientation.data();
aax::Vector vel = velocity.data(); aax::Vector vel = velocity.data();
printf("src vel: %f\n", length(velocity));
aax::Matrix64 mtx(pos, ori); aax::Matrix64 mtx(pos, ori);
TRY( emitter.matrix(mtx) ); TRY( emitter.matrix(mtx) );

View File

@ -38,7 +38,6 @@
#include "soundmgr.hxx" #include "soundmgr.hxx"
#include "readwav.hxx" #include "readwav.hxx"
#include "soundmgr_openal_private.hxx"
#include "sample_group.hxx" #include "sample_group.hxx"
#include <simgear/sg_inlines.h> #include <simgear/sg_inlines.h>
@ -46,6 +45,17 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#if defined(__APPLE__)
# include <OpenAL/al.h>
# include <OpenAL/alc.h>
#elif defined(OPENALSDK)
# include <al.h>
# include <alc.h>
#else
# include <AL/al.h>
# include <AL/alc.h>
#endif
using std::vector; using std::vector;
@ -64,10 +74,29 @@ using std::vector;
# define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C # define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C
#endif #endif
struct refUint {
unsigned int refctr;
ALuint id;
refUint() { refctr = 0; id = (ALuint)-1; };
refUint(ALuint i) { refctr = 1; id = i; };
~refUint() {};
};
using buffer_map = std::map < std::string, refUint >;
using sample_group_map = std::map < std::string, SGSharedPtr<SGSampleGroup> >;
inline bool isNaN(float *v) {
return (SGMisc<float>::isNaN(v[0]) || SGMisc<float>::isNaN(v[1]) || SGMisc<float>::isNaN(v[2]));
}
class SGSoundMgr::SoundManagerPrivate class SGSoundMgr::SoundManagerPrivate
{ {
public: public:
SoundManagerPrivate() = default; SoundManagerPrivate() = default;
~SoundManagerPrivate() = default;
void init() void init()
{ {
@ -112,6 +141,8 @@ public:
// 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];
bool _bad_doppler = false;
sample_group_map _sample_groups; sample_group_map _sample_groups;
buffer_map _buffers; buffer_map _buffers;
@ -201,7 +232,7 @@ void SGSoundMgr::init()
alListenerfv( AL_POSITION, SGVec3f::zeros().data() ); alListenerfv( AL_POSITION, SGVec3f::zeros().data() );
alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() ); alListenerfv( AL_VELOCITY, SGVec3f::zeros().data() );
alDopplerFactor(1.0); alDopplerFactor(1.0f);
alDopplerVelocity(_sound_velocity); alDopplerVelocity(_sound_velocity);
// gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE + // gain = AL_REFERENCE_DISTANCE / (AL_REFERENCE_DISTANCE +
@ -231,9 +262,11 @@ void SGSoundMgr::init()
_renderer = (const char *)alGetString(AL_RENDERER); _renderer = (const char *)alGetString(AL_RENDERER);
if (_vendor == "Creative Labs Inc.") { if (_vendor == "Creative Labs Inc.") {
_bad_doppler = true; alDopplerFactor(100.0f);
d->_bad_doppler = true;
} else if (_vendor == "OpenAL Community" && _renderer == "OpenAL Soft") { } else if (_vendor == "OpenAL Community" && _renderer == "OpenAL Soft") {
_bad_doppler = true; alDopplerFactor(100.0f);
d->_bad_doppler = true;
} }
if (d->_free_sources.empty()) { if (d->_free_sources.empty()) {
@ -264,10 +297,8 @@ void SGSoundMgr::activate()
if ( is_working() ) { if ( is_working() ) {
_active = true; _active = true;
for ( auto current = d->_sample_groups.begin(); for ( auto current : d->_sample_groups ) {
current != d->_sample_groups.end(); ++current ) { current.second->activate();
SGSampleGroup *sgrp = current->second;
sgrp->activate();
} }
} }
#endif #endif
@ -278,10 +309,8 @@ void SGSoundMgr::stop()
{ {
#ifdef ENABLE_SOUND #ifdef ENABLE_SOUND
// first stop all sample groups // first stop all sample groups
for ( auto current = d->_sample_groups.begin(); for ( auto current : d->_sample_groups ) {
current != d->_sample_groups.end(); ++current ) { current.second->stop();
SGSampleGroup *sgrp = current->second;
sgrp->stop();
} }
// clear all OpenAL sources // clear all OpenAL sources
@ -292,9 +321,8 @@ void SGSoundMgr::stop()
d->_free_sources.clear(); d->_free_sources.clear();
// clear any OpenAL buffers before shutting down // clear any OpenAL buffers before shutting down
for ( auto current = d->_buffers.begin(); for ( auto current : d->_buffers ) {
current != d->_buffers.begin(); ++current ) { refUint ref = current.second;
refUint ref = current->second;
ALuint buffer = ref.id; ALuint buffer = ref.id;
alDeleteBuffers(1, &buffer); alDeleteBuffers(1, &buffer);
testForError("SGSoundMgr::stop: delete buffers"); testForError("SGSoundMgr::stop: delete buffers");
@ -320,10 +348,8 @@ void SGSoundMgr::suspend()
{ {
#ifdef ENABLE_SOUND #ifdef ENABLE_SOUND
if (is_working()) { if (is_working()) {
for ( auto current = d->_sample_groups.begin(); for ( auto current : d->_sample_groups ) {
current != d->_sample_groups.end(); ++current ) { current.second->suspend();
SGSampleGroup *sgrp = current->second;
sgrp->suspend();
} }
_active = false; _active = false;
} }
@ -334,10 +360,8 @@ void SGSoundMgr::resume()
{ {
#ifdef ENABLE_SOUND #ifdef ENABLE_SOUND
if (is_working()) { if (is_working()) {
for ( auto current = d->_sample_groups.begin(); for ( auto current : d->_sample_groups ) {
current != d->_sample_groups.end(); ++current ) { current.second->resume();
SGSampleGroup *sgrp = current->second;
sgrp->resume();
} }
_active = true; _active = true;
} }
@ -355,10 +379,8 @@ void SGSoundMgr::update( double dt )
d->update_pos_and_orientation(); d->update_pos_and_orientation();
} }
for ( auto current = d->_sample_groups.begin(); for ( auto current : d->_sample_groups ) {
current != d->_sample_groups.end(); ++current ) { current.second->update(dt);
SGSampleGroup *sgrp = current->second;
sgrp->update(dt);
} }
if (_changed) { if (_changed) {
@ -376,19 +398,19 @@ if (isNaN(toVec3f(_velocity).data())) printf("NaN in listener velocity\n");
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 ( d->_bad_doppler ) {
double fact = 100.0; float fact = 100.0f;
double mag = length( velocity*fact ); float mag = length( velocity );
if (mag > _sound_velocity) { if (mag > _sound_velocity) {
fact *= _sound_velocity / mag; fact *= _sound_velocity / mag;
} }
velocity *= fact; alDopplerFactor(fact);
} }
} }
alListenerfv( AL_VELOCITY, toVec3f(velocity).data() ); alListenerfv( AL_VELOCITY, toVec3f(velocity).data() );
alDopplerVelocity(_sound_velocity); // alDopplerVelocity(_sound_velocity);
testForError("update"); testForError("update");
_changed = false; _changed = false;
} }

View File

@ -1,75 +0,0 @@
// soundmgr_openal_prviate.hxx -- Implementation details of the soung manager
//
// Sound manager initially written by David Findlay
// <david_j_findlay@yahoo.com.au> 2001
//
// C++-ified by Curtis Olson, started March 2001.
// Modified for the new SoundSystem by Erik Hofman, October 2009
//
// Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
// Copyright (C) 2009 Erik Hofman <erik@ehofman.com>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#ifndef _SG_SOUNDMGR_OPENAL_PRIVATE_HXX
#define _SG_SOUNDMGR_OPENAL_PRIVATE_HXX 1
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <string>
#include <vector>
#include <cmath>
#include <map>
#if defined(__APPLE__)
# include <OpenAL/al.h>
# include <OpenAL/alc.h>
#elif defined(OPENALSDK)
# include <al.h>
# include <alc.h>
#else
# include <AL/al.h>
# include <AL/alc.h>
#endif
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/SGMisc.hxx>
class SGSampleGroup;
struct refUint {
unsigned int refctr;
ALuint id;
refUint() { refctr = 0; id = (ALuint)-1; };
refUint(ALuint i) { refctr = 1; id = i; };
~refUint() {};
};
using buffer_map = std::map < std::string, refUint >;
using sample_group_map = std::map < std::string, SGSharedPtr<SGSampleGroup> >;
inline bool isNaN(float *v) {
return (SGMisc<float>::isNaN(v[0]) || SGMisc<float>::isNaN(v[1]) || SGMisc<float>::isNaN(v[2]));
}
#endif // _SG_SOUNDMGR_OPENAL_PRIVATE_HXX