Don't expose effect-specific structures
This commit is contained in:
parent
e12ac95d69
commit
74dc7090fd
15
Alc/ALu.c
15
Alc/ALu.c
@ -36,7 +36,6 @@
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alu.h"
|
||||
#include "bs2b.h"
|
||||
#include "alReverb.h"
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
@ -1310,18 +1309,8 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
|
||||
// effect slot processing
|
||||
while(ALEffectSlot)
|
||||
{
|
||||
switch(ALEffectSlot->effect.type)
|
||||
{
|
||||
case AL_EFFECT_REVERB:
|
||||
VerbProcess(ALEffectSlot->ReverbState, SamplesToDo, ALEffectSlot->WetBuffer, DryBuffer);
|
||||
break;
|
||||
case AL_EFFECT_ECHO:
|
||||
EchoProcess(ALEffectSlot->EchoState, SamplesToDo, ALEffectSlot->WetBuffer, DryBuffer);
|
||||
break;
|
||||
case AL_EFFECT_EAXREVERB:
|
||||
EAXVerbProcess(ALEffectSlot->ReverbState, SamplesToDo, ALEffectSlot->WetBuffer, DryBuffer);
|
||||
break;
|
||||
}
|
||||
if(ALEffectSlot->EffectState)
|
||||
ALEffect_Process(ALEffectSlot->EffectState, SamplesToDo, ALEffectSlot->WetBuffer, DryBuffer);
|
||||
|
||||
for(i = 0;i < SamplesToDo;i++)
|
||||
ALEffectSlot->WetBuffer[i] = 0.0f;
|
||||
|
100
Alc/alcEcho.c
100
Alc/alcEcho.c
@ -23,13 +23,15 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
#include "alFilter.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alEcho.h"
|
||||
#include "alu.h"
|
||||
|
||||
struct ALechoState {
|
||||
typedef struct ALechoState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
ALfloat *SampleBuffer;
|
||||
ALuint BufferLength;
|
||||
|
||||
@ -46,7 +48,7 @@ struct ALechoState {
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[2];
|
||||
};
|
||||
} ALechoState;
|
||||
|
||||
// Find the next power of 2. Actually, this will return the input value if
|
||||
// it is already a power of 2.
|
||||
@ -66,46 +68,9 @@ static ALuint NextPowerOf2(ALuint value)
|
||||
return powerOf2;
|
||||
}
|
||||
|
||||
ALechoState *EchoCreate(ALCcontext *Context)
|
||||
{
|
||||
ALechoState *state;
|
||||
ALuint i, maxlen;
|
||||
|
||||
state = malloc(sizeof(*state));
|
||||
if(!state)
|
||||
return NULL;
|
||||
|
||||
maxlen = (ALuint)(AL_ECHO_MAX_DELAY * Context->Frequency);
|
||||
maxlen += (ALuint)(AL_ECHO_MAX_LRDELAY * Context->Frequency);
|
||||
|
||||
// Use the next power of 2 for the buffer length, so the tap offsets can be
|
||||
// wrapped using a mask instead of a modulo
|
||||
state->BufferLength = NextPowerOf2(maxlen+1);
|
||||
state->SampleBuffer = malloc(state->BufferLength * sizeof(ALfloat));
|
||||
if(!state->SampleBuffer)
|
||||
{
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0;i < state->BufferLength;i++)
|
||||
state->SampleBuffer[i] = 0.0f;
|
||||
|
||||
state->Tap[0].offset = 0;
|
||||
state->Tap[1].offset = 0;
|
||||
state->Tap[2].offset = 0;
|
||||
state->GainL = 0.0f;
|
||||
state->GainR = 0.0f;
|
||||
|
||||
for(i = 0;i < 2;i++)
|
||||
state->iirFilter.history[i] = 0.0f;
|
||||
state->iirFilter.coeff = 0.0f;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
ALvoid EchoDestroy(ALechoState *state)
|
||||
ALvoid EchoDestroy(ALeffectState *effect)
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
if(state)
|
||||
{
|
||||
free(state->SampleBuffer);
|
||||
@ -114,9 +79,9 @@ ALvoid EchoDestroy(ALechoState *state)
|
||||
}
|
||||
}
|
||||
|
||||
ALvoid EchoUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect)
|
||||
ALvoid EchoUpdate(ALeffectState *effect, ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect)
|
||||
{
|
||||
ALechoState *state = Slot->EchoState;
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
ALuint newdelay1, newdelay2;
|
||||
ALfloat lrpan, cw, a, g;
|
||||
|
||||
@ -142,8 +107,9 @@ ALvoid EchoUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effe
|
||||
state->iirFilter.coeff = a;
|
||||
}
|
||||
|
||||
ALvoid EchoProcess(ALechoState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
const ALuint delay = state->BufferLength-1;
|
||||
ALuint tap1off = state->Tap[0].offset;
|
||||
ALuint tap2off = state->Tap[1].offset;
|
||||
@ -182,3 +148,45 @@ ALvoid EchoProcess(ALechoState *state, ALuint SamplesToDo, const ALfloat *Sample
|
||||
state->Tap[1].offset = tap2off;
|
||||
state->Tap[2].offset = fboff;
|
||||
}
|
||||
|
||||
ALeffectState *EchoCreate(ALCcontext *Context)
|
||||
{
|
||||
ALechoState *state;
|
||||
ALuint i, maxlen;
|
||||
|
||||
state = malloc(sizeof(*state));
|
||||
if(!state)
|
||||
return NULL;
|
||||
|
||||
state->state.Destroy = EchoDestroy;
|
||||
state->state.Update = EchoUpdate;
|
||||
state->state.Process = EchoProcess;
|
||||
|
||||
maxlen = (ALuint)(AL_ECHO_MAX_DELAY * Context->Frequency);
|
||||
maxlen += (ALuint)(AL_ECHO_MAX_LRDELAY * Context->Frequency);
|
||||
|
||||
// Use the next power of 2 for the buffer length, so the tap offsets can be
|
||||
// wrapped using a mask instead of a modulo
|
||||
state->BufferLength = NextPowerOf2(maxlen+1);
|
||||
state->SampleBuffer = malloc(state->BufferLength * sizeof(ALfloat));
|
||||
if(!state->SampleBuffer)
|
||||
{
|
||||
free(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0;i < state->BufferLength;i++)
|
||||
state->SampleBuffer[i] = 0.0f;
|
||||
|
||||
state->Tap[0].offset = 0;
|
||||
state->Tap[1].offset = 0;
|
||||
state->Tap[2].offset = 0;
|
||||
state->GainL = 0.0f;
|
||||
state->GainR = 0.0f;
|
||||
|
||||
for(i = 0;i < 2;i++)
|
||||
state->iirFilter.history[i] = 0.0f;
|
||||
state->iirFilter.coeff = 0.0f;
|
||||
|
||||
return &state->state;
|
||||
}
|
||||
|
282
Alc/alcReverb.c
282
Alc/alcReverb.c
@ -28,7 +28,6 @@
|
||||
#include "alMain.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alEffect.h"
|
||||
#include "alReverb.h"
|
||||
#include "alu.h"
|
||||
|
||||
typedef struct DelayLine
|
||||
@ -39,8 +38,10 @@ typedef struct DelayLine
|
||||
ALfloat *Line;
|
||||
} DelayLine;
|
||||
|
||||
struct ALverbState
|
||||
{
|
||||
typedef struct ALverbState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
// All delay lines are allocated as a single buffer to reduce memory
|
||||
// fragmentation and management code.
|
||||
ALfloat *SampleBuffer;
|
||||
@ -87,7 +88,7 @@ struct ALverbState
|
||||
} Late;
|
||||
// The current read offset for all delay lines.
|
||||
ALuint Offset;
|
||||
};
|
||||
} ALverbState;
|
||||
|
||||
// All delay line lengths are specified in seconds.
|
||||
|
||||
@ -340,138 +341,11 @@ static __inline ALvoid ReverbInOut(ALverbState *State, ALfloat in, ALfloat *earl
|
||||
State->Offset++;
|
||||
}
|
||||
|
||||
// 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.
|
||||
ALverbState *VerbCreate(ALCcontext *Context)
|
||||
{
|
||||
ALverbState *State = NULL;
|
||||
ALuint samples, length[13], totalLength, index;
|
||||
|
||||
State = malloc(sizeof(ALverbState));
|
||||
if(!State)
|
||||
return NULL;
|
||||
|
||||
// All line lengths are powers of 2, calculated from their lengths, with
|
||||
// an additional sample in case of rounding errors.
|
||||
|
||||
// See VerbUpdate() for an explanation of the additional calculation
|
||||
// added to the master line length.
|
||||
samples = (ALuint)
|
||||
((MASTER_LINE_LENGTH +
|
||||
(LATE_LINE_LENGTH[0] * (1.0f + LATE_LINE_MULTIPLIER) *
|
||||
(DECO_FRACTION * ((DECO_MULTIPLIER * DECO_MULTIPLIER *
|
||||
DECO_MULTIPLIER) - 1.0f)))) *
|
||||
Context->Frequency) + 1;
|
||||
length[0] = NextPowerOf2(samples);
|
||||
totalLength = length[0];
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
samples = (ALuint)(EARLY_LINE_LENGTH[index] * Context->Frequency) + 1;
|
||||
length[1 + index] = NextPowerOf2(samples);
|
||||
totalLength += length[1 + index];
|
||||
}
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
samples = (ALuint)(ALLPASS_LINE_LENGTH[index] * Context->Frequency) + 1;
|
||||
length[5 + index] = NextPowerOf2(samples);
|
||||
totalLength += length[5 + index];
|
||||
}
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
samples = (ALuint)(LATE_LINE_LENGTH[index] *
|
||||
(1.0f + LATE_LINE_MULTIPLIER) * Context->Frequency) + 1;
|
||||
length[9 + index] = NextPowerOf2(samples);
|
||||
totalLength += length[9 + index];
|
||||
}
|
||||
|
||||
// All lines share a single sample buffer and have their masks and start
|
||||
// addresses calculated once.
|
||||
State->SampleBuffer = malloc(totalLength * sizeof(ALfloat));
|
||||
if(!State->SampleBuffer)
|
||||
{
|
||||
free(State);
|
||||
return NULL;
|
||||
}
|
||||
for(index = 0; index < totalLength;index++)
|
||||
State->SampleBuffer[index] = 0.0f;
|
||||
|
||||
State->LpCoeff = 0.0f;
|
||||
State->LpSamples[0] = 0.0f;
|
||||
State->LpSamples[1] = 0.0f;
|
||||
State->Delay.Mask = length[0] - 1;
|
||||
State->Delay.Line = &State->SampleBuffer[0];
|
||||
totalLength = length[0];
|
||||
|
||||
State->Tap[0] = 0;
|
||||
State->Tap[1] = 0;
|
||||
State->Tap[2] = 0;
|
||||
State->Tap[3] = 0;
|
||||
State->Tap[4] = 0;
|
||||
|
||||
State->Early.Gain = 0.0f;
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
State->Early.Coeff[index] = 0.0f;
|
||||
State->Early.Delay[index].Mask = length[1 + index] - 1;
|
||||
State->Early.Delay[index].Line = &State->SampleBuffer[totalLength];
|
||||
totalLength += length[1 + index];
|
||||
|
||||
// The early delay lines have their read offsets calculated once.
|
||||
State->Early.Offset[index] = (ALuint)(EARLY_LINE_LENGTH[index] *
|
||||
Context->Frequency);
|
||||
}
|
||||
|
||||
State->Late.Gain = 0.0f;
|
||||
State->Late.DensityGain = 0.0f;
|
||||
State->Late.ApFeedCoeff = 0.0f;
|
||||
State->Late.MixCoeff = 0.0f;
|
||||
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
State->Late.ApCoeff[index] = 0.0f;
|
||||
State->Late.ApDelay[index].Mask = length[5 + index] - 1;
|
||||
State->Late.ApDelay[index].Line = &State->SampleBuffer[totalLength];
|
||||
totalLength += length[5 + index];
|
||||
|
||||
// The late all-pass lines have their read offsets calculated once.
|
||||
State->Late.ApOffset[index] = (ALuint)(ALLPASS_LINE_LENGTH[index] *
|
||||
Context->Frequency);
|
||||
}
|
||||
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
State->Late.Coeff[index] = 0.0f;
|
||||
State->Late.Delay[index].Mask = length[9 + index] - 1;
|
||||
State->Late.Delay[index].Line = &State->SampleBuffer[totalLength];
|
||||
totalLength += length[9 + index];
|
||||
|
||||
State->Late.Offset[index] = 0;
|
||||
|
||||
State->Late.LpCoeff[index] = 0.0f;
|
||||
State->Late.LpSample[index] = 0.0f;
|
||||
}
|
||||
|
||||
// Panning is applied as an independent gain for each output channel.
|
||||
for(index = 0;index < OUTPUTCHANNELS;index++)
|
||||
{
|
||||
State->Early.PanGain[index] = 0.0f;
|
||||
State->Late.PanGain[index] = 0.0f;
|
||||
}
|
||||
|
||||
State->Offset = 0;
|
||||
return State;
|
||||
}
|
||||
|
||||
ALverbState *EAXVerbCreate(ALCcontext *Context)
|
||||
{
|
||||
ALverbState *State = VerbCreate(Context);
|
||||
return State;
|
||||
}
|
||||
|
||||
// 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.
|
||||
ALvoid VerbDestroy(ALverbState *State)
|
||||
ALvoid VerbDestroy(ALeffectState *effect)
|
||||
{
|
||||
ALverbState *State = (ALverbState*)effect;
|
||||
if(State)
|
||||
{
|
||||
free(State->SampleBuffer);
|
||||
@ -497,9 +371,9 @@ static __inline ALint aluCart2LUTpos(ALfloat re, ALfloat im)
|
||||
|
||||
// This updates the reverb state. This is called any time the reverb effect
|
||||
// is loaded into a slot.
|
||||
ALvoid VerbUpdate(ALCcontext *Context, ALeffectslot *Slot, ALeffect *Effect)
|
||||
ALvoid VerbUpdate(ALeffectState *effect, ALCcontext *Context, ALeffectslot *Slot, ALeffect *Effect)
|
||||
{
|
||||
ALverbState *State = Slot->ReverbState;
|
||||
ALverbState *State = (ALverbState*)effect;
|
||||
ALuint index;
|
||||
ALfloat length, mixCoeff, cw, g, coeff;
|
||||
ALfloat hfRatio = Effect->Reverb.DecayHFRatio;
|
||||
@ -695,8 +569,9 @@ ALvoid VerbUpdate(ALCcontext *Context, ALeffectslot *Slot, ALeffect *Effect)
|
||||
|
||||
// This processes the reverb state, given the input samples and an output
|
||||
// buffer.
|
||||
ALvoid VerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
{
|
||||
ALverbState *State = (ALverbState*)effect;
|
||||
ALuint index;
|
||||
ALfloat early[4], late[4], out[4];
|
||||
|
||||
@ -725,8 +600,9 @@ ALvoid VerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *Sample
|
||||
|
||||
// This processes the EAX reverb state, given the input samples and an output
|
||||
// buffer.
|
||||
ALvoid EAXVerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
{
|
||||
ALverbState *State = (ALverbState*)effect;
|
||||
ALuint index;
|
||||
ALfloat early[4], late[4];
|
||||
|
||||
@ -765,3 +641,135 @@ ALvoid EAXVerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *Sam
|
||||
}
|
||||
}
|
||||
|
||||
// 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 *VerbCreate(ALCcontext *Context)
|
||||
{
|
||||
ALverbState *State = NULL;
|
||||
ALuint samples, length[13], totalLength, index;
|
||||
|
||||
State = malloc(sizeof(ALverbState));
|
||||
if(!State)
|
||||
return NULL;
|
||||
|
||||
State->state.Destroy = VerbDestroy;
|
||||
State->state.Update = VerbUpdate;
|
||||
State->state.Process = VerbProcess;
|
||||
|
||||
// All line lengths are powers of 2, calculated from their lengths, with
|
||||
// an additional sample in case of rounding errors.
|
||||
|
||||
// See VerbUpdate() for an explanation of the additional calculation
|
||||
// added to the master line length.
|
||||
samples = (ALuint)
|
||||
((MASTER_LINE_LENGTH +
|
||||
(LATE_LINE_LENGTH[0] * (1.0f + LATE_LINE_MULTIPLIER) *
|
||||
(DECO_FRACTION * ((DECO_MULTIPLIER * DECO_MULTIPLIER *
|
||||
DECO_MULTIPLIER) - 1.0f)))) *
|
||||
Context->Frequency) + 1;
|
||||
length[0] = NextPowerOf2(samples);
|
||||
totalLength = length[0];
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
samples = (ALuint)(EARLY_LINE_LENGTH[index] * Context->Frequency) + 1;
|
||||
length[1 + index] = NextPowerOf2(samples);
|
||||
totalLength += length[1 + index];
|
||||
}
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
samples = (ALuint)(ALLPASS_LINE_LENGTH[index] * Context->Frequency) + 1;
|
||||
length[5 + index] = NextPowerOf2(samples);
|
||||
totalLength += length[5 + index];
|
||||
}
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
samples = (ALuint)(LATE_LINE_LENGTH[index] *
|
||||
(1.0f + LATE_LINE_MULTIPLIER) * Context->Frequency) + 1;
|
||||
length[9 + index] = NextPowerOf2(samples);
|
||||
totalLength += length[9 + index];
|
||||
}
|
||||
|
||||
// All lines share a single sample buffer and have their masks and start
|
||||
// addresses calculated once.
|
||||
State->SampleBuffer = malloc(totalLength * sizeof(ALfloat));
|
||||
if(!State->SampleBuffer)
|
||||
{
|
||||
free(State);
|
||||
return NULL;
|
||||
}
|
||||
for(index = 0; index < totalLength;index++)
|
||||
State->SampleBuffer[index] = 0.0f;
|
||||
|
||||
State->LpCoeff = 0.0f;
|
||||
State->LpSamples[0] = 0.0f;
|
||||
State->LpSamples[1] = 0.0f;
|
||||
State->Delay.Mask = length[0] - 1;
|
||||
State->Delay.Line = &State->SampleBuffer[0];
|
||||
totalLength = length[0];
|
||||
|
||||
State->Tap[0] = 0;
|
||||
State->Tap[1] = 0;
|
||||
State->Tap[2] = 0;
|
||||
State->Tap[3] = 0;
|
||||
State->Tap[4] = 0;
|
||||
|
||||
State->Early.Gain = 0.0f;
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
State->Early.Coeff[index] = 0.0f;
|
||||
State->Early.Delay[index].Mask = length[1 + index] - 1;
|
||||
State->Early.Delay[index].Line = &State->SampleBuffer[totalLength];
|
||||
totalLength += length[1 + index];
|
||||
|
||||
// The early delay lines have their read offsets calculated once.
|
||||
State->Early.Offset[index] = (ALuint)(EARLY_LINE_LENGTH[index] *
|
||||
Context->Frequency);
|
||||
}
|
||||
|
||||
State->Late.Gain = 0.0f;
|
||||
State->Late.DensityGain = 0.0f;
|
||||
State->Late.ApFeedCoeff = 0.0f;
|
||||
State->Late.MixCoeff = 0.0f;
|
||||
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
State->Late.ApCoeff[index] = 0.0f;
|
||||
State->Late.ApDelay[index].Mask = length[5 + index] - 1;
|
||||
State->Late.ApDelay[index].Line = &State->SampleBuffer[totalLength];
|
||||
totalLength += length[5 + index];
|
||||
|
||||
// The late all-pass lines have their read offsets calculated once.
|
||||
State->Late.ApOffset[index] = (ALuint)(ALLPASS_LINE_LENGTH[index] *
|
||||
Context->Frequency);
|
||||
}
|
||||
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
State->Late.Coeff[index] = 0.0f;
|
||||
State->Late.Delay[index].Mask = length[9 + index] - 1;
|
||||
State->Late.Delay[index].Line = &State->SampleBuffer[totalLength];
|
||||
totalLength += length[9 + index];
|
||||
|
||||
State->Late.Offset[index] = 0;
|
||||
|
||||
State->Late.LpCoeff[index] = 0.0f;
|
||||
State->Late.LpSample[index] = 0.0f;
|
||||
}
|
||||
|
||||
// Panning is applied as an independent gain for each output channel.
|
||||
for(index = 0;index < OUTPUTCHANNELS;index++)
|
||||
{
|
||||
State->Early.PanGain[index] = 0.0f;
|
||||
State->Late.PanGain[index] = 0.0f;
|
||||
}
|
||||
|
||||
State->Offset = 0;
|
||||
return &State->state;
|
||||
}
|
||||
|
||||
ALeffectState *EAXVerbCreate(ALCcontext *Context)
|
||||
{
|
||||
ALeffectState *State = VerbCreate(Context);
|
||||
if(State) State->Process = EAXVerbProcess;
|
||||
return State;
|
||||
}
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include "AL/al.h"
|
||||
#include "alEffect.h"
|
||||
#include "alFilter.h"
|
||||
#include "alReverb.h"
|
||||
#include "alEcho.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -17,6 +15,8 @@ extern "C" {
|
||||
|
||||
#define AL_EFFECTSLOT_NULL 0x0000
|
||||
|
||||
typedef struct ALeffectState ALeffectState;
|
||||
|
||||
typedef struct ALeffectslot
|
||||
{
|
||||
ALeffect effect;
|
||||
@ -24,8 +24,7 @@ typedef struct ALeffectslot
|
||||
ALfloat Gain;
|
||||
ALboolean AuxSendAuto;
|
||||
|
||||
ALverbState *ReverbState;
|
||||
ALechoState *EchoState;
|
||||
ALeffectState *EffectState;
|
||||
|
||||
ALfloat WetBuffer[BUFFERSIZE];
|
||||
|
||||
@ -53,6 +52,22 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
|
||||
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
|
||||
|
||||
|
||||
struct ALeffectState {
|
||||
ALvoid (*Destroy)(ALeffectState *State);
|
||||
ALvoid (*Update)(ALeffectState *State, ALCcontext *Context, ALeffectslot *Slot, ALeffect *Effect);
|
||||
ALvoid (*Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
|
||||
};
|
||||
|
||||
ALeffectState *EAXVerbCreate(ALCcontext *Context);
|
||||
ALeffectState *VerbCreate(ALCcontext *Context);
|
||||
ALeffectState *EchoCreate(ALCcontext *Context);
|
||||
|
||||
#define ALEffect_Destroy(a) ((a)->Destroy((a)))
|
||||
#define ALEffect_Update(a,b,c,d) ((a)->Update((a),(b),(c),(d)))
|
||||
#define ALEffect_Process(a,b,c,d) ((a)->Process((a),(b),(c),(d)))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,24 +0,0 @@
|
||||
#ifndef AL_ECHO_H
|
||||
#define AL_ECHO_H
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alEffect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALechoState ALechoState;
|
||||
|
||||
ALechoState *EchoCreate(ALCcontext *Context);
|
||||
ALvoid EchoDestroy(ALechoState *State);
|
||||
ALvoid EchoUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect);
|
||||
ALvoid EchoProcess(ALechoState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
#ifndef _AL_REVERB_H_
|
||||
#define _AL_REVERB_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alEffect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALverbState ALverbState;
|
||||
|
||||
ALverbState *VerbCreate(ALCcontext *Context);
|
||||
ALverbState *EAXVerbCreate(ALCcontext *Context);
|
||||
ALvoid VerbDestroy(ALverbState *State);
|
||||
ALvoid VerbUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect);
|
||||
ALvoid VerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
|
||||
ALvoid EAXVerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
#include "alReverb.h"
|
||||
|
||||
|
||||
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, ALeffect *effect);
|
||||
@ -150,8 +149,8 @@ ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
*list = (*list)->next;
|
||||
ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot);
|
||||
|
||||
VerbDestroy(ALAuxiliaryEffectSlot->ReverbState);
|
||||
EchoDestroy(ALAuxiliaryEffectSlot->EchoState);
|
||||
if(ALAuxiliaryEffectSlot->EffectState)
|
||||
ALEffect_Destroy(ALAuxiliaryEffectSlot->EffectState);
|
||||
|
||||
memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot));
|
||||
free(ALAuxiliaryEffectSlot);
|
||||
@ -472,10 +471,9 @@ static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot,
|
||||
{
|
||||
if((!effect) || (effect->type != ALEffectSlot->effect.type))
|
||||
{
|
||||
VerbDestroy(ALEffectSlot->ReverbState);
|
||||
ALEffectSlot->ReverbState = NULL;
|
||||
EchoDestroy(ALEffectSlot->EchoState);
|
||||
ALEffectSlot->EchoState = NULL;
|
||||
if(ALEffectSlot->EffectState)
|
||||
ALEffect_Destroy(ALEffectSlot->EffectState);
|
||||
ALEffectSlot->EffectState = NULL;
|
||||
}
|
||||
if(!effect)
|
||||
{
|
||||
@ -483,24 +481,17 @@ static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot,
|
||||
return;
|
||||
}
|
||||
memcpy(&ALEffectSlot->effect, effect, sizeof(*effect));
|
||||
if(effect->type == AL_EFFECT_EAXREVERB)
|
||||
|
||||
if(!ALEffectSlot->EffectState)
|
||||
{
|
||||
if(!ALEffectSlot->ReverbState)
|
||||
ALEffectSlot->ReverbState = EAXVerbCreate(Context);
|
||||
VerbUpdate(Context, ALEffectSlot, effect);
|
||||
}
|
||||
else if(effect->type == AL_EFFECT_REVERB)
|
||||
{
|
||||
if(!ALEffectSlot->ReverbState)
|
||||
ALEffectSlot->ReverbState = VerbCreate(Context);
|
||||
VerbUpdate(Context, ALEffectSlot, effect);
|
||||
}
|
||||
else if(effect->type == AL_EFFECT_ECHO)
|
||||
{
|
||||
if(!ALEffectSlot->EchoState)
|
||||
ALEffectSlot->EchoState = EchoCreate(Context);
|
||||
EchoUpdate(Context, ALEffectSlot, effect);
|
||||
if(effect->type == AL_EFFECT_EAXREVERB)
|
||||
ALEffectSlot->EffectState = EAXVerbCreate(Context);
|
||||
else if(effect->type == AL_EFFECT_REVERB)
|
||||
ALEffectSlot->EffectState = VerbCreate(Context);
|
||||
else if(effect->type == AL_EFFECT_ECHO)
|
||||
ALEffectSlot->EffectState = EchoCreate(Context);
|
||||
}
|
||||
ALEffect_Update(ALEffectSlot->EffectState, Context, ALEffectSlot, effect);
|
||||
}
|
||||
|
||||
|
||||
@ -517,8 +508,8 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
|
||||
Context->AuxiliaryEffectSlot = Context->AuxiliaryEffectSlot->next;
|
||||
|
||||
// Release effectslot structure
|
||||
VerbDestroy(temp->ReverbState);
|
||||
EchoDestroy(temp->EchoState);
|
||||
if(temp->EffectState)
|
||||
ALEffect_Destroy(temp->EffectState);
|
||||
ALTHUNK_REMOVEENTRY(temp->effectslot);
|
||||
|
||||
memset(temp, 0, sizeof(ALeffectslot));
|
||||
|
Loading…
Reference in New Issue
Block a user