diff options
author | Chris Robinson <[email protected]> | 2016-09-11 12:25:06 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-09-11 12:25:06 -0700 |
commit | 651715abc96dd2925486507f8197a18a5f2f11e3 (patch) | |
tree | 1aa43badd3265974348cc0e4b6faaebe25dfd9c7 | |
parent | 4fcf9279febdaf9136e2ea61602dc39dcf5391dd (diff) |
Combine the reverb decorrelator delay line with the main delay line
Since it was merely acting as an extension of it anyway, with the second delay
line tap (for late reverb) copying attenuated samples to the decorrelator line
that was being tapped off of. Just extend the delay line and offset the
decorrelator taps to be relative to the late reverb tap.
-rw-r--r-- | Alc/effects/reverb.c | 72 |
1 files changed, 26 insertions, 46 deletions
diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index ef25c076..7068e077 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -88,11 +88,16 @@ typedef struct ALreverbState { ALfloat Filter; } Mod; // EAX only - // Initial effect delay. + /* Core delay line (early reflections and late reverb tap from this). */ DelayLine Delay; - // The tap points for the initial delay. First tap goes to early - // reflections, the last to late reverb. + /* The tap points for the initial delay. First tap goes to early + * reflections, second to late reverb. + */ ALuint DelayTap[2]; + /* There are actually 4 decorrelator taps, but the first occurs at the late + * reverb tap. + */ + ALuint DecoTap[3]; struct { // Early reflections are done with 4 delay lines. @@ -105,12 +110,6 @@ typedef struct ALreverbState { ALfloat PanGain[4][MAX_OUTPUT_CHANNELS+2]; } Early; - // Decorrelator delay line. - DelayLine Decorrelator; - // There are actually 4 decorrelator taps, but the first occurs at the - // initial sample. - ALuint DecoTap[3]; - struct { // Output gain for late reverb. ALfloat Gain; @@ -213,6 +212,9 @@ static void ALreverbState_Construct(ALreverbState *state) state->Delay.Line = NULL; state->DelayTap[0] = 0; state->DelayTap[1] = 0; + state->DecoTap[0] = 0; + state->DecoTap[1] = 0; + state->DecoTap[2] = 0; for(index = 0;index < 4;index++) { @@ -222,12 +224,6 @@ static void ALreverbState_Construct(ALreverbState *state) state->Early.Offset[index] = 0; } - state->Decorrelator.Mask = 0; - state->Decorrelator.Line = NULL; - state->DecoTap[0] = 0; - state->DecoTap[1] = 0; - state->DecoTap[2] = 0; - state->Late.Gain = 0.0f; state->Late.DensityGain = 0.0f; state->Late.ApFeedCoeff = 0.0f; @@ -407,11 +403,15 @@ static ALboolean AllocLines(ALuint frequency, ALreverbState *State) totalSamples += CalcLineLength(length, totalSamples, frequency, 1, &State->Mod.Delay); - // The initial delay is the sum of the reflections and late reverb - // delays. This must include space for storing a loop update to feed the - // early reflections, decorrelator, and echo. + /* The initial delay is the sum of the reflections and late reverb delays. + * The decorrelator length is calculated from the lowest reverb density (a + * parameter value of 1). This must include space for storing a loop + * update. + */ length = AL_EAXREVERB_MAX_REFLECTIONS_DELAY + AL_EAXREVERB_MAX_LATE_REVERB_DELAY; + length += (DECO_FRACTION * DECO_MULTIPLIER * DECO_MULTIPLIER) * + LATE_LINE_LENGTH[0] * (1.0f + LATE_LINE_MULTIPLIER); totalSamples += CalcLineLength(length, totalSamples, frequency, MAX_UPDATE_SAMPLES, &State->Delay); @@ -420,14 +420,6 @@ static ALboolean AllocLines(ALuint frequency, ALreverbState *State) totalSamples += CalcLineLength(EARLY_LINE_LENGTH[index], totalSamples, frequency, 0, &State->Early.Delay[index]); - // The decorrelator line is calculated from the lowest reverb density (a - // parameter value of 1). This must include space for storing a loop update - // to feed the late reverb. - length = (DECO_FRACTION * DECO_MULTIPLIER * DECO_MULTIPLIER) * - LATE_LINE_LENGTH[0] * (1.0f + LATE_LINE_MULTIPLIER); - totalSamples += CalcLineLength(length, totalSamples, frequency, MAX_UPDATE_SAMPLES, - &State->Decorrelator); - // The late all-pass lines. for(index = 0;index < 4;index++) totalSamples += CalcLineLength(ALLPASS_LINE_LENGTH[index], totalSamples, @@ -462,7 +454,6 @@ static ALboolean AllocLines(ALuint frequency, ALreverbState *State) // Update all delays to reflect the new sample buffer. RealizeLineOffset(State->SampleBuffer, &State->Delay); - RealizeLineOffset(State->SampleBuffer, &State->Decorrelator); for(index = 0;index < 4;index++) { RealizeLineOffset(State->SampleBuffer, &State->Early.Delay[index]); @@ -697,7 +688,7 @@ static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALreverbStat { length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (ALfloat)index)) * LATE_LINE_LENGTH[0] * (1.0f + (density * LATE_LINE_MULTIPLIER)); - State->DecoTap[index] = fastf2u(length * frequency); + State->DecoTap[index] = fastf2u(length * frequency) + State->DelayTap[1]; } } @@ -1023,12 +1014,12 @@ static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device UpdateDelayLine(props->Reverb.ReflectionsDelay, props->Reverb.LateReverbDelay, frequency, State); - // Update the early lines. - UpdateEarlyLines(props->Reverb.LateReverbDelay, State); - // Update the decorrelator. UpdateDecorrelator(props->Reverb.Density, frequency, State); + // Update the early lines. + UpdateEarlyLines(props->Reverb.LateReverbDelay, State); + // Get the mixing matrix coefficients (x and y). CalcMatrixCoeffs(props->Reverb.Diffusion, &x, &y); // Then divide x into y to simplify the matrix calculation. @@ -1230,17 +1221,6 @@ static inline ALvoid LateReverb(ALreverbState *State, ALuint todo, ALfloat (*res ALuint offset; ALuint base, i; - // Feed the decorrelator from the energy-attenuated output of the second - // delay tap. - offset = State->Offset; - for(i = 0;i < todo;i++) - { - ALfloat sample = DelayLineOut(&State->Delay, offset - State->DelayTap[1]) * - State->Late.DensityGain; - DelayLineIn(&State->Decorrelator, offset, sample); - offset++; - } - offset = State->Offset; for(base = 0;base < todo;) { @@ -1250,10 +1230,10 @@ static inline ALvoid LateReverb(ALreverbState *State, ALuint todo, ALfloat (*res for(i = 0;i < tmp_todo;i++) { /* Obtain four decorrelated input samples. */ - f[0] = DelayLineOut(&State->Decorrelator, offset); - f[1] = DelayLineOut(&State->Decorrelator, offset-State->DecoTap[0]); - f[2] = DelayLineOut(&State->Decorrelator, offset-State->DecoTap[1]); - f[3] = DelayLineOut(&State->Decorrelator, offset-State->DecoTap[2]); + f[0] = DelayLineOut(&State->Delay, offset-State->DelayTap[1]) * State->Late.DensityGain; + f[1] = DelayLineOut(&State->Delay, offset-State->DecoTap[0]) * State->Late.DensityGain; + f[2] = DelayLineOut(&State->Delay, offset-State->DecoTap[1]) * State->Late.DensityGain; + f[3] = DelayLineOut(&State->Delay, offset-State->DecoTap[2]) * State->Late.DensityGain; /* Add the decayed results of the cyclical delay lines, then pass * the results through the low-pass filters. |