diff options
author | Chris Robinson <[email protected]> | 2017-05-26 08:40:32 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-05-26 08:52:07 -0700 |
commit | 2b14c1d62389f3bb8fe52cac9b8d3cc97da0838f (patch) | |
tree | b9435bfb739d98f60fa9ee5559318c227967a935 | |
parent | 59d016dfcded9211f8342f39b619502487228401 (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.c | 27 | ||||
-rw-r--r-- | Alc/effects/flanger.c | 27 |
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++; \ } \ |