aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-12-08 14:18:07 -0800
committerChris Robinson <[email protected]>2009-12-08 14:18:07 -0800
commit84d2d623b644880eb4d677d45e257ffb00f6244c (patch)
tree67702ebf113415bbc3a95361d122c2b41fdb32f3 /Alc
parent1694e5bd12d021169cf6cf541c5a5d0c652c8989 (diff)
Add a head-dampening option
This simulates occlusion of the player's head for sounds coming from behind, when outputing to mono or stereo
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c9
-rw-r--r--Alc/ALu.c24
2 files changed, 27 insertions, 6 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 383e2c47..3f4fb706 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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++)
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 8874cccc..c99ac881 100644
--- a/Alc/ALu.c
+++ b/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);