Separate early and late reverb output for standard reverb too

This commit is contained in:
Chris Robinson 2016-02-05 07:46:33 -08:00
parent 305ef3215d
commit b8e74c88cf

View File

@ -88,8 +88,7 @@ typedef struct ALreverbState {
DelayLine Delay[4]; DelayLine Delay[4];
ALuint Offset[4]; ALuint Offset[4];
// The gain for each output channel based on 3D panning (only for the // The gain for each output channel based on 3D panning.
// EAX path).
ALfloat PanGain[4][MAX_OUTPUT_CHANNELS]; ALfloat PanGain[4][MAX_OUTPUT_CHANNELS];
} Early; } Early;
@ -127,8 +126,7 @@ typedef struct ALreverbState {
ALfloat LpCoeff[4]; ALfloat LpCoeff[4];
ALfloat LpSample[4]; ALfloat LpSample[4];
// The gain for each output channel based on 3D panning (only for the // The gain for each output channel based on 3D panning.
// EAX path).
ALfloat PanGain[4][MAX_OUTPUT_CHANNELS]; ALfloat PanGain[4][MAX_OUTPUT_CHANNELS];
} Late; } Late;
@ -159,10 +157,6 @@ typedef struct ALreverbState {
// The current read offset for all delay lines. // The current read offset for all delay lines.
ALuint Offset; ALuint Offset;
// The gain for each output channel (non-EAX path only; aliased from
// Late.PanGain)
ALfloat (*Gain)[MAX_OUTPUT_CHANNELS];
/* Temporary storage used when processing. */ /* Temporary storage used when processing. */
ALfloat ReverbSamples[MAX_UPDATE_SAMPLES][4]; ALfloat ReverbSamples[MAX_UPDATE_SAMPLES][4];
ALfloat EarlySamples[MAX_UPDATE_SAMPLES][4]; ALfloat EarlySamples[MAX_UPDATE_SAMPLES][4];
@ -434,10 +428,10 @@ static inline ALvoid LateReverb(ALreverbState *State, ALuint todo, ALfloat (*res
// Output the results of the matrix for all four channels, attenuated by // Output the results of the matrix for all four channels, attenuated by
// the late reverb gain (which is attenuated by the 'x' mix coefficient). // the late reverb gain (which is attenuated by the 'x' mix coefficient).
// Mix early reflections and late reverb. // Mix early reflections and late reverb.
out[i][0] += State->Late.Gain * f[0]; out[i][0] = State->Late.Gain * f[0];
out[i][1] += State->Late.Gain * f[1]; out[i][1] = State->Late.Gain * f[1];
out[i][2] += State->Late.Gain * f[2]; out[i][2] = State->Late.Gain * f[2];
out[i][3] += State->Late.Gain * f[3]; out[i][3] = State->Late.Gain * f[3];
// Re-feed the cyclical delay lines. // Re-feed the cyclical delay lines.
DelayLineIn(&State->Late.Delay[0], offset, f[0]); DelayLineIn(&State->Late.Delay[0], offset, f[0]);
@ -488,7 +482,7 @@ static inline ALvoid EAXEcho(ALreverbState *State, ALuint todo, ALfloat (*restri
// Perform the non-EAX reverb pass on a given input sample, resulting in // Perform the non-EAX reverb pass on a given input sample, resulting in
// four-channel output. // four-channel output.
static inline ALvoid VerbPass(ALreverbState *State, ALuint todo, const ALfloat *in, ALfloat (*restrict out)[4]) static inline ALvoid VerbPass(ALreverbState *State, ALuint todo, const ALfloat *in, ALfloat (*restrict early)[4], ALfloat (*restrict late)[4])
{ {
ALuint i; ALuint i;
@ -499,7 +493,7 @@ static inline ALvoid VerbPass(ALreverbState *State, ALuint todo, const ALfloat *
); );
// Calculate the early reflection from the first delay tap. // Calculate the early reflection from the first delay tap.
EarlyReflection(State, todo, out); EarlyReflection(State, todo, early);
// Feed the decorrelator from the energy-attenuated output of the second // Feed the decorrelator from the energy-attenuated output of the second
// delay tap. // delay tap.
@ -512,7 +506,7 @@ static inline ALvoid VerbPass(ALreverbState *State, ALuint todo, const ALfloat *
} }
// Calculate the late reverb from the decorrelator taps. // Calculate the late reverb from the decorrelator taps.
LateReverb(State, todo, out); LateReverb(State, todo, late);
// Step all delays forward one sample. // Step all delays forward one sample.
State->Offset += todo; State->Offset += todo;
@ -552,7 +546,6 @@ static inline ALvoid EAXVerbPass(ALreverbState *State, ALuint todo, const ALfloa
} }
// Calculate the late reverb from the decorrelator taps. // Calculate the late reverb from the decorrelator taps.
memset(late, 0, sizeof(*late)*todo);
LateReverb(State, todo, late); LateReverb(State, todo, late);
// Calculate and mix in any echo. // Calculate and mix in any echo.
@ -564,25 +557,34 @@ static inline ALvoid EAXVerbPass(ALreverbState *State, ALuint todo, const ALfloa
static ALvoid ALreverbState_processStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) static ALvoid ALreverbState_processStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
{ {
ALfloat (*restrict out)[4] = State->ReverbSamples; ALfloat (*restrict early)[4] = State->EarlySamples;
ALfloat (*restrict late)[4] = State->ReverbSamples;
ALuint index, c, i, l; ALuint index, c, i, l;
ALfloat gain;
/* Process reverb for these samples. */ /* Process reverb for these samples. */
for(index = 0;index < SamplesToDo;) for(index = 0;index < SamplesToDo;)
{ {
ALuint todo = minu(SamplesToDo-index, MAX_UPDATE_SAMPLES); ALuint todo = minu(SamplesToDo-index, MAX_UPDATE_SAMPLES);
VerbPass(State, todo, &SamplesIn[index], out); VerbPass(State, todo, &SamplesIn[index], early, late);
for(l = 0;l < 4;l++) for(l = 0;l < 4;l++)
{ {
for(c = 0;c < NumChannels;c++) for(c = 0;c < NumChannels;c++)
{ {
ALfloat gain = State->Gain[l][c]; gain = State->Early.PanGain[l][c];
if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD)) if(fabsf(gain) > GAIN_SILENCE_THRESHOLD)
continue; {
for(i = 0;i < todo;i++) for(i = 0;i < todo;i++)
SamplesOut[c][index+i] += gain*out[i][l]; SamplesOut[c][index+i] += gain*early[i][l];
}
gain = State->Late.PanGain[l][c];
if(fabsf(gain) > GAIN_SILENCE_THRESHOLD)
{
for(i = 0;i < todo;i++)
SamplesOut[c][index+i] += gain*late[i][l];
}
} }
} }
@ -1147,10 +1149,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
* equals sqrt(1/4), a nice gain scaling for the four virtual points * equals sqrt(1/4), a nice gain scaling for the four virtual points
* producing an "ambient" response. * producing an "ambient" response.
*/ */
gain[0] = 0.5f; gain[0] = gain[1] = gain[2] = gain[3] = 0.5f;
gain[1] = 0.5f;
gain[2] = 0.5f;
gain[3] = 0.5f;
length = sqrtf(ReflectionsPan[0]*ReflectionsPan[0] + ReflectionsPan[1]*ReflectionsPan[1] + ReflectionsPan[2]*ReflectionsPan[2]); length = sqrtf(ReflectionsPan[0]*ReflectionsPan[0] + ReflectionsPan[1]*ReflectionsPan[1] + ReflectionsPan[2]*ReflectionsPan[2]);
if(length > 1.0f) if(length > 1.0f)
{ {
@ -1180,10 +1179,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain*gain[i], State->Early.PanGain[i]); ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain*gain[i], State->Early.PanGain[i]);
} }
gain[0] = 0.5f; gain[0] = gain[1] = gain[2] = gain[3] = 0.5f;
gain[1] = 0.5f;
gain[2] = 0.5f;
gain[3] = 0.5f;
length = sqrtf(LateReverbPan[0]*LateReverbPan[0] + LateReverbPan[1]*LateReverbPan[1] + LateReverbPan[2]*LateReverbPan[2]); length = sqrtf(LateReverbPan[0]*LateReverbPan[0] + LateReverbPan[1]*LateReverbPan[1] + LateReverbPan[2]*LateReverbPan[2]);
if(length > 1.0f) if(length > 1.0f)
{ {
@ -1392,8 +1388,6 @@ static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(f
state->Offset = 0; state->Offset = 0;
state->Gain = state->Late.PanGain;
return STATIC_CAST(ALeffectState, state); return STATIC_CAST(ALeffectState, state);
} }