From 9341f4f884ff01a1443e82fce3d5c62f1fc25ef0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 30 May 2009 00:32:17 -0700 Subject: [PATCH] Fixup panning gain calculations Clamp the panning vector magnitude to 1, and use an energy-reduction method as the vector magnitude increases (to simulate reverb area occlusion) --- Alc/alcReverb.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index 24d1eb39..1d89e04d 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -539,11 +539,29 @@ ALvoid VerbUpdate(ALeffectState *effect, ALCcontext *Context, ALeffect *Effect) // Calculate the 3D-panning gains for the early reflections and late // reverb (for EAX mode). { - ALfloat *earlyPan = Effect->Reverb.ReflectionsPan; - ALfloat *latePan = Effect->Reverb.LateReverbPan; + ALfloat earlyPan[3] = { Effect->Reverb.ReflectionsPan[0], Effect->Reverb.ReflectionsPan[1], Effect->Reverb.ReflectionsPan[2] }; + ALfloat latePan[3] = { Effect->Reverb.LateReverbPan[0], Effect->Reverb.LateReverbPan[1], Effect->Reverb.LateReverbPan[2] }; ALfloat *speakerGain, dirGain, ambientGain; + ALfloat length; ALint pos; + length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2]; + if(length > 1.0f) + { + length = 1.0f / aluSqrt(length); + earlyPan[0] *= length; + earlyPan[1] *= length; + earlyPan[2] *= length; + } + length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2]; + if(length > 1.0f) + { + length = 1.0f / aluSqrt(length); + latePan[0] *= length; + latePan[1] *= length; + latePan[2] *= length; + } + // This code applies directional reverb just like the mixer applies // directional sources. It diffuses the sound toward all speakers // as the magnitude of the panning vector drops, which is only an @@ -552,14 +570,14 @@ ALvoid VerbUpdate(ALeffectState *effect, ALCcontext *Context, ALeffect *Effect) pos = aluCart2LUTpos(earlyPan[2], earlyPan[0]); speakerGain = &Context->PanningLUT[OUTPUTCHANNELS * pos]; dirGain = aluSqrt((earlyPan[0] * earlyPan[0]) + (earlyPan[2] * earlyPan[2])); - ambientGain = 1.0 / aluSqrt(Context->NumChan) * (1.0 - dirGain); + ambientGain = (1.0 - dirGain); for(index = 0;index < OUTPUTCHANNELS;index++) State->Early.PanGain[index] = dirGain * speakerGain[index] + ambientGain; pos = aluCart2LUTpos(latePan[2], latePan[0]); speakerGain = &Context->PanningLUT[OUTPUTCHANNELS * pos]; dirGain = aluSqrt((latePan[0] * latePan[0]) + (latePan[2] * latePan[2])); - ambientGain = 1.0 / aluSqrt(Context->NumChan) * (1.0 - dirGain); + ambientGain = (1.0 - dirGain); for(index = 0;index < OUTPUTCHANNELS;index++) State->Late.PanGain[index] = dirGain * speakerGain[index] + ambientGain; } -- 2.11.4.GIT