diff options
author | Chris Robinson <[email protected]> | 2009-05-30 00:32:17 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2009-05-30 00:32:17 -0700 |
commit | 9341f4f884ff01a1443e82fce3d5c62f1fc25ef0 (patch) | |
tree | fb59f7a6ac4328853c8e25fd8432f9e00e183aab | |
parent | 2c20f2678478c2320a0236baf288baed8987b1f8 (diff) |
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)
-rw-r--r-- | Alc/alcReverb.c | 26 |
1 files 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; } |