From a77387b5490e8f40c682118c2a1c192cddc06939 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 11 Oct 2014 09:35:32 -0700 Subject: [PATCH] Avoid taking the square-root of the ambient gain Although it is more correct for preserving the apparent volume, the ambisonics- based panning does not work on the same power scale, making it louder by comparison. --- Alc/ALu.c | 31 ++++++++++--------------------- Alc/effects/autowah.c | 6 +++--- Alc/effects/compressor.c | 2 +- Alc/effects/distortion.c | 2 +- Alc/effects/equalizer.c | 2 +- Alc/effects/modulator.c | 2 +- Alc/effects/reverb.c | 46 +++++++++++++--------------------------------- 7 files changed, 30 insertions(+), 61 deletions(-) diff --git a/Alc/ALu.c b/Alc/ALu.c index 49ebd0c2..547a00a4 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -287,12 +287,12 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ALfloat WetGain[MAX_SENDS]; ALfloat WetGainHF[MAX_SENDS]; ALfloat WetGainLF[MAX_SENDS]; - ALint NumSends, Frequency; + ALuint NumSends, Frequency; const struct ChanMap *chans = NULL; - ALint num_channels = 0; + ALuint num_channels = 0; ALboolean DirectChannels; ALfloat Pitch; - ALint i, j, c; + ALuint i, j, c; /* Get device properties */ NumSends = Device->NumAuxSends; @@ -464,7 +464,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A Target[chans[c].channel] = DryGain; ok = true; } - else for(i = 0;i < (ALint)Device->NumSpeakers;i++) + else for(i = 0;i < Device->NumSpeakers;i++) { /* Attempt to match the input channel to an output based on its * location. */ @@ -937,32 +937,21 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte else { MixGains *gains = voice->Direct.Mix.Gains[0]; + ALfloat Target[MaxChannels]; /* Normalize the length, and compute panned gains. */ - if(!(Distance > FLT_EPSILON)) - { - ALfloat gain = 1.0f / sqrtf((float)Device->NumSpeakers); - for(j = 0;j < MaxChannels;j++) - gains[j].Target = 0.0f; - for(i = 0;i < (ALint)Device->NumSpeakers;i++) - { - enum Channel chan = Device->Speaker[i].ChanName; - gains[chan].Target = gain; - } - } - else + if(Distance > FLT_EPSILON) { ALfloat radius = ALSource->Radius; - ALfloat Target[MaxChannels]; ALfloat invlen = 1.0f/maxf(Distance, radius); Position[0] *= invlen; Position[1] *= invlen; Position[2] *= invlen; - - ComputeDirectionalGains(Device, Position, DryGain, Target); - for(j = 0;j < MaxChannels;j++) - gains[j].Target = Target[j]; } + ComputeDirectionalGains(Device, Position, DryGain, Target); + + for(j = 0;j < MaxChannels;j++) + gains[j].Target = Target[j]; UpdateDryStepping(&voice->Direct, 1); voice->IsHrtf = AL_FALSE; diff --git a/Alc/effects/autowah.c b/Alc/effects/autowah.c index 09474d56..f4aaf49f 100644 --- a/Alc/effects/autowah.c +++ b/Alc/effects/autowah.c @@ -31,8 +31,8 @@ /* Auto-wah is simply a low-pass filter with a cutoff frequency that shifts up * or down depending on the input signal, and a resonant peak at the cutoff. * - * Currently, we assume a cutoff frequency range of 500hz (no amplitude) to - * 3khz (peak gain). Peak gain is assumed to be in normalized scale. + * Currently, we assume a cutoff frequency range of 20hz (no amplitude) to + * 20khz (peak gain). Peak gain is assumed to be in normalized scale. */ typedef struct ALautowahState { @@ -76,7 +76,7 @@ static ALvoid ALautowahState_update(ALautowahState *state, ALCdevice *device, co state->PeakGain = slot->EffectProps.Autowah.PeakGain; state->Resonance = slot->EffectProps.Autowah.Resonance; - gain = sqrtf(1.0f / device->NumSpeakers) * slot->Gain; + gain = 1.0f/device->NumSpeakers * slot->Gain; SetGains(device, gain, state->Gain); } diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index 1c0054e7..9554a0f2 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -61,7 +61,7 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, ALCdevice *Devi state->Enabled = Slot->EffectProps.Compressor.OnOff; - gain = sqrtf(1.0f / Device->NumSpeakers) * Slot->Gain; + gain = 1.0f/Device->NumSpeakers * Slot->Gain; SetGains(Device, gain, state->Gain); } diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index 04a05d99..9e36ea20 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -82,7 +82,7 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, ALCdevice *Devi ALfilterState_setParams(&state->bandpass, ALfilterType_BandPass, 1.0f, cutoff / (frequency*4.0f), bandwidth); - gain = sqrtf(1.0f / Device->NumSpeakers) * Slot->Gain; + gain = 1.0f/Device->NumSpeakers * Slot->Gain; SetGains(Device, gain, state->Gain); } diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index 5677426d..d04f36ee 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -93,7 +93,7 @@ static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *UNUSED(state), static ALvoid ALequalizerState_update(ALequalizerState *state, ALCdevice *device, const ALeffectslot *slot) { ALfloat frequency = (ALfloat)device->Frequency; - ALfloat gain = sqrtf(1.0f / device->NumSpeakers) * slot->Gain; + ALfloat gain = 1.0f/device->NumSpeakers * slot->Gain; SetGains(device, gain, state->Gain); diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index 0665ad6c..e57040b3 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -149,7 +149,7 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, ALCdevice *Device state->Filter.a[1] = -a; state->Filter.a[2] = 0.0f; - gain = sqrtf(1.0f/Device->NumSpeakers) * Slot->Gain; + gain = 1.0f/Device->NumSpeakers * Slot->Gain; SetGains(Device, gain, state->Gain); } diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index 8c17076a..45d25da7 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -1033,52 +1033,31 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection { ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], ReflectionsPan[2] }; ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], LateReverbPan[2] }; - ALfloat earlyLen = 0.0f; - ALfloat lateLen = 0.0f; ALfloat length, invlen; - ALfloat ambientGain; - ALuint i; - - Gain *= ReverbBoost; - - /* Attenuate reverb according to its coverage (len=0 will give - * ambientGain, and len>=1 will be fully panned using Gain). */ - ambientGain = minf(sqrtf(2.0f/Device->NumSpeakers), 1.0f) * Gain; length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2]; - if(length > FLT_EPSILON) + if(!(length > FLT_EPSILON)) + earlyPan[0] = earlyPan[1] = earlyPan[2] = 0.0f; + else { - length = sqrtf(length); - - invlen = 1.0f / length; + invlen = 1.0f / sqrtf(length); earlyPan[0] *= invlen; earlyPan[1] *= invlen; earlyPan[2] *= invlen; - - earlyLen = minf(1.0f, length); - ComputeDirectionalGains(Device, earlyPan, Gain, State->Early.PanGain); } + ComputeDirectionalGains(Device, earlyPan, Gain, State->Early.PanGain); length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2]; - if(length > FLT_EPSILON) + if(!(length > FLT_EPSILON)) + latePan[0] = latePan[1] = latePan[2] = 0.0f; + else { - length = sqrtf(length); - - invlen = 1.0f / length; + invlen = 1.0f / sqrtf(length); latePan[0] *= invlen; latePan[1] *= invlen; latePan[2] *= invlen; - - lateLen = minf(1.0f, length); - ComputeDirectionalGains(Device, latePan, Gain, State->Late.PanGain); - } - - for(i = 0;i < Device->NumSpeakers;i++) - { - enum Channel chan = Device->Speaker[i].ChanName; - State->Early.PanGain[chan] = lerp(ambientGain, State->Early.PanGain[chan], earlyLen); - State->Late.PanGain[chan] = lerp(ambientGain, State->Late.PanGain[chan], lateLen); } + ComputeDirectionalGains(Device, latePan, Gain, State->Late.PanGain); } static ALvoid ALreverbState_update(ALreverbState *State, ALCdevice *Device, const ALeffectslot *Slot) @@ -1163,12 +1142,13 @@ static ALvoid ALreverbState_update(ALreverbState *State, ALCdevice *Device, cons // Update early and late 3D panning. Update3DPanning(Device, Slot->EffectProps.Reverb.ReflectionsPan, - Slot->EffectProps.Reverb.LateReverbPan, Slot->Gain, State); + Slot->EffectProps.Reverb.LateReverbPan, + Slot->Gain * ReverbBoost, State); } else { /* Update channel gains */ - ALfloat gain = sqrtf(2.0f/Device->NumSpeakers) * ReverbBoost * Slot->Gain; + ALfloat gain = 2.0f/Device->NumSpeakers * Slot->Gain * ReverbBoost; SetGains(Device, gain, State->Gain); } } -- 2.11.4.GIT