aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-10-06 19:45:48 -0700
committerChris Robinson <[email protected]>2016-10-06 19:45:48 -0700
commitf826f8684280c722a19ccb1814a0ec0ae4b83ded (patch)
treeedf6e44e9837702730807d386ac025cf96ccbefe
parent76cd6797b7e58272e4e5268f1461f209045b9de4 (diff)
Decorrelate the early reflection inputs
-rw-r--r--Alc/effects/reverb.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c
index 46883104..7dfa37d1 100644
--- a/Alc/effects/reverb.c
+++ b/Alc/effects/reverb.c
@@ -97,6 +97,7 @@ typedef struct ALreverbState {
/* There are actually 4 decorrelator taps, but the first occurs at the late
* reverb tap.
*/
+ ALuint EarlyDecoTap[3];
ALuint LateDecoTap[3];
struct {
@@ -222,6 +223,9 @@ static void ALreverbState_Construct(ALreverbState *state)
state->Delay.Line = NULL;
state->DelayTap[0] = 0;
state->DelayTap[1] = 0;
+ state->EarlyDecoTap[0] = 0;
+ state->EarlyDecoTap[1] = 0;
+ state->EarlyDecoTap[2] = 0;
state->LateDecoTap[0] = 0;
state->LateDecoTap[1] = 0;
state->LateDecoTap[2] = 0;
@@ -324,9 +328,10 @@ static const ALfloat MODULATION_FILTER_CONST = 100000.0f;
// the echo effect. It uses the following line length (in seconds).
static const ALfloat ECHO_ALLPASS_LENGTH = 0.0133f;
-// Input into the late reverb is decorrelated between four channels. Their
-// timings are dependent on a fraction and multiplier. See the
-// UpdateDecorrelator() routine for the calculations involved.
+/* Input into the early reflections and late reverb are decorrelated between
+ * four channels. Their timings are dependent on a fraction and multiplier. See
+ * the UpdateDecorrelator() routine for the calculations involved.
+ */
static const ALfloat DECO_FRACTION = 0.15f;
static const ALfloat DECO_MULTIPLIER = 2.0f;
@@ -691,16 +696,20 @@ static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALreverbStat
ALuint index;
ALfloat length;
- /* The late reverb inputs are decorrelated to smooth the reverb tail and
- * reduce harsh echos. The first tap occurs immediately, while the
- * remaining taps are delayed by multiples of a fraction of the smallest
- * cyclical delay time.
+ /* The early reflections and late reverb inputs are decorrelated to provide
+ * time-varying reflections, smooth out the reverb tail, and reduce harsh
+ * echos. The first tap occurs immediately, while the remaining taps are
+ * delayed by multiples of a fraction of the smallest cyclical delay time.
*
* offset[index] = (FRACTION (MULTIPLIER^index)) smallest_delay
*/
for(index = 0;index < 3;index++)
{
length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (ALfloat)index)) *
+ EARLY_LINE_LENGTH[0];
+ State->EarlyDecoTap[index] = fastf2u(length * frequency) + State->DelayTap[0];
+
+ length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (ALfloat)index)) *
LATE_LINE_LENGTH[0] * (1.0f + (density * LATE_LINE_MULTIPLIER));
State->LateDecoTap[index] = fastf2u(length * frequency) + State->DelayTap[1];
}
@@ -1104,9 +1113,9 @@ static ALvoid EarlyReflection(ALreverbState *State, ALuint todo, ALfloat (*restr
/* Obtain the first reflection samples from the main delay line. */
f[0] = DelayLineOut(&State->Delay, (offset-State->DelayTap[0])*4 + 0);
- f[1] = DelayLineOut(&State->Delay, (offset-State->DelayTap[0])*4 + 1);
- f[2] = DelayLineOut(&State->Delay, (offset-State->DelayTap[0])*4 + 2);
- f[3] = DelayLineOut(&State->Delay, (offset-State->DelayTap[0])*4 + 3);
+ f[1] = DelayLineOut(&State->Delay, (offset-State->EarlyDecoTap[0])*4 + 1);
+ f[2] = DelayLineOut(&State->Delay, (offset-State->EarlyDecoTap[1])*4 + 2);
+ f[3] = DelayLineOut(&State->Delay, (offset-State->EarlyDecoTap[2])*4 + 3);
/* The following uses a lossless scattering junction from waveguide
* theory. It actually amounts to a householder mixing matrix, which