aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/effects/chorus.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2013-11-08 16:33:42 -0800
committerChris Robinson <[email protected]>2013-11-08 16:33:42 -0800
commit9228d133335811f9d27648454ebad1ece0493e7c (patch)
tree6c277e56b7bd8c7077e3e46d813b7376673188b6 /Alc/effects/chorus.c
parentbca959f37273a5f6d152dc82327f8e8e60508b57 (diff)
Use integer modulo for chorus and flanger
Also simplify LFO coefficient calculations.
Diffstat (limited to 'Alc/effects/chorus.c')
-rw-r--r--Alc/effects/chorus.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c
index ce535cfe..a1c0ccf3 100644
--- a/Alc/effects/chorus.c
+++ b/Alc/effects/chorus.c
@@ -36,7 +36,8 @@ typedef struct ALchorusState {
ALfloat *SampleBufferLeft;
ALfloat *SampleBufferRight;
ALuint BufferLength;
- ALint offset;
+ ALuint offset;
+ ALuint lfo_range;
ALfloat lfo_coeff;
ALint lfo_disp;
@@ -108,55 +109,55 @@ static ALvoid ALchorusState_update(ALchorusState *state, ALCdevice *Device, cons
phase = Slot->EffectProps.Chorus.Phase;
rate = Slot->EffectProps.Chorus.Rate;
-
- /* Calculate LFO coefficient */
- switch (state->waveform)
+ if(!(rate > 0.0f))
{
- case AL_CHORUS_WAVEFORM_TRIANGLE:
- if(rate == 0.0f)
- state->lfo_coeff = 0.0f;
- else
- state->lfo_coeff = 1.0f / (frequency / rate);
- break;
- case AL_CHORUS_WAVEFORM_SINUSOID:
- if(rate == 0.0f)
- state->lfo_coeff = 0.0f;
- else
- state->lfo_coeff = F_2PI / (frequency / rate);
- break;
- }
-
- /* Calculate lfo phase displacement */
- if(phase == 0 || rate == 0.0f)
+ state->lfo_coeff = 0.0f;
+ state->lfo_range = 1;
state->lfo_disp = 0;
+ }
else
- state->lfo_disp = fastf2i(frequency / rate / (360.0f/phase));
+ {
+ /* Calculate LFO coefficient */
+ state->lfo_range = fastf2u(frequency/rate + 0.5f);
+ switch(state->waveform)
+ {
+ case AL_CHORUS_WAVEFORM_TRIANGLE:
+ state->lfo_coeff = 1.0f / state->lfo_range;
+ break;
+ case AL_CHORUS_WAVEFORM_SINUSOID:
+ state->lfo_coeff = F_2PI / state->lfo_range;
+ break;
+ }
+
+ /* Calculate lfo phase displacement */
+ state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f));
+ }
}
-static inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state)
+static inline void Triangle(ALint *delay_left, ALint *delay_right, ALuint offset, const ALchorusState *state)
{
ALfloat lfo_value;
- lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff*offset*4.0f, 4.0f));
+ lfo_value = 2.0f - fabsf(2.0f - state->lfo_coeff*(offset%state->lfo_range)*4.0f);
lfo_value *= state->depth * state->delay;
*delay_left = fastf2i(lfo_value) + state->delay;
- lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff *
- (offset+state->lfo_disp)*4.0f,
- 4.0f));
+ offset += state->lfo_disp;
+ lfo_value = 2.0f - fabsf(2.0f - state->lfo_coeff*(offset%state->lfo_range)*4.0f);
lfo_value *= state->depth * state->delay;
*delay_right = fastf2i(lfo_value) + state->delay;
}
-static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state)
+static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALuint offset, const ALchorusState *state)
{
ALfloat lfo_value;
- lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff*offset, F_2PI));
+ lfo_value = 1.0f + sinf(state->lfo_coeff*(offset%state->lfo_range));
lfo_value *= state->depth * state->delay;
*delay_left = fastf2i(lfo_value) + state->delay;
- lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff*(offset+state->lfo_disp), F_2PI));
+ offset += state->lfo_disp;
+ lfo_value = 1.0f + sinf(state->lfo_coeff*(offset%state->lfo_range));
lfo_value *= state->depth * state->delay;
*delay_right = fastf2i(lfo_value) + state->delay;
}
@@ -253,6 +254,7 @@ static ALeffectState *ALchorusStateFactory_create(ALchorusStateFactory *UNUSED(f
state->SampleBufferLeft = NULL;
state->SampleBufferRight = NULL;
state->offset = 0;
+ state->lfo_range = 1;
return STATIC_CAST(ALeffectState, state);
}