diff options
author | Chris Robinson <[email protected]> | 2015-10-11 10:21:37 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2015-10-11 10:21:37 -0700 |
commit | b859f1bdc3fc1c288dd041ebbcf33a54e99be82a (patch) | |
tree | 35d79554d95fcc5d3c37cbe41b6e39f201803603 | |
parent | db22465c1d7a45493b63387de70911e9ca98dead (diff) |
Avoid multiple sin, cos, and sqrt calls for filter calculations
-rw-r--r-- | OpenAL32/alFilter.c | 66 |
1 files changed, 35 insertions, 31 deletions
diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index ccf256e1..f2538818 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -338,70 +338,74 @@ void ALfilterState_clear(ALfilterState *filter) void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_mult, ALfloat bandwidth) { - ALfloat alpha; - ALfloat w0; + ALfloat alpha, sqrtgain_alpha_2; + ALfloat w0, sin_w0, cos_w0; // Limit gain to -100dB gain = maxf(gain, 0.00001f); w0 = F_TAU * freq_mult; + sin_w0 = sinf(w0); + cos_w0 = cosf(w0); /* 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; + alpha = sin_w0/2.0f*sqrtf((gain + 1.0f/gain)*(1.0f/0.75f - 1.0f) + 2.0f); + sqrtgain_alpha_2 = 2.0f * sqrtf(gain) * alpha; + filter->b[0] = gain*((gain+1.0f) + (gain-1.0f)*cos_w0 + sqrtgain_alpha_2); + filter->b[1] = -2.0f*gain*((gain-1.0f) + (gain+1.0f)*cos_w0 ); + filter->b[2] = gain*((gain+1.0f) + (gain-1.0f)*cos_w0 - sqrtgain_alpha_2); + filter->a[0] = (gain+1.0f) - (gain-1.0f)*cos_w0 + sqrtgain_alpha_2; + filter->a[1] = 2.0f* ((gain-1.0f) - (gain+1.0f)*cos_w0 ); + filter->a[2] = (gain+1.0f) - (gain-1.0f)*cos_w0 - sqrtgain_alpha_2; 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; + alpha = sin_w0/2.0f*sqrtf((gain + 1.0f/gain)*(1.0f/0.75f - 1.0f) + 2.0f); + sqrtgain_alpha_2 = 2.0f * sqrtf(gain) * alpha; + filter->b[0] = gain*((gain+1.0f) - (gain-1.0f)*cos_w0 + sqrtgain_alpha_2); + filter->b[1] = 2.0f*gain*((gain-1.0f) - (gain+1.0f)*cos_w0 ); + filter->b[2] = gain*((gain+1.0f) - (gain-1.0f)*cos_w0 - sqrtgain_alpha_2); + filter->a[0] = (gain+1.0f) + (gain-1.0f)*cos_w0 + sqrtgain_alpha_2; + filter->a[1] = -2.0f* ((gain-1.0f) + (gain+1.0f)*cos_w0 ); + filter->a[2] = (gain+1.0f) + (gain-1.0f)*cos_w0 - sqrtgain_alpha_2; break; case ALfilterType_Peaking: - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + alpha = sin_w0 * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sin_w0); filter->b[0] = 1.0f + alpha * gain; - filter->b[1] = -2.0f * cosf(w0); + filter->b[1] = -2.0f * cos_w0; filter->b[2] = 1.0f - alpha * gain; filter->a[0] = 1.0f + alpha / gain; - filter->a[1] = -2.0f * cosf(w0); + filter->a[1] = -2.0f * cos_w0; filter->a[2] = 1.0f - alpha / gain; break; case ALfilterType_LowPass: - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); - filter->b[0] = (1.0f - cosf(w0)) / 2.0f; - filter->b[1] = 1.0f - cosf(w0); - filter->b[2] = (1.0f - cosf(w0)) / 2.0f; + alpha = sin_w0 * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sin_w0); + filter->b[0] = (1.0f - cos_w0) / 2.0f; + filter->b[1] = 1.0f - cos_w0; + filter->b[2] = (1.0f - cos_w0) / 2.0f; filter->a[0] = 1.0f + alpha; - filter->a[1] = -2.0f * cosf(w0); + filter->a[1] = -2.0f * cos_w0; filter->a[2] = 1.0f - alpha; break; case ALfilterType_HighPass: - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); - filter->b[0] = (1.0f + cosf(w0)) / 2.0f; - filter->b[1] = -(1.0f + cosf(w0)); - filter->b[2] = (1.0f + cosf(w0)) / 2.0f; + alpha = sin_w0 * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sin_w0); + filter->b[0] = (1.0f + cos_w0) / 2.0f; + filter->b[1] = -(1.0f + cos_w0); + filter->b[2] = (1.0f + cos_w0) / 2.0f; filter->a[0] = 1.0f + alpha; - filter->a[1] = -2.0f * cosf(w0); + filter->a[1] = -2.0f * cos_w0; filter->a[2] = 1.0f - alpha; break; case ALfilterType_BandPass: - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + alpha = sin_w0 * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sin_w0); filter->b[0] = alpha; filter->b[1] = 0; filter->b[2] = -alpha; filter->a[0] = 1.0f + alpha; - filter->a[1] = -2.0f * cosf(w0); + filter->a[1] = -2.0f * cos_w0; filter->a[2] = 1.0f - alpha; break; } |