mirror of
https://github.com/UberGames/ioef.git
synced 2024-11-24 05:01:40 +00:00
- Explicitly set distance attenuation model.
- Mute sounds that exceed a certain distance from the listener.
This commit is contained in:
parent
90208be35a
commit
b57a970034
2 changed files with 137 additions and 64 deletions
4
README
4
README
|
@ -116,8 +116,12 @@ New cvars
|
|||
s_alDopplerSpeed - the value passed to alDopplerVelocity
|
||||
s_alMinDistance - the value of AL_REFERENCE_DISTANCE for
|
||||
each source
|
||||
s_alMaxDistance - the maximum distance before sounds start
|
||||
to become inaudible.
|
||||
s_alRolloff - the value of AL_ROLLOFF_FACTOR for each
|
||||
source
|
||||
s_alGraceDistance - after having passed MaxDistance, length
|
||||
until sounds are completely inaudible.
|
||||
s_alMaxSpeakerDistance - ET_SPEAKERS beyond this distance are
|
||||
culled
|
||||
s_alDriver - which OpenAL library to use
|
||||
|
|
|
@ -36,7 +36,9 @@ cvar_t *s_alSources;
|
|||
cvar_t *s_alDopplerFactor;
|
||||
cvar_t *s_alDopplerSpeed;
|
||||
cvar_t *s_alMinDistance;
|
||||
cvar_t *s_alMaxDistance;
|
||||
cvar_t *s_alRolloff;
|
||||
cvar_t *s_alGraceDistance;
|
||||
cvar_t *s_alDriver;
|
||||
cvar_t *s_alDevice;
|
||||
cvar_t *s_alAvailableDevices;
|
||||
|
@ -464,6 +466,9 @@ typedef struct src_s
|
|||
int isLooping; // Is this a looping effect (attached to an entity)
|
||||
int isTracking; // Is this object tracking it's owner
|
||||
|
||||
float curGain; // gain employed if source is within maxdistance.
|
||||
float scaleGain; // Last gain value for this source. 0 if muted.
|
||||
|
||||
qboolean local; // Is this local (relative to the cam)
|
||||
} src_t;
|
||||
|
||||
|
@ -511,6 +516,50 @@ static void _S_AL_SanitiseVector( vec3_t v, int line )
|
|||
|
||||
#define AL_THIRD_PERSON_THRESHOLD_SQ (48.0f*48.0f)
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AL_ScaleGain
|
||||
Adapt the gain if necessary to get a quicker fadeout when the source is too far away.
|
||||
=================
|
||||
*/
|
||||
|
||||
static void S_AL_ScaleGain(src_t *chksrc, vec3_t origin)
|
||||
{
|
||||
float distance;
|
||||
|
||||
if(chksrc->local)
|
||||
distance = VectorLength(origin);
|
||||
else
|
||||
distance = Distance(origin, lastListenerOrigin);
|
||||
|
||||
// If we exceed a certain distance, scale the gain linearly until the sound
|
||||
// vanishes into nothingness.
|
||||
if((distance -= s_alMaxDistance->value) > 0)
|
||||
{
|
||||
float scaleFactor;
|
||||
|
||||
if(distance >= s_alGraceDistance->value)
|
||||
scaleFactor = 0.0f;
|
||||
else
|
||||
scaleFactor = 1.0f - distance / s_alGraceDistance->value;
|
||||
|
||||
scaleFactor *= chksrc->curGain;
|
||||
|
||||
if(chksrc->scaleGain != scaleFactor);
|
||||
{
|
||||
chksrc->scaleGain = scaleFactor;
|
||||
// if(scaleFactor > 0.0f)
|
||||
// Com_Printf("%f\n", scaleFactor);
|
||||
qalSourcef(chksrc->alSource, AL_GAIN, chksrc->scaleGain);
|
||||
}
|
||||
}
|
||||
else if(chksrc->scaleGain != chksrc->curGain)
|
||||
{
|
||||
chksrc->scaleGain = chksrc->curGain;
|
||||
qalSourcef(chksrc->alSource, AL_GAIN, chksrc->scaleGain);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AL_HearingThroughEntity
|
||||
|
@ -616,41 +665,46 @@ static void S_AL_SrcSetup(srcHandle_t src, sfxHandle_t sfx, alSrcPriority_t prio
|
|||
int entity, int channel, qboolean local)
|
||||
{
|
||||
ALuint buffer;
|
||||
src_t *curSource;
|
||||
|
||||
// Mark the SFX as used, and grab the raw AL buffer
|
||||
S_AL_BufferUse(sfx);
|
||||
buffer = S_AL_BufferGet(sfx);
|
||||
|
||||
// Set up src struct
|
||||
srcList[src].lastUsedTime = Sys_Milliseconds();
|
||||
srcList[src].sfx = sfx;
|
||||
srcList[src].priority = priority;
|
||||
srcList[src].entity = entity;
|
||||
srcList[src].channel = channel;
|
||||
srcList[src].isActive = qtrue;
|
||||
srcList[src].isLocked = qfalse;
|
||||
srcList[src].isLooping = qfalse;
|
||||
srcList[src].isTracking = qfalse;
|
||||
srcList[src].local = local;
|
||||
curSource = &srcList[src];
|
||||
|
||||
curSource->lastUsedTime = Sys_Milliseconds();
|
||||
curSource->sfx = sfx;
|
||||
curSource->priority = priority;
|
||||
curSource->entity = entity;
|
||||
curSource->channel = channel;
|
||||
curSource->isActive = qtrue;
|
||||
curSource->isLocked = qfalse;
|
||||
curSource->isLooping = qfalse;
|
||||
curSource->isTracking = qfalse;
|
||||
curSource->curGain = s_alGain->value * s_volume->value;
|
||||
curSource->scaleGain = curSource->curGain;
|
||||
curSource->local = local;
|
||||
|
||||
// Set up OpenAL source
|
||||
qalSourcei(srcList[src].alSource, AL_BUFFER, buffer);
|
||||
qalSourcef(srcList[src].alSource, AL_PITCH, 1.0f);
|
||||
qalSourcef(srcList[src].alSource, AL_GAIN, s_alGain->value * s_volume->value);
|
||||
qalSourcefv(srcList[src].alSource, AL_POSITION, vec3_origin);
|
||||
qalSourcefv(srcList[src].alSource, AL_VELOCITY, vec3_origin);
|
||||
qalSourcei(srcList[src].alSource, AL_LOOPING, AL_FALSE);
|
||||
qalSourcef(srcList[src].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
|
||||
qalSourcei(curSource->alSource, AL_BUFFER, buffer);
|
||||
qalSourcef(curSource->alSource, AL_PITCH, 1.0f);
|
||||
qalSourcef(curSource->alSource, AL_GAIN, curSource->curGain);
|
||||
qalSourcefv(curSource->alSource, AL_POSITION, vec3_origin);
|
||||
qalSourcefv(curSource->alSource, AL_VELOCITY, vec3_origin);
|
||||
qalSourcei(curSource->alSource, AL_LOOPING, AL_FALSE);
|
||||
qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
|
||||
|
||||
if(local)
|
||||
{
|
||||
qalSourcei(srcList[src].alSource, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
qalSourcef(srcList[src].alSource, AL_ROLLOFF_FACTOR, 0.0f);
|
||||
qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
qalSourcei(srcList[src].alSource, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
qalSourcef(srcList[src].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
|
||||
qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -887,6 +941,7 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx
|
|||
|
||||
S_AL_SanitiseVector( sorigin );
|
||||
qalSourcefv( srcList[ src ].alSource, AL_POSITION, sorigin );
|
||||
S_AL_ScaleGain(&srcList[src], sorigin);
|
||||
|
||||
// Start it playing
|
||||
qalSourcePlay(srcList[src].alSource);
|
||||
|
@ -918,6 +973,7 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
|
|||
{
|
||||
int src;
|
||||
sentity_t *sent = &entityList[ entityNum ];
|
||||
src_t *curSource;
|
||||
|
||||
// Do we need to allocate a new source for this entity
|
||||
if( !sent->srcAllocated )
|
||||
|
@ -945,28 +1001,33 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
|
|||
// If this is not set then the looping sound is removed
|
||||
sent->loopAddedThisFrame = qtrue;
|
||||
|
||||
curSource = &srcList[src];
|
||||
|
||||
// UGH
|
||||
// These lines should be called via S_AL_SrcSetup, but we
|
||||
// can't call that yet as it buffers sfxes that may change
|
||||
// with subsequent calls to S_AL_SrcLoop
|
||||
srcList[ src ].entity = entityNum;
|
||||
srcList[ src ].isLooping = qtrue;
|
||||
srcList[ src ].isActive = qtrue;
|
||||
curSource->entity = entityNum;
|
||||
curSource->isLooping = qtrue;
|
||||
curSource->isActive = qtrue;
|
||||
|
||||
if( S_AL_HearingThroughEntity( entityNum ) )
|
||||
{
|
||||
srcList[ src ].local = qtrue;
|
||||
curSource->local = qtrue;
|
||||
|
||||
qalSourcefv( srcList[ src ].alSource, AL_POSITION, vec3_origin );
|
||||
qalSourcefv( srcList[ src ].alSource, AL_VELOCITY, vec3_origin );
|
||||
qalSourcefv( curSource->alSource, AL_POSITION, vec3_origin );
|
||||
qalSourcefv( curSource->alSource, AL_VELOCITY, vec3_origin );
|
||||
}
|
||||
else
|
||||
{
|
||||
srcList[ src ].local = qfalse;
|
||||
curSource->local = qfalse;
|
||||
|
||||
qalSourcefv( srcList[ src ].alSource, AL_POSITION, (ALfloat *)sent->origin );
|
||||
qalSourcefv( srcList[ src ].alSource, AL_VELOCITY, (ALfloat *)velocity );
|
||||
qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sent->origin );
|
||||
qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity );
|
||||
|
||||
}
|
||||
|
||||
S_AL_ScaleGain(curSource, sent->origin);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1028,63 +1089,65 @@ void S_AL_SrcUpdate( void )
|
|||
int i;
|
||||
int entityNum;
|
||||
ALint state;
|
||||
src_t *curSource;
|
||||
|
||||
for(i = 0; i < srcCount; i++)
|
||||
{
|
||||
entityNum = srcList[i].entity;
|
||||
curSource = &srcList[i];
|
||||
|
||||
if(srcList[i].isLocked)
|
||||
if(curSource->isLocked)
|
||||
continue;
|
||||
|
||||
if(!srcList[i].isActive)
|
||||
if(!curSource->isActive)
|
||||
continue;
|
||||
|
||||
// Update source parameters
|
||||
if((s_alGain->modified)||(s_volume->modified))
|
||||
qalSourcef(srcList[i].alSource, AL_GAIN, s_alGain->value * s_volume->value);
|
||||
if((s_alRolloff->modified)&&(!srcList[i].local))
|
||||
qalSourcef(srcList[i].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
|
||||
curSource->curGain = s_alGain->value * s_volume->value;
|
||||
if((s_alRolloff->modified)&&(!curSource->local))
|
||||
qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
|
||||
if(s_alMinDistance->modified)
|
||||
qalSourcef(srcList[i].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
|
||||
qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
|
||||
|
||||
if( srcList[ i ].isLooping )
|
||||
if(curSource->isLooping)
|
||||
{
|
||||
sentity_t *sent = &entityList[ entityNum ];
|
||||
|
||||
// If a looping effect hasn't been touched this frame, kill it
|
||||
if( sent->loopAddedThisFrame )
|
||||
if(sent->loopAddedThisFrame)
|
||||
{
|
||||
// The sound has changed without an intervening removal
|
||||
if( srcList[ i ].isActive && !sent->startLoopingSound &&
|
||||
srcList[ i ].sfx != sent->loopSfx )
|
||||
if(curSource->isActive && !sent->startLoopingSound &&
|
||||
curSource->sfx != sent->loopSfx)
|
||||
{
|
||||
qalSourceStop( srcList[ i ].alSource );
|
||||
qalSourcei( srcList[ i ].alSource, AL_BUFFER, 0 );
|
||||
qalSourceStop(curSource->alSource);
|
||||
qalSourcei(curSource->alSource, AL_BUFFER, 0);
|
||||
sent->startLoopingSound = qtrue;
|
||||
}
|
||||
|
||||
// Ths sound hasn't been started yet
|
||||
if( sent->startLoopingSound )
|
||||
// The sound hasn't been started yet
|
||||
if(sent->startLoopingSound)
|
||||
{
|
||||
S_AL_SrcSetup( i, sent->loopSfx, sent->loopPriority,
|
||||
entityNum, -1, srcList[ i ].local );
|
||||
srcList[ i ].isLooping = qtrue;
|
||||
qalSourcei( srcList[ i ].alSource, AL_LOOPING, AL_TRUE );
|
||||
qalSourcePlay( srcList[ i ].alSource );
|
||||
S_AL_SrcSetup(i, sent->loopSfx, sent->loopPriority,
|
||||
entityNum, -1, curSource->local);
|
||||
curSource->isLooping = qtrue;
|
||||
qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE);
|
||||
qalSourcePlay(curSource->alSource);
|
||||
|
||||
sent->startLoopingSound = qfalse;
|
||||
}
|
||||
|
||||
// Update locality
|
||||
if( srcList[ i ].local)
|
||||
if(curSource->local)
|
||||
{
|
||||
qalSourcei( srcList[ i ].alSource, AL_SOURCE_RELATIVE, AL_TRUE );
|
||||
qalSourcef( srcList[ i ].alSource, AL_ROLLOFF_FACTOR, 0.0f );
|
||||
qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
qalSourcei( srcList[ i ].alSource, AL_SOURCE_RELATIVE, AL_FALSE );
|
||||
qalSourcef( srcList[ i ].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value );
|
||||
qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1093,20 +1156,23 @@ void S_AL_SrcUpdate( void )
|
|||
continue;
|
||||
}
|
||||
|
||||
// Query relativity of source, don't move if it's true
|
||||
qalGetSourcei( srcList[ i ].alSource, AL_SOURCE_RELATIVE, &state );
|
||||
|
||||
// See if it needs to be moved
|
||||
if( srcList[ i ].isTracking && !state )
|
||||
qalSourcefv(srcList[i].alSource, AL_POSITION, entityList[entityNum].origin);
|
||||
|
||||
// Check if it's done, and flag it
|
||||
qalGetSourcei(srcList[i].alSource, AL_SOURCE_STATE, &state);
|
||||
qalGetSourcei(curSource->alSource, AL_SOURCE_STATE, &state);
|
||||
if(state == AL_STOPPED)
|
||||
{
|
||||
S_AL_SrcKill(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Query relativity of source, don't move if it's true
|
||||
qalGetSourcei(curSource->alSource, AL_SOURCE_RELATIVE, &state);
|
||||
|
||||
// See if it needs to be moved
|
||||
if(curSource->isTracking && !state)
|
||||
{
|
||||
qalSourcefv(curSource->alSource, AL_POSITION, entityList[entityNum].origin);
|
||||
S_AL_ScaleGain(curSource, entityList[entityNum].origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1775,7 +1841,9 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
s_alDopplerFactor = Cvar_Get( "s_alDopplerFactor", "1.0", CVAR_ARCHIVE );
|
||||
s_alDopplerSpeed = Cvar_Get( "s_alDopplerSpeed", "2200", CVAR_ARCHIVE );
|
||||
s_alMinDistance = Cvar_Get( "s_alMinDistance", "120", CVAR_CHEAT );
|
||||
s_alRolloff = Cvar_Get( "s_alRolloff", "0.8", CVAR_CHEAT );
|
||||
s_alMaxDistance = Cvar_Get("s_alMaxDistance", "1024", CVAR_CHEAT);
|
||||
s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT);
|
||||
s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT);
|
||||
s_alMaxSpeakerDistance = Cvar_Get( "s_alMaxSpeakerDistance", "1024", CVAR_ARCHIVE );
|
||||
|
||||
s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE );
|
||||
|
@ -1787,7 +1855,7 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
// Device enumeration support (extension currently only exists for windows).
|
||||
// Device enumeration support (extension is implemented reasonably only on Windows right now).
|
||||
if((enumsupport = qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT")))
|
||||
{
|
||||
char devicenames[1024] = "";
|
||||
|
@ -1863,6 +1931,7 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
S_AL_SrcInit( );
|
||||
|
||||
// Set up OpenAL parameters (doppler, etc)
|
||||
qalDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
qalDopplerFactor( s_alDopplerFactor->value );
|
||||
qalDopplerVelocity( s_alDopplerSpeed->value );
|
||||
|
||||
|
|
Loading…
Reference in a new issue