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)
This commit is contained in:
Chris Robinson
2009-05-30 00:32:17 -07:00
parent 2c20f26784
commit 9341f4f884
+22 -4
View File
@@ -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;
}