diff options
author | Chris Robinson <[email protected]> | 2013-05-27 15:32:02 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2013-05-27 15:32:02 -0700 |
commit | b1ae44206f66114fb7d3a76e912fbdeaeb792c7b (patch) | |
tree | 6f58f6f5b1ec43352c9ea897401abfd83a0d8948 /OpenAL32 | |
parent | 0ad71a67d4c3003ffe73f5fddfea963fab5e7bf8 (diff) |
Move ALEQFilter to alFilter.c/h and rename it to ALfilterState
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alFilter.h | 43 | ||||
-rw-r--r-- | OpenAL32/alFilter.c | 78 |
2 files changed, 121 insertions, 0 deletions
diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h index 94feb3ee..f70b839e 100644 --- a/OpenAL32/Include/alFilter.h +++ b/OpenAL32/Include/alFilter.h @@ -46,6 +46,49 @@ static __inline ALfloat lpFilter2PC(const FILTER *iir, ALfloat input) ALfloat lpCoeffCalc(ALfloat g, ALfloat cw); +typedef enum ALfilterType { + ALfilterType_HighShelf, + ALfilterType_LowShelf, + ALfilterType_Peaking, +} ALfilterType; + +typedef struct ALfilterState { + ALfloat x[2]; /* History of two last input samples */ + ALfloat y[2]; /* History of two last output samples */ + ALfloat a[3]; /* Transfer function coefficients "a" */ + ALfloat b[3]; /* Transfer function coefficients "b" */ +} ALfilterState; + +void ALfilterState_clear(ALfilterState *filter); +void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_scale, ALfloat bandwidth); + +static __inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample) +{ + ALfloat outsmp; + + outsmp = filter->b[0] * sample + + filter->b[1] * filter->x[0] + + filter->b[2] * filter->x[1] - + filter->a[1] * filter->y[0] - + filter->a[2] * filter->y[1]; + filter->x[1] = filter->x[0]; + filter->x[0] = sample; + filter->y[1] = filter->y[0]; + filter->y[0] = outsmp; + + return outsmp; +} + +static __inline ALfloat ALfilterState_processSingleC(const ALfilterState *filter, ALfloat sample) +{ + return filter->b[0] * sample + + filter->b[1] * filter->x[0] + + filter->b[2] * filter->x[1] - + filter->a[1] * filter->y[0] - + filter->a[2] * filter->y[1]; +} + + typedef struct ALfilter { // Filter type (AL_FILTER_NULL, ...) ALenum type; diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 312cf681..6b4ce633 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -325,6 +325,84 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *va } +void ALfilterState_clear(ALfilterState *filter) +{ + filter->x[0] = 0.0f; + filter->x[1] = 0.0f; + filter->y[0] = 0.0f; + filter->y[1] = 0.0f; +} + +void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_scale, ALfloat bandwidth) +{ + ALfloat alpha; + ALfloat w0; + + w0 = 2.0f*F_PI * freq_scale; + + /* Calculate filter coefficients depending on filter type */ + switch(type) + { + case ALfilterType_HighShelf: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f/gain) * + (1.0f/0.75f - 1.0f) + 2.0f); + filter->b[0] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + filter->b[1] = -2.0f * gain * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + filter->b[2] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + filter->a[0] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + filter->a[1] = 2.0f * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + filter->a[2] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case ALfilterType_LowShelf: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * + (1.0f / 0.75f - 1.0f) + 2.0f); + filter->b[0] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + filter->b[1] = 2.0f * gain * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + filter->b[2] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + filter->a[0] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + filter->a[1] = -2.0f * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + filter->a[2] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case ALfilterType_Peaking: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = 1.0f + alpha * gain; + filter->b[1] = -2.0f * cosf(w0); + filter->b[2] = 1.0f - alpha * gain; + filter->a[0] = 1.0f + alpha / gain; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha / gain; + break; + } + + filter->b[0] /= filter->a[0]; + filter->b[1] /= filter->a[0]; + filter->b[2] /= filter->a[0]; + filter->a[0] /= filter->a[0]; + filter->a[1] /= filter->a[0]; + filter->a[2] /= filter->a[0]; +} + + ALfloat lpCoeffCalc(ALfloat g, ALfloat cw) { ALfloat a = 0.0f; |