Cleanup EFX code

Add error checking.
Add debug printf()s, enable via EFX_VERBOSE.
This commit is contained in:
dhewg 2012-01-10 17:03:30 +01:00
parent b8f9829255
commit bdbee3543c
5 changed files with 111 additions and 65 deletions

View file

@ -8,8 +8,17 @@
#include "idlib/Str.h" #include "idlib/Str.h"
#include "idlib/Lexer.h" #include "idlib/Lexer.h"
#include "idlib/Heap.h" #include "idlib/Heap.h"
#include "framework/Common.h"
#include "sound/sound.h" #include "sound/sound.h"
#define EFX_VERBOSE 0
#if EFX_VERBOSE
#define EFXprintf(...) do { common->Printf(__VA_ARGS__); } while (false)
#else
#define EFXprintf(...) do { } while (false)
#endif
struct idSoundEffect { struct idSoundEffect {
idSoundEffect(); idSoundEffect();
~idSoundEffect(); ~idSoundEffect();

View file

@ -40,7 +40,7 @@ idSoundEffect::idSoundEffect() :
} }
idSoundEffect::~idSoundEffect() { idSoundEffect::~idSoundEffect() {
if (effect) if (soundSystemLocal.alIsEffect(effect))
soundSystemLocal.alDeleteEffects(1, &effect); soundSystemLocal.alDeleteEffects(1, &effect);
} }
@ -50,12 +50,16 @@ bool idSoundEffect::alloc() {
ALenum e; ALenum e;
soundSystemLocal.alGenEffects(1, &effect); soundSystemLocal.alGenEffects(1, &effect);
if ((e = alGetError()) != AL_NO_ERROR) { e = alGetError();
if (e != AL_NO_ERROR) {
common->Warning("idSoundEffect::alloc: alGenEffects failed: 0x%x", e);
return false; return false;
} }
soundSystemLocal.alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); soundSystemLocal.alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
if ((e = alGetError()) != AL_NO_ERROR) { e = alGetError();
if (e != AL_NO_ERROR) {
common->Warning("idSoundEffect::alloc: alEffecti failed: 0x%x", e);
return false; return false;
} }
@ -111,6 +115,43 @@ bool idEFXFile::FindEffect( idStr &name, ALuint *effect ) {
idEFXFile::ReadEffect idEFXFile::ReadEffect
=============== ===============
*/ */
#define efxi(param, value) \
do { \
ALint _v = value; \
EFXprintf("alEffecti(" #param ", %d)\n", _v); \
soundSystemLocal.alEffecti(effect->effect, param, _v); \
err = alGetError(); \
if (err != AL_NO_ERROR) \
common->Warning("alEffecti(" # param ", %d) " \
"failed: 0x%x", _v, err); \
} while (false)
#define efxf(param, value) \
do { \
ALfloat _v = value; \
EFXprintf("alEffectf(" #param ", %.3f)\n", _v); \
soundSystemLocal.alEffectf(effect->effect, param, _v); \
err = alGetError(); \
if (err != AL_NO_ERROR) \
common->Warning("alEffectf(" # param ", %.3f) " \
"failed: 0x%x", _v, err); \
} while (false)
#define efxfv(param, value0, value1, value2) \
do { \
ALfloat _v[3]; \
_v[0] = value0; \
_v[1] = value1; \
_v[2] = value2; \
EFXprintf("alEffectfv(" #param ", %.3f, %.3f, %.3f)\n", \
_v[0], _v[1], _v[2]); \
soundSystemLocal.alEffectfv(effect->effect, param, _v); \
err = alGetError(); \
if (err != AL_NO_ERROR) \
common->Warning("alEffectfv(" # param ", %.3f, %.3f, %.3f) " \
"failed: 0x%x", _v[0], _v[1], _v[2], err); \
} while (false)
bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) { bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) {
idToken name, token; idToken name, token;
@ -136,6 +177,10 @@ bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) {
return false; return false;
} }
ALenum err;
alGetError();
EFXprintf("Loading EFX effect '%s' (#%u)\n", name.c_str(), effect->effect);
do { do {
if ( !src.ReadToken( &token ) ) { if ( !src.ReadToken( &token ) ) {
src.Error( "idEFXFile::ReadEffect: EOF without closing brace" ); src.Error( "idEFXFile::ReadEffect: EOF without closing brace" );
@ -147,72 +192,59 @@ bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) {
break; break;
} }
ALuint e = effect->effect;
// mappings taken from
// http://repo.or.cz/w/dsound-openal.git/blob/HEAD:/primary.c#l1795
// which are marked with a FIXME, so this is maybe not 100% correct
if ( token == "environment" ) { if ( token == "environment" ) {
// <+KittyCat> the "environment" token should be ignored (efx has nothing equatable to it) // <+KittyCat> the "environment" token should be ignored (efx has nothing equatable to it)
src.ParseInt(); src.ParseInt();
} else if ( token == "environment size" ) { } else if ( token == "environment size" ) {
float size = src.ParseFloat(); float size = src.ParseFloat();
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DENSITY, ((size < 2.0f) ? (size - 1.0f) : 1.0f)); efxf(AL_EAXREVERB_DENSITY, (size < 2.0f) ? (size - 1.0f) : 1.0f);
} else if ( token == "environment diffusion" ) { } else if ( token == "environment diffusion" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DIFFUSION, src.ParseFloat()); efxf(AL_EAXREVERB_DIFFUSION, src.ParseFloat());
} else if ( token == "room" ) { } else if ( token == "room" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_GAIN, mB_to_gain(src.ParseInt())); efxf(AL_EAXREVERB_GAIN, mB_to_gain(src.ParseInt()));
} else if ( token == "room hf" ) { } else if ( token == "room hf" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_GAINHF, mB_to_gain(src.ParseInt())); efxf(AL_EAXREVERB_GAINHF, mB_to_gain(src.ParseInt()));
} else if ( token == "room lf" ) { } else if ( token == "room lf" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_GAINLF, mB_to_gain(src.ParseInt())); efxf(AL_EAXREVERB_GAINLF, mB_to_gain(src.ParseInt()));
} else if ( token == "decay time" ) { } else if ( token == "decay time" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DECAY_TIME, src.ParseFloat()); efxf(AL_EAXREVERB_DECAY_TIME, src.ParseFloat());
} else if ( token == "decay hf ratio" ) { } else if ( token == "decay hf ratio" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DECAY_HFRATIO, src.ParseFloat()); efxf(AL_EAXREVERB_DECAY_HFRATIO, src.ParseFloat());
} else if ( token == "decay lf ratio" ) { } else if ( token == "decay lf ratio" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DECAY_LFRATIO, src.ParseFloat()); efxf(AL_EAXREVERB_DECAY_LFRATIO, src.ParseFloat());
} else if ( token == "reflections" ) { } else if ( token == "reflections" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_REFLECTIONS_GAIN, mB_to_gain(src.ParseInt())); efxf(AL_EAXREVERB_REFLECTIONS_GAIN, mB_to_gain(src.ParseInt()));
} else if ( token == "reflections delay" ) { } else if ( token == "reflections delay" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_REFLECTIONS_DELAY, src.ParseFloat()); efxf(AL_EAXREVERB_REFLECTIONS_DELAY, src.ParseFloat());
} else if ( token == "reflections pan" ) { } else if ( token == "reflections pan" ) {
float fv[3]; efxfv(AL_EAXREVERB_REFLECTIONS_PAN, src.ParseFloat(), src.ParseFloat(), src.ParseFloat());
fv[0] = src.ParseFloat();
fv[1] = src.ParseFloat();
fv[2] = src.ParseFloat();
soundSystemLocal.alEffectfv(e, AL_EAXREVERB_REFLECTIONS_PAN, fv);
} else if ( token == "reverb" ) { } else if ( token == "reverb" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_LATE_REVERB_GAIN, mB_to_gain(src.ParseInt())); efxf(AL_EAXREVERB_LATE_REVERB_GAIN, mB_to_gain(src.ParseInt()));
} else if ( token == "reverb delay" ) { } else if ( token == "reverb delay" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_LATE_REVERB_DELAY, src.ParseFloat()); efxf(AL_EAXREVERB_LATE_REVERB_DELAY, src.ParseFloat());
} else if ( token == "reverb pan" ) { } else if ( token == "reverb pan" ) {
float fv[3]; efxfv(AL_EAXREVERB_LATE_REVERB_PAN, src.ParseFloat(), src.ParseFloat(), src.ParseFloat());
fv[0] = src.ParseFloat();
fv[1] = src.ParseFloat();
fv[2] = src.ParseFloat();
soundSystemLocal.alEffectfv(e, AL_EAXREVERB_LATE_REVERB_PAN, fv);
} else if ( token == "echo time" ) { } else if ( token == "echo time" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_ECHO_TIME, src.ParseFloat()); efxf(AL_EAXREVERB_ECHO_TIME, src.ParseFloat());
} else if ( token == "echo depth" ) { } else if ( token == "echo depth" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_ECHO_DEPTH, src.ParseFloat()); efxf(AL_EAXREVERB_ECHO_DEPTH, src.ParseFloat());
} else if ( token == "modulation time" ) { } else if ( token == "modulation time" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_MODULATION_TIME, src.ParseFloat()); efxf(AL_EAXREVERB_MODULATION_TIME, src.ParseFloat());
} else if ( token == "modulation depth" ) { } else if ( token == "modulation depth" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_MODULATION_DEPTH, src.ParseFloat()); efxf(AL_EAXREVERB_MODULATION_DEPTH, src.ParseFloat());
} else if ( token == "air absorption hf" ) { } else if ( token == "air absorption hf" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, mB_to_gain(src.ParseFloat())); efxf(AL_EAXREVERB_AIR_ABSORPTION_GAINHF, mB_to_gain(src.ParseFloat()));
} else if ( token == "hf reference" ) { } else if ( token == "hf reference" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_HFREFERENCE, src.ParseFloat()); efxf(AL_EAXREVERB_HFREFERENCE, src.ParseFloat());
} else if ( token == "lf reference" ) { } else if ( token == "lf reference" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_LFREFERENCE, src.ParseFloat()); efxf(AL_EAXREVERB_LFREFERENCE, src.ParseFloat());
} else if ( token == "room rolloff factor" ) { } else if ( token == "room rolloff factor" ) {
soundSystemLocal.alEffectf(e, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, src.ParseFloat()); efxf(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, src.ParseFloat());
} else if ( token == "flags" ) { } else if ( token == "flags" ) {
src.ReadTokenOnLine( &token ); src.ReadTokenOnLine( &token );
unsigned int flags = token.GetUnsignedLongValue(); unsigned int flags = token.GetUnsignedLongValue();
soundSystemLocal.alEffecti(e, AL_EAXREVERB_DECAY_HFLIMIT, (flags & 0x20) ? AL_TRUE : AL_FALSE); efxi(AL_EAXREVERB_DECAY_HFLIMIT, (flags & 0x20) ? AL_TRUE : AL_FALSE);
// the other SCALE flags have no equivalent in efx // the other SCALE flags have no equivalent in efx
} else { } else {
src.ReadTokenOnLine( &token ); src.ReadTokenOnLine( &token );

View file

@ -732,11 +732,13 @@ public:
LPALGENEFFECTS alGenEffects; LPALGENEFFECTS alGenEffects;
LPALDELETEEFFECTS alDeleteEffects; LPALDELETEEFFECTS alDeleteEffects;
LPALISEFFECT alIsEffect;
LPALEFFECTI alEffecti; LPALEFFECTI alEffecti;
LPALEFFECTF alEffectf; LPALEFFECTF alEffectf;
LPALEFFECTFV alEffectfv; LPALEFFECTFV alEffectfv;
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
idEFXFile EFXDatabase; idEFXFile EFXDatabase;

View file

@ -345,11 +345,13 @@ void idSoundSystemLocal::Init() {
alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects"); alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects");
alDeleteEffects = (LPALDELETEEFFECTS)alGetProcAddress("alDeleteEffects"); alDeleteEffects = (LPALDELETEEFFECTS)alGetProcAddress("alDeleteEffects");
alIsEffect = (LPALISEFFECT)alGetProcAddress("alIsEffect");
alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti"); alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti");
alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf"); alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf");
alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv"); alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv");
alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots"); alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots");
alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots"); alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots");
alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)alGetProcAddress("alIsAuxiliaryEffectSlot");;
alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti"); alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti");
} else { } else {
common->Printf( "OpenAL: EFX extension not found\n" ); common->Printf( "OpenAL: EFX extension not found\n" );
@ -358,11 +360,13 @@ void idSoundSystemLocal::Init() {
alGenEffects = NULL; alGenEffects = NULL;
alDeleteEffects = NULL; alDeleteEffects = NULL;
alIsEffect = NULL;
alEffecti = NULL; alEffecti = NULL;
alEffectf = NULL; alEffectf = NULL;
alEffectfv = NULL; alEffectfv = NULL;
alGenAuxiliaryEffectSlots = NULL; alGenAuxiliaryEffectSlots = NULL;
alDeleteAuxiliaryEffectSlots = NULL; alDeleteAuxiliaryEffectSlots = NULL;
alIsAuxiliaryEffectSlot = NULL;
alAuxiliaryEffectSloti = NULL; alAuxiliaryEffectSloti = NULL;
} }

View file

@ -49,14 +49,14 @@ void idSoundWorldLocal::Init( idRenderWorld *renderWorld ) {
listenerArea = 0; listenerArea = 0;
listenerAreaName = "Undefined"; listenerAreaName = "Undefined";
if (idSoundSystemLocal::useEFXReverb) { if (idSoundSystemLocal::useEFXReverb && !soundSystemLocal.alIsAuxiliaryEffectSlot(listenerSlot)) {
alGetError(); alGetError();
soundSystemLocal.alGenAuxiliaryEffectSlots(1, &listenerSlot); soundSystemLocal.alGenAuxiliaryEffectSlots(1, &listenerSlot);
ALuint e = alGetError(); ALuint e = alGetError();
if (e != AL_NO_ERROR) { if (e != AL_NO_ERROR) {
common->Warning("idSoundWorldLocal::Init: alGenAuxiliaryEffectSlots failed: %u", e); common->Warning("idSoundWorldLocal::Init: alGenAuxiliaryEffectSlots failed: 0x%x", e);
listenerSlot = 0; listenerSlot = AL_EFFECTSLOT_NULL;
} }
} }
@ -118,9 +118,10 @@ void idSoundWorldLocal::Shutdown() {
AVIClose(); AVIClose();
if (idSoundSystemLocal::useEFXReverb && listenerSlot) { if (idSoundSystemLocal::useEFXReverb && soundSystemLocal.alIsAuxiliaryEffectSlot(listenerSlot)) {
soundSystemLocal.alAuxiliaryEffectSloti(listenerSlot, AL_EFFECTSLOT_EFFECT, AL_EFFECTSLOT_NULL);
soundSystemLocal.alDeleteAuxiliaryEffectSlots(1, &listenerSlot); soundSystemLocal.alDeleteAuxiliaryEffectSlots(1, &listenerSlot);
listenerSlot = 0; listenerSlot = AL_EFFECTSLOT_NULL;
} }
for ( i = 0; i < emitters.Num(); i++ ) { for ( i = 0; i < emitters.Num(); i++ ) {
@ -465,23 +466,25 @@ void idSoundWorldLocal::MixLoop( int current44kHz, int numSpeakers, float *final
alListenerfv( AL_POSITION, listenerPosition ); alListenerfv( AL_POSITION, listenerPosition );
alListenerfv( AL_ORIENTATION, listenerOrientation ); alListenerfv( AL_ORIENTATION, listenerOrientation );
if (idSoundSystemLocal::useEFXReverb) { if (idSoundSystemLocal::useEFXReverb && soundSystemLocal.efxloaded) {
if ( soundSystemLocal.efxloaded ) { ALuint effect = 0;
ALuint effect; idStr s(listenerArea);
idStr defaultStr( "default" );
idStr listenerAreaStr( listenerArea );
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaStr, &effect ); bool found = soundSystemLocal.EFXDatabase.FindEffect(s, &effect);
if (!effect) if (!found) {
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaName, &effect ); s = listenerAreaName;
if (!effect) found = soundSystemLocal.EFXDatabase.FindEffect(s, &effect);
soundSystemLocal.EFXDatabase.FindEffect( defaultStr, &effect ); }
if (!found) {
s = "default";
found = soundSystemLocal.EFXDatabase.FindEffect(s, &effect);
}
// only update if change in settings // only update if change in settings
if ( listenerEffect != effect ) { if (found && listenerEffect != effect) {
listenerEffect = effect; EFXprintf("Switching to EFX '%s' (#%u)\n", s.c_str(), effect);
soundSystemLocal.alAuxiliaryEffectSloti(listenerSlot, AL_EFFECTSLOT_EFFECT, effect); listenerEffect = effect;
} soundSystemLocal.alAuxiliaryEffectSloti(listenerSlot, AL_EFFECTSLOT_EFFECT, effect);
} }
} }
@ -1748,12 +1751,8 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
#endif #endif
alSourcef( chan->openalSource, AL_PITCH, ( slowmoActive && !chan->disallowSlow ) ? ( slowmoSpeed ) : ( 1.0f ) ); alSourcef( chan->openalSource, AL_PITCH, ( slowmoActive && !chan->disallowSlow ) ? ( slowmoSpeed ) : ( 1.0f ) );
if (idSoundSystemLocal::useEFXReverb) { if (idSoundSystemLocal::useEFXReverb)
if (listenerSlot) alSource3i(chan->openalSource, AL_AUXILIARY_SEND_FILTER, listenerSlot, 0, AL_FILTER_NULL);
alSource3i(chan->openalSource, AL_AUXILIARY_SEND_FILTER, listenerSlot, 0, AL_FILTER_NULL);
else
alSource3i(chan->openalSource, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL);
}
#if 0 // TODO how to port this to efx? #if 0 // TODO how to port this to efx?
long lOcclusion = ( enviroSuitActive ? -1150 : 0); long lOcclusion = ( enviroSuitActive ? -1150 : 0);