aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALu.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 37d30851..f2ffb739 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -327,7 +327,7 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
//2. Calculate distance attenuation
Distance = aluSqrt(aluDotproduct(Position, Position));
- if(ALSource->Send[0].Slot && !ALSource->Send[0].Slot->AuxSendAuto)
+ if(ALSource->Send[0].Slot)
{
if(ALSource->Send[0].Slot->effect.type == AL_EFFECT_REVERB)
RoomRolloff += ALSource->Send[0].Slot->effect.Reverb.RoomRolloffFactor;
@@ -394,11 +394,23 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
DryMix = __min(DryMix,MaxVolume);
DryMix = __max(DryMix,MinVolume);
- WetMix = SourceVolume * (ALSource->WetGainAuto ?
- RoomAttenuation : 1.0f);
+ WetMix = SourceVolume * RoomAttenuation;
WetMix = __min(WetMix,MaxVolume);
WetMix = __max(WetMix,MinVolume);
+ // Distance-based air absorption
+ if(ALSource->AirAbsorptionFactor > 0.0f)
+ {
+ ALfloat dist = Distance-MinDist;
+ ALfloat absorb;
+
+ if(dist < 0.0f) dist = 0.0f;
+ absorb = pow(ALSource->AirAbsorptionFactor * AIRABSORBGAINHF,
+ Distance * MetersPerUnit);
+ DryGainHF *= absorb;
+ WetGainHF *= absorb;
+ }
+
//3. Apply directional soundcones
Angle = aluAcos(aluDotproduct(Direction,SourceToListener)) * 180.0f /
3.141592654f;
@@ -406,6 +418,7 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
{
ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle);
ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f)*scale);
+ DryMix *= ConeVolume;
if(ALSource->WetGainAuto)
WetMix *= ConeVolume;
if(ALSource->DryGainHFAuto)
@@ -416,6 +429,7 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
else if(Angle > OuterAngle)
{
ConeVolume = (1.0f+(ALSource->flOuterGain-1.0f));
+ DryMix *= ConeVolume;
if(ALSource->WetGainAuto)
WetMix *= ConeVolume;
if(ALSource->DryGainHFAuto)
@@ -423,8 +437,6 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
if(ALSource->WetGainHFAuto)
WetGainHF *= (1.0f+(OuterGainHF-1.0f));
}
- else
- ConeVolume = 1.0f;
//4. Calculate Velocity
if(DopplerFactor != 0.0f)
@@ -454,31 +466,23 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
else
pitch[0] = ALSource->flPitch;
- //5. Apply filter gains and filters
- switch(ALSource->DirectFilter.type)
- {
- case AL_FILTER_LOWPASS:
- DryMix *= ALSource->DirectFilter.Gain;
- DryGainHF *= ALSource->DirectFilter.GainHF;
- break;
- }
-
- switch(ALSource->Send[0].WetFilter.type)
- {
- case AL_FILTER_LOWPASS:
- WetMix *= ALSource->Send[0].WetFilter.Gain;
- WetGainHF *= ALSource->Send[0].WetFilter.GainHF;
- break;
- }
-
- if(ALSource->AirAbsorptionFactor > 0.0f)
- DryGainHF *= pow(ALSource->AirAbsorptionFactor * AIRABSORBGAINHF,
- Distance * MetersPerUnit);
-
if(ALSource->Send[0].Slot)
{
- WetMix *= ALSource->Send[0].Slot->Gain;
+ // If the slot's auxilliary send auto is off, the data sent to the
+ // effect slot is the same as the dry path, sans filter effects
+ if(!ALSource->Send[0].Slot->AuxSendAuto)
+ {
+ WetMix = DryMix;
+ WetGainHF = DryGainHF;
+ }
+ // Note that these are really applied by the effect slot. However,
+ // it's easier to handle them here (particularly the lowpass
+ // filter). Applying the gain to the individual sources going to
+ // the effect slot should have the same effect as applying the gain
+ // to the accumulated sources in the effect slot.
+ // vol1*g + vol2*g + ... voln*g = (vol1+vol2+...voln)*g
+ WetMix *= ALSource->Send[0].Slot->Gain;
if(ALSource->Send[0].Slot->effect.type == AL_EFFECT_REVERB)
{
WetMix *= ALSource->Send[0].Slot->effect.Reverb.Gain;
@@ -493,7 +497,24 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
WetGainHF = 1.0f;
}
- DryMix *= ListenerGain * ConeVolume;
+ //5. Apply filter gains and filters
+ switch(ALSource->DirectFilter.type)
+ {
+ case AL_FILTER_LOWPASS:
+ DryMix *= ALSource->DirectFilter.Gain;
+ DryGainHF *= ALSource->DirectFilter.GainHF;
+ break;
+ }
+
+ switch(ALSource->Send[0].WetFilter.type)
+ {
+ case AL_FILTER_LOWPASS:
+ WetMix *= ALSource->Send[0].WetFilter.Gain;
+ WetGainHF *= ALSource->Send[0].WetFilter.GainHF;
+ break;
+ }
+
+ DryMix *= ListenerGain;
WetMix *= ListenerGain;
//6. Convert normalized position into pannings, then into channel volumes