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:
parent
1694e5bd12
commit
84d2d623b6
@ -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++)
|
||||
|
24
Alc/ALu.c
24
Alc/ALu.c
@ -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);
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user