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()
set(SOURCES ${SOURCES}
soundmgr_openal.cxx
soundmgr_openal_private.hxx
)
endif()

View File

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

View File

@ -41,7 +41,7 @@
// Speed of sound in meters per second
#define SPEED_OF_SOUND 340.3f
#define SPEED_OF_SOUND 340.3
// forward decls
class SGSampleGroup;
@ -202,7 +202,7 @@ public:
*
* @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
@ -299,14 +299,6 @@ public:
*/
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.
*
@ -347,7 +339,7 @@ private:
bool _changed = true;
float _volume = 0.0f;
float _sound_velocity = SPEED_OF_SOUND;
double _sound_velocity = SPEED_OF_SOUND;
// Position of the listener.
SGGeod _geod_pos;
@ -355,7 +347,6 @@ private:
// Velocity of the listener.
SGVec3d _velocity = SGVec3d::zeros();
bool _bad_doppler = false;
std::string _renderer = "unknown";
std::string _vendor = "unknown";
std::string _device_name;

View File

@ -298,6 +298,7 @@ void SGSoundMgr::update( double dt )
SGVec3d velocity = SGVec3d::zeros();
if ( _velocity[0] || _velocity[1] || _velocity[2] ) {
velocity = hlOr.backTransform(_velocity*SG_FEET_TO_METER);
printf("lst vel: %f\n", length(velocity));
}
aax::Vector vel( toVec3f(velocity).data() );
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::Vector ori = orientation.data();
aax::Vector vel = velocity.data();
printf("src vel: %f\n", length(velocity));
aax::Matrix64 mtx(pos, ori);
TRY( emitter.matrix(mtx) );

View File

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