Make the reverb's early and late feedback lines interleaved
This commit is contained in:
parent
cc1b774837
commit
b2760baa64
@ -117,7 +117,7 @@ typedef struct ALreverbState {
|
|||||||
/* Echo lines are used to complete the second half of the early
|
/* Echo lines are used to complete the second half of the early
|
||||||
* reflections.
|
* reflections.
|
||||||
*/
|
*/
|
||||||
DelayLine Delay[4];
|
DelayLine Delay;
|
||||||
ALsizei Offset[4][2];
|
ALsizei Offset[4][2];
|
||||||
ALfloat Coeff[4];
|
ALfloat Coeff[4];
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ typedef struct ALreverbState {
|
|||||||
ALfloat DensityGain;
|
ALfloat DensityGain;
|
||||||
|
|
||||||
/* Recursive delay lines are used fill in the reverb tail. */
|
/* Recursive delay lines are used fill in the reverb tail. */
|
||||||
DelayLine Delay[4];
|
DelayLine Delay;
|
||||||
ALsizei Offset[4][2];
|
ALsizei Offset[4][2];
|
||||||
|
|
||||||
/* T60 decay filters are used to simulate absorption. */
|
/* T60 decay filters are used to simulate absorption. */
|
||||||
@ -228,14 +228,14 @@ static void ALreverbState_Construct(ALreverbState *state)
|
|||||||
state->MixX = 0.0f;
|
state->MixX = 0.0f;
|
||||||
state->MixY = 0.0f;
|
state->MixY = 0.0f;
|
||||||
|
|
||||||
|
state->Early.Delay.Mask = 0;
|
||||||
|
state->Early.Delay.Line = NULL;
|
||||||
state->Early.VecAp.Delay.Mask = 0;
|
state->Early.VecAp.Delay.Mask = 0;
|
||||||
state->Early.VecAp.Delay.Line = NULL;
|
state->Early.VecAp.Delay.Line = NULL;
|
||||||
for(i = 0;i < 4;i++)
|
for(i = 0;i < 4;i++)
|
||||||
{
|
{
|
||||||
state->Early.VecAp.Offset[i][0] = 0;
|
state->Early.VecAp.Offset[i][0] = 0;
|
||||||
state->Early.VecAp.Offset[i][1] = 0;
|
state->Early.VecAp.Offset[i][1] = 0;
|
||||||
state->Early.Delay[i].Mask = 0;
|
|
||||||
state->Early.Delay[i].Line = NULL;
|
|
||||||
state->Early.Offset[i][0] = 0;
|
state->Early.Offset[i][0] = 0;
|
||||||
state->Early.Offset[i][1] = 0;
|
state->Early.Offset[i][1] = 0;
|
||||||
state->Early.Coeff[i] = 0.0f;
|
state->Early.Coeff[i] = 0.0f;
|
||||||
@ -249,6 +249,8 @@ static void ALreverbState_Construct(ALreverbState *state)
|
|||||||
|
|
||||||
state->Late.DensityGain = 0.0f;
|
state->Late.DensityGain = 0.0f;
|
||||||
|
|
||||||
|
state->Late.Delay.Mask = 0;
|
||||||
|
state->Late.Delay.Line = NULL;
|
||||||
state->Late.VecAp.Delay.Mask = 0;
|
state->Late.VecAp.Delay.Mask = 0;
|
||||||
state->Late.VecAp.Delay.Line = NULL;
|
state->Late.VecAp.Delay.Line = NULL;
|
||||||
for(i = 0;i < 4;i++)
|
for(i = 0;i < 4;i++)
|
||||||
@ -256,8 +258,6 @@ static void ALreverbState_Construct(ALreverbState *state)
|
|||||||
state->Late.VecAp.Offset[i][0] = 0;
|
state->Late.VecAp.Offset[i][0] = 0;
|
||||||
state->Late.VecAp.Offset[i][1] = 0;
|
state->Late.VecAp.Offset[i][1] = 0;
|
||||||
|
|
||||||
state->Late.Delay[i].Mask = 0;
|
|
||||||
state->Late.Delay[i].Line = NULL;
|
|
||||||
state->Late.Offset[i][0] = 0;
|
state->Late.Offset[i][0] = 0;
|
||||||
state->Late.Offset[i][1] = 0;
|
state->Late.Offset[i][1] = 0;
|
||||||
|
|
||||||
@ -556,12 +556,9 @@ static ALboolean AllocLines(const ALuint frequency, ALreverbState *State)
|
|||||||
&State->Early.VecAp.Delay);
|
&State->Early.VecAp.Delay);
|
||||||
|
|
||||||
/* The early reflection lines. */
|
/* The early reflection lines. */
|
||||||
for(i = 0;i < 4;i++)
|
length = EARLY_LINE_LENGTHS[3] * multiplier;
|
||||||
{
|
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, 4,
|
||||||
length = EARLY_LINE_LENGTHS[i] * multiplier;
|
&State->Early.Delay);
|
||||||
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, 1,
|
|
||||||
&State->Early.Delay[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The late vector all-pass line. Multiply by 4, for 4 interleaved channels. */
|
/* The late vector all-pass line. Multiply by 4, for 4 interleaved channels. */
|
||||||
length = (LATE_ALLPASS_LENGTHS[0]+LATE_ALLPASS_LENGTHS[1]+
|
length = (LATE_ALLPASS_LENGTHS[0]+LATE_ALLPASS_LENGTHS[1]+
|
||||||
@ -575,13 +572,10 @@ static ALboolean AllocLines(const ALuint frequency, ALreverbState *State)
|
|||||||
* maximum modulation time and depth coefficient, and halved for the low-
|
* maximum modulation time and depth coefficient, and halved for the low-
|
||||||
* to-high frequency swing.
|
* to-high frequency swing.
|
||||||
*/
|
*/
|
||||||
for(i = 0;i < 4;i++)
|
length = maxf(AL_EAXREVERB_MAX_ECHO_TIME, LATE_LINE_LENGTHS[3]*multiplier) +
|
||||||
{
|
AL_EAXREVERB_MAX_MODULATION_TIME*MODULATION_DEPTH_COEFF/2.0f;
|
||||||
length = maxf(AL_EAXREVERB_MAX_ECHO_TIME, LATE_LINE_LENGTHS[i]*multiplier) +
|
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, 4,
|
||||||
AL_EAXREVERB_MAX_MODULATION_TIME*MODULATION_DEPTH_COEFF/2.0f;
|
&State->Late.Delay);
|
||||||
totalSamples += CalcLineLength(length, totalSamples, frequency, 0, 1,
|
|
||||||
&State->Late.Delay[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(totalSamples != State->TotalSamples)
|
if(totalSamples != State->TotalSamples)
|
||||||
{
|
{
|
||||||
@ -599,11 +593,9 @@ static ALboolean AllocLines(const ALuint frequency, ALreverbState *State)
|
|||||||
/* Update all delays to reflect the new sample buffer. */
|
/* Update all delays to reflect the new sample buffer. */
|
||||||
RealizeLineOffset(State->SampleBuffer, &State->Delay);
|
RealizeLineOffset(State->SampleBuffer, &State->Delay);
|
||||||
RealizeLineOffset(State->SampleBuffer, &State->Early.VecAp.Delay);
|
RealizeLineOffset(State->SampleBuffer, &State->Early.VecAp.Delay);
|
||||||
for(i = 0;i < 4;i++)
|
RealizeLineOffset(State->SampleBuffer, &State->Early.Delay);
|
||||||
RealizeLineOffset(State->SampleBuffer, &State->Early.Delay[i]);
|
|
||||||
RealizeLineOffset(State->SampleBuffer, &State->Late.VecAp.Delay);
|
RealizeLineOffset(State->SampleBuffer, &State->Late.VecAp.Delay);
|
||||||
for(i = 0;i < 4;i++)
|
RealizeLineOffset(State->SampleBuffer, &State->Late.Delay);
|
||||||
RealizeLineOffset(State->SampleBuffer, &State->Late.Delay[i]);
|
|
||||||
|
|
||||||
/* Clear the sample buffer. */
|
/* Clear the sample buffer. */
|
||||||
for(i = 0;i < State->TotalSamples;i++)
|
for(i = 0;i < State->TotalSamples;i++)
|
||||||
@ -1442,6 +1434,22 @@ static inline ALvoid DelayLineIn(DelayLine *Delay, const ALsizei offset, const A
|
|||||||
Delay->Line[offset&Delay->Mask] = in;
|
Delay->Line[offset&Delay->Mask] = in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ALvoid DelayLineIn4(DelayLine *Delay, ALsizei offset, const ALfloat in[4])
|
||||||
|
{
|
||||||
|
ALsizei i;
|
||||||
|
offset = (offset*4) & Delay->Mask;
|
||||||
|
for(i = 0;i < 4;i++)
|
||||||
|
Delay->Line[offset+i] = in[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ALvoid DelayLineIn4Rev(DelayLine *Delay, ALsizei offset, const ALfloat in[4])
|
||||||
|
{
|
||||||
|
ALsizei i;
|
||||||
|
offset = (offset*4) & Delay->Mask;
|
||||||
|
for(i = 0;i < 4;i++)
|
||||||
|
Delay->Line[offset+i] = in[3-i];
|
||||||
|
}
|
||||||
|
|
||||||
static void CalcModulationDelays(ALreverbState *State, ALfloat *restrict delays, const ALsizei todo)
|
static void CalcModulationDelays(ALreverbState *State, ALfloat *restrict delays, const ALsizei todo)
|
||||||
{
|
{
|
||||||
ALfloat sinus, range;
|
ALfloat sinus, range;
|
||||||
@ -1554,8 +1562,7 @@ static void VectorAllpass_##T(ALfloat *restrict vec, const ALsizei offset, \
|
|||||||
\
|
\
|
||||||
VectorPartialScatter(f, xCoeff, yCoeff); \
|
VectorPartialScatter(f, xCoeff, yCoeff); \
|
||||||
\
|
\
|
||||||
for(i = 0;i < 4;i++) \
|
DelayLineIn4(&Vap->Delay, offset, f); \
|
||||||
DelayLineIn(&Vap->Delay, offset*4 + i, f[i]); \
|
|
||||||
}
|
}
|
||||||
DECL_TEMPLATE(Unfaded)
|
DECL_TEMPLATE(Unfaded)
|
||||||
DECL_TEMPLATE(Faded)
|
DECL_TEMPLATE(Faded)
|
||||||
@ -1614,14 +1621,13 @@ static ALvoid EarlyReflection_##T(ALreverbState *State, const ALsizei todo, \
|
|||||||
VectorAllpass_##T(f, offset, apFeedCoeff, mixX, mixY, fade, \
|
VectorAllpass_##T(f, offset, apFeedCoeff, mixX, mixY, fade, \
|
||||||
&State->Early.VecAp); \
|
&State->Early.VecAp); \
|
||||||
\
|
\
|
||||||
for(j = 0;j < 4;j++) \
|
DelayLineIn4Rev(&State->Early.Delay, offset, f); \
|
||||||
DelayLineIn(&State->Early.Delay[j], offset, f[3 - j]); \
|
|
||||||
\
|
\
|
||||||
for(j = 0;j < 4;j++) \
|
for(j = 0;j < 4;j++) \
|
||||||
f[j] += DELAY_OUT_##T(&State->Early.Delay[j], \
|
f[j] += DELAY_OUT_##T(&State->Early.Delay, \
|
||||||
offset-State->Early.Offset[j][0], \
|
(offset-State->Early.Offset[j][0])*4 + j, \
|
||||||
offset-State->Early.Offset[j][1], fade) * \
|
(offset-State->Early.Offset[j][1])*4 + j, fade \
|
||||||
State->Early.Coeff[j]; \
|
) * State->Early.Coeff[j]; \
|
||||||
\
|
\
|
||||||
for(j = 0;j < 4;j++) \
|
for(j = 0;j < 4;j++) \
|
||||||
out[j][i] = f[j]; \
|
out[j][i] = f[j]; \
|
||||||
@ -1630,9 +1636,7 @@ static ALvoid EarlyReflection_##T(ALreverbState *State, const ALsizei todo, \
|
|||||||
\
|
\
|
||||||
VectorPartialScatter(f, mixX, mixY); \
|
VectorPartialScatter(f, mixX, mixY); \
|
||||||
\
|
\
|
||||||
for(j = 0;j < 4;j++) \
|
DelayLineIn4(&State->Delay, offset-State->LateFeedTap, f); \
|
||||||
DelayLineIn(&State->Delay, (offset-State->LateFeedTap)*4 + j, \
|
|
||||||
f[j]); \
|
|
||||||
\
|
\
|
||||||
offset++; \
|
offset++; \
|
||||||
fade += FadeStep; \
|
fade += FadeStep; \
|
||||||
@ -1715,12 +1719,14 @@ static ALvoid LateReverb_##T(ALreverbState *State, const ALsizei todo, \
|
|||||||
ALfloat out0, out1; \
|
ALfloat out0, out1; \
|
||||||
\
|
\
|
||||||
/* Get the two samples crossed by the offset delay. */ \
|
/* Get the two samples crossed by the offset delay. */ \
|
||||||
out0 = DELAY_OUT_##T(&State->Late.Delay[j], \
|
out0 = DELAY_OUT_##T(&State->Late.Delay, \
|
||||||
delay-State->Late.Offset[j][0], \
|
(delay-State->Late.Offset[j][0])*4 + j, \
|
||||||
delay-State->Late.Offset[j][1], fade); \
|
(delay-State->Late.Offset[j][1])*4 + j, fade \
|
||||||
out1 = DELAY_OUT_##T(&State->Late.Delay[j], \
|
); \
|
||||||
delay-State->Late.Offset[j][0]-1, \
|
out1 = DELAY_OUT_##T(&State->Late.Delay, \
|
||||||
delay-State->Late.Offset[j][1]-1, fade); \
|
(delay-State->Late.Offset[j][0]-1)*4 + j, \
|
||||||
|
(delay-State->Late.Offset[j][1]-1)*4 + j, fade \
|
||||||
|
); \
|
||||||
\
|
\
|
||||||
/* The modulated result is obtained by linearly interpolating the \
|
/* The modulated result is obtained by linearly interpolating the \
|
||||||
* two samples that were acquired above. \
|
* two samples that were acquired above. \
|
||||||
@ -1741,8 +1747,7 @@ static ALvoid LateReverb_##T(ALreverbState *State, const ALsizei todo, \
|
|||||||
\
|
\
|
||||||
VectorPartialScatter(f, mixX, mixY); \
|
VectorPartialScatter(f, mixX, mixY); \
|
||||||
\
|
\
|
||||||
for(j = 0;j < 4;j++) \
|
DelayLineIn4(&State->Late.Delay, offset, f); \
|
||||||
DelayLineIn(&State->Late.Delay[j], offset, f[j]); \
|
|
||||||
\
|
\
|
||||||
offset++; \
|
offset++; \
|
||||||
fade += FadeStep; \
|
fade += FadeStep; \
|
||||||
|
Loading…
Reference in New Issue
Block a user