summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALu.c36
-rw-r--r--Alc/alcReverb.c31
-rw-r--r--OpenAL32/Include/alFilter.h16
3 files changed, 29 insertions, 54 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 8cc965e8..fb4757c4 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -412,8 +412,8 @@ static ALvoid CalcNonAttnSourceParams(const ALCcontext *ALContext, ALsource *ALS
ALfloat WetGain[MAX_SENDS];
ALfloat WetGainHF[MAX_SENDS];
ALint NumSends, Frequency;
+ ALfloat cw;
ALint i;
- ALfloat cw, a, g;
//Get context properties
NumSends = ALContext->Device->NumAuxSends;
@@ -479,27 +479,16 @@ static ALvoid CalcNonAttnSourceParams(const ALCcontext *ALContext, ALsource *ALS
/* Update filter coefficients. Calculations based on the I3DL2
* spec. */
cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / Frequency);
+
/* We use two chained one-pole filters, so we need to take the
* square root of the squared gain, which is the same as the base
* gain. */
- g = __max(DryGainHF, 0.01f);
- a = 0.0f;
- /* Be careful with gains < 0.0001, as that causes the coefficient
- * head towards 1, which will flatten the signal */
- if(g < 0.9999f) /* 1-epsilon */
- a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
- (1 - g);
- ALSource->Params.iirFilter.coeff = a;
+ ALSource->Params.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw);
for(i = 0;i < NumSends;i++)
{
/* We use a one-pole filter, so we need to take the squared gain */
- g = __max(WetGainHF[i], 0.1f);
- g *= g;
- a = 0.0f;
- if(g < 0.9999f) /* 1-epsilon */
- a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
- (1 - g);
+ ALfloat a = lpCoeffCalc(WetGainHF[i]*WetGainHF[i], cw);
ALSource->Params.Send[i].iirFilter.coeff = a;
}
}
@@ -526,7 +515,7 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource)
ALuint Frequency;
ALint NumSends;
ALint pos, s, i;
- ALfloat cw, a, g;
+ ALfloat cw;
for(i = 0;i < MAX_SENDS;i++)
WetGainHF[i] = 1.0f;
@@ -862,26 +851,17 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource)
/* Update filter coefficients. */
cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / Frequency);
+
/* Spatialized sources use four chained one-pole filters, so we need to
* take the fourth root of the squared gain, which is the same as the
* square root of the base gain. */
- g = aluSqrt(__max(DryGainHF, 0.0001f));
- a = 0.0f;
- if(g < 0.9999f) /* 1-epsilon */
- a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
- (1 - g);
- ALSource->Params.iirFilter.coeff = a;
+ ALSource->Params.iirFilter.coeff = lpCoeffCalc(aluSqrt(DryGainHF), cw);
for(i = 0;i < NumSends;i++)
{
/* The wet path uses two chained one-pole filters, so take the
* base gain (square root of the squared gain) */
- g = __max(WetGainHF[i], 0.01f);
- a = 0.0f;
- if(g < 0.9999f) /* 1-epsilon */
- a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
- (1 - g);
- ALSource->Params.Send[i].iirFilter.coeff = a;
+ ALSource->Params.Send[i].iirFilter.coeff = lpCoeffCalc(WetGainHF[i], cw);
}
}
diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c
index fed1d5d2..3d6e2734 100644
--- a/Alc/alcReverb.c
+++ b/Alc/alcReverb.c
@@ -328,24 +328,6 @@ static __inline ALfloat CalcI3DL2HFreq(ALfloat hfRef, ALuint frequency)
return cos(2.0f * M_PI * hfRef / frequency);
}
-/* Calculate the I3DL2 coefficient given the gain and frequency parameters.
- * To allow for optimization when using multiple chained filters, the gain
- * is not squared in this function. Callers using a single filter should
- * square it to produce the correct coefficient. Those using multiple
- * filters should find its N-1 root (where N is the number of chained
- * filters).
- */
-static __inline ALfloat CalcI3DL2Coeff(ALfloat g, ALfloat cw)
-{
- ALfloat coeff;
-
- coeff = 0.0f;
- if(g < 0.9999f) // 1-epsilon
- coeff = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / (1 - g);
-
- return coeff;
-}
-
// Calculate an attenuation to be applied to the input of any echo models to
// compensate for modal density and decay time.
static __inline ALfloat CalcDensityGain(ALfloat a)
@@ -417,11 +399,10 @@ static __inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloa
// Calculate the low-pass coefficient by dividing the HF decay
// coefficient by the full decay coefficient.
g = CalcDecayCoeff(length, decayTime * hfRatio) / decayCoeff;
- g = __max(g, 0.1f);
// Damping is done with a 1-pole filter, so g needs to be squared.
g *= g;
- coeff = CalcI3DL2Coeff(g, cw);
+ coeff = lpCoeffCalc(g, cw);
// Very low decay times will produce minimal output, so apply an
// upper bound to the coefficient.
@@ -1067,13 +1048,12 @@ static ALvoid VerbUpdate(ALeffectState *effect, ALCcontext *Context, const ALeff
{
ALverbState *State = (ALverbState*)effect;
ALuint frequency = Context->Device->Frequency;
- ALfloat cw, g, x, y, hfRatio;
+ ALfloat cw, x, y, hfRatio;
// Calculate the master low-pass filter (from the master effect HF gain).
cw = CalcI3DL2HFreq(Effect->Reverb.HFReference, frequency);
- g = __max(Effect->Reverb.GainHF, 0.0001f);
// This is done with 2 chained 1-pole filters, so no need to square g.
- State->LpFilter.coeff = CalcI3DL2Coeff(g, cw);
+ State->LpFilter.coeff = lpCoeffCalc(Effect->Reverb.GainHF, cw);
// Update the initial effect delay.
UpdateDelayLine(Effect->Reverb.ReflectionsDelay,
@@ -1110,13 +1090,12 @@ static ALvoid EAXVerbUpdate(ALeffectState *effect, ALCcontext *Context, const AL
{
ALverbState *State = (ALverbState*)effect;
ALuint frequency = Context->Device->Frequency;
- ALfloat cw, g, x, y, hfRatio;
+ ALfloat cw, x, y, hfRatio;
// Calculate the master low-pass filter (from the master effect HF gain).
cw = CalcI3DL2HFreq(Effect->Reverb.HFReference, frequency);
- g = __max(Effect->Reverb.GainHF, 0.0001f);
// This is done with 2 chained 1-pole filters, so no need to square g.
- State->LpFilter.coeff = CalcI3DL2Coeff(g, cw);
+ State->LpFilter.coeff = lpCoeffCalc(Effect->Reverb.GainHF, cw);
// Update the modulator line.
UpdateModulator(Effect->Reverb.ModulationTime,
diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h
index 754b0b6f..d5ca965a 100644
--- a/OpenAL32/Include/alFilter.h
+++ b/OpenAL32/Include/alFilter.h
@@ -61,6 +61,22 @@ static __inline ALfloat lpFilter1P(FILTER *iir, ALuint offset, ALfloat input)
return output;
}
+/* Calculates the low-pass filter coefficient given the pre-scaled gain and
+ * cos(w) value. Note that g should be pre-scaled (sqr(gain) for one-pole,
+ * sqrt(gain) for four-pole, etc) */
+static __inline ALfloat lpCoeffCalc(ALfloat g, ALfloat cw)
+{
+ ALfloat a = 0.0f;
+
+ /* Be careful with gains < 0.01, as that causes the coefficient
+ * head towards 1, which will flatten the signal */
+ g = __max(g, 0.01f);
+ if(g < 0.9999f) /* 1-epsilon */
+ a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
+ (1 - g);
+
+ return a;
+}
#define AL_FILTER_TYPE 0x8001