mirror of
https://github.com/dhewm/dhewm3.git
synced 2024-11-26 22:31:17 +00:00
Port EAX to EFX
First attempt at porting the EAX reverb code to EFX. This only works when the ALC_EXT_EFX extension is supported by the OpenAL vendor (which is not the case for the OSX supplied framework, use OpenAL soft instead). The current stable version of OpenAL Soft (v1.13 as of this writing) can barely handle this additional workload, current master is highly recommended when using this feature.
This commit is contained in:
parent
1ce658e835
commit
ece2adbdcd
9 changed files with 245 additions and 287 deletions
|
@ -104,10 +104,6 @@ If you have questions concerning this license or the applicable additional terms
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ID_OPENAL_EAX
|
||||
# define ID_OPENAL_EAX 0
|
||||
#endif
|
||||
|
||||
// async network
|
||||
|
||||
/*
|
||||
|
|
|
@ -888,8 +888,8 @@ void idSessionLocal::HandleMainMenuCommands( const char *menuCommand ) {
|
|||
}
|
||||
if ( !vcmd.Icmp( "eax" ) ) {
|
||||
if ( cvarSystem->GetCVarBool( "s_useEAXReverb" ) ) {
|
||||
int eax = soundSystem->IsEAXAvailable();
|
||||
switch ( eax ) {
|
||||
int efx = soundSystem->IsEFXAvailable();
|
||||
switch ( efx ) {
|
||||
case 1:
|
||||
// when you restart
|
||||
MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04137" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
|
||||
|
|
|
@ -4,62 +4,35 @@
|
|||
#ifndef __EFXLIBH
|
||||
#define __EFXLIBH
|
||||
|
||||
#if ID_OPENAL_EAX
|
||||
#include <eax4.h>
|
||||
#endif
|
||||
|
||||
#include "idlib/containers/List.h"
|
||||
#include "idlib/Str.h"
|
||||
#include "idlib/Lexer.h"
|
||||
#include "idlib/Heap.h"
|
||||
#include "sound/sound.h"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Class definitions.
|
||||
class idSoundEffect
|
||||
{
|
||||
public:
|
||||
idSoundEffect() {
|
||||
};
|
||||
~idSoundEffect() {
|
||||
if ( data && datasize ) {
|
||||
Mem_Free( data );
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
struct idSoundEffect {
|
||||
idSoundEffect();
|
||||
~idSoundEffect();
|
||||
|
||||
bool alloc();
|
||||
|
||||
idStr name;
|
||||
int datasize;
|
||||
void *data;
|
||||
ALuint effect;
|
||||
};
|
||||
|
||||
class idEFXFile
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
// Protected data members.
|
||||
|
||||
public:
|
||||
// Public data members.
|
||||
|
||||
private:
|
||||
|
||||
class idEFXFile {
|
||||
public:
|
||||
idEFXFile();
|
||||
~idEFXFile();
|
||||
|
||||
bool FindEffect( idStr &name, idSoundEffect **effect, int *index );
|
||||
bool ReadEffect( idLexer &lexer, idSoundEffect *effect );
|
||||
bool FindEffect( idStr &name, ALuint *effect );
|
||||
bool LoadFile( const char *filename, bool OSPath = false );
|
||||
void UnloadFile( void );
|
||||
void Clear( void );
|
||||
|
||||
private:
|
||||
bool ReadEffect( idLexer &lexer, idSoundEffect *effect );
|
||||
|
||||
idList<idSoundEffect *>effects;
|
||||
};
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __EFXLIBH
|
||||
|
|
|
@ -524,11 +524,7 @@ void idSoundSample::Load( void ) {
|
|||
|
||||
// OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default)
|
||||
if ( objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG ) {
|
||||
#if !ID_OPENAL_EAX
|
||||
if ( ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) {
|
||||
#else
|
||||
if ( ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) && ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) ) {
|
||||
#endif
|
||||
alGetError();
|
||||
alGenBuffers( 1, &openalBuffer );
|
||||
if ( alGetError() != AL_NO_ERROR )
|
||||
|
|
|
@ -30,12 +30,40 @@ If you have questions concerning this license or the applicable additional terms
|
|||
|
||||
#include "sound/snd_local.h"
|
||||
|
||||
idSoundEffect::idSoundEffect() :
|
||||
effect(0) {
|
||||
}
|
||||
|
||||
idSoundEffect::~idSoundEffect() {
|
||||
if (effect)
|
||||
soundSystemLocal.alDeleteEffects(1, &effect);
|
||||
}
|
||||
|
||||
bool idSoundEffect::alloc() {
|
||||
alGetError();
|
||||
|
||||
ALenum e;
|
||||
|
||||
soundSystemLocal.alGenEffects(1, &effect);
|
||||
if ((e = alGetError()) != AL_NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
soundSystemLocal.alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||
if ((e = alGetError()) != AL_NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
idEFXFile::idEFXFile
|
||||
===============
|
||||
*/
|
||||
idEFXFile::idEFXFile( void ) { }
|
||||
idEFXFile::idEFXFile( void ) {
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -60,16 +88,16 @@ idEFXFile::~idEFXFile( void ) {
|
|||
idEFXFile::FindEffect
|
||||
===============
|
||||
*/
|
||||
bool idEFXFile::FindEffect( idStr &name, idSoundEffect **effect, int *index ) {
|
||||
bool idEFXFile::FindEffect( idStr &name, ALuint *effect ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < effects.Num(); i++ ) {
|
||||
if ( ( effects[i] ) && ( effects[i]->name == name ) ) {
|
||||
*effect = effects[i];
|
||||
*index = i;
|
||||
if ( effects[i]->name == name ) {
|
||||
*effect = effects[i]->effect;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -79,117 +107,111 @@ idEFXFile::ReadEffect
|
|||
===============
|
||||
*/
|
||||
bool idEFXFile::ReadEffect( idLexer &src, idSoundEffect *effect ) {
|
||||
#if ID_OPENAL_EAX
|
||||
idToken name, token;
|
||||
|
||||
if ( !src.ReadToken( &token ) )
|
||||
return false;
|
||||
|
||||
// reverb effect
|
||||
if ( token == "reverb" ) {
|
||||
EAXREVERBPROPERTIES *reverb = ( EAXREVERBPROPERTIES * )Mem_Alloc( sizeof( EAXREVERBPROPERTIES ) );
|
||||
if ( reverb ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
name = token;
|
||||
|
||||
if ( !src.ReadToken( &token ) ) {
|
||||
Mem_Free( reverb );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( token != "{" ) {
|
||||
src.Error( "idEFXFile::ReadEffect: { not found, found %s", token.c_str() );
|
||||
Mem_Free( reverb );
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if ( !src.ReadToken( &token ) ) {
|
||||
src.Error( "idEFXFile::ReadEffect: EOF without closing brace" );
|
||||
Mem_Free( reverb );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( token == "}" ) {
|
||||
effect->name = name;
|
||||
effect->data = ( void * )reverb;
|
||||
effect->datasize = sizeof( EAXREVERBPROPERTIES );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( token == "environment" ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
reverb->ulEnvironment = token.GetUnsignedLongValue();
|
||||
} else if ( token == "environment size" ) {
|
||||
reverb->flEnvironmentSize = src.ParseFloat();
|
||||
} else if ( token == "environment diffusion" ) {
|
||||
reverb->flEnvironmentDiffusion = src.ParseFloat();
|
||||
} else if ( token == "room" ) {
|
||||
reverb->lRoom = src.ParseInt();
|
||||
} else if ( token == "room hf" ) {
|
||||
reverb->lRoomHF = src.ParseInt();
|
||||
} else if ( token == "room lf" ) {
|
||||
reverb->lRoomLF = src.ParseInt();
|
||||
} else if ( token == "decay time" ) {
|
||||
reverb->flDecayTime = src.ParseFloat();
|
||||
} else if ( token == "decay hf ratio" ) {
|
||||
reverb->flDecayHFRatio = src.ParseFloat();
|
||||
} else if ( token == "decay lf ratio" ) {
|
||||
reverb->flDecayLFRatio = src.ParseFloat();
|
||||
} else if ( token == "reflections" ) {
|
||||
reverb->lReflections = src.ParseInt();
|
||||
} else if ( token == "reflections delay" ) {
|
||||
reverb->flReflectionsDelay = src.ParseFloat();
|
||||
} else if ( token == "reflections pan" ) {
|
||||
reverb->vReflectionsPan.x = src.ParseFloat();
|
||||
reverb->vReflectionsPan.y = src.ParseFloat();
|
||||
reverb->vReflectionsPan.z = src.ParseFloat();
|
||||
} else if ( token == "reverb" ) {
|
||||
reverb->lReverb = src.ParseInt();
|
||||
} else if ( token == "reverb delay" ) {
|
||||
reverb->flReverbDelay = src.ParseFloat();
|
||||
} else if ( token == "reverb pan" ) {
|
||||
reverb->vReverbPan.x = src.ParseFloat();
|
||||
reverb->vReverbPan.y = src.ParseFloat();
|
||||
reverb->vReverbPan.z = src.ParseFloat();
|
||||
} else if ( token == "echo time" ) {
|
||||
reverb->flEchoTime = src.ParseFloat();
|
||||
} else if ( token == "echo depth" ) {
|
||||
reverb->flEchoDepth = src.ParseFloat();
|
||||
} else if ( token == "modulation time" ) {
|
||||
reverb->flModulationTime = src.ParseFloat();
|
||||
} else if ( token == "modulation depth" ) {
|
||||
reverb->flModulationDepth = src.ParseFloat();
|
||||
} else if ( token == "air absorption hf" ) {
|
||||
reverb->flAirAbsorptionHF = src.ParseFloat();
|
||||
} else if ( token == "hf reference" ) {
|
||||
reverb->flHFReference = src.ParseFloat();
|
||||
} else if ( token == "lf reference" ) {
|
||||
reverb->flLFReference = src.ParseFloat();
|
||||
} else if ( token == "room rolloff factor" ) {
|
||||
reverb->flRoomRolloffFactor = src.ParseFloat();
|
||||
} else if ( token == "flags" ) {
|
||||
src.ReadTokenOnLine( &token );
|
||||
reverb->ulFlags = token.GetUnsignedLongValue();
|
||||
} else {
|
||||
src.ReadTokenOnLine( &token );
|
||||
src.Error( "idEFXFile::ReadEffect: Invalid parameter in reverb definition" );
|
||||
Mem_Free( reverb );
|
||||
}
|
||||
} while ( 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ( token != "reverb" ) {
|
||||
// other effect (not supported at the moment)
|
||||
src.Error( "idEFXFile::ReadEffect: Unknown effect definition" );
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
src.ReadTokenOnLine( &token );
|
||||
name = token;
|
||||
|
||||
if ( !src.ReadToken( &token ) )
|
||||
return false;
|
||||
|
||||
if ( token != "{" ) {
|
||||
src.Error( "idEFXFile::ReadEffect: { not found, found %s", token.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if ( !src.ReadToken( &token ) ) {
|
||||
src.Error( "idEFXFile::ReadEffect: EOF without closing brace" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( token == "}" ) {
|
||||
effect->name = name;
|
||||
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" ) {
|
||||
soundSystemLocal.alEffecti(e, AL_EAXREVERB_GAIN, src.ParseInt());
|
||||
} else if ( token == "environment size" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DENSITY, src.ParseFloat());
|
||||
} else if ( token == "environment diffusion" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DIFFUSION, src.ParseFloat());
|
||||
} else if ( token == "room" ) {
|
||||
soundSystemLocal.alEffecti(e, AL_EAXREVERB_GAIN, src.ParseInt());
|
||||
} else if ( token == "room hf" ) {
|
||||
soundSystemLocal.alEffecti(e, AL_EAXREVERB_GAINHF, src.ParseInt());
|
||||
} else if ( token == "room lf" ) {
|
||||
soundSystemLocal.alEffecti(e, AL_EAXREVERB_GAINLF, src.ParseInt());
|
||||
} else if ( token == "decay time" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DECAY_TIME, src.ParseFloat());
|
||||
} else if ( token == "decay hf ratio" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DECAY_HFRATIO, src.ParseFloat());
|
||||
} else if ( token == "decay lf ratio" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_DECAY_LFRATIO, src.ParseFloat());
|
||||
} else if ( token == "reflections" ) {
|
||||
soundSystemLocal.alEffecti(e, AL_EAXREVERB_REFLECTIONS_GAIN, src.ParseInt());
|
||||
} else if ( token == "reflections delay" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_REFLECTIONS_DELAY, src.ParseFloat());
|
||||
} else if ( token == "reflections pan" ) {
|
||||
float fv[3];
|
||||
fv[0] = src.ParseFloat();
|
||||
fv[1] = src.ParseFloat();
|
||||
fv[2] = src.ParseFloat();
|
||||
soundSystemLocal.alEffectfv(e, AL_EAXREVERB_REFLECTIONS_PAN, fv);
|
||||
} else if ( token == "reverb" ) {
|
||||
soundSystemLocal.alEffecti(e, AL_EAXREVERB_LATE_REVERB_GAIN, src.ParseInt());
|
||||
} else if ( token == "reverb delay" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_LATE_REVERB_DELAY, src.ParseFloat());
|
||||
} else if ( token == "reverb pan" ) {
|
||||
float fv[3];
|
||||
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" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_ECHO_TIME, src.ParseFloat());
|
||||
} else if ( token == "echo depth" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_ECHO_DEPTH, src.ParseFloat());
|
||||
} else if ( token == "modulation time" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_MODULATION_TIME, src.ParseFloat());
|
||||
} else if ( token == "modulation depth" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_MODULATION_DEPTH, src.ParseFloat());
|
||||
} else if ( token == "air absorption hf" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, src.ParseFloat());
|
||||
} else if ( token == "hf reference" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_HFREFERENCE, src.ParseFloat());
|
||||
} else if ( token == "lf reference" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_LFREFERENCE, src.ParseFloat());
|
||||
} else if ( token == "room rolloff factor" ) {
|
||||
soundSystemLocal.alEffectf(e, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, src.ParseFloat());
|
||||
} else if ( token == "flags" ) {
|
||||
src.ParseInt(); // TODO no idea what to do with this
|
||||
} else {
|
||||
src.ReadTokenOnLine( &token );
|
||||
src.Error( "idEFXFile::ReadEffect: Invalid parameter in reverb definition" );
|
||||
}
|
||||
} while ( 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
idEFXFile::LoadFile
|
||||
|
@ -215,20 +237,18 @@ bool idEFXFile::LoadFile( const char *filename, bool OSPath ) {
|
|||
|
||||
while ( !src.EndOfFile() ) {
|
||||
idSoundEffect *effect = new idSoundEffect;
|
||||
if ( ReadEffect( src, effect ) ) {
|
||||
effects.Append( effect );
|
||||
|
||||
if (!effect->alloc()) {
|
||||
delete effect;
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReadEffect(src, effect))
|
||||
effects.Append(effect);
|
||||
else
|
||||
delete effect;
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
idEFXFile::UnloadFile
|
||||
===============
|
||||
*/
|
||||
void idEFXFile::UnloadFile( void ) {
|
||||
Clear();
|
||||
}
|
||||
|
|
|
@ -33,15 +33,18 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#ifdef _WIN32
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#include <alext.h>
|
||||
// broken OpenAL SDK ?
|
||||
#define ID_ALCHAR (ALubyte *)
|
||||
#elif defined( MACOS_X )
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#include <OpenAL/alext.h>
|
||||
#define ID_ALCHAR
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alext.h>
|
||||
#define ID_ALCHAR
|
||||
#endif
|
||||
|
||||
|
@ -595,7 +598,8 @@ public:
|
|||
idVec3 listenerQU; // position in "quake units"
|
||||
int listenerArea;
|
||||
idStr listenerAreaName;
|
||||
int listenerEnvironmentID;
|
||||
ALuint listenerEffect;
|
||||
ALuint listenerSlot;
|
||||
|
||||
int gameMsec;
|
||||
int game44kHz;
|
||||
|
@ -679,7 +683,7 @@ public:
|
|||
|
||||
virtual void PrintMemInfo( MemInfo_t *mi );
|
||||
|
||||
virtual int IsEAXAvailable( void );
|
||||
virtual int IsEFXAvailable( void );
|
||||
|
||||
//-------------------------
|
||||
|
||||
|
@ -725,19 +729,22 @@ public:
|
|||
ALCcontext *openalContext;
|
||||
ALsizei openalSourceCount;
|
||||
openalSource_t openalSources[256];
|
||||
#if ID_OPENAL_EAX
|
||||
EAXSet alEAXSet;
|
||||
EAXGet alEAXGet;
|
||||
EAXSetBufferMode alEAXSetBufferMode;
|
||||
EAXGetBufferMode alEAXGetBufferMode;
|
||||
#endif
|
||||
|
||||
LPALGENEFFECTS alGenEffects;
|
||||
LPALDELETEEFFECTS alDeleteEffects;
|
||||
LPALEFFECTI alEffecti;
|
||||
LPALEFFECTF alEffectf;
|
||||
LPALEFFECTFV alEffectfv;
|
||||
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
|
||||
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
|
||||
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
|
||||
|
||||
idEFXFile EFXDatabase;
|
||||
bool efxloaded;
|
||||
// latches
|
||||
static bool useEAXReverb;
|
||||
static bool useEFXReverb;
|
||||
// mark available during initialization, or through an explicit test
|
||||
static int EAXAvailable;
|
||||
|
||||
static int EFXAvailable;
|
||||
|
||||
static idCVar s_noSound;
|
||||
static idCVar s_quadraticFalloff;
|
||||
|
@ -767,7 +774,6 @@ public:
|
|||
static idCVar s_libOpenAL;
|
||||
static idCVar s_useOpenAL;
|
||||
static idCVar s_useEAXReverb;
|
||||
static idCVar s_muteEAXReverb;
|
||||
static idCVar s_decompressionLimit;
|
||||
|
||||
static idCVar s_slowAttenuate;
|
||||
|
|
|
@ -69,22 +69,19 @@ idCVar idSoundSystemLocal::s_enviroSuitVolumeScale( "s_enviroSuitVolumeScale", "
|
|||
idCVar idSoundSystemLocal::s_skipHelltimeFX( "s_skipHelltimeFX", "0", CVAR_SOUND | CVAR_BOOL, "" );
|
||||
|
||||
#if ID_OPENAL
|
||||
// off by default. OpenAL DLL gets loaded on-demand
|
||||
idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "openal32.dll", CVAR_SOUND | CVAR_ARCHIVE, "Deprecated, kept for compability" );
|
||||
idCVar idSoundSystemLocal::s_useOpenAL( "s_useOpenAL", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "Deprecated, kept for compability" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use EAX reverb" );
|
||||
idCVar idSoundSystemLocal::s_muteEAXReverb( "s_muteEAXReverb", "0", CVAR_SOUND | CVAR_BOOL, "mute eax reverb" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ARCHIVE, "use EFX reverb" );
|
||||
idCVar idSoundSystemLocal::s_decompressionLimit( "s_decompressionLimit", "6", CVAR_SOUND | CVAR_INTEGER | CVAR_ARCHIVE, "specifies maximum uncompressed sample length in seconds" );
|
||||
#else
|
||||
idCVar idSoundSystemLocal::s_libOpenAL( "s_libOpenAL", "openal32.dll", CVAR_SOUND | CVAR_ARCHIVE, "OpenAL is not supported in this build" );
|
||||
idCVar idSoundSystemLocal::s_useOpenAL( "s_useOpenAL", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "OpenAL is not supported in this build" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "EAX not available in this build" );
|
||||
idCVar idSoundSystemLocal::s_muteEAXReverb( "s_muteEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "mute eax reverb" );
|
||||
idCVar idSoundSystemLocal::s_useEAXReverb( "s_useEAXReverb", "0", CVAR_SOUND | CVAR_BOOL | CVAR_ROM, "EFX not available in this build" );
|
||||
idCVar idSoundSystemLocal::s_decompressionLimit( "s_decompressionLimit", "6", CVAR_SOUND | CVAR_INTEGER | CVAR_ROM, "specifies maximum uncompressed sample length in seconds" );
|
||||
#endif
|
||||
|
||||
bool idSoundSystemLocal::useEAXReverb = false;
|
||||
int idSoundSystemLocal::EAXAvailable = -1;
|
||||
bool idSoundSystemLocal::useEFXReverb = false;
|
||||
int idSoundSystemLocal::EFXAvailable = -1;
|
||||
|
||||
idSoundSystemLocal soundSystemLocal;
|
||||
idSoundSystem *soundSystem = &soundSystemLocal;
|
||||
|
@ -161,9 +158,6 @@ void ListSounds_f( const idCmdArgs &args ) {
|
|||
common->Printf( "%8d total sounds\n", totalSounds );
|
||||
common->Printf( "%8d total samples loaded\n", totalSamples );
|
||||
common->Printf( "%8d kB total system memory used\n", totalMemory >> 10 );
|
||||
#if ID_OPENAL
|
||||
common->Printf( "%8d kB total OpenAL audio memory used\n", ( alGetInteger( alGetEnumValue( "AL_EAX_RAM_SIZE" ) ) - alGetInteger( alGetEnumValue( "AL_EAX_RAM_FREE" ) ) ) >> 10 );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -330,9 +324,9 @@ void idSoundSystemLocal::Init() {
|
|||
|
||||
// set up openal device and context
|
||||
common->StartupVariable( "s_useOpenAL", true );
|
||||
common->StartupVariable( "s_useEAXReverb", true );
|
||||
|
||||
common->Printf( "Setup OpenAL device and context... " );
|
||||
|
||||
openalDevice = alcOpenDevice( NULL );
|
||||
openalContext = alcCreateContext( openalDevice, NULL );
|
||||
alcMakeContextCurrent( openalContext );
|
||||
|
@ -344,38 +338,33 @@ void idSoundSystemLocal::Init() {
|
|||
common->Printf( "AL_RENDERER: %s\n", alGetString(AL_RENDERER));
|
||||
common->Printf( "AL_EXTENSIONS: %s\n", alGetString(AL_EXTENSIONS));
|
||||
|
||||
#if ID_OPENAL_EAX
|
||||
// try to obtain EAX extensions
|
||||
if ( idSoundSystemLocal::s_useEAXReverb.GetBool() && alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) {
|
||||
alEAXSet = (EAXSet)alGetProcAddress( ID_ALCHAR "EAXSet" );
|
||||
alEAXGet = (EAXGet)alGetProcAddress( ID_ALCHAR "EAXGet" );
|
||||
common->Printf( "OpenAL: found EAX 4.0 extension\n" );
|
||||
EAXAvailable = 1;
|
||||
} else {
|
||||
common->Printf( "OpenAL: EAX 4.0 extension not found\n" );
|
||||
idSoundSystemLocal::s_useEAXReverb.SetBool( false );
|
||||
alEAXSet = (EAXSet)NULL;
|
||||
alEAXGet = (EAXGet)NULL;
|
||||
EAXAvailable = 0;
|
||||
}
|
||||
#else
|
||||
common->Printf("OpenAL: EAX 4.0 not supported in this build\n");
|
||||
idSoundSystemLocal::s_useEAXReverb.SetBool( false );
|
||||
EAXAvailable = 0;
|
||||
#endif
|
||||
// try to obtain EFX extensions
|
||||
if (alcIsExtensionPresent(openalDevice, "ALC_EXT_EFX")) {
|
||||
common->Printf( "OpenAL: found EFX extension\n" );
|
||||
EFXAvailable = 1;
|
||||
|
||||
#if ID_OPENAL_EAX
|
||||
// try to obtain EAX-RAM extension - not required for operation
|
||||
if ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) {
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)alGetProcAddress( ID_ALCHAR "EAXSetBufferMode" );
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)alGetProcAddress( ID_ALCHAR "EAXGetBufferMode" );
|
||||
common->Printf( "OpenAL: found EAX-RAM extension, %dkB\\%dkB\n", alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_FREE" ) ) / 1024, alGetInteger( alGetEnumValue( ID_ALCHAR "AL_EAX_RAM_SIZE" ) ) / 1024 );
|
||||
alGenEffects = (LPALGENEFFECTS)alGetProcAddress("alGenEffects");
|
||||
alDeleteEffects = (LPALDELETEEFFECTS)alGetProcAddress("alDeleteEffects");
|
||||
alEffecti = (LPALEFFECTI)alGetProcAddress("alEffecti");
|
||||
alEffectf = (LPALEFFECTF)alGetProcAddress("alEffectf");
|
||||
alEffectfv = (LPALEFFECTFV)alGetProcAddress("alEffectfv");
|
||||
alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)alGetProcAddress("alGenAuxiliaryEffectSlots");
|
||||
alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)alGetProcAddress("alDeleteAuxiliaryEffectSlots");
|
||||
alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)alGetProcAddress("alAuxiliaryEffectSloti");
|
||||
} else {
|
||||
alEAXSetBufferMode = (EAXSetBufferMode)NULL;
|
||||
alEAXGetBufferMode = (EAXGetBufferMode)NULL;
|
||||
common->Printf( "OpenAL: no EAX-RAM extension\n" );
|
||||
common->Printf( "OpenAL: EFX extension not found\n" );
|
||||
EFXAvailable = 0;
|
||||
idSoundSystemLocal::s_useEAXReverb.SetBool( false );
|
||||
|
||||
alGenEffects = NULL;
|
||||
alDeleteEffects = NULL;
|
||||
alEffecti = NULL;
|
||||
alEffectf = NULL;
|
||||
alEffectfv = NULL;
|
||||
alGenAuxiliaryEffectSlots = NULL;
|
||||
alDeleteAuxiliaryEffectSlots = NULL;
|
||||
alAuxiliaryEffectSloti = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ALuint handle;
|
||||
openalSourceCount = 0;
|
||||
|
@ -403,11 +392,13 @@ void idSoundSystemLocal::Init() {
|
|||
|
||||
common->Printf( "OpenAL: found %s\n", alcGetString( openalDevice, ALC_DEVICE_SPECIFIER ) );
|
||||
common->Printf( "OpenAL: found %d hardware voices\n", openalSourceCount );
|
||||
common->Printf( "ALC_EXTENSIONS: %s\n", alcGetString(openalDevice, ALC_EXTENSIONS));
|
||||
|
||||
// adjust source count to allow for at least eight stereo sounds to play
|
||||
openalSourceCount -= 8;
|
||||
|
||||
useEAXReverb = idSoundSystemLocal::s_useEAXReverb.GetBool();
|
||||
useEFXReverb = idSoundSystemLocal::s_useEAXReverb.GetBool();
|
||||
efxloaded = false;
|
||||
|
||||
cmdSystem->AddCommand( "listSounds", ListSounds_f, CMD_FL_SOUND, "lists all sounds" );
|
||||
cmdSystem->AddCommand( "listSoundDecoders", ListSoundDecoders_f, CMD_FL_SOUND, "list active sound decoders" );
|
||||
|
@ -427,7 +418,7 @@ idSoundSystemLocal::Shutdown
|
|||
void idSoundSystemLocal::Shutdown() {
|
||||
ShutdownHW();
|
||||
|
||||
// EAX or not, the list needs to be cleared
|
||||
// EFX or not, the list needs to be cleared
|
||||
EFXDatabase.Clear();
|
||||
|
||||
efxloaded = false;
|
||||
|
@ -991,7 +982,7 @@ void idSoundSystemLocal::BeginLevelLoad() {
|
|||
soundCache->BeginLevelLoad();
|
||||
|
||||
if ( efxloaded ) {
|
||||
EFXDatabase.UnloadFile();
|
||||
EFXDatabase.Clear();
|
||||
efxloaded = false;
|
||||
}
|
||||
}
|
||||
|
@ -1007,7 +998,9 @@ void idSoundSystemLocal::EndLevelLoad( const char *mapstring ) {
|
|||
}
|
||||
soundCache->EndLevelLoad();
|
||||
|
||||
#if ID_OPENAL_EAX
|
||||
if (!useEFXReverb)
|
||||
return;
|
||||
|
||||
idStr efxname( "efxs/" );
|
||||
idStr mapname( mapstring );
|
||||
|
||||
|
@ -1022,7 +1015,6 @@ void idSoundSystemLocal::EndLevelLoad( const char *mapstring ) {
|
|||
} else {
|
||||
common->Printf("sound: missing %s\n", efxname.c_str() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1120,13 +1112,7 @@ void idSoundSystemLocal::FreeOpenALSource( ALuint handle ) {
|
|||
if ( openalSources[i].chan ) {
|
||||
openalSources[i].chan->openalSource = 0;
|
||||
}
|
||||
#if ID_OPENAL_EAX
|
||||
// Reset source EAX ROOM level when freeing stereo source
|
||||
if ( openalSources[i].stereo && alEAXSet ) {
|
||||
long Room = EAXSOURCE_DEFAULTROOM;
|
||||
alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_ROOM, openalSources[i].handle, &Room, sizeof(Room));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize structure
|
||||
openalSources[i].startTime = 0;
|
||||
openalSources[i].chan = NULL;
|
||||
|
@ -1300,35 +1286,13 @@ void idSoundSystemLocal::PrintMemInfo( MemInfo_t *mi ) {
|
|||
|
||||
/*
|
||||
===============
|
||||
idSoundSystemLocal::IsEAXAvailable
|
||||
idSoundSystemLocal::IsEFXAvailable
|
||||
===============
|
||||
*/
|
||||
int idSoundSystemLocal::IsEAXAvailable( void ) {
|
||||
#if !ID_OPENAL || !ID_OPENAL_EAX
|
||||
int idSoundSystemLocal::IsEFXAvailable( void ) {
|
||||
#if !ID_OPENAL
|
||||
return -1;
|
||||
#else
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
|
||||
if ( EAXAvailable != -1 ) {
|
||||
return EAXAvailable;
|
||||
}
|
||||
|
||||
// when dynamically loading the OpenAL subsystem, we need to get a context before alIsExtensionPresent would work
|
||||
device = alcOpenDevice( NULL );
|
||||
context = alcCreateContext( device, NULL );
|
||||
alcMakeContextCurrent( context );
|
||||
if ( alIsExtensionPresent( ID_ALCHAR "EAX4.0" ) ) {
|
||||
alcMakeContextCurrent( NULL );
|
||||
alcDestroyContext( context );
|
||||
alcCloseDevice( device );
|
||||
EAXAvailable = 1;
|
||||
return 1;
|
||||
}
|
||||
alcMakeContextCurrent( NULL );
|
||||
alcDestroyContext( context );
|
||||
alcCloseDevice( device );
|
||||
EAXAvailable = 0;
|
||||
return 0;
|
||||
return EFXAvailable;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -48,7 +48,17 @@ void idSoundWorldLocal::Init( idRenderWorld *renderWorld ) {
|
|||
listenerQU.Zero();
|
||||
listenerArea = 0;
|
||||
listenerAreaName = "Undefined";
|
||||
listenerEnvironmentID = -2;
|
||||
|
||||
if (idSoundSystemLocal::useEFXReverb) {
|
||||
alGetError();
|
||||
|
||||
soundSystemLocal.alGenAuxiliaryEffectSlots(1, &listenerSlot);
|
||||
ALuint e = alGetError();
|
||||
if (e != AL_NO_ERROR) {
|
||||
common->Warning("idSoundWorldLocal::Init: alGenAuxiliaryEffectSlots failed: %u", e);
|
||||
listenerSlot = 0;
|
||||
}
|
||||
}
|
||||
|
||||
gameMsec = 0;
|
||||
game44kHz = 0;
|
||||
|
@ -108,6 +118,11 @@ void idSoundWorldLocal::Shutdown() {
|
|||
|
||||
AVIClose();
|
||||
|
||||
if (idSoundSystemLocal::useEFXReverb && listenerSlot) {
|
||||
soundSystemLocal.alDeleteAuxiliaryEffectSlots(1, &listenerSlot);
|
||||
listenerSlot = 0;
|
||||
}
|
||||
|
||||
for ( i = 0; i < emitters.Num(); i++ ) {
|
||||
if ( emitters[i] ) {
|
||||
delete emitters[i];
|
||||
|
@ -450,39 +465,25 @@ void idSoundWorldLocal::MixLoop( int current44kHz, int numSpeakers, float *final
|
|||
alListenerfv( AL_POSITION, listenerPosition );
|
||||
alListenerfv( AL_ORIENTATION, listenerOrientation );
|
||||
|
||||
#if ID_OPENAL_EAX
|
||||
if ( soundSystemLocal.s_useEAXReverb.GetBool() ) {
|
||||
if (idSoundSystemLocal::useEFXReverb) {
|
||||
if ( soundSystemLocal.efxloaded ) {
|
||||
idSoundEffect *effect = NULL;
|
||||
int EnvironmentID = -1;
|
||||
ALuint effect;
|
||||
idStr defaultStr( "default" );
|
||||
idStr listenerAreaStr( listenerArea );
|
||||
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaStr, &effect, &EnvironmentID );
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaStr, &effect );
|
||||
if (!effect)
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaName, &effect, &EnvironmentID );
|
||||
soundSystemLocal.EFXDatabase.FindEffect( listenerAreaName, &effect );
|
||||
if (!effect)
|
||||
soundSystemLocal.EFXDatabase.FindEffect( defaultStr, &effect, &EnvironmentID );
|
||||
soundSystemLocal.EFXDatabase.FindEffect( defaultStr, &effect );
|
||||
|
||||
// only update if change in settings
|
||||
if ( soundSystemLocal.s_muteEAXReverb.GetBool() || ( listenerEnvironmentID != EnvironmentID ) ) {
|
||||
EAXREVERBPROPERTIES EnvironmentParameters;
|
||||
|
||||
// get area reverb setting from EAX Manager
|
||||
if ( ( effect ) && ( effect->data) && ( memcpy( &EnvironmentParameters, effect->data, effect->datasize ) ) ) {
|
||||
if ( soundSystemLocal.s_muteEAXReverb.GetBool() ) {
|
||||
EnvironmentParameters.lRoom = -10000;
|
||||
EnvironmentID = -2;
|
||||
}
|
||||
if ( soundSystemLocal.alEAXSet ) {
|
||||
soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_FXSlot0, EAXREVERB_ALLPARAMETERS, 0, &EnvironmentParameters, sizeof( EnvironmentParameters ) );
|
||||
}
|
||||
}
|
||||
listenerEnvironmentID = EnvironmentID;
|
||||
if ( listenerEffect != effect ) {
|
||||
listenerEffect = effect;
|
||||
soundSystemLocal.alAuxiliaryEffectSloti(listenerSlot, AL_EFFECTSLOT_EFFECT, effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// debugging option to mute all but a single soundEmitter
|
||||
if ( idSoundSystemLocal::s_singleEmitter.GetInteger() > 0 && idSoundSystemLocal::s_singleEmitter.GetInteger() < emitters.Num() ) {
|
||||
|
@ -1741,13 +1742,20 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
|
|||
alSourcef( chan->openalSource, AL_GAIN, ( volume ) < ( 1.0f ) ? ( volume ) : ( 1.0f ) );
|
||||
}
|
||||
alSourcei( chan->openalSource, AL_LOOPING, ( looping && chan->soundShader->entries[0]->hardwareBuffer ) ? AL_TRUE : AL_FALSE );
|
||||
// TODO is this correct? (was: "!defined(MACOS_X)")
|
||||
#if ID_OPENAL_EAX
|
||||
#if 1
|
||||
alSourcef( chan->openalSource, AL_REFERENCE_DISTANCE, mind );
|
||||
alSourcef( chan->openalSource, AL_MAX_DISTANCE, maxd );
|
||||
#endif
|
||||
alSourcef( chan->openalSource, AL_PITCH, ( slowmoActive && !chan->disallowSlow ) ? ( slowmoSpeed ) : ( 1.0f ) );
|
||||
#if ID_OPENAL_EAX
|
||||
|
||||
if (idSoundSystemLocal::useEFXReverb) {
|
||||
if (listenerSlot)
|
||||
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?
|
||||
long lOcclusion = ( enviroSuitActive ? -1150 : 0);
|
||||
if ( soundSystemLocal.alEAXSet ) {
|
||||
soundSystemLocal.alEAXSet( &EAXPROPERTYID_EAX_Source, EAXSOURCE_OCCLUSION, chan->openalSource, &lOcclusion, sizeof(lOcclusion) );
|
||||
|
@ -1770,11 +1778,6 @@ void idSoundWorldLocal::AddChannelContribution( idSoundEmitterLocal *sound, idSo
|
|||
chan->lastopenalStreamingBuffer[1] = chan->openalStreamingBuffer[1];
|
||||
chan->lastopenalStreamingBuffer[2] = chan->openalStreamingBuffer[2];
|
||||
alGenBuffers( 3, &chan->openalStreamingBuffer[0] );
|
||||
#if ID_OPENAL_EAX
|
||||
if ( soundSystemLocal.alEAXSetBufferMode ) {
|
||||
soundSystemLocal.alEAXSetBufferMode( 3, &chan->openalStreamingBuffer[0], alGetEnumValue( ID_ALCHAR "AL_STORAGE_ACCESSIBLE" ) );
|
||||
}
|
||||
#endif
|
||||
buffers[0] = chan->openalStreamingBuffer[0];
|
||||
buffers[1] = chan->openalStreamingBuffer[1];
|
||||
buffers[2] = chan->openalStreamingBuffer[2];
|
||||
|
|
|
@ -341,8 +341,8 @@ public:
|
|||
// prints memory info
|
||||
virtual void PrintMemInfo( MemInfo_t *mi ) = 0;
|
||||
|
||||
// is EAX support present - -1: disabled at compile time, 0: no suitable hardware, 1: ok, 2: failed to load OpenAL DLL
|
||||
virtual int IsEAXAvailable( void ) = 0;
|
||||
// is EFX support present - -1: disabled at compile time, 0: no suitable hardware, 1: ok
|
||||
virtual int IsEFXAvailable( void ) = 0;
|
||||
};
|
||||
|
||||
extern idSoundSystem *soundSystem;
|
||||
|
|
Loading…
Reference in a new issue