From 51e4aa7fc6399cd9eb5864e17ef1a9d49c8b4b24 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 16 May 2016 22:42:41 -0700 Subject: Ignore the listening angle for the wet path sound cones Since the wet path is essentially the room response to a sound, the direction of the sound to the listener doesn't change the amount of energy the room receives. Instead, the surface area defined by the cones dictate the volume the room gets for the sound. --- Alc/ALu.c | 83 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 32 deletions(-) (limited to 'Alc') diff --git a/Alc/ALu.c b/Alc/ALu.c index 8594afb8..4c7000d7 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -793,9 +793,9 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; aluVector Position, Velocity, Direction, SourceToListener; - ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist; + ALfloat InnerAngle,OuterAngle,Distance,ClampedDist; ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff; - ALfloat ConeVolume,ConeHF,SourceVolume,ListenerGain; + ALfloat SourceVolume,ListenerGain; ALfloat DopplerFactor, SpeedOfSound; ALfloat AirAbsorptionFactor; ALfloat RoomAirAbsorption[MAX_SENDS]; @@ -1033,38 +1033,57 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } /* Calculate directional soundcones */ - Angle = RAD2DEG(acosf(aluDotproduct(&Direction, &SourceToListener)) * ConeScale) * 2.0f; - if(Angle > InnerAngle && Angle <= OuterAngle) + if(InnerAngle < 360.0f) { - ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp(1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), - scale); - ConeHF = lerp(1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), - scale); - } - else if(Angle > OuterAngle) - { - ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed); - ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed); - } - else - { - ConeVolume = 1.0f; - ConeHF = 1.0f; - } + ALfloat ConeVolume; + ALfloat ConeHF; + ALfloat Angle; + ALfloat scale; - DryGain *= ConeVolume; - if(WetGainAuto) - { - for(i = 0;i < NumSends;i++) - WetGain[i] *= ConeVolume; - } - if(DryGainHFAuto) - DryGainHF *= ConeHF; - if(WetGainHFAuto) - { - for(i = 0;i < NumSends;i++) - WetGainHF[i] *= ConeHF; + Angle = RAD2DEG(acosf(aluDotproduct(&Direction, &SourceToListener)) * ConeScale) * 2.0f; + if(Angle > InnerAngle) + { + if(Angle < OuterAngle) + { + scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); + ConeVolume = lerp( + 1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), scale + ); + ConeHF = lerp( + 1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), scale + ); + } + else + { + ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed); + ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed); + } + DryGain *= ConeVolume; + if(DryGainHFAuto) + DryGainHF *= ConeHF; + } + + /* Wet path uses the total area of the cone emitter (the room will + * receive the same amount of sound regardless of its direction). + */ + scale = (asinf(maxf((OuterAngle-InnerAngle)/360.0f, 0.0f)) / F_PI) + + (InnerAngle/360.0f); + if(WetGainAuto) + { + ConeVolume = lerp( + 1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), scale + ); + for(i = 0;i < NumSends;i++) + WetGain[i] *= ConeVolume; + } + if(WetGainHFAuto) + { + ConeHF = lerp( + 1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), scale + ); + for(i = 0;i < NumSends;i++) + WetGainHF[i] *= ConeHF; + } } /* Clamp to Min/Max Gain */ -- cgit v1.2.3