Add a head-dampening option

This simulates occlusion of the player's head for sounds coming from behind,
when outputing to mono or stereo
This commit is contained in:
Chris Robinson 2009-12-08 14:18:07 -08:00
parent 1694e5bd12
commit 84d2d623b6
4 changed files with 40 additions and 6 deletions

View File

@ -1711,6 +1711,15 @@ ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
device->Bs2bLevel = GetConfigValueInt(NULL, "cf_level", 0);
if(aluChannelsFromFormat(device->Format) <= 2)
{
device->HeadDampen = GetConfigValueFloat(NULL, "head_dampen", DEFAULT_HEAD_DAMPEN);
device->HeadDampen = __min(device->HeadDampen, 1.0f);
device->HeadDampen = __max(device->HeadDampen, 0.0f);
}
else
device->HeadDampen = 0.0f;
// Find a playback device to open
SuspendContext(NULL);
for(i = 0;BackendList[i].Init;i++)

View File

@ -685,17 +685,11 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource,
ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f)*scale);
ConeHF = (1.0f+(OuterGainHF-1.0f)*scale);
DryMix *= ConeVolume;
if(ALSource->DryGainHFAuto)
DryGainHF *= ConeHF;
}
else if(Angle > OuterAngle)
{
ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f));
ConeHF = (1.0f+(OuterGainHF-1.0f));
DryMix *= ConeVolume;
if(ALSource->DryGainHFAuto)
DryGainHF *= ConeHF;
}
else
{
@ -703,6 +697,24 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource,
ConeHF = 1.0f;
}
// Apply some high-frequency attenuation for sources behind the listener
// NOTE: This should be aluDotproduct({0,0,-1}, ListenerToSource), however
// that is equivalent to aluDotproduct({0,0,1}, SourceToListener), which is
// the same as SourceToListener[2]
Angle = aluAcos(SourceToListener[2]) * 180.0f/M_PI;
// Sources within the minimum distance attenuate less
if(OrigDist < MinDist)
Angle *= OrigDist/MinDist;
if(Angle > 90.0f)
{
ALfloat scale = (Angle-90.0f) / (180.1f-90.0f); // .1 to account for fp errors
ConeHF *= 1.0f - (ALContext->Device->HeadDampen*scale);
}
DryMix *= ConeVolume;
if(ALSource->DryGainHFAuto)
DryGainHF *= ConeHF;
// Clamp to Min/Max Gain
DryMix = __min(DryMix,MaxVolume);
DryMix = __max(DryMix,MinVolume);

View File

@ -163,6 +163,8 @@ static __inline void al_print(const char *fname, unsigned int line, const char *
#define LOWPASSFREQCUTOFF (5000)
#define DEFAULT_HEAD_DAMPEN (0.25f)
// Find the next power-of-2 for non-power-of-2 numbers.
static __inline ALuint NextPowerOf2(ALuint value)
@ -269,6 +271,9 @@ struct ALCdevice_struct
struct bs2b *Bs2b;
ALCint Bs2bLevel;
// Simulated dampening from head occlusion
ALfloat HeadDampen;
// Dry path buffer mix
float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS];

View File

@ -48,6 +48,14 @@
# stereo modes.
#cf_level = 0
## head_dampen:
# Sets the amount of dampening on sounds emanating from behind the listener.
# This is used to simulate the natural occlusion of the head, which is
# typically missing with mono and stereo output, and as such, only works on
# mono and stereo output modes. Valid values range from 0 to 1 (inclusive),
# and higher values provide a stronger effect.
#head_dampen = 0.25
## frequency:
# Sets the output frequency.
#frequency = 44100