mirror of
https://github.com/love2d/megasource.git
synced 2026-08-19 20:20:11 +02:00
Update OpenAL Soft to 1.18.2
This commit is contained in:
@@ -39,9 +39,9 @@ typedef struct ALflangerState {
|
||||
DERIVE_FROM_TYPE(ALeffectState);
|
||||
|
||||
ALfloat *SampleBuffer[2];
|
||||
ALuint BufferLength;
|
||||
ALuint offset;
|
||||
ALuint lfo_range;
|
||||
ALsizei BufferLength;
|
||||
ALsizei offset;
|
||||
ALsizei lfo_range;
|
||||
ALfloat lfo_scale;
|
||||
ALint lfo_disp;
|
||||
|
||||
@@ -55,27 +55,51 @@ typedef struct ALflangerState {
|
||||
ALfloat feedback;
|
||||
} ALflangerState;
|
||||
|
||||
static ALvoid ALflangerState_Destruct(ALflangerState *state)
|
||||
static ALvoid ALflangerState_Destruct(ALflangerState *state);
|
||||
static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *Device);
|
||||
static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props);
|
||||
static ALvoid ALflangerState_process(ALflangerState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels);
|
||||
DECLARE_DEFAULT_ALLOCATORS(ALflangerState)
|
||||
|
||||
DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState);
|
||||
|
||||
|
||||
static void ALflangerState_Construct(ALflangerState *state)
|
||||
{
|
||||
free(state->SampleBuffer[0]);
|
||||
ALeffectState_Construct(STATIC_CAST(ALeffectState, state));
|
||||
SET_VTABLE2(ALflangerState, ALeffectState, state);
|
||||
|
||||
state->BufferLength = 0;
|
||||
state->SampleBuffer[0] = NULL;
|
||||
state->SampleBuffer[1] = NULL;
|
||||
state->offset = 0;
|
||||
state->lfo_range = 1;
|
||||
state->waveform = FWF_Triangle;
|
||||
}
|
||||
|
||||
static ALvoid ALflangerState_Destruct(ALflangerState *state)
|
||||
{
|
||||
al_free(state->SampleBuffer[0]);
|
||||
state->SampleBuffer[0] = NULL;
|
||||
state->SampleBuffer[1] = NULL;
|
||||
|
||||
ALeffectState_Destruct(STATIC_CAST(ALeffectState,state));
|
||||
}
|
||||
|
||||
static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *Device)
|
||||
{
|
||||
ALuint maxlen;
|
||||
ALuint it;
|
||||
ALsizei maxlen;
|
||||
ALsizei it;
|
||||
|
||||
maxlen = fastf2u(AL_FLANGER_MAX_DELAY * 3.0f * Device->Frequency) + 1;
|
||||
maxlen = fastf2i(AL_FLANGER_MAX_DELAY * 2.0f * Device->Frequency) + 1;
|
||||
maxlen = NextPowerOf2(maxlen);
|
||||
|
||||
if(maxlen != state->BufferLength)
|
||||
{
|
||||
void *temp;
|
||||
|
||||
temp = realloc(state->SampleBuffer[0], maxlen * sizeof(ALfloat) * 2);
|
||||
void *temp = al_calloc(16, maxlen * sizeof(ALfloat) * 2);
|
||||
if(!temp) return AL_FALSE;
|
||||
|
||||
al_free(state->SampleBuffer[0]);
|
||||
state->SampleBuffer[0] = temp;
|
||||
state->SampleBuffer[1] = state->SampleBuffer[0] + maxlen;
|
||||
|
||||
@@ -91,15 +115,14 @@ static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *D
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot)
|
||||
static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props)
|
||||
{
|
||||
static const ALfloat left_dir[3] = { -1.0f, 0.0f, 0.0f };
|
||||
static const ALfloat right_dir[3] = { 1.0f, 0.0f, 0.0f };
|
||||
ALfloat frequency = (ALfloat)Device->Frequency;
|
||||
ALfloat coeffs[MAX_AMBI_COEFFS];
|
||||
ALfloat rate;
|
||||
ALint phase;
|
||||
|
||||
switch(Slot->EffectProps.Flanger.Waveform)
|
||||
switch(props->Flanger.Waveform)
|
||||
{
|
||||
case AL_FLANGER_WAVEFORM_TRIANGLE:
|
||||
state->waveform = FWF_Triangle;
|
||||
@@ -108,16 +131,19 @@ static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, co
|
||||
state->waveform = FWF_Sinusoid;
|
||||
break;
|
||||
}
|
||||
state->depth = Slot->EffectProps.Flanger.Depth;
|
||||
state->feedback = Slot->EffectProps.Flanger.Feedback;
|
||||
state->delay = fastf2i(Slot->EffectProps.Flanger.Delay * frequency);
|
||||
state->feedback = props->Flanger.Feedback;
|
||||
state->delay = fastf2i(props->Flanger.Delay * frequency);
|
||||
/* The LFO depth is scaled to be relative to the sample delay. */
|
||||
state->depth = props->Flanger.Depth * state->delay;
|
||||
|
||||
/* Gains for left and right sides */
|
||||
ComputeDirectionalGains(Device, left_dir, Slot->Gain, state->Gain[0]);
|
||||
ComputeDirectionalGains(Device, right_dir, Slot->Gain, state->Gain[1]);
|
||||
CalcAngleCoeffs(-F_PI_2, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry, coeffs, Slot->Params.Gain, state->Gain[0]);
|
||||
CalcAngleCoeffs( F_PI_2, 0.0f, 0.0f, coeffs);
|
||||
ComputePanningGains(Device->Dry, coeffs, Slot->Params.Gain, state->Gain[1]);
|
||||
|
||||
phase = Slot->EffectProps.Flanger.Phase;
|
||||
rate = Slot->EffectProps.Flanger.Rate;
|
||||
phase = props->Flanger.Phase;
|
||||
rate = props->Flanger.Rate;
|
||||
if(!(rate > 0.0f))
|
||||
{
|
||||
state->lfo_scale = 0.0f;
|
||||
@@ -127,7 +153,7 @@ static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, co
|
||||
else
|
||||
{
|
||||
/* Calculate LFO coefficient */
|
||||
state->lfo_range = fastf2u(frequency/rate + 0.5f);
|
||||
state->lfo_range = fastf2i(frequency/rate + 0.5f);
|
||||
switch(state->waveform)
|
||||
{
|
||||
case FWF_Triangle:
|
||||
@@ -139,115 +165,107 @@ static ALvoid ALflangerState_update(ALflangerState *state, ALCdevice *Device, co
|
||||
}
|
||||
|
||||
/* Calculate lfo phase displacement */
|
||||
state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f));
|
||||
if(phase >= 0)
|
||||
state->lfo_disp = fastf2i(state->lfo_range * (phase/360.0f));
|
||||
else
|
||||
state->lfo_disp = fastf2i(state->lfo_range * ((360+phase)/360.0f));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void Triangle(ALint *delay_left, ALint *delay_right, ALuint offset, const ALflangerState *state)
|
||||
static void GetTriangleDelays(ALint *restrict delays, ALsizei offset, const ALsizei lfo_range,
|
||||
const ALfloat lfo_scale, const ALfloat depth, const ALsizei delay,
|
||||
const ALsizei todo)
|
||||
{
|
||||
ALfloat lfo_value;
|
||||
|
||||
lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
|
||||
lfo_value *= state->depth * state->delay;
|
||||
*delay_left = fastf2i(lfo_value) + state->delay;
|
||||
|
||||
offset += state->lfo_disp;
|
||||
lfo_value = 2.0f - fabsf(2.0f - state->lfo_scale*(offset%state->lfo_range));
|
||||
lfo_value *= state->depth * state->delay;
|
||||
*delay_right = fastf2i(lfo_value) + state->delay;
|
||||
ALsizei i;
|
||||
for(i = 0;i < todo;i++)
|
||||
{
|
||||
delays[i] = fastf2i((1.0f - fabsf(2.0f - lfo_scale*offset)) * depth) + delay;
|
||||
offset = (offset+1)%lfo_range;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALuint offset, const ALflangerState *state)
|
||||
static void GetSinusoidDelays(ALint *restrict delays, ALsizei offset, const ALsizei lfo_range,
|
||||
const ALfloat lfo_scale, const ALfloat depth, const ALsizei delay,
|
||||
const ALsizei todo)
|
||||
{
|
||||
ALfloat lfo_value;
|
||||
|
||||
lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range));
|
||||
lfo_value *= state->depth * state->delay;
|
||||
*delay_left = fastf2i(lfo_value) + state->delay;
|
||||
|
||||
offset += state->lfo_disp;
|
||||
lfo_value = 1.0f + sinf(state->lfo_scale*(offset%state->lfo_range));
|
||||
lfo_value *= state->depth * state->delay;
|
||||
*delay_right = fastf2i(lfo_value) + state->delay;
|
||||
ALsizei i;
|
||||
for(i = 0;i < todo;i++)
|
||||
{
|
||||
delays[i] = fastf2i(sinf(lfo_scale*offset) * depth) + delay;
|
||||
offset = (offset+1)%lfo_range;
|
||||
}
|
||||
}
|
||||
|
||||
#define DECL_TEMPLATE(Func) \
|
||||
static void Process##Func(ALflangerState *state, const ALuint SamplesToDo, \
|
||||
const ALfloat *restrict SamplesIn, ALfloat (*restrict out)[2]) \
|
||||
{ \
|
||||
const ALuint bufmask = state->BufferLength-1; \
|
||||
ALfloat *restrict leftbuf = state->SampleBuffer[0]; \
|
||||
ALfloat *restrict rightbuf = state->SampleBuffer[1]; \
|
||||
ALuint offset = state->offset; \
|
||||
const ALfloat feedback = state->feedback; \
|
||||
ALuint it; \
|
||||
\
|
||||
for(it = 0;it < SamplesToDo;it++) \
|
||||
{ \
|
||||
ALint delay_left, delay_right; \
|
||||
Func(&delay_left, &delay_right, offset, state); \
|
||||
\
|
||||
out[it][0] = leftbuf[(offset-delay_left)&bufmask]; \
|
||||
leftbuf[offset&bufmask] = (out[it][0]+SamplesIn[it]) * feedback; \
|
||||
\
|
||||
out[it][1] = rightbuf[(offset-delay_right)&bufmask]; \
|
||||
rightbuf[offset&bufmask] = (out[it][1]+SamplesIn[it]) * feedback; \
|
||||
\
|
||||
offset++; \
|
||||
} \
|
||||
state->offset = offset; \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(Triangle)
|
||||
DECL_TEMPLATE(Sinusoid)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
static ALvoid ALflangerState_process(ALflangerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels)
|
||||
static ALvoid ALflangerState_process(ALflangerState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels)
|
||||
{
|
||||
ALuint it, kt;
|
||||
ALuint base;
|
||||
ALfloat *restrict leftbuf = state->SampleBuffer[0];
|
||||
ALfloat *restrict rightbuf = state->SampleBuffer[1];
|
||||
const ALsizei bufmask = state->BufferLength-1;
|
||||
const ALfloat feedback = state->feedback;
|
||||
ALsizei offset = state->offset;
|
||||
ALsizei i, c;
|
||||
ALsizei base;
|
||||
|
||||
for(base = 0;base < SamplesToDo;)
|
||||
{
|
||||
const ALsizei todo = mini(128, SamplesToDo-base);
|
||||
ALfloat temps[128][2];
|
||||
ALuint td = minu(128, SamplesToDo-base);
|
||||
ALint moddelays[2][128];
|
||||
|
||||
switch(state->waveform)
|
||||
{
|
||||
case FWF_Triangle:
|
||||
ProcessTriangle(state, td, SamplesIn+base, temps);
|
||||
GetTriangleDelays(moddelays[0], offset%state->lfo_range, state->lfo_range,
|
||||
state->lfo_scale, state->depth, state->delay, todo);
|
||||
GetTriangleDelays(moddelays[1], (offset+state->lfo_disp)%state->lfo_range,
|
||||
state->lfo_range, state->lfo_scale, state->depth, state->delay,
|
||||
todo);
|
||||
break;
|
||||
case FWF_Sinusoid:
|
||||
ProcessSinusoid(state, td, SamplesIn+base, temps);
|
||||
GetSinusoidDelays(moddelays[0], offset%state->lfo_range, state->lfo_range,
|
||||
state->lfo_scale, state->depth, state->delay, todo);
|
||||
GetSinusoidDelays(moddelays[1], (offset+state->lfo_disp)%state->lfo_range,
|
||||
state->lfo_range, state->lfo_scale, state->depth, state->delay,
|
||||
todo);
|
||||
break;
|
||||
}
|
||||
|
||||
for(kt = 0;kt < NumChannels;kt++)
|
||||
for(i = 0;i < todo;i++)
|
||||
{
|
||||
ALfloat gain = state->Gain[0][kt];
|
||||
leftbuf[offset&bufmask] = SamplesIn[0][base+i];
|
||||
temps[i][0] = leftbuf[(offset-moddelays[0][i])&bufmask] * feedback;
|
||||
leftbuf[offset&bufmask] += temps[i][0];
|
||||
|
||||
rightbuf[offset&bufmask] = SamplesIn[0][base+i];
|
||||
temps[i][1] = rightbuf[(offset-moddelays[1][i])&bufmask] * feedback;
|
||||
rightbuf[offset&bufmask] += temps[i][1];
|
||||
|
||||
offset++;
|
||||
}
|
||||
|
||||
for(c = 0;c < NumChannels;c++)
|
||||
{
|
||||
ALfloat gain = state->Gain[0][c];
|
||||
if(fabsf(gain) > GAIN_SILENCE_THRESHOLD)
|
||||
{
|
||||
for(it = 0;it < td;it++)
|
||||
SamplesOut[kt][it+base] += temps[it][0] * gain;
|
||||
for(i = 0;i < todo;i++)
|
||||
SamplesOut[c][i+base] += temps[i][0] * gain;
|
||||
}
|
||||
|
||||
gain = state->Gain[1][kt];
|
||||
gain = state->Gain[1][c];
|
||||
if(fabsf(gain) > GAIN_SILENCE_THRESHOLD)
|
||||
{
|
||||
for(it = 0;it < td;it++)
|
||||
SamplesOut[kt][it+base] += temps[it][1] * gain;
|
||||
for(i = 0;i < todo;i++)
|
||||
SamplesOut[c][i+base] += temps[i][1] * gain;
|
||||
}
|
||||
}
|
||||
|
||||
base += td;
|
||||
base += todo;
|
||||
}
|
||||
|
||||
state->offset = offset;
|
||||
}
|
||||
|
||||
DECLARE_DEFAULT_ALLOCATORS(ALflangerState)
|
||||
|
||||
DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState);
|
||||
|
||||
|
||||
typedef struct ALflangerStateFactory {
|
||||
DERIVE_FROM_TYPE(ALeffectStateFactory);
|
||||
@@ -257,16 +275,8 @@ ALeffectState *ALflangerStateFactory_create(ALflangerStateFactory *UNUSED(factor
|
||||
{
|
||||
ALflangerState *state;
|
||||
|
||||
state = ALflangerState_New(sizeof(*state));
|
||||
NEW_OBJ0(state, ALflangerState)();
|
||||
if(!state) return NULL;
|
||||
SET_VTABLE2(ALflangerState, ALeffectState, state);
|
||||
|
||||
state->BufferLength = 0;
|
||||
state->SampleBuffer[0] = NULL;
|
||||
state->SampleBuffer[1] = NULL;
|
||||
state->offset = 0;
|
||||
state->lfo_range = 1;
|
||||
state->waveform = FWF_Triangle;
|
||||
|
||||
return STATIC_CAST(ALeffectState, state);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user