aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-10-21 13:08:50 -0700
committerChris Robinson <[email protected]>2009-10-21 13:08:50 -0700
commit4e399b41cdae165c35d924ef27b6683ae7361ebc (patch)
tree644d0c7b060f794c0888f1821bb5b39ed05be45b /Alc
parentbdec1e037f035fe38322879dc5d8e25117ec2171 (diff)
Calculate source filter coefficients with the source parameters
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALu.c140
1 files changed, 65 insertions, 75 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 29984948..a8dc9fef 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -416,8 +416,8 @@ static __inline ALint aluCart2LUTpos(ALfloat re, ALfloat im)
static ALvoid CalcSourceParams(const ALCcontext *ALContext,
const ALsource *ALSource, ALenum isMono,
ALfloat *drysend, ALfloat *wetsend,
- ALfloat *pitch, ALfloat *drygainhf,
- ALfloat *wetgainhf)
+ ALfloat *pitch, FILTER *DryFilter,
+ FILTER *WetFilter[MAX_SENDS])
{
ALfloat InnerAngle,OuterAngle,Angle,Distance,DryMix;
ALfloat Direction[3],Position[3],SourceToListener[3];
@@ -431,17 +431,21 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
ALfloat MetersPerUnit;
ALfloat RoomRolloff[MAX_SENDS];
ALfloat DryGainHF = 1.0f;
+ ALfloat WetGainHF[MAX_SENDS];
ALfloat DirGain, AmbientGain;
ALfloat length;
const ALfloat *SpeakerGain;
+ ALuint Frequency;
ALint NumSends;
ALint pos, s, i;
+ ALfloat cw, a, g;
//Get context properties
DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor;
DopplerVelocity = ALContext->DopplerVelocity;
flSpeedOfSound = ALContext->flSpeedOfSound;
NumSends = ALContext->Device->NumAuxSends;
+ Frequency = ALContext->Device->Frequency;
//Get listener properties
ListenerGain = ALContext->Listener.Gain;
@@ -487,13 +491,25 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
drysend[FRONT_CENTER] = DryMix * ListenerGain;
drysend[BACK_CENTER] = DryMix * ListenerGain;
drysend[LFE] = DryMix * ListenerGain;
- *drygainhf = DryGainHF;
-
for(i = 0;i < MAX_SENDS;i++)
- {
wetsend[i] = 0.0f;
- wetgainhf[i] = 1.0f;
- }
+
+ /* 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);
+ DryFilter->coeff = a;
+ for(i = 0;i < MAX_SENDS;i++)
+ WetFilter[i]->coeff = 0.0f;
return;
}
@@ -617,7 +633,7 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
ALfloat WetMix = SourceVolume * RoomAttenuation[i];
WetMix = __min(WetMix,MaxVolume);
wetsend[i] = __max(WetMix,MinVolume);
- wetgainhf[i] = 1.0f;
+ WetGainHF[i] = 1.0f;
}
// Distance-based air absorption
@@ -634,7 +650,7 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
absorb = pow(10.0, absorb/20.0);
DryGainHF *= absorb;
for(i = 0;i < MAX_SENDS;i++)
- wetgainhf[i] *= absorb;
+ WetGainHF[i] *= absorb;
}
//3. Apply directional soundcones
@@ -699,7 +715,7 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
if(ALSource->WetGainAuto)
wetsend[i] *= ConeVolume;
if(ALSource->WetGainHFAuto)
- wetgainhf[i] *= ConeHF;
+ WetGainHF[i] *= ConeHF;
if(ALSource->Send[i].Slot->AuxSendAuto)
{
@@ -713,14 +729,14 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
// the effect slot is the same as the dry path, sans filter
// effects
wetsend[i] = DryMix;
- wetgainhf[i] = DryGainHF;
+ WetGainHF[i] = DryGainHF;
}
switch(ALSource->Send[i].WetFilter.type)
{
case AL_FILTER_LOWPASS:
wetsend[i] *= ALSource->Send[i].WetFilter.Gain;
- wetgainhf[i] *= ALSource->Send[i].WetFilter.GainHF;
+ WetGainHF[i] *= ALSource->Send[i].WetFilter.GainHF;
break;
}
wetsend[i] *= ListenerGain;
@@ -728,13 +744,13 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
else
{
wetsend[i] = 0.0f;
- wetgainhf[i] = 1.0f;
+ WetGainHF[i] = 1.0f;
}
}
for(i = NumSends;i < MAX_SENDS;i++)
{
wetsend[i] = 0.0f;
- wetgainhf[i] = 1.0f;
+ WetGainHF[i] = 1.0f;
}
//5. Apply filter gains and filters
@@ -771,7 +787,30 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext,
ALfloat gain = SpeakerGain[s]*DirGain + AmbientGain;
drysend[s] = DryMix * gain;
}
- *drygainhf = DryGainHF;
+
+ /* 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);
+ DryFilter->coeff = a;
+
+ 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);
+ WetFilter[i]->coeff = a;
+ }
}
static __inline ALshort lerp(ALshort val1, ALshort val2, ALint frac)
@@ -795,8 +834,6 @@ static void MixSomeSources(ALCcontext *ALContext, float (*DryBuffer)[OUTPUTCHANN
ALint64 DataSize64,DataPos64;
FILTER *DryFilter, *WetFilter[MAX_SENDS];
ALfloat WetSend[MAX_SENDS];
- ALfloat DryGainHF = 0.0f;
- ALfloat WetGainHF[MAX_SENDS];
ALuint rampLength;
ALuint frequency;
ALint Looping,State;
@@ -851,69 +888,22 @@ another_source:
}
CalcSourceParams(ALContext, ALSource, (Channels==1)?AL_TRUE:AL_FALSE,
- DrySend, WetSend, &Pitch, &DryGainHF, WetGainHF);
+ DrySend, WetSend, &Pitch, DryFilter, WetFilter);
Pitch = (Pitch*ALBuffer->frequency) / frequency;
- if(Channels == 1)
+ if(DuplicateStereo && Channels == 2)
{
- ALfloat cw, a, g;
-
- /* Update filter coefficients. Calculations based on the I3DL2
- * spec. */
- cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / frequency);
- /* We 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. */
- /* Be careful with gains < 0.0001, as that causes the coefficient
- * head towards 1, which will flatten the signal */
- 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);
- DryFilter->coeff = a;
-
- for(i = 0;i < MAX_SENDS;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);
- WetFilter[i]->coeff = a;
- }
+ Matrix[FRONT_LEFT][SIDE_LEFT] = 1.0f;
+ Matrix[FRONT_RIGHT][SIDE_RIGHT] = 1.0f;
+ Matrix[FRONT_LEFT][BACK_LEFT] = 1.0f;
+ Matrix[FRONT_RIGHT][BACK_RIGHT] = 1.0f;
}
- else
+ else if(DuplicateStereo)
{
- ALfloat cw, a, g;
-
- /* Multi-channel sources use two chained one-pole filters */
- cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / frequency);
- g = __max(DryGainHF, 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);
- DryFilter->coeff = a;
- for(i = 0;i < MAX_SENDS;i++)
- WetFilter[i]->coeff = 0.0f;
-
- if(DuplicateStereo && Channels == 2)
- {
- Matrix[FRONT_LEFT][SIDE_LEFT] = 1.0f;
- Matrix[FRONT_RIGHT][SIDE_RIGHT] = 1.0f;
- Matrix[FRONT_LEFT][BACK_LEFT] = 1.0f;
- Matrix[FRONT_RIGHT][BACK_RIGHT] = 1.0f;
- }
- else if(DuplicateStereo)
- {
- Matrix[FRONT_LEFT][SIDE_LEFT] = 0.0f;
- Matrix[FRONT_RIGHT][SIDE_RIGHT] = 0.0f;
- Matrix[FRONT_LEFT][BACK_LEFT] = 0.0f;
- Matrix[FRONT_RIGHT][BACK_RIGHT] = 0.0f;
- }
+ Matrix[FRONT_LEFT][SIDE_LEFT] = 0.0f;
+ Matrix[FRONT_RIGHT][SIDE_RIGHT] = 0.0f;
+ Matrix[FRONT_LEFT][BACK_LEFT] = 0.0f;
+ Matrix[FRONT_RIGHT][BACK_RIGHT] = 0.0f;
}
/* Compute the gain steps for each output channel */