From 4a530e2146bdc007a54eb50bac07c9adefee3412 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 16 Sep 2008 07:36:48 -0700 Subject: [PATCH] Fixup some source parameter calculations --- Alc/ALu.c | 77 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file 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 -- 2.11.4.GIT