aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c9
-rw-r--r--Alc/ALu.c24
-rw-r--r--OpenAL32/Include/alMain.h5
-rw-r--r--alsoftrc.sample8
4 files changed, 40 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);
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 324c18fa..cb290e0c 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -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];
diff --git a/alsoftrc.sample b/alsoftrc.sample
index 8efae414..6f25d3eb 100644
--- a/alsoftrc.sample
+++ b/alsoftrc.sample
@@ -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