engine: sound: remove s_cull and s_phs, because they never worked. It's better to write our own occluder in future or use any opensource library

This commit is contained in:
Alibek Omarov 2019-07-09 13:17:10 +03:00
parent be98a228a7
commit 40211efa9a
5 changed files with 9 additions and 541 deletions

View File

@ -1376,20 +1376,10 @@ qboolean CL_GetEntitySpatialization( channel_t *ch )
if( ent->curstate.messagenum != cl.parsecount )
return valid_origin;
#endif
ch->movetype = ent->curstate.movetype;
// setup origin
VectorAverage( ent->curstate.mins, ent->curstate.maxs, ch->origin );
VectorAdd( ch->origin, ent->curstate.origin, ch->origin );
// setup mins\maxs
VectorAdd( ent->curstate.mins, ent->curstate.origin, ch->absmin );
VectorAdd( ent->curstate.maxs, ent->curstate.origin, ch->absmax );
// setup radius
if( ent->model != NULL && ent->model->radius ) ch->radius = ent->model->radius;
else ch->radius = RadiusFromBounds( ent->curstate.mins, ent->curstate.maxs );
return true;
}

View File

@ -855,18 +855,6 @@ void CheckNewDspPresets( void )
DLY_CheckNewStereoDelayVal();
}
/*
===========
DSP_GetGain
(xash dsp interface)
===========
*/
float DSP_GetGain( int idsp )
{
return 1.0f;
}
void SX_Profiling_f( void )
{
portable_samplepair_t testbuffer[512];
@ -904,4 +892,4 @@ void SX_Profiling_f( void )
SX_ReloadRoomFX();
CheckNewDspPresets();
}
}
}

View File

@ -46,40 +46,10 @@ convar_t *s_lerping;
convar_t *s_ambient_level;
convar_t *s_ambient_fade;
convar_t *s_combine_sounds;
convar_t *snd_foliage_db_loss;
convar_t *snd_gain;
convar_t *snd_gain_max;
convar_t *snd_gain_min;
convar_t *snd_mute_losefocus;
convar_t *s_refdist;
convar_t *s_refdb;
convar_t *s_cull; // cull sounds by geometry
convar_t *s_test; // cvar for testing new effects
convar_t *s_phs;
convar_t *s_samplecount;
/*
=============================================================================
SOUND COMMON UTILITES
=============================================================================
*/
// dB = 20 log (amplitude/32768) 0 to -90.3dB
// amplitude = 32768 * 10 ^ (dB/20) 0 to +/- 32768
// gain = amplitude/32768 0 to 1.0
_inline float Gain_To_dB( float gain ) { return 20 * log( gain ); }
_inline float dB_To_Gain ( float dB ) { return pow( 10, dB / 20.0f ); }
_inline float Gain_To_Amplitude( float gain ) { return gain * 32768; }
_inline float Amplitude_To_Gain( float amplitude ) { return amplitude / 32768; }
// convert sound db level to approximate sound source radius,
// used only for determining how much of sound is obscured by world
_inline float dB_To_Radius( float db )
{
return (SND_RADIUS_MIN + (SND_RADIUS_MAX - SND_RADIUS_MIN) * (db - SND_DB_MIN) / (SND_DB_MAX - SND_DB_MIN));
}
/*
=============================================================================
@ -207,74 +177,6 @@ void S_UpdateSoundFade( void )
}
}
/*
=================
SND_ChannelOkToTrace
All new sounds must traceline once,
but cap the max number of tracelines performed per frame
for longer or looping sounds to SND_TRACE_UPDATE_MAX.
=================
*/
qboolean SND_ChannelOkToTrace( channel_t *ch )
{
int i, j;
// always trace first time sound is spatialized
if( ch->bfirstpass ) return true;
// if already traced max channels, return
if( trace_count >= SND_TRACE_UPDATE_MAX )
return false;
// search through all channels starting at g_snd_last_trace_chan index
j = last_trace_chan;
for( i = 0; i < total_channels; i++ )
{
if( &( channels[j] ) == ch )
{
ch->bTraced = true;
trace_count++;
return true;
}
// wrap channel index
if( ++j >= total_channels )
j = 0;
}
// why didn't we find this channel?
return false;
}
/*
=================
SND_ChannelTraceReset
reset counters for traceline limiting per audio update
=================
*/
void SND_ChannelTraceReset( void )
{
int i;
// reset search point - make sure we start counting from a new spot
// in channel list each time
last_trace_chan += SND_TRACE_UPDATE_MAX;
// wrap at total_channels
if( last_trace_chan >= total_channels )
last_trace_chan = last_trace_chan - total_channels;
// reset traceline counter
trace_count = 0;
// reset channel traceline flag
for( i = 0; i < total_channels; i++ )
channels[i].bTraced = false;
}
/*
=================
SND_FStreamIsPlaying
@ -497,278 +399,6 @@ int S_AlterChannel( int entnum, int channel, sfx_t *sfx, int vol, int pitch, int
return false;
}
/*
=================
SND_FadeToNewGain
always ramp channel gain changes over time
returns ramped gain, given new target gain
=================
*/
float SND_FadeToNewGain( channel_t *ch, float gain_new )
{
float speed, frametime;
if( gain_new == -1.0 )
{
// if -1 passed in, just keep fading to existing target
gain_new = ch->ob_gain_target;
}
// if first time updating, store new gain into gain & target, return
// if gain_new is close to existing gain, store new gain into gain & target, return
if( ch->bfirstpass || ( fabs( gain_new - ch->ob_gain ) < 0.01f ))
{
ch->ob_gain = gain_new;
ch->ob_gain_target = gain_new;
ch->ob_gain_inc = 0.0f;
return gain_new;
}
// set up new increment to new target
frametime = s_listener.frametime;
speed = ( frametime / SND_GAIN_FADE_TIME ) * ( gain_new - ch->ob_gain );
ch->ob_gain_inc = fabs( speed );
// ch->ob_gain_inc = fabs( gain_new - ch->ob_gain ) / 10.0f;
ch->ob_gain_target = gain_new;
// if not hit target, keep approaching
if( fabs( ch->ob_gain - ch->ob_gain_target ) > 0.01f )
{
ch->ob_gain = ApproachVal( ch->ob_gain_target, ch->ob_gain, ch->ob_gain_inc );
}
else
{
// close enough, set gain = target
ch->ob_gain = ch->ob_gain_target;
}
return ch->ob_gain;
}
/*
=================
SND_GetGainObscured
drop gain on channel if sound emitter obscured by
world, unbroken windows, closed doors, large solid entities etc.
=================
*/
float SND_GetGainObscured( channel_t *ch, qboolean fplayersound, qboolean flooping )
{
float gain = 1.0f;
vec3_t endpoint;
int count = 1;
pmtrace_t tr;
if( fplayersound ) return gain; // unchanged
// during signon just apply regular state machine since world hasn't been
// created or settled yet...
if( !CL_Active( ))
{
gain = SND_FadeToNewGain( ch, -1.0f );
return gain;
}
// don't do gain obscuring more than once on short one-shot sounds
if( !ch->bfirstpass && !ch->isSentence && !flooping && ( ch->entchannel != CHAN_STREAM ))
{
gain = SND_FadeToNewGain( ch, -1.0f );
return gain;
}
// if long or looping sound, process N channels per frame - set 'processed' flag, clear by
// cycling through all channels - this maintains a cap on traces per frame
if( !SND_ChannelOkToTrace( ch ))
{
// just keep updating fade to existing target gain - no new trace checking
gain = SND_FadeToNewGain( ch, -1.0 );
return gain;
}
// set up traceline from player eyes to sound emitting entity origin
VectorCopy( ch->origin, endpoint );
tr = CL_TraceLine( s_listener.origin, endpoint, PM_STUDIO_IGNORE );
if(( tr.fraction < 1.0f || tr.allsolid || tr.startsolid ) && tr.fraction < 0.99f )
{
// can't see center of sound source:
// build extents based on dB sndlvl of source,
// test to see how many extents are visible,
// drop gain by g_snd_obscured_loss_db per extent hidden
vec3_t endpoints[4];
int i, sndlvl = DIST_MULT_TO_SNDLVL( ch->dist_mult );
vec3_t vecl, vecr, vecl2, vecr2;
vec3_t vsrc_forward;
vec3_t vsrc_right;
vec3_t vsrc_up;
float radius;
// get radius
if( ch->radius > 0 ) radius = ch->radius;
else radius = dB_To_Radius( sndlvl ); // approximate radius from soundlevel
// set up extent endpoints - on upward or downward diagonals, facing player
for( i = 0; i < 4; i++ ) VectorCopy( endpoint, endpoints[i] );
// vsrc_forward is normalized vector from sound source to listener
VectorSubtract( s_listener.origin, endpoint, vsrc_forward );
VectorNormalize( vsrc_forward );
VectorVectors( vsrc_forward, vsrc_right, vsrc_up );
VectorAdd( vsrc_up, vsrc_right, vecl );
// if src above listener, force 'up' vector to point down - create diagonals up & down
if( endpoint[2] > s_listener.origin[2] + ( 10 * 12 ))
vsrc_up[2] = -vsrc_up[2];
VectorSubtract( vsrc_up, vsrc_right, vecr );
VectorNormalize( vecl );
VectorNormalize( vecr );
// get diagonal vectors from sound source
VectorScale( vecl, radius, vecl2 );
VectorScale( vecr, radius, vecr2 );
VectorScale( vecl, (radius / 2.0f), vecl );
VectorScale( vecr, (radius / 2.0f), vecr );
// endpoints from diagonal vectors
VectorAdd( endpoints[0], vecl, endpoints[0] );
VectorAdd( endpoints[1], vecr, endpoints[1] );
VectorAdd( endpoints[2], vecl2, endpoints[2] );
VectorAdd( endpoints[3], vecr2, endpoints[3] );
// drop gain for each point on radius diagonal that is obscured
for( count = 0, i = 0; i < 4; i++ )
{
// UNDONE: some endpoints are in walls - in this case, trace from the wall hit location
tr = CL_TraceLine( s_listener.origin, endpoints[i], PM_STUDIO_IGNORE );
if(( tr.fraction < 1.0f || tr.allsolid || tr.startsolid ) && tr.fraction < 0.99f && !tr.startsolid )
{
// skip first obscured point: at least 2 points + center should be obscured to hear db loss
if( ++count > 1 ) gain = gain * dB_To_Gain( SND_OBSCURED_LOSS_DB );
}
}
}
// crossfade to new gain
gain = SND_FadeToNewGain( ch, gain );
return gain;
}
/*
=================
SND_GetGain
The complete gain calculation, with SNDLVL given in dB is:
GAIN = 1/dist * snd_refdist * 10 ^ (( SNDLVL - snd_refdb - (dist * snd_foliage_db_loss / 1200)) / 20 )
for gain > SND_GAIN_THRESH, start curve smoothing with
GAIN = 1 - 1 / (Y * GAIN ^ SND_GAIN_POWER)
where Y = -1 / ( (SND_GAIN_THRESH ^ SND_GAIN_POWER) * ( SND_GAIN_THRESH - 1 ))
gain curve construction
=================
*/
float SND_GetGain( channel_t *ch, qboolean fplayersound, qboolean flooping, float dist )
{
float gain = snd_gain->value;
if( ch->dist_mult )
{
// test additional attenuation
// at 30c, 14.7psi, 60% humidity, 1000Hz == 0.22dB / 100ft.
// dense foliage is roughly 2dB / 100ft
float additional_dB_loss = snd_foliage_db_loss->value * (dist / 1200);
float additional_dist_mult = pow( 10, additional_dB_loss / 20 );
float relative_dist = dist * ch->dist_mult * additional_dist_mult;
// hard code clamp gain to 10x normal (assumes volume and external clipping)
if( relative_dist > 0.1f )
gain *= ( 1.0f / relative_dist );
else gain *= 10.0f;
// if gain passess threshold, compress gain curve such that gain smoothly approaches 1.0
if( gain > SND_GAIN_COMP_THRESH )
{
float snd_gain_comp_power = SND_GAIN_COMP_EXP_MAX;
int sndlvl = DIST_MULT_TO_SNDLVL( ch->dist_mult );
float Y;
// decrease compression curve fit for higher sndlvl values
if( sndlvl > SND_DB_MED )
{
// snd_gain_power varies from max to min as sndlvl varies from 90 to 140
snd_gain_comp_power = RemapVal((float)sndlvl, SND_DB_MED, SND_DB_MAX, SND_GAIN_COMP_EXP_MAX, SND_GAIN_COMP_EXP_MIN );
}
// calculate crossover point
Y = -1.0f / ( pow( SND_GAIN_COMP_THRESH, snd_gain_comp_power ) * ( SND_GAIN_COMP_THRESH - 1 ));
// calculate compressed gain
gain = 1.0f - 1.0f / (Y * pow( gain, snd_gain_comp_power ));
gain = gain * snd_gain_max->value;
}
if( gain < snd_gain_min->value )
{
// sounds less than snd_gain_min fall off to 0 in distance it took them to fall to snd_gain_min
gain = snd_gain_min->value * ( 2.0f - relative_dist * snd_gain_min->value );
if( gain <= 0.0f ) gain = 0.001f; // don't propagate 0 gain
}
}
if( fplayersound )
{
// player weapon sounds get extra gain - this compensates
// for npc distance effect weapons which mix louder as L+R into L, R
if( ch->entchannel == CHAN_WEAPON )
gain = gain * dB_To_Gain( SND_GAIN_PLAYER_WEAPON_DB );
}
// modify gain if sound source not visible to player
gain = gain * SND_GetGainObscured( ch, fplayersound, flooping );
return gain;
}
/*
=================
SND_CheckPHS
using a 'fat' radius
=================
*/
qboolean SND_CheckPHS( channel_t *ch )
{
mleaf_t *leaf;
if( !s_phs->value )
return true;
if( !ch->dist_mult && ch->entnum )
return true; // no attenuation
if( ch->movetype == MOVETYPE_PUSH )
{
if( Mod_BoxVisible( ch->absmin, ch->absmax, s_listener.pasbytes ))
return true;
}
else
{
leaf = Mod_PointInLeaf( ch->origin, cl.worldmodel->nodes );
if( CHECKVISBIT( s_listener.pasbytes, leaf->cluster ))
return true;
}
return false;
}
/*
=================
S_SpatializeChannel
@ -782,12 +412,10 @@ void S_SpatializeChannel( int *left_vol, int *right_vol, int master_vol, float g
lscale = 1.0f - dot;
// add in distance effect
if( s_cull->value ) scale = gain * rscale / 2;
else scale = ( 1.0f - dist ) * rscale;
scale = ( 1.0f - dist ) * rscale;
*right_vol = (int)( master_vol * scale );
if( s_cull->value ) scale = gain * lscale / 2;
else scale = ( 1.0f - dist ) * lscale;
scale = ( 1.0f - dist ) * lscale;
*left_vol = (int)( master_vol * scale );
*right_vol = bound( 0, *right_vol, 255 );
@ -803,22 +431,15 @@ void SND_Spatialize( channel_t *ch )
{
vec3_t source_vec;
float dist, dot, gain = 1.0f;
qboolean fplayersound = false;
qboolean looping = false;
wavdata_t *pSource;
// anything coming from the view entity will allways be full volume
if( S_IsClient( ch->entnum ))
{
if( !s_cull->value )
{
ch->leftvol = ch->master_vol;
ch->rightvol = ch->master_vol;
return;
}
// sounds coming from listener actually come from a short distance directly in front of listener
fplayersound = true;
ch->leftvol = ch->master_vol;
ch->rightvol = ch->master_vol;
return;
}
pSource = ch->sfx->cache;
@ -828,49 +449,22 @@ void SND_Spatialize( channel_t *ch )
if( !ch->staticsound )
{
if( !CL_GetEntitySpatialization( ch ) || !SND_CheckPHS( ch ))
if( !CL_GetEntitySpatialization( ch ))
{
// origin is null and entity not exist on client
ch->leftvol = ch->rightvol = 0;
ch->bfirstpass = false;
return;
}
}
// source_vec is vector from listener to sound source
// player sounds come from 1' in front of player
if( fplayersound ) VectorScale( s_listener.forward, 12.0f, source_vec );
else VectorSubtract( ch->origin, s_listener.origin, source_vec );
VectorSubtract( ch->origin, s_listener.origin, source_vec );
// normalize source_vec and get distance from listener to source
dist = VectorNormalizeLength( source_vec );
dot = DotProduct( s_listener.right, source_vec );
// a1ba: disabled for better multiplayer
#if 0
// for sounds with a radius, spatialize left/right evenly within the radius
if( ch->radius > 0 && dist < ch->radius )
{
float interval = ch->radius * 0.5f;
float blend = dist - interval;
if( blend < 0 ) blend = 0;
blend /= interval;
// blend is 0.0 - 1.0, from 50% radius -> 100% radius
// at radius * 0.5, dot is 0 (ie: sound centered left/right)
// at radius dot == dot
dot *= blend;
}
#endif
if( s_cull->value )
{
// calculate gain based on distance, atmospheric attenuation, interposed objects
// perform compression as gain approaches 1.0
gain = SND_GetGain( ch, fplayersound, looping, dist );
}
// don't pan sounds with no attenuation
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
@ -879,9 +473,6 @@ void SND_Spatialize( channel_t *ch )
// if playing a word, set volume
VOX_SetChanVol( ch );
// end of first time spatializing sound
if( CL_Active( )) ch->bfirstpass = false;
}
/*
@ -954,16 +545,8 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
target_chan->entchannel = chan;
target_chan->basePitch = pitch;
target_chan->isSentence = false;
target_chan->radius = 0.0f;
target_chan->sfx = sfx;
// initialize gain due to obscured sound source
target_chan->bfirstpass = true;
target_chan->ob_gain = 0.0f;
target_chan->ob_gain_inc = 0.0f;
target_chan->ob_gain_target = 0.0f;
target_chan->bTraced = false;
pSource = NULL;
if( S_TestSoundChar( sfx->name, '!' ))
@ -1074,16 +657,8 @@ void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float
target_chan->entchannel = chan;
target_chan->basePitch = pitch;
target_chan->isSentence = false;
target_chan->radius = 0.0f;
target_chan->sfx = sfx;
// initialize gain due to obscured sound source
target_chan->bfirstpass = true;
target_chan->ob_gain = 0.0f;
target_chan->ob_gain_inc = 0.0f;
target_chan->ob_gain_target = 0.0f;
target_chan->bTraced = false;
pSource = NULL;
if( S_TestSoundChar( sfx->name, '!' ))
@ -1162,7 +737,6 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
wavdata_t *pSource = NULL;
sfx_t *sfx = NULL;
int vol, fvox = 0;
float radius = SND_RADIUS_MAX;
if( !dma.initialized ) return;
sfx = S_GetSfxByHandle( handle );
@ -1224,14 +798,6 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
ch->entchannel = CHAN_STATIC;
ch->basePitch = pitch;
ch->radius = radius;
// initialize gain due to obscured sound source
ch->bfirstpass = true;
ch->ob_gain = 0.0;
ch->ob_gain_inc = 0.0;
ch->ob_gain_target = 0.0;
ch->bTraced = false;
SND_Spatialize( ch );
}
@ -1788,21 +1354,6 @@ static void S_SpatializeRawChannels( void )
dist = VectorNormalizeLength( source_vec );
dot = DotProduct( s_listener.right, source_vec );
// for sounds with a radius, spatialize left/right evenly within the radius
if( ch->radius > 0 && dist < ch->radius )
{
float interval = ch->radius * 0.5f;
float blend = dist - interval;
if( blend < 0 ) blend = 0;
blend /= interval;
// blend is 0.0 - 1.0, from 50% radius -> 100% radius
// at radius * 0.5, dot is 0 (ie: sound centered left/right)
// at radius dot == dot
dot *= blend;
}
// don't pan sounds with no attenuation
if( ch->dist_mult <= 0.0f ) dot = 0.0f;
@ -1997,9 +1548,6 @@ void SND_UpdateSound( void )
s_listener.inmenu = CL_IsInMenu();
s_listener.paused = cl.paused;
if( cl.worldmodel != NULL )
Mod_FatPVS( s_listener.origin, FATPHS_RADIUS, s_listener.pasbytes, world.visbytes, false, !s_phs->value );
// update general area ambient sound sources
S_UpdateAmbientSounds();
@ -2075,14 +1623,7 @@ void SND_UpdateSound( void )
}
}
// to differentiate modes
if( s_cull->value && s_phs->value )
VectorSet( info.color, 0.0f, 1.0f, 0.0f );
else if( s_phs->value )
VectorSet( info.color, 1.0f, 1.0f, 0.0f );
else if( s_cull->value )
VectorSet( info.color, 1.0f, 0.0f, 0.0f );
else VectorSet( info.color, 1.0f, 1.0f, 1.0f );
VectorSet( info.color, 1.0f, 1.0f, 1.0f );
info.index = 0;
Con_NXPrintf( &info, "room_type: %i ----(%i)---- painted: %i\n", idsp_room, total - 1, paintedtime );
@ -2285,16 +1826,8 @@ qboolean S_Init( void )
s_ambient_level = Cvar_Get( "ambient_level", "0.3", FCVAR_ARCHIVE, "volume of environment noises (water and wind)" );
s_ambient_fade = Cvar_Get( "ambient_fade", "1000", FCVAR_ARCHIVE, "rate of volume fading when client is moving" );
s_combine_sounds = Cvar_Get( "s_combine_channels", "0", FCVAR_ARCHIVE, "combine channels with same sounds" );
snd_foliage_db_loss = Cvar_Get( "snd_foliage_db_loss", "4", 0, "foliage loss factor" );
snd_gain_max = Cvar_Get( "snd_gain_max", "1", 0, "gain maximal threshold" );
snd_gain_min = Cvar_Get( "snd_gain_min", "0.01", 0, "gain minimal threshold" );
snd_mute_losefocus = Cvar_Get( "snd_mute_losefocus", "1", FCVAR_ARCHIVE, "silence the audio when game window loses focus" );
s_refdist = Cvar_Get( "s_refdist", "36", 0, "soundlevel reference distance" );
s_refdb = Cvar_Get( "s_refdb", "60", 0, "soundlevel refernce dB" );
snd_gain = Cvar_Get( "snd_gain", "1", 0, "sound default gain" );
s_cull = Cvar_Get( "s_cull", "0", FCVAR_ARCHIVE, "cull sounds by geometry" );
s_test = Cvar_Get( "s_test", "0", 0, "engine developer cvar for quick testing new features" );
s_phs = Cvar_Get( "s_phs", "0", FCVAR_ARCHIVE, "cull sounds by PHS" );
s_samplecount = Cvar_Get( "s_samplecount", "0", FCVAR_ARCHIVE, "sample count (0 for default value)" );
Cmd_AddCommand( "play", S_Play_f, "playing a specified sound file" );

View File

@ -1015,14 +1015,9 @@ void MIX_UpsampleAllPaintbuffers( int end, int count )
void MIX_PaintChannels( int endtime )
{
int end, count;
float dsp_room_gain;
CheckNewDspPresets();
// get dsp preset gain values, update gain crossfaders,
// used when mixing dsp processed buffers into paintbuffer
dsp_room_gain = DSP_GetGain( idsp_room ); // update crossfader - gain only used in MIX_ScaleChannelVolume
while( paintedtime < endtime )
{
// if paintbuffer is smaller than DMA buffer

View File

@ -29,23 +29,6 @@ extern byte *sndpool;
#define SOUND_44k 44100 // 44khz sample rate
#define DMA_MSEC_PER_SAMPLE ((float)(1000.0 / SOUND_DMA_SPEED))
#define SND_TRACE_UPDATE_MAX 2 // max of N channels may be checked for obscured source per frame
#define SND_RADIUS_MAX 240.0f // max sound source radius
#define SND_RADIUS_MIN 24.0f // min sound source radius
#define SND_OBSCURED_LOSS_DB -2.70f // dB loss due to obscured sound source
// calculate gain based on atmospheric attenuation.
// as gain excedes threshold, round off (compress) towards 1.0 using spline
#define SND_GAIN_COMP_EXP_MAX 2.5f // Increasing SND_GAIN_COMP_EXP_MAX fits compression curve
// more closely to original gain curve as it approaches 1.0.
#define SND_GAIN_FADE_TIME 0.25f // xfade seconds between obscuring gain changes
#define SND_GAIN_COMP_EXP_MIN 0.8f
#define SND_GAIN_COMP_THRESH 0.5f // gain value above which gain curve is rounded to approach 1.0
#define SND_DB_MAX 140.0f // max db of any sound source
#define SND_DB_MED 90.0f // db at which compression curve changes
#define SND_DB_MIN 60.0f // min db of any sound source
#define SND_GAIN_PLAYER_WEAPON_DB 2.0f // increase player weapon gain by N dB
// fixed point stuff for real-time resampling
#define FIX_BITS 28
#define FIX_SCALE (1 << FIX_BITS)
@ -56,17 +39,8 @@ extern byte *sndpool;
#define FIX_FRACTION(a,b) (FIX(a)/(b))
#define FIX_FRACPART(a) ((a) & FIX_MASK)
#define SNDLVL_TO_DIST_MULT( sndlvl ) \
( sndlvl ? ((pow( 10, s_refdb->value / 20 ) / pow( 10, (float)sndlvl / 20 )) / s_refdist->value ) : 0 )
#define DIST_MULT_TO_SNDLVL( dist_mult ) \
(int)( dist_mult ? ( 20 * log10( pow( 10, s_refdb->value / 20 ) / (dist_mult * s_refdist->value ))) : 0 )
// NOTE: clipped sound at 32760 to avoid overload
#define CLIP( x ) (( x ) > 32760 ? 32760 : (( x ) < -32760 ? -32760 : ( x )))
#define SWAP( a, b, t ) {(t) = (a); (a) = (b); (b) = (t);}
#define AVG( a, b ) (((a) + (b)) >> 1 )
#define AVG4( a, b, c, d ) (((a) + (b) + (c) + (d)) >> 2 )
#define PAINTBUFFER_SIZE 1024 // 44k: was 512
#define PAINTBUFFER (g_curpaintbuffer)
@ -193,16 +167,6 @@ typedef struct channel_s
qboolean localsound; // it's a local menu sound (not looped, not paused)
mixer_t pMixer;
// sound culling
qboolean bfirstpass; // true if this is first time sound is spatialized
float ob_gain; // gain drop if sound source obscured from listener
float ob_gain_target; // target gain while crossfading between ob_gain & ob_gain_target
float ob_gain_inc; // crossfade increment
qboolean bTraced; // true if channel was already checked this frame for obscuring
float radius; // radius of this sound effect
vec3_t absmin, absmax; // filled in CL_GetEntitySpatialization
int movetype; // to determine point entities
// sentence mixer
int wordIndex;
mixer_t *currentWord; // NULL if sentence is finished
@ -225,8 +189,6 @@ typedef struct
qboolean paused;
qboolean streaming; // playing AVI-file
qboolean stream_paused; // pause only background track
byte pasbytes[(MAX_MAP_LEAFS+7)/8];// actual PHS for current frame
} listener_t;
typedef struct