aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-05-26 08:40:32 -0700
committerChris Robinson <[email protected]>2017-05-26 08:52:07 -0700
commit2b14c1d62389f3bb8fe52cac9b8d3cc97da0838f (patch)
treeb9435bfb739d98f60fa9ee5559318c227967a935
parent59d016dfcded9211f8342f39b619502487228401 (diff)
Properly handle the chorus and flanger LFOs
The effects' specified delay is the average delay time, meaning the delay offset should move between -n and +n relative to the delay, where n <= delay.
-rw-r--r--Alc/effects/chorus.c27
-rw-r--r--Alc/effects/flanger.c27
2 files changed, 30 insertions, 24 deletions
diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c
index df8721b3..21db73f6 100644
--- a/Alc/effects/chorus.c
+++ b/Alc/effects/chorus.c
@@ -91,7 +91,7 @@ static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Dev
ALsizei maxlen;
ALsizei it;
- maxlen = fastf2u(AL_CHORUS_MAX_DELAY * 3.0f * Device->Frequency) + 1;
+ maxlen = fastf2u(AL_CHORUS_MAX_DELAY * 2.0f * Device->Frequency) + 1;
maxlen = NextPowerOf2(maxlen);
if(maxlen != state->BufferLength)
@@ -131,9 +131,10 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device
state->waveform = CWF_Sinusoid;
break;
}
- state->depth = props->Chorus.Depth;
state->feedback = props->Chorus.Feedback;
state->delay = fastf2i(props->Chorus.Delay * frequency);
+ /* The LFO depth is scaled to be relative to the sample delay. */
+ state->depth = props->Chorus.Depth * state->delay;
/* Gains for left and right sides */
CalcAngleCoeffs(-F_PI_2, 0.0f, 0.0f, coeffs);
@@ -172,13 +173,13 @@ static inline void Triangle(ALint *delay_left, ALint *delay_right, ALuint offset
{
ALfloat lfo_value;
- lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = 1.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_left = fastf2i(lfo_value) + state->delay;
offset += state->lfo_disp;
- lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = 1.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_right = fastf2i(lfo_value) + state->delay;
}
@@ -186,13 +187,13 @@ static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALuint offset
{
ALfloat lfo_value;
- lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = sinf(state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_left = fastf2i(lfo_value) + state->delay;
offset += state->lfo_disp;
- lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = sinf(state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_right = fastf2i(lfo_value) + state->delay;
}
@@ -212,11 +213,13 @@ static void Process##Func(ALchorusState *state, const ALsizei SamplesToDo, \
ALint delay_left, delay_right; \
Func(&delay_left, &delay_right, offset, state); \
\
+ leftbuf[offset&bufmask] = SamplesIn[it]; \
out[it][0] = leftbuf[(offset-delay_left)&bufmask]; \
- leftbuf[offset&bufmask] = (out[it][0]+SamplesIn[it]) * feedback; \
+ leftbuf[offset&bufmask] += out[it][0] * feedback; \
\
+ rightbuf[offset&bufmask] = SamplesIn[it]; \
out[it][1] = rightbuf[(offset-delay_right)&bufmask]; \
- rightbuf[offset&bufmask] = (out[it][1]+SamplesIn[it]) * feedback; \
+ rightbuf[offset&bufmask] += out[it][1] * feedback; \
\
offset++; \
} \
diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c
index 346478e4..5593d549 100644
--- a/Alc/effects/flanger.c
+++ b/Alc/effects/flanger.c
@@ -91,7 +91,7 @@ static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *D
ALsizei maxlen;
ALsizei it;
- maxlen = fastf2i(AL_FLANGER_MAX_DELAY * 3.0f * Device->Frequency) + 1;
+ maxlen = fastf2i(AL_FLANGER_MAX_DELAY * 2.0f * Device->Frequency) + 1;
maxlen = NextPowerOf2(maxlen);
if(maxlen != state->BufferLength)
@@ -131,9 +131,10 @@ static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Devi
state->waveform = FWF_Sinusoid;
break;
}
- state->depth = props->Flanger.Depth;
state->feedback = props->Flanger.Feedback;
state->delay = fastf2i(props->Flanger.Delay * frequency);
+ /* The LFO depth is scaled to be relative to the sample delay. */
+ state->depth = props->Flanger.Depth * state->delay;
/* Gains for left and right sides */
CalcAngleCoeffs(-F_PI_2, 0.0f, 0.0f, coeffs);
@@ -172,13 +173,13 @@ static inline void Triangle(ALint *delay_left, ALint *delay_right, ALuint offset
{
ALfloat lfo_value;
- lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = 1.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_left = fastf2i(lfo_value) + state->delay;
offset += state->lfo_disp;
- lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = 1.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_right = fastf2i(lfo_value) + state->delay;
}
@@ -186,13 +187,13 @@ static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALuint offset
{
ALfloat lfo_value;
- lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = sinf(state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_left = fastf2i(lfo_value) + state->delay;
offset += state->lfo_disp;
- lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range));
- lfo_value *= state->depth * state->delay;
+ lfo_value = sinf(state->lfo_scale*(offset%state->lfo_range));
+ lfo_value *= state->depth;
*delay_right = fastf2i(lfo_value) + state->delay;
}
@@ -212,11 +213,13 @@ static void Process##Func(ALflangerState *state, const ALsizei SamplesToDo, \
ALint delay_left, delay_right; \
Func(&delay_left, &delay_right, offset, state); \
\
+ leftbuf[offset&bufmask] = SamplesIn[it]; \
out[it][0] = leftbuf[(offset-delay_left)&bufmask]; \
- leftbuf[offset&bufmask] = (out[it][0]+SamplesIn[it]) * feedback; \
+ leftbuf[offset&bufmask] += out[it][0] * feedback; \
\
+ rightbuf[offset&bufmask] = SamplesIn[it]; \
out[it][1] = rightbuf[(offset-delay_right)&bufmask]; \
- rightbuf[offset&bufmask] = (out[it][1]+SamplesIn[it]) * feedback; \
+ rightbuf[offset&bufmask] += out[it][1] * feedback; \
\
offset++; \
} \