diff options
-rw-r--r-- | Alc/ALu.c | 39 | ||||
-rw-r--r-- | Alc/mixer.c | 10 | ||||
-rw-r--r-- | OpenAL32/Include/alFilter.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 6 | ||||
-rw-r--r-- | OpenAL32/alFilter.c | 11 |
5 files changed, 37 insertions, 31 deletions
@@ -254,8 +254,6 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALboolean DirectChannels; ALfloat hwidth = 0.0f; ALfloat Pitch; - ALfloat coeff; - ALfloat cw; ALint i, c; /* Get device properties */ @@ -453,21 +451,20 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALSource->Params.Send[i].Gain = WetGain[i]; } - /* Update filter coefficients. Calculations based on the I3DL2 - * spec. */ - cw = cosf(F_PI*2.0f * LOWPASSFREQREF / 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. */ - coeff = lpCoeffCalc(DryGainHF, cw); - for(c = 0;c < num_channels;c++) - ALSource->Params.Direct.Filter[c].coeff = lpCoeffCalc(DryGainHF, cw); + { + ALfloat gain = maxf(0.001f, DryGainHF); + for(c = 0;c < num_channels;c++) + ALfilterState_setParams(&ALSource->Params.Direct.Filter[c], + ALfilterType_LowPass, gain, + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); + } for(i = 0;i < NumSends;i++) { - coeff = lpCoeffCalc(WetGainHF[i], cw); + ALfloat gain = maxf(0.001f, WetGainHF[i]); for(c = 0;c < num_channels;c++) - ALSource->Params.Send[i].Filter[c].coeff = coeff; + ALfilterState_setParams(&ALSource->Params.Send[i].Filter[c], + ALfilterType_LowPass, gain, + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); } } @@ -499,7 +496,6 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALfloat Pitch; ALuint Frequency; ALint NumSends; - ALfloat cw; ALint i, j; DryGainHF = 1.0f; @@ -904,15 +900,14 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) for(i = 0;i < NumSends;i++) ALSource->Params.Send[i].Gain = WetGain[i]; - /* Update filter coefficients. */ - cw = cosf(F_PI*2.0f * LOWPASSFREQREF / Frequency); - ALSource->Params.Direct.Filter[0].coeff = lpCoeffCalc(DryGainHF, cw); + ALfilterState_setParams(&ALSource->Params.Direct.Filter[0], + ALfilterType_LowPass, maxf(0.001f, DryGainHF), + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); for(i = 0;i < NumSends;i++) - { - ALfloat a = lpCoeffCalc(WetGainHF[i], cw); - ALSource->Params.Send[i].Filter[0].coeff = a; - } + ALfilterState_setParams(&ALSource->Params.Send[i].Filter[0], + ALfilterType_LowPass, maxf(0.001f, WetGainHF[i]), + (ALfloat)LOWPASSFREQREF/Frequency, 0.0f); } diff --git a/Alc/mixer.c b/Alc/mixer.c index 58e3a535..b9dcc1c1 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -84,13 +84,13 @@ static void SilenceData(ALfloat *dst, ALuint samples) } -static void Filter2P(FILTER *filter, ALfloat *restrict dst, const ALfloat *restrict src, +static void DoFilter(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *restrict src, ALuint numsamples) { ALuint i; for(i = 0;i < numsamples;i++) - dst[i] = lpFilter2P(filter, src[i]); - dst[i] = lpFilter2PC(filter, src[i]); + dst[i] = ALfilterState_processSingle(filter, src[i]); + dst[i] = ALfilterState_processSingleC(filter, src[i]); } @@ -328,7 +328,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) { DirectParams *directparms = &Source->Params.Direct; - Filter2P(&directparms->Filter[chan], SrcData, ResampledData, + DoFilter(&directparms->Filter[chan], SrcData, ResampledData, DstBufferSize); Source->Params.DryMix(directparms, SrcData, chan, OutPos, SamplesToDo, DstBufferSize); @@ -340,7 +340,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) if(!sendparms->Slot) continue; - Filter2P(&sendparms->Filter[chan], SrcData, ResampledData, + DoFilter(&sendparms->Filter[chan], SrcData, ResampledData, DstBufferSize); Source->Params.WetMix(sendparms, SrcData, OutPos, SamplesToDo, DstBufferSize); diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h index f70b839e..9273f15c 100644 --- a/OpenAL32/Include/alFilter.h +++ b/OpenAL32/Include/alFilter.h @@ -47,6 +47,8 @@ ALfloat lpCoeffCalc(ALfloat g, ALfloat cw); typedef enum ALfilterType { + ALfilterType_LowPass, + ALfilterType_HighShelf, ALfilterType_LowShelf, ALfilterType_Peaking, diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index bd1b2931..8766c85e 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -61,8 +61,7 @@ typedef struct DirectParams { * target (eg. FrontLeft). Not used with HRTF. */ ALfloat Gains[MaxChannels][MaxChannels]; - /* A low-pass filter, using 2 chained one-pole filters. */ - FILTER Filter[MaxChannels]; + ALfilterState Filter[MaxChannels]; } DirectParams; typedef struct SendParams { @@ -72,8 +71,7 @@ typedef struct SendParams { * output buffer. */ ALfloat Gain; - /* A low-pass filter, using 2 chained one-pole filters. */ - FILTER Filter[MaxChannels]; + ALfilterState Filter[MaxChannels]; } SendParams; diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 5bef87fd..550c99f5 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -343,6 +343,17 @@ void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat g /* Calculate filter coefficients depending on filter type */ switch(type) { + case ALfilterType_LowPass: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f/gain) * + (1.0f/0.75f - 1.0f) + 2.0f); + filter->b[0] = (1.0f - cosf(w0)) * 0.5f; + filter->b[1] = 1.0f - cosf(w0); + filter->b[2] = (1.0f - cosf(w0)) * 0.5f; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f*cosf(w0); + filter->a[2] = 1.0f - alpha; + break; + case ALfilterType_HighShelf: alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f/gain) * (1.0f/0.75f - 1.0f) + 2.0f); |