aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/alcReverb.c
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/alcReverb.c')
-rw-r--r--Alc/alcReverb.c108
1 files changed, 54 insertions, 54 deletions
diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c
index 6de2c66f..b84dad96 100644
--- a/Alc/alcReverb.c
+++ b/Alc/alcReverb.c
@@ -39,9 +39,11 @@ typedef struct DelayLine
ALfloat *Line;
} DelayLine;
-typedef struct ALverbState {
+typedef struct ALreverbState {
DERIVE_FROM_TYPE(ALeffectState);
+ ALboolean IsEax;
+
// All delay lines are allocated as a single buffer to reduce memory
// fragmentation and management code.
ALfloat *SampleBuffer;
@@ -159,7 +161,7 @@ typedef struct ALverbState {
/* Temporary storage used when processing, before deinterlacing. */
ALfloat ReverbSamples[BUFFERSIZE][4];
ALfloat EarlySamples[BUFFERSIZE][4];
-} ALverbState;
+} ALreverbState;
/* This is a user config option for modifying the overall output of the reverb
* effect.
@@ -254,7 +256,7 @@ static __inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint
// Given an input sample, this function produces modulation for the late
// reverb.
-static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in)
+static __inline ALfloat EAXModulation(ALreverbState *State, ALfloat in)
{
ALfloat sinus, frac;
ALuint offset;
@@ -291,7 +293,7 @@ static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in)
}
// Delay line output routine for early reflections.
-static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index)
+static __inline ALfloat EarlyDelayLineOut(ALreverbState *State, ALuint index)
{
return AttenuatedDelayLineOut(&State->Early.Delay[index],
State->Offset - State->Early.Offset[index],
@@ -300,7 +302,7 @@ static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index)
// Given an input sample, this function produces four-channel output for the
// early reflections.
-static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *RESTRICT out)
+static __inline ALvoid EarlyReflection(ALreverbState *State, ALfloat in, ALfloat *RESTRICT out)
{
ALfloat d[4], v, f[4];
@@ -345,7 +347,7 @@ static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *
}
// All-pass input/output routine for late reverb.
-static __inline ALfloat LateAllPassInOut(ALverbState *State, ALuint index, ALfloat in)
+static __inline ALfloat LateAllPassInOut(ALreverbState *State, ALuint index, ALfloat in)
{
return AllpassInOut(&State->Late.ApDelay[index],
State->Offset - State->Late.ApOffset[index],
@@ -354,7 +356,7 @@ static __inline ALfloat LateAllPassInOut(ALverbState *State, ALuint index, ALflo
}
// Delay line output routine for late reverb.
-static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index)
+static __inline ALfloat LateDelayLineOut(ALreverbState *State, ALuint index)
{
return AttenuatedDelayLineOut(&State->Late.Delay[index],
State->Offset - State->Late.Offset[index],
@@ -362,7 +364,7 @@ static __inline ALfloat LateDelayLineOut(ALverbState *State, ALuint index)
}
// Low-pass filter input/output routine for late reverb.
-static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALfloat in)
+static __inline ALfloat LateLowPassInOut(ALreverbState *State, ALuint index, ALfloat in)
{
in = lerp(in, State->Late.LpSample[index], State->Late.LpCoeff[index]);
State->Late.LpSample[index] = in;
@@ -371,7 +373,7 @@ static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALflo
// Given four decorrelated input samples, this function produces four-channel
// output for the late reverb.
-static __inline ALvoid LateReverb(ALverbState *State, const ALfloat *RESTRICT in, ALfloat *RESTRICT out)
+static __inline ALvoid LateReverb(ALreverbState *State, const ALfloat *RESTRICT in, ALfloat *RESTRICT out)
{
ALfloat d[4], f[4];
@@ -442,7 +444,7 @@ static __inline ALvoid LateReverb(ALverbState *State, const ALfloat *RESTRICT in
// Given an input sample, this function mixes echo into the four-channel late
// reverb.
-static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *RESTRICT late)
+static __inline ALvoid EAXEcho(ALreverbState *State, ALfloat in, ALfloat *RESTRICT late)
{
ALfloat out, feed;
@@ -476,7 +478,7 @@ static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *RESTRICT
// Perform the non-EAX reverb pass on a given input sample, resulting in
// four-channel output.
-static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *RESTRICT out)
+static __inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *RESTRICT out)
{
ALfloat feed, late[4], taps[4];
@@ -515,7 +517,7 @@ static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *RESTRIC
// Perform the EAX reverb pass on a given input sample, resulting in four-
// channel output.
-static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *RESTRICT early, ALfloat *RESTRICT late)
+static __inline ALvoid EAXVerbPass(ALreverbState *State, ALfloat in, ALfloat *RESTRICT early, ALfloat *RESTRICT late)
{
ALfloat feed, taps[4];
@@ -552,11 +554,10 @@ static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *REST
State->Offset++;
}
-// This processes the reverb state, given the input samples and an output
-// buffer.
-static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
+// This processes the standard reverb state, given the input samples and an
+// output buffer.
+static ALvoid ALreverbState_ProcessStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
{
- ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect);
ALfloat (*RESTRICT out)[4] = State->ReverbSamples;
ALuint index, c;
@@ -577,9 +578,8 @@ static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo
// This processes the EAX reverb state, given the input samples and an output
// buffer.
-static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
+static ALvoid ALreverbState_ProcessEax(ALreverbState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
{
- ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect);
ALfloat (*RESTRICT early)[4] = State->EarlySamples;
ALfloat (*RESTRICT late)[4] = State->ReverbSamples;
ALuint index, c;
@@ -606,6 +606,14 @@ static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const AL
}
}
+static ALvoid ALreverbState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
+{
+ ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect);
+ if(State->IsEax)
+ ALreverbState_ProcessEax(State, SamplesToDo, SamplesIn, SamplesOut);
+ else
+ ALreverbState_ProcessStandard(State, SamplesToDo, SamplesIn, SamplesOut);
+}
// Given the allocated sample buffer, this function updates each delay line
// offset.
@@ -633,7 +641,7 @@ static ALuint CalcLineLength(ALfloat length, ALintptrEXT offset, ALuint frequenc
* for all lines given the sample rate (frequency). If an allocation failure
* occurs, it returns AL_FALSE.
*/
-static ALboolean AllocLines(ALuint frequency, ALverbState *State)
+static ALboolean AllocLines(ALuint frequency, ALreverbState *State)
{
ALuint totalSamples, index;
ALfloat length;
@@ -724,9 +732,9 @@ static ALboolean AllocLines(ALuint frequency, ALverbState *State)
// This updates the device-dependant EAX reverb state. This is called on
// initialization and any time the device parameters (eg. playback frequency,
// format) have been changed.
-static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
+static ALboolean ALreverbState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device)
{
- ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect);
+ ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect);
ALuint frequency = Device->Frequency, index;
// Allocate the delay lines.
@@ -861,7 +869,7 @@ static __inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloa
// Update the EAX modulation index, range, and depth. Keep in mind that this
// kind of vibrato is additive and not multiplicative as one may expect. The
// downswing will sound stronger than the upswing.
-static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequency, ALverbState *State)
+static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequency, ALreverbState *State)
{
ALuint range;
@@ -891,7 +899,7 @@ static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequenc
}
// Update the offsets for the initial effect delay line.
-static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint frequency, ALverbState *State)
+static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint frequency, ALreverbState *State)
{
// Calculate the initial delay taps.
State->DelayTap[0] = fastf2u(earlyDelay * frequency);
@@ -899,7 +907,7 @@ static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint freq
}
// Update the early reflections gain and line coefficients.
-static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat lateDelay, ALverbState *State)
+static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat lateDelay, ALreverbState *State)
{
ALuint index;
@@ -916,7 +924,7 @@ static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat la
}
// Update the offsets for the decorrelator line.
-static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALverbState *State)
+static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALreverbState *State)
{
ALuint index;
ALfloat length;
@@ -937,7 +945,7 @@ static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALverbState
}
// Update the late reverb gains, line lengths, and line coefficients.
-static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix, ALfloat density, ALfloat decayTime, ALfloat diffusion, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALverbState *State)
+static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix, ALfloat density, ALfloat decayTime, ALfloat diffusion, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALreverbState *State)
{
ALfloat length;
ALuint index;
@@ -995,7 +1003,7 @@ static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix
// Update the echo gain, line offset, line coefficients, and mixing
// coefficients.
-static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoTime, ALfloat decayTime, ALfloat diffusion, ALfloat echoDepth, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALverbState *State)
+static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoTime, ALfloat decayTime, ALfloat diffusion, ALfloat echoDepth, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALreverbState *State)
{
// Update the offset and coefficient for the echo delay line.
State->Echo.Offset = fastf2u(echoTime * frequency);
@@ -1027,7 +1035,7 @@ static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoT
}
// Update the early and late 3D panning gains.
-static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALverbState *State)
+static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALreverbState *State)
{
ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1],
ReflectionsPan[2] };
@@ -1076,31 +1084,26 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
// This updates the EAX reverb state. This is called any time the EAX reverb
// effect is loaded into a slot.
-static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
+static ALvoid ALreverbState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot)
{
- ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect);
+ ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect);
ALuint frequency = Device->Frequency;
- ALboolean isEAX = AL_FALSE;
ALfloat cw, x, y, hfRatio;
if(Slot->effect.type == AL_EFFECT_EAXREVERB && !EmulateEAXReverb)
- {
- STATIC_CAST(ALeffectState, State)->Process = EAXVerbProcess;
- isEAX = AL_TRUE;
- }
+ State->IsEax = AL_TRUE;
else if(Slot->effect.type == AL_EFFECT_REVERB || EmulateEAXReverb)
- {
- STATIC_CAST(ALeffectState, State)->Process = VerbProcess;
- isEAX = AL_FALSE;
- }
+ State->IsEax = AL_FALSE;
// Calculate the master low-pass filter (from the master effect HF gain).
- if(isEAX) cw = CalcI3DL2HFreq(Slot->effect.Reverb.HFReference, frequency);
- else cw = CalcI3DL2HFreq(LOWPASSFREQREF, frequency);
+ if(State->IsEax)
+ cw = CalcI3DL2HFreq(Slot->effect.Reverb.HFReference, frequency);
+ else
+ cw = CalcI3DL2HFreq(LOWPASSFREQREF, frequency);
// This is done with 2 chained 1-pole filters, so no need to square g.
State->LpFilter.coeff = lpCoeffCalc(Slot->effect.Reverb.GainHF, cw);
- if(isEAX)
+ if(State->IsEax)
{
// Update the modulator line.
UpdateModulator(Slot->effect.Reverb.ModulationTime,
@@ -1140,7 +1143,7 @@ static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff
x, Slot->effect.Reverb.Density, Slot->effect.Reverb.DecayTime,
Slot->effect.Reverb.Diffusion, hfRatio, cw, frequency, State);
- if(isEAX)
+ if(State->IsEax)
{
// Update the echo line.
UpdateEchoLine(Slot->effect.Reverb.Gain, Slot->effect.Reverb.LateReverbGain,
@@ -1171,9 +1174,9 @@ static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff
// This destroys the reverb state. It should be called only when the effect
// slot has a different (or no) effect loaded over the reverb effect.
-static ALvoid ReverbDestroy(ALeffectState *effect)
+static ALvoid ALreverbState_Destroy(ALeffectState *effect)
{
- ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect);
+ ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect);
free(State->SampleBuffer);
State->SampleBuffer = NULL;
@@ -1181,21 +1184,18 @@ static ALvoid ReverbDestroy(ALeffectState *effect)
free(State);
}
+DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState);
+
// This creates the reverb state. It should be called only when the reverb
// effect is loaded into a slot that doesn't already have a reverb effect.
ALeffectState *ReverbCreate(void)
{
- ALverbState *State = NULL;
+ ALreverbState *State = NULL;
ALuint index;
- State = malloc(sizeof(ALverbState));
- if(!State)
- return NULL;
-
- STATIC_CAST(ALeffectState, State)->Destroy = ReverbDestroy;
- STATIC_CAST(ALeffectState, State)->DeviceUpdate = ReverbDeviceUpdate;
- STATIC_CAST(ALeffectState, State)->Update = ReverbUpdate;
- STATIC_CAST(ALeffectState, State)->Process = VerbProcess;
+ State = malloc(sizeof(ALreverbState));
+ if(!State) return NULL;
+ SET_VTABLE2(ALreverbState, ALeffectState, State);
State->TotalSamples = 0;
State->SampleBuffer = NULL;