diff options
author | Chris Robinson <[email protected]> | 2008-12-10 11:54:13 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2008-12-10 11:54:13 -0800 |
commit | 3056f91ec54b2066b0e939ebcb540ca99a256110 (patch) | |
tree | f926ea341a246c98c64355862e99fe1c9b193c01 /Alc/ALu.c | |
parent | ed03570e1afc8547069216ed7952cd779da7b20b (diff) |
Apply the dry filter to multi-channel sources
Unlike mono sources, they use 2 chained one-pole filters instead of 4
Diffstat (limited to 'Alc/ALu.c')
-rw-r--r-- | Alc/ALu.c | 63 |
1 files changed, 48 insertions, 15 deletions
@@ -178,6 +178,20 @@ static __inline ALfloat lpFilter(FILTER *iir, ALfloat input) return output; } +static __inline ALfloat lpFilterMC(FILTER *iir, ALuint chan, ALfloat input) +{ + ALfloat *history = &iir->history[chan*2]; + ALfloat a = iir->coeff; + ALfloat output = input; + + output = output + (history[0]-output)*a; + history[0] = output; + output = output + (history[1]-output)*a; + history[1] = output; + + return output; +} + static __inline ALshort aluF2S(ALfloat Value) { @@ -594,16 +608,33 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource, //1. Multi-channel buffers always play "normal" pitch[0] = ALSource->flPitch; - drysend[FRONT_LEFT] = SourceVolume * ListenerGain; - drysend[FRONT_RIGHT] = SourceVolume * ListenerGain; - drysend[SIDE_LEFT] = SourceVolume * ListenerGain; - drysend[SIDE_RIGHT] = SourceVolume * ListenerGain; - drysend[BACK_LEFT] = SourceVolume * ListenerGain; - drysend[BACK_RIGHT] = SourceVolume * ListenerGain; - drysend[CENTER] = SourceVolume * ListenerGain; - drysend[LFE] = SourceVolume * ListenerGain; + DryMix = SourceVolume; + + switch(ALSource->DirectFilter.type) + { + case AL_FILTER_LOWPASS: + DryMix *= ALSource->DirectFilter.Gain; + DryGainHF *= ALSource->DirectFilter.GainHF; + break; + } + + drysend[FRONT_LEFT] = DryMix * ListenerGain; + drysend[FRONT_RIGHT] = DryMix * ListenerGain; + drysend[SIDE_LEFT] = DryMix * ListenerGain; + drysend[SIDE_RIGHT] = DryMix * ListenerGain; + drysend[BACK_LEFT] = DryMix * ListenerGain; + drysend[BACK_RIGHT] = DryMix * ListenerGain; + drysend[CENTER] = DryMix * ListenerGain; + drysend[LFE] = DryMix * ListenerGain; *wetsend = 0.0f; - WetGainHF = 1.0f; + + cw = cos(2.0f*3.141592654f * LOWPASSFREQCUTOFF / ALContext->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); + ALSource->iirFilter.coeff = a; + ALSource->Send[0].iirFilter.coeff = 0.0f; *drygainhf = DryGainHF; *wetgainhf = WetGainHF; @@ -825,9 +856,11 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma ALfloat samp1, samp2; //First order interpolator (front left) samp1 = lerp(Data[k*Channels], Data[(k+1)*Channels], DataPosFrac); + samp1 = lpFilterMC(DryFilter, FRONT_LEFT, samp1); DryBuffer[j][FRONT_LEFT] += samp1*DrySend[FRONT_LEFT]; //First order interpolator (front right) samp2 = lerp(Data[k*Channels+1], Data[(k+1)*Channels+1], DataPosFrac); + samp2 = lpFilterMC(DryFilter, FRONT_RIGHT, samp2); DryBuffer[j][FRONT_RIGHT] += samp2*DrySend[FRONT_RIGHT]; if(Channels >= 4) { @@ -838,31 +871,31 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma { //First order interpolator (center) value = lerp(Data[k*Channels+i], Data[(k+1)*Channels+i], DataPosFrac); - DryBuffer[j][CENTER] += value*DrySend[CENTER]; + DryBuffer[j][CENTER] += lpFilterMC(DryFilter, CENTER, value)*DrySend[CENTER]; i++; } //First order interpolator (lfe) value = lerp(Data[k*Channels+i], Data[(k+1)*Channels+i], DataPosFrac); - DryBuffer[j][LFE] += value*DrySend[LFE]; + DryBuffer[j][LFE] += lpFilterMC(DryFilter, LFE, value)*DrySend[LFE]; i++; } //First order interpolator (back left) value = lerp(Data[k*Channels+i], Data[(k+1)*Channels+i], DataPosFrac); - DryBuffer[j][BACK_LEFT] += value*DrySend[BACK_LEFT]; + DryBuffer[j][BACK_LEFT] += lpFilterMC(DryFilter, BACK_LEFT, value)*DrySend[BACK_LEFT]; i++; //First order interpolator (back right) value = lerp(Data[k*Channels+i], Data[(k+1)*Channels+i], DataPosFrac); - DryBuffer[j][BACK_RIGHT] += value*DrySend[BACK_RIGHT]; + DryBuffer[j][BACK_RIGHT] += lpFilterMC(DryFilter, BACK_RIGHT, value)*DrySend[BACK_RIGHT]; i++; if(Channels >= 7) { //First order interpolator (side left) value = lerp(Data[k*Channels+i], Data[(k+1)*Channels+i], DataPosFrac); - DryBuffer[j][SIDE_LEFT] += value*DrySend[SIDE_LEFT]; + DryBuffer[j][SIDE_LEFT] += lpFilterMC(DryFilter, SIDE_LEFT, value)*DrySend[SIDE_LEFT]; i++; //First order interpolator (side right) value = lerp(Data[k*Channels+i], Data[(k+1)*Channels+i], DataPosFrac); - DryBuffer[j][SIDE_RIGHT] += value*DrySend[SIDE_RIGHT]; + DryBuffer[j][SIDE_RIGHT] += lpFilterMC(DryFilter, SIDE_RIGHT, value)*DrySend[SIDE_RIGHT]; i++; } } |