diff options
Diffstat (limited to 'Alc')
-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. |