From 991aba286f32e8760811bc061b15c5102c66b3e1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 13 Mar 2013 21:53:42 -0700 Subject: Move the effect-specific get/set methods to where the effect is implemented --- Alc/alcModulator.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index de062151..05b2fb00 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -202,3 +202,100 @@ ALeffectState *ModulatorCreate(void) return &state->state; } + +void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + if(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY) + effect->Modulator.Frequency = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + if(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF) + effect->Modulator.HighPassCutoff = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + mod_SetParamf(effect, context, param, vals[0]); +} +void mod_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + mod_SetParamf(effect, context, param, (ALfloat)val); + break; + + case AL_RING_MODULATOR_WAVEFORM: + if(val >= AL_RING_MODULATOR_MIN_WAVEFORM && val <= AL_RING_MODULATOR_MAX_WAVEFORM) + effect->Modulator.Waveform = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + mod_SetParami(effect, context, param, vals[0]); +} + +void mod_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + *val = (ALint)effect->Modulator.Frequency; + break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + *val = (ALint)effect->Modulator.HighPassCutoff; + break; + case AL_RING_MODULATOR_WAVEFORM: + *val = effect->Modulator.Waveform; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + mod_GetParami(effect, context, param, vals); +} +void mod_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + *val = effect->Modulator.Frequency; + break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + *val = effect->Modulator.HighPassCutoff; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + mod_GetParamf(effect, context, param, vals); +} -- cgit v1.2.3 From a7ad6080f0d3fc783fd5e1811b961ab9efe79cde Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 18 May 2013 00:43:09 -0700 Subject: Modulator fixes Modulator functions return 0..1 instead of -1..+1 Apply high-pass filter before modulation Increase fractional precision to 24 bits from 16 Thanks to Mike Gorchak --- Alc/alcModulator.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index 05b2fb00..f1f8dadd 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -49,23 +49,23 @@ typedef struct ALmodulatorState { ALfloat history[1]; } ALmodulatorState; -#define WAVEFORM_FRACBITS 16 +#define WAVEFORM_FRACBITS 24 #define WAVEFORM_FRACONE (1<>(WAVEFORM_FRACBITS-1))&1)*2.0f - 1.0f; + return (ALfloat)((index >> (WAVEFORM_FRACBITS - 1)) & 1); } @@ -95,13 +95,12 @@ static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ for(i = 0;i < SamplesToDo;i++) \ { \ samp = SamplesIn[i]; \ + samp = hpFilter1P(&state->iirFilter, 0, samp); \ \ index += step; \ index &= WAVEFORM_FRACMASK; \ samp *= func(index); \ \ - samp = hpFilter1P(&state->iirFilter, 0, samp); \ - \ for(k = 0;k < MaxChannels;k++) \ SamplesOut[k][i] += state->Gain[k] * samp; \ } \ -- cgit v1.2.3 From 4c436b106d1a2b57e28fcaff0d5ec4a7abc6badc Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 20 May 2013 01:32:02 -0700 Subject: Use some macros to help with deriving types --- Alc/alcChorus.c | 22 ++++++++++------------ Alc/alcDedicated.c | 19 +++++++++---------- Alc/alcDistortion.c | 22 ++++++++++------------ Alc/alcEcho.c | 21 ++++++++++----------- Alc/alcEqualizer.c | 22 ++++++++++------------ Alc/alcFlanger.c | 22 ++++++++++------------ Alc/alcModulator.c | 19 +++++++++---------- Alc/alcReverb.c | 27 +++++++++++++-------------- OpenAL32/Include/alMain.h | 4 ++++ 9 files changed, 85 insertions(+), 93 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index 5a25d4d1..6a56cf68 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -31,8 +31,7 @@ typedef struct ALchorusState { - // Must be first in all effects! - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); ALfloat *SampleBufferLeft; ALfloat *SampleBufferRight; @@ -56,8 +55,7 @@ typedef struct ALchorusState { static ALvoid ChorusDestroy(ALeffectState *effect) { - ALchorusState *state = (ALchorusState*)effect; - + ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); if(state) { free(state->SampleBufferLeft); @@ -72,7 +70,7 @@ static ALvoid ChorusDestroy(ALeffectState *effect) static ALboolean ChorusDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALchorusState *state = (ALchorusState*)effect; + ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); ALuint maxlen; ALuint it; @@ -113,7 +111,7 @@ static ALboolean ChorusDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid ChorusUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALchorusState *state = (ALchorusState*)effect; + ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); ALuint it; for (it = 0; it < MaxChannels; it++) @@ -173,7 +171,7 @@ static ALvoid ChorusUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff static ALvoid ChorusProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALchorusState *state = (ALchorusState*)effect; + ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); const ALuint mask = state->BufferLength-1; ALuint it; ALuint kt; @@ -257,17 +255,17 @@ ALeffectState *ChorusCreate(void) if(!state) return NULL; - state->state.Destroy = ChorusDestroy; - state->state.DeviceUpdate = ChorusDeviceUpdate; - state->state.Update = ChorusUpdate; - state->state.Process = ChorusProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = ChorusDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = ChorusDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = ChorusUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = ChorusProcess; state->BufferLength = 0; state->SampleBufferLeft = NULL; state->SampleBufferRight = NULL; state->offset = 0; - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void chorus_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index d73d8959..e10ad9e9 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -30,8 +30,7 @@ typedef struct ALdedicatedState { - // Must be first in all effects! - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); ALfloat gains[MaxChannels]; } ALdedicatedState; @@ -39,7 +38,7 @@ typedef struct ALdedicatedState { static ALvoid DedicatedDestroy(ALeffectState *effect) { - ALdedicatedState *state = (ALdedicatedState*)effect; + ALdedicatedState *state = GET_PARENT_TYPE(ALdedicatedState, ALeffectState, effect); free(state); } @@ -52,7 +51,7 @@ static ALboolean DedicatedDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot) { - ALdedicatedState *state = (ALdedicatedState*)effect; + ALdedicatedState *state = GET_PARENT_TYPE(ALdedicatedState, ALeffectState, effect); ALfloat Gain; ALsizei s; @@ -68,7 +67,7 @@ static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const AL static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALdedicatedState *state = (ALdedicatedState*)effect; + ALdedicatedState *state = GET_PARENT_TYPE(ALdedicatedState, ALeffectState, effect); const ALfloat *gains = state->gains; ALuint i, c; @@ -88,15 +87,15 @@ ALeffectState *DedicatedCreate(void) if(!state) return NULL; - state->state.Destroy = DedicatedDestroy; - state->state.DeviceUpdate = DedicatedDeviceUpdate; - state->state.Update = DedicatedUpdate; - state->state.Process = DedicatedProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = DedicatedDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = DedicatedDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = DedicatedUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = DedicatedProcess; for(s = 0;s < MaxChannels;s++) state->gains[s] = 0.0f; - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 59ccca73..05833680 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -47,8 +47,7 @@ typedef struct ALEQFilter { } ALEQFilter; typedef struct ALdistortionState { - /* Must be first in all effects! */ - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); /* Effect gains for each channel */ ALfloat Gain[MaxChannels]; @@ -66,14 +65,13 @@ typedef struct ALdistortionState { static ALvoid DistortionDestroy(ALeffectState *effect) { - ALdistortionState *state = (ALdistortionState*)effect; - + ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); free(state); } static ALboolean DistortionDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALdistortionState *state = (ALdistortionState*)effect; + ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); state->frequency = (ALfloat)Device->Frequency; @@ -82,7 +80,7 @@ static ALboolean DistortionDeviceUpdate(ALeffectState *effect, ALCdevice *Device static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALdistortionState *state = (ALdistortionState*)effect; + ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; ALuint it; ALfloat w0; @@ -135,7 +133,7 @@ static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const A static ALvoid DistortionProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALdistortionState *state = (ALdistortionState*)effect; + ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); float *RESTRICT oversample_buffer = &state->oversample_buffer[0][0]; ALfloat tempsmp; ALuint it; @@ -222,10 +220,10 @@ ALeffectState *DistortionCreate(void) if(!state) return NULL; - state->state.Destroy = DistortionDestroy; - state->state.DeviceUpdate = DistortionDeviceUpdate; - state->state.Update = DistortionUpdate; - state->state.Process = DistortionProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = DistortionDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = DistortionDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = DistortionUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = DistortionProcess; state->bandpass.type = BANDPASS; state->lowpass.type = LOWPASS; @@ -237,7 +235,7 @@ ALeffectState *DistortionCreate(void) state->lowpass.y[0] = 0.0f; state->lowpass.y[1] = 0.0f; - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void distortion_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index 55a5b599..1d06e68a 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -31,8 +31,7 @@ typedef struct ALechoState { - // Must be first in all effects! - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); ALfloat *SampleBuffer; ALuint BufferLength; @@ -54,7 +53,7 @@ typedef struct ALechoState { static ALvoid EchoDestroy(ALeffectState *effect) { - ALechoState *state = (ALechoState*)effect; + ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); if(state) { free(state->SampleBuffer); @@ -65,7 +64,7 @@ static ALvoid EchoDestroy(ALeffectState *effect) static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALechoState *state = (ALechoState*)effect; + ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); ALuint maxlen, i; // Use the next power of 2 for the buffer length, so the tap offsets can be @@ -92,7 +91,7 @@ static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALechoState *state = (ALechoState*)effect; + ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); ALuint frequency = Device->Frequency; ALfloat lrpan, cw, g, gain; ALfloat dirGain; @@ -128,7 +127,7 @@ static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffec static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALechoState *state = (ALechoState*)effect; + ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; @@ -164,10 +163,10 @@ ALeffectState *EchoCreate(void) if(!state) return NULL; - state->state.Destroy = EchoDestroy; - state->state.DeviceUpdate = EchoDeviceUpdate; - state->state.Update = EchoUpdate; - state->state.Process = EchoProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = EchoDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = EchoDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = EchoUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = EchoProcess; state->BufferLength = 0; state->SampleBuffer = NULL; @@ -180,7 +179,7 @@ ALeffectState *EchoCreate(void) state->iirFilter.history[0] = 0.0f; state->iirFilter.history[1] = 0.0f; - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index dffc431a..c10eba2a 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -85,8 +85,7 @@ typedef struct ALEQFilter { } ALEQFilter; typedef struct ALequalizerState { - /* Must be first in all effects! */ - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); /* Effect gains for each channel */ ALfloat Gain[MaxChannels]; @@ -98,14 +97,13 @@ typedef struct ALequalizerState { static ALvoid EqualizerDestroy(ALeffectState *effect) { - ALequalizerState *state = (ALequalizerState*)effect; - + ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); free(state); } static ALboolean EqualizerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALequalizerState *state = (ALequalizerState*)effect; + ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); state->frequency = (ALfloat)Device->Frequency; @@ -114,7 +112,7 @@ static ALboolean EqualizerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALequalizerState *state = (ALequalizerState*)effect; + ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; ALuint it; @@ -215,7 +213,7 @@ static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const AL static ALvoid EqualizerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALequalizerState *state = (ALequalizerState*)effect; + ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); ALuint it; ALuint kt; ALuint ft; @@ -254,10 +252,10 @@ ALeffectState *EqualizerCreate(void) if(!state) return NULL; - state->state.Destroy = EqualizerDestroy; - state->state.DeviceUpdate = EqualizerDeviceUpdate; - state->state.Update = EqualizerUpdate; - state->state.Process = EqualizerProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = EqualizerDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = EqualizerDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = EqualizerUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = EqualizerProcess; state->bandfilter[0].type = LOW_SHELF; state->bandfilter[1].type = PEAKING; @@ -274,7 +272,7 @@ ALeffectState *EqualizerCreate(void) state->bandfilter[it].y[1] = 0.0f; } - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void equalizer_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index d5764706..5b643a46 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -31,8 +31,7 @@ typedef struct ALflangerState { - // Must be first in all effects! - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); ALfloat *SampleBufferLeft; ALfloat *SampleBufferRight; @@ -56,8 +55,7 @@ typedef struct ALflangerState { static ALvoid FlangerDestroy(ALeffectState *effect) { - ALflangerState *state = (ALflangerState*)effect; - + ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); if(state) { free(state->SampleBufferLeft); @@ -72,7 +70,7 @@ static ALvoid FlangerDestroy(ALeffectState *effect) static ALboolean FlangerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALflangerState *state = (ALflangerState*)effect; + ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); ALuint maxlen; ALuint it; @@ -113,7 +111,7 @@ static ALboolean FlangerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid FlangerUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALflangerState *state = (ALflangerState*)effect; + ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); ALuint it; for (it = 0; it < MaxChannels; it++) @@ -173,7 +171,7 @@ static ALvoid FlangerUpdate(ALeffectState *effect, ALCdevice *Device, const ALef static ALvoid FlangerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALflangerState *state = (ALflangerState*)effect; + ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); const ALuint mask = state->BufferLength-1; ALuint it; ALuint kt; @@ -257,17 +255,17 @@ ALeffectState *FlangerCreate(void) if(!state) return NULL; - state->state.Destroy = FlangerDestroy; - state->state.DeviceUpdate = FlangerDeviceUpdate; - state->state.Update = FlangerUpdate; - state->state.Process = FlangerProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = FlangerDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = FlangerDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = FlangerUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = FlangerProcess; state->BufferLength = 0; state->SampleBufferLeft = NULL; state->SampleBufferRight = NULL; state->offset = 0; - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void flanger_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index f1f8dadd..d33811ba 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -31,8 +31,7 @@ typedef struct ALmodulatorState { - // Must be first in all effects! - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); enum { SINUSOID, @@ -116,7 +115,7 @@ DECL_TEMPLATE(Square) static ALvoid ModulatorDestroy(ALeffectState *effect) { - ALmodulatorState *state = (ALmodulatorState*)effect; + ALmodulatorState *state = GET_PARENT_TYPE(ALmodulatorState, ALeffectState, effect); free(state); } @@ -129,7 +128,7 @@ static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALmodulatorState *state = (ALmodulatorState*)effect; + ALmodulatorState *state = GET_PARENT_TYPE(ALmodulatorState, ALeffectState, effect); ALfloat gain, cw, a = 0.0f; ALuint index; @@ -162,7 +161,7 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const AL static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALmodulatorState *state = (ALmodulatorState*)effect; + ALmodulatorState *state = GET_PARENT_TYPE(ALmodulatorState, ALeffectState, effect); switch(state->Waveform) { @@ -188,10 +187,10 @@ ALeffectState *ModulatorCreate(void) if(!state) return NULL; - state->state.Destroy = ModulatorDestroy; - state->state.DeviceUpdate = ModulatorDeviceUpdate; - state->state.Update = ModulatorUpdate; - state->state.Process = ModulatorProcess; + GET_DERIVED_TYPE(ALeffectState, state)->Destroy = ModulatorDestroy; + GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = ModulatorDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Update = ModulatorUpdate; + GET_DERIVED_TYPE(ALeffectState, state)->Process = ModulatorProcess; state->index = 0; state->step = 1; @@ -199,7 +198,7 @@ ALeffectState *ModulatorCreate(void) state->iirFilter.coeff = 0.0f; state->iirFilter.history[0] = 0.0f; - return &state->state; + return GET_DERIVED_TYPE(ALeffectState, state); } void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index ab52ae77..ac9af905 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -40,8 +40,7 @@ typedef struct DelayLine } DelayLine; typedef struct ALverbState { - // Must be first in all effects! - ALeffectState state; + DERIVE_FROM_TYPE(ALeffectState); // All delay lines are allocated as a single buffer to reduce memory // fragmentation and management code. @@ -557,7 +556,7 @@ static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *REST // buffer. static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALverbState *State = (ALverbState*)effect; + ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); ALfloat (*RESTRICT out)[4] = State->ReverbSamples; ALuint index, c; @@ -580,7 +579,7 @@ static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo // buffer. static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALverbState *State = (ALverbState*)effect; + ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); ALfloat (*RESTRICT early)[4] = State->EarlySamples; ALfloat (*RESTRICT late)[4] = State->ReverbSamples; ALuint index, c; @@ -727,7 +726,7 @@ static ALboolean AllocLines(ALuint frequency, ALverbState *State) // format) have been changed. static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALverbState *State = (ALverbState*)effect; + ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); ALuint frequency = Device->Frequency, index; // Allocate the delay lines. @@ -1079,19 +1078,19 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection // effect is loaded into a slot. static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALverbState *State = (ALverbState*)effect; + ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); ALuint frequency = Device->Frequency; ALboolean isEAX = AL_FALSE; ALfloat cw, x, y, hfRatio; if(Slot->effect.type == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) { - State->state.Process = EAXVerbProcess; + GET_DERIVED_TYPE(ALeffectState, State)->Process = EAXVerbProcess; isEAX = AL_TRUE; } else if(Slot->effect.type == AL_EFFECT_REVERB || EmulateEAXReverb) { - State->state.Process = VerbProcess; + GET_DERIVED_TYPE(ALeffectState, State)->Process = VerbProcess; isEAX = AL_FALSE; } @@ -1174,7 +1173,7 @@ static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff // slot has a different (or no) effect loaded over the reverb effect. static ALvoid ReverbDestroy(ALeffectState *effect) { - ALverbState *State = (ALverbState*)effect; + ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); if(State) { free(State->SampleBuffer); @@ -1194,10 +1193,10 @@ ALeffectState *ReverbCreate(void) if(!State) return NULL; - State->state.Destroy = ReverbDestroy; - State->state.DeviceUpdate = ReverbDeviceUpdate; - State->state.Update = ReverbUpdate; - State->state.Process = VerbProcess; + GET_DERIVED_TYPE(ALeffectState, State)->Destroy = ReverbDestroy; + GET_DERIVED_TYPE(ALeffectState, State)->DeviceUpdate = ReverbDeviceUpdate; + GET_DERIVED_TYPE(ALeffectState, State)->Update = ReverbUpdate; + GET_DERIVED_TYPE(ALeffectState, State)->Process = VerbProcess; State->TotalSamples = 0; State->SampleBuffer = NULL; @@ -1279,7 +1278,7 @@ ALeffectState *ReverbCreate(void) State->Gain = State->Late.PanGain; - return &State->state; + return GET_DERIVED_TYPE(ALeffectState, State); } void eaxreverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index d234ae13..a1a90b2f 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -62,6 +62,10 @@ static const union { #define COUNTOF(x) (sizeof((x))/sizeof((x)[0])) +#define DERIVE_FROM_TYPE(t) t t##_parent +#define GET_DERIVED_TYPE(t, o) (&(o)->t##_parent) +#define GET_PARENT_TYPE(t1, t2, o) ((t1*)((char*)(o) - offsetof(t1, t2##_parent))) + #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN -- cgit v1.2.3 From 5b706f3bdc1a8c8f064a253b53b4e86f9d88da8d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 20 May 2013 04:16:48 -0700 Subject: Process 64 samples at a time for some effects This should help with the non-interleaved samples of the output, and allow skipping channels that don't contribute to the output. --- Alc/alcDedicated.c | 3 + Alc/alcDistortion.c | 157 +++++++++++++++++++++++++++++----------------------- Alc/alcEcho.c | 48 +++++++++++----- Alc/alcEqualizer.c | 76 ++++++++++++++++--------- Alc/alcModulator.c | 34 +++++++++--- 5 files changed, 201 insertions(+), 117 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index e10ad9e9..bb82bbcb 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -73,6 +73,9 @@ static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const for(c = 0;c < MaxChannels;c++) { + if(!(gains[c] > 0.00001f)) + continue; + for(i = 0;i < SamplesToDo;i++) SamplesOut[c][i] = SamplesIn[i] * gains[c]; } diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 05833680..315a7761 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -58,9 +58,6 @@ typedef struct ALdistortionState { ALfloat frequency; ALfloat attenuation; ALfloat edge_coeff; - - /* Oversample data */ - ALfloat oversample_buffer[BUFFERSIZE][4]; } ALdistortionState; static ALvoid DistortionDestroy(ALeffectState *effect) @@ -134,81 +131,103 @@ static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const A static ALvoid DistortionProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); - float *RESTRICT oversample_buffer = &state->oversample_buffer[0][0]; + const ALfloat fc = state->edge_coeff; + float oversample_buffer[64][4]; ALfloat tempsmp; + ALuint base; ALuint it; + ALuint ot; ALuint kt; - /* Perform 4x oversampling to avoid aliasing. */ - /* Oversampling greatly improves distortion */ - /* quality and allows to implement lowpass and */ - /* bandpass filters using high frequencies, at */ - /* which classic IIR filters became unstable. */ - - /* Fill oversample buffer using zero stuffing */ - for(it = 0; it < SamplesToDo; it++) + for(base = 0;base < SamplesToDo;) { - oversample_buffer[it*4 + 0] = SamplesIn[it]; - oversample_buffer[it*4 + 1] = 0.0f; - oversample_buffer[it*4 + 2] = 0.0f; - oversample_buffer[it*4 + 3] = 0.0f; - } + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); - /* First step, do lowpass filtering of original signal, */ - /* additionally perform buffer interpolation and lowpass */ - /* cutoff for oversampling (which is fortunately first */ - /* step of distortion). So combine three operations into */ - /* the one. */ - for(it = 0; it < SamplesToDo * 4; it++) - { - tempsmp = state->lowpass.b[0] / state->lowpass.a[0] * oversample_buffer[it] + - state->lowpass.b[1] / state->lowpass.a[0] * state->lowpass.x[0] + - state->lowpass.b[2] / state->lowpass.a[0] * state->lowpass.x[1] - - state->lowpass.a[1] / state->lowpass.a[0] * state->lowpass.y[0] - - state->lowpass.a[2] / state->lowpass.a[0] * state->lowpass.y[1]; - - state->lowpass.x[1] = state->lowpass.x[0]; - state->lowpass.x[0] = oversample_buffer[it]; - state->lowpass.y[1] = state->lowpass.y[0]; - state->lowpass.y[0] = tempsmp; - /* Restore signal power by multiplying sample by amount of oversampling */ - oversample_buffer[it] = tempsmp * 4.0f; - } + /* Perform 4x oversampling to avoid aliasing. */ + /* Oversampling greatly improves distortion */ + /* quality and allows to implement lowpass and */ + /* bandpass filters using high frequencies, at */ + /* which classic IIR filters became unstable. */ - for(it = 0; it < SamplesToDo * 4; it++) - { - ALfloat smp = oversample_buffer[it]; - ALfloat fc = state->edge_coeff; - - /* Second step, do distortion using waveshaper function */ - /* to emulate signal processing during tube overdriving. */ - /* Three steps of waveshaping are intended to modify */ - /* waveform without boost/clipping/attenuation process. */ - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)) * -1.0f; - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); - - /* Third step, do bandpass filtering of distorted signal */ - tempsmp = state->bandpass.b[0] / state->bandpass.a[0] * smp + - state->bandpass.b[1] / state->bandpass.a[0] * state->bandpass.x[0] + - state->bandpass.b[2] / state->bandpass.a[0] * state->bandpass.x[1] - - state->bandpass.a[1] / state->bandpass.a[0] * state->bandpass.y[0] - - state->bandpass.a[2] / state->bandpass.a[0] * state->bandpass.y[1]; - - state->bandpass.x[1] = state->bandpass.x[0]; - state->bandpass.x[0] = smp; - state->bandpass.y[1] = state->bandpass.y[0]; - state->bandpass.y[0] = tempsmp; - smp = tempsmp; - - /* Fourth step, final, do attenuation and perform decimation, */ - /* store only one sample out of 4. */ - if(!(it&3)) + /* Fill oversample buffer using zero stuffing */ + for(it = 0;it < td;it++) + { + oversample_buffer[it][0] = SamplesIn[it+base]; + oversample_buffer[it][1] = 0.0f; + oversample_buffer[it][2] = 0.0f; + oversample_buffer[it][3] = 0.0f; + } + + /* First step, do lowpass filtering of original signal, */ + /* additionally perform buffer interpolation and lowpass */ + /* cutoff for oversampling (which is fortunately first */ + /* step of distortion). So combine three operations into */ + /* the one. */ + for(it = 0;it < td;it++) { - smp *= state->attenuation; - for(kt = 0; kt < MaxChannels; kt++) - SamplesOut[kt][it>>2] += state->Gain[kt] * smp; + for(ot = 0;ot < 4;ot++) + { + tempsmp = state->lowpass.b[0] / state->lowpass.a[0] * oversample_buffer[it][ot] + + state->lowpass.b[1] / state->lowpass.a[0] * state->lowpass.x[0] + + state->lowpass.b[2] / state->lowpass.a[0] * state->lowpass.x[1] - + state->lowpass.a[1] / state->lowpass.a[0] * state->lowpass.y[0] - + state->lowpass.a[2] / state->lowpass.a[0] * state->lowpass.y[1]; + + state->lowpass.x[1] = state->lowpass.x[0]; + state->lowpass.x[0] = oversample_buffer[it][ot]; + state->lowpass.y[1] = state->lowpass.y[0]; + state->lowpass.y[0] = tempsmp; + /* Restore signal power by multiplying sample by amount of oversampling */ + oversample_buffer[it][ot] = tempsmp * 4.0f; + } } + + for(it = 0;it < td;it++) + { + /* Second step, do distortion using waveshaper function */ + /* to emulate signal processing during tube overdriving. */ + /* Three steps of waveshaping are intended to modify */ + /* waveform without boost/clipping/attenuation process. */ + for(ot = 0;ot < 4;ot++) + { + ALfloat smp = oversample_buffer[it][ot]; + + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)) * -1.0f; + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); + + /* Third step, do bandpass filtering of distorted signal */ + tempsmp = state->bandpass.b[0] / state->bandpass.a[0] * smp + + state->bandpass.b[1] / state->bandpass.a[0] * state->bandpass.x[0] + + state->bandpass.b[2] / state->bandpass.a[0] * state->bandpass.x[1] - + state->bandpass.a[1] / state->bandpass.a[0] * state->bandpass.y[0] - + state->bandpass.a[2] / state->bandpass.a[0] * state->bandpass.y[1]; + + state->bandpass.x[1] = state->bandpass.x[0]; + state->bandpass.x[0] = smp; + state->bandpass.y[1] = state->bandpass.y[0]; + state->bandpass.y[0] = tempsmp; + + oversample_buffer[it][ot] = tempsmp; + } + + /* Fourth step, final, do attenuation and perform decimation, */ + /* store only one sample out of 4. */ + temps[it] = oversample_buffer[it][0] * state->attenuation; + } + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > 0.00001f)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; } } diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index 1d06e68a..498ebbc7 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -133,25 +133,47 @@ static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo const ALuint tap2 = state->Tap[1].delay; ALuint offset = state->Offset; ALfloat smp; + ALuint base; ALuint i, k; - for(i = 0;i < SamplesToDo;i++,offset++) + for(base = 0;base < SamplesToDo;) { - /* First tap */ - smp = state->SampleBuffer[(offset-tap1) & mask]; - for(k = 0;k < MaxChannels;k++) - SamplesOut[k][i] += smp * state->Gain[0][k]; + ALfloat temps[64][2]; + ALuint td = minu(SamplesToDo-base, 64); + + for(i = 0;i < td;i++) + { + /* First tap */ + temps[i][0] = state->SampleBuffer[(offset-tap1) & mask]; + /* Second tap */ + temps[i][1] = state->SampleBuffer[(offset-tap2) & mask]; + + // Apply damping and feedback gain to the second tap, and mix in the + // new sample + smp = lpFilter2P(&state->iirFilter, 0, temps[i][1]+SamplesIn[i]); + state->SampleBuffer[offset&mask] = smp * state->FeedGain; + } - /* Second tap */ - smp = state->SampleBuffer[(offset-tap2) & mask]; for(k = 0;k < MaxChannels;k++) - SamplesOut[k][i] += smp * state->Gain[1][k]; - - // Apply damping and feedback gain to the second tap, and mix in the - // new sample - smp = lpFilter2P(&state->iirFilter, 0, smp+SamplesIn[i]); - state->SampleBuffer[offset&mask] = smp * state->FeedGain; + { + ALfloat gain = state->Gain[0][k]; + if(gain > 0.00001f) + { + for(i = 0;i < td;i++) + SamplesOut[k][i+base] += temps[i][0] * gain; + } + + gain = state->Gain[1][k]; + if(gain > 0.00001f) + { + for(i = 0;i < td;i++) + SamplesOut[k][i+base] += temps[i][1] * gain; + } + } + + base += td; } + state->Offset = offset; } diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index c10eba2a..d4b4f855 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -162,20 +162,24 @@ static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const AL switch(state->bandfilter[it].type) { case LOW_SHELF: - alpha = sinf(w0) / 2.0f * - sqrtf((gain + 1.0f / gain) * (1.0f / 0.75f - 1.0f) + 2.0f); + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * + (1.0f / 0.75f - 1.0f) + 2.0f); state->bandfilter[it].b[0] = gain * ((gain + 1.0f) - - (gain - 1.0f) * cosf(w0) + 2.0f * sqrtf(gain) * alpha); + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); state->bandfilter[it].b[1] = 2.0f * gain * ((gain - 1.0f) - - (gain + 1.0f) * cosf(w0)); + (gain + 1.0f) * cosf(w0)); state->bandfilter[it].b[2] = gain * ((gain + 1.0f) - - (gain - 1.0f) * cosf(w0) - 2.0f * sqrtf(gain) * alpha); - state->bandfilter[it].a[0] = (gain + 1.0f) + (gain - 1.0f) * - cosf(w0) + 2.0f * sqrtf(gain) * alpha; + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + state->bandfilter[it].a[0] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; state->bandfilter[it].a[1] = -2.0f * ((gain - 1.0f) + - (gain + 1.0f) * cosf(w0)); - state->bandfilter[it].a[2] = (gain + 1.0f) + (gain - 1.0f) * - cosf(w0) - 2.0f * sqrtf(gain) * alpha; + (gain + 1.0f) * cosf(w0)); + state->bandfilter[it].a[2] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; break; case HIGH_SHELF: alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * @@ -214,32 +218,52 @@ static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const AL static ALvoid EqualizerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); + ALuint base; ALuint it; ALuint kt; ALuint ft; - for (it = 0; it < SamplesToDo; it++) + for(base = 0;base < SamplesToDo;) { - ALfloat tempsmp; - ALfloat smp = SamplesIn[it]; + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); - for(ft = 0;ft < 4;ft++) + for(it = 0;it < td;it++) { - tempsmp = state->bandfilter[ft].b[0] / state->bandfilter[ft].a[0] * smp + - state->bandfilter[ft].b[1] / state->bandfilter[ft].a[0] * state->bandfilter[ft].x[0] + - state->bandfilter[ft].b[2] / state->bandfilter[ft].a[0] * state->bandfilter[ft].x[1] - - state->bandfilter[ft].a[1] / state->bandfilter[ft].a[0] * state->bandfilter[ft].y[0] - - state->bandfilter[ft].a[2] / state->bandfilter[ft].a[0] * state->bandfilter[ft].y[1]; - - state->bandfilter[ft].x[1] = state->bandfilter[ft].x[0]; - state->bandfilter[ft].x[0] = smp; - state->bandfilter[ft].y[1] = state->bandfilter[ft].y[0]; - state->bandfilter[ft].y[0] = tempsmp; - smp = tempsmp; + ALfloat smp = SamplesIn[base+it]; + ALfloat tempsmp; + + for(ft = 0;ft < 4;ft++) + { + ALEQFilter *filter = &state->bandfilter[ft]; + + tempsmp = filter->b[0] / filter->a[0] * smp + + filter->b[1] / filter->a[0] * filter->x[0] + + filter->b[2] / filter->a[0] * filter->x[1] - + filter->a[1] / filter->a[0] * filter->y[0] - + filter->a[2] / filter->a[0] * filter->y[1]; + + filter->x[1] = filter->x[0]; + filter->x[0] = smp; + filter->y[1] = filter->y[0]; + filter->y[0] = tempsmp; + smp = tempsmp; + } + + temps[it] = smp; } for(kt = 0;kt < MaxChannels;kt++) - SamplesOut[kt][it] += state->Gain[kt] * smp; + { + ALfloat gain = state->Gain[kt]; + if(!(gain > 0.00001f)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; } } diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index d33811ba..c9f1edf4 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -88,20 +88,36 @@ static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ { \ const ALuint step = state->step; \ ALuint index = state->index; \ - ALfloat samp; \ - ALuint i, k; \ + ALuint base; \ \ - for(i = 0;i < SamplesToDo;i++) \ + for(base = 0;base < SamplesToDo;) \ { \ - samp = SamplesIn[i]; \ - samp = hpFilter1P(&state->iirFilter, 0, samp); \ + ALfloat temps[64]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + ALuint i, k; \ \ - index += step; \ - index &= WAVEFORM_FRACMASK; \ - samp *= func(index); \ + for(i = 0;i < td;i++) \ + { \ + ALfloat samp; \ + samp = SamplesIn[base+i]; \ + samp = hpFilter1P(&state->iirFilter, 0, samp); \ + \ + index += step; \ + index &= WAVEFORM_FRACMASK; \ + temps[i] = samp * func(index); \ + } \ \ for(k = 0;k < MaxChannels;k++) \ - SamplesOut[k][i] += state->Gain[k] * samp; \ + { \ + ALfloat gain = state->Gain[k]; \ + if(!(gain > 0.00001f)) \ + continue; \ + \ + for(i = 0;i < td;i++) \ + SamplesOut[k][base+i] += gain * temps[i]; \ + } \ + \ + base += td; \ } \ state->index = index; \ } -- cgit v1.2.3 From 44da54ec7f1826e3318202084e49a58a886a3f7b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 May 2013 02:30:11 -0700 Subject: Rename some inheritance macros --- Alc/alcChorus.c | 18 +++++++++--------- Alc/alcDedicated.c | 16 ++++++++-------- Alc/alcDistortion.c | 18 +++++++++--------- Alc/alcEcho.c | 18 +++++++++--------- Alc/alcEqualizer.c | 18 +++++++++--------- Alc/alcFlanger.c | 18 +++++++++--------- Alc/alcModulator.c | 16 ++++++++-------- Alc/alcReverb.c | 24 ++++++++++++------------ OpenAL32/Include/alMain.h | 6 +++--- 9 files changed, 76 insertions(+), 76 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index 87e186e9..5f360d17 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -52,7 +52,7 @@ typedef struct ALchorusState { static ALvoid ChorusDestroy(ALeffectState *effect) { - ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); + ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); if(state) { free(state->SampleBufferLeft); @@ -67,7 +67,7 @@ static ALvoid ChorusDestroy(ALeffectState *effect) static ALboolean ChorusDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); + ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); ALuint maxlen; ALuint it; @@ -100,7 +100,7 @@ static ALboolean ChorusDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid ChorusUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); + ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); ALfloat frequency = Device->Frequency; ALfloat rate; ALint phase; @@ -238,7 +238,7 @@ DECL_TEMPLATE(Sinusoid) static ALvoid ChorusProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALchorusState *state = GET_PARENT_TYPE(ALchorusState, ALeffectState, effect); + ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); @@ -254,17 +254,17 @@ ALeffectState *ChorusCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = ChorusDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = ChorusDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = ChorusUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = ChorusProcess; + STATIC_CAST(ALeffectState, state)->Destroy = ChorusDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = ChorusDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = ChorusUpdate; + STATIC_CAST(ALeffectState, state)->Process = ChorusProcess; state->BufferLength = 0; state->SampleBufferLeft = NULL; state->SampleBufferRight = NULL; state->offset = 0; - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void chorus_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index bb82bbcb..35de345f 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -38,7 +38,7 @@ typedef struct ALdedicatedState { static ALvoid DedicatedDestroy(ALeffectState *effect) { - ALdedicatedState *state = GET_PARENT_TYPE(ALdedicatedState, ALeffectState, effect); + ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); free(state); } @@ -51,7 +51,7 @@ static ALboolean DedicatedDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot) { - ALdedicatedState *state = GET_PARENT_TYPE(ALdedicatedState, ALeffectState, effect); + ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); ALfloat Gain; ALsizei s; @@ -67,7 +67,7 @@ static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const AL static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALdedicatedState *state = GET_PARENT_TYPE(ALdedicatedState, ALeffectState, effect); + ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); const ALfloat *gains = state->gains; ALuint i, c; @@ -90,15 +90,15 @@ ALeffectState *DedicatedCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = DedicatedDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = DedicatedDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = DedicatedUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = DedicatedProcess; + STATIC_CAST(ALeffectState, state)->Destroy = DedicatedDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = DedicatedDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = DedicatedUpdate; + STATIC_CAST(ALeffectState, state)->Process = DedicatedProcess; for(s = 0;s < MaxChannels;s++) state->gains[s] = 0.0f; - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 315a7761..c431a2ca 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -62,13 +62,13 @@ typedef struct ALdistortionState { static ALvoid DistortionDestroy(ALeffectState *effect) { - ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); + ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); free(state); } static ALboolean DistortionDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); + ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); state->frequency = (ALfloat)Device->Frequency; @@ -77,7 +77,7 @@ static ALboolean DistortionDeviceUpdate(ALeffectState *effect, ALCdevice *Device static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); + ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; ALuint it; ALfloat w0; @@ -130,7 +130,7 @@ static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const A static ALvoid DistortionProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALdistortionState *state = GET_PARENT_TYPE(ALdistortionState, ALeffectState, effect); + ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); const ALfloat fc = state->edge_coeff; float oversample_buffer[64][4]; ALfloat tempsmp; @@ -239,10 +239,10 @@ ALeffectState *DistortionCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = DistortionDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = DistortionDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = DistortionUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = DistortionProcess; + STATIC_CAST(ALeffectState, state)->Destroy = DistortionDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = DistortionDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = DistortionUpdate; + STATIC_CAST(ALeffectState, state)->Process = DistortionProcess; state->bandpass.type = BANDPASS; state->lowpass.type = LOWPASS; @@ -254,7 +254,7 @@ ALeffectState *DistortionCreate(void) state->lowpass.y[0] = 0.0f; state->lowpass.y[1] = 0.0f; - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void distortion_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index 498ebbc7..297d6e76 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -53,7 +53,7 @@ typedef struct ALechoState { static ALvoid EchoDestroy(ALeffectState *effect) { - ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); + ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); if(state) { free(state->SampleBuffer); @@ -64,7 +64,7 @@ static ALvoid EchoDestroy(ALeffectState *effect) static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); + ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); ALuint maxlen, i; // Use the next power of 2 for the buffer length, so the tap offsets can be @@ -91,7 +91,7 @@ static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); + ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); ALuint frequency = Device->Frequency; ALfloat lrpan, cw, g, gain; ALfloat dirGain; @@ -127,7 +127,7 @@ static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffec static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALechoState *state = GET_PARENT_TYPE(ALechoState, ALeffectState, effect); + ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; @@ -185,10 +185,10 @@ ALeffectState *EchoCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = EchoDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = EchoDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = EchoUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = EchoProcess; + STATIC_CAST(ALeffectState, state)->Destroy = EchoDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = EchoDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = EchoUpdate; + STATIC_CAST(ALeffectState, state)->Process = EchoProcess; state->BufferLength = 0; state->SampleBuffer = NULL; @@ -201,7 +201,7 @@ ALeffectState *EchoCreate(void) state->iirFilter.history[0] = 0.0f; state->iirFilter.history[1] = 0.0f; - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index d4b4f855..62097cd5 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -97,13 +97,13 @@ typedef struct ALequalizerState { static ALvoid EqualizerDestroy(ALeffectState *effect) { - ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); + ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); free(state); } static ALboolean EqualizerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); + ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); state->frequency = (ALfloat)Device->Frequency; @@ -112,7 +112,7 @@ static ALboolean EqualizerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); + ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; ALuint it; @@ -217,7 +217,7 @@ static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const AL static ALvoid EqualizerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALequalizerState *state = GET_PARENT_TYPE(ALequalizerState, ALeffectState, effect); + ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); ALuint base; ALuint it; ALuint kt; @@ -276,10 +276,10 @@ ALeffectState *EqualizerCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = EqualizerDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = EqualizerDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = EqualizerUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = EqualizerProcess; + STATIC_CAST(ALeffectState, state)->Destroy = EqualizerDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = EqualizerDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = EqualizerUpdate; + STATIC_CAST(ALeffectState, state)->Process = EqualizerProcess; state->bandfilter[0].type = LOW_SHELF; state->bandfilter[1].type = PEAKING; @@ -296,7 +296,7 @@ ALeffectState *EqualizerCreate(void) state->bandfilter[it].y[1] = 0.0f; } - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void equalizer_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index 7409a4c1..7c753eb6 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -52,7 +52,7 @@ typedef struct ALflangerState { static ALvoid FlangerDestroy(ALeffectState *effect) { - ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); + ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); if(state) { free(state->SampleBufferLeft); @@ -67,7 +67,7 @@ static ALvoid FlangerDestroy(ALeffectState *effect) static ALboolean FlangerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); + ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); ALuint maxlen; ALuint it; @@ -100,7 +100,7 @@ static ALboolean FlangerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid FlangerUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); + ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); ALfloat frequency = Device->Frequency; ALfloat rate; ALint phase; @@ -238,7 +238,7 @@ DECL_TEMPLATE(Sinusoid) static ALvoid FlangerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALflangerState *state = GET_PARENT_TYPE(ALflangerState, ALeffectState, effect); + ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); @@ -254,17 +254,17 @@ ALeffectState *FlangerCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = FlangerDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = FlangerDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = FlangerUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = FlangerProcess; + STATIC_CAST(ALeffectState, state)->Destroy = FlangerDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = FlangerDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = FlangerUpdate; + STATIC_CAST(ALeffectState, state)->Process = FlangerProcess; state->BufferLength = 0; state->SampleBufferLeft = NULL; state->SampleBufferRight = NULL; state->offset = 0; - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void flanger_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index c9f1edf4..daf5416c 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -131,7 +131,7 @@ DECL_TEMPLATE(Square) static ALvoid ModulatorDestroy(ALeffectState *effect) { - ALmodulatorState *state = GET_PARENT_TYPE(ALmodulatorState, ALeffectState, effect); + ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); free(state); } @@ -144,7 +144,7 @@ static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device) static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALmodulatorState *state = GET_PARENT_TYPE(ALmodulatorState, ALeffectState, effect); + ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); ALfloat gain, cw, a = 0.0f; ALuint index; @@ -177,7 +177,7 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const AL static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALmodulatorState *state = GET_PARENT_TYPE(ALmodulatorState, ALeffectState, effect); + ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); switch(state->Waveform) { @@ -203,10 +203,10 @@ ALeffectState *ModulatorCreate(void) if(!state) return NULL; - GET_DERIVED_TYPE(ALeffectState, state)->Destroy = ModulatorDestroy; - GET_DERIVED_TYPE(ALeffectState, state)->DeviceUpdate = ModulatorDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Update = ModulatorUpdate; - GET_DERIVED_TYPE(ALeffectState, state)->Process = ModulatorProcess; + STATIC_CAST(ALeffectState, state)->Destroy = ModulatorDestroy; + STATIC_CAST(ALeffectState, state)->DeviceUpdate = ModulatorDeviceUpdate; + STATIC_CAST(ALeffectState, state)->Update = ModulatorUpdate; + STATIC_CAST(ALeffectState, state)->Process = ModulatorProcess; state->index = 0; state->step = 1; @@ -214,7 +214,7 @@ ALeffectState *ModulatorCreate(void) state->iirFilter.coeff = 0.0f; state->iirFilter.history[0] = 0.0f; - return GET_DERIVED_TYPE(ALeffectState, state); + return STATIC_CAST(ALeffectState, state); } void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index ac9af905..71b21e1b 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -556,7 +556,7 @@ static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *REST // buffer. static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); + ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect); ALfloat (*RESTRICT out)[4] = State->ReverbSamples; ALuint index, c; @@ -579,7 +579,7 @@ static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo // buffer. static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); + ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect); ALfloat (*RESTRICT early)[4] = State->EarlySamples; ALfloat (*RESTRICT late)[4] = State->ReverbSamples; ALuint index, c; @@ -726,7 +726,7 @@ static ALboolean AllocLines(ALuint frequency, ALverbState *State) // format) have been changed. static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device) { - ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); + ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect); ALuint frequency = Device->Frequency, index; // Allocate the delay lines. @@ -1078,19 +1078,19 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection // effect is loaded into a slot. static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { - ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); + ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect); ALuint frequency = Device->Frequency; ALboolean isEAX = AL_FALSE; ALfloat cw, x, y, hfRatio; if(Slot->effect.type == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) { - GET_DERIVED_TYPE(ALeffectState, State)->Process = EAXVerbProcess; + STATIC_CAST(ALeffectState, State)->Process = EAXVerbProcess; isEAX = AL_TRUE; } else if(Slot->effect.type == AL_EFFECT_REVERB || EmulateEAXReverb) { - GET_DERIVED_TYPE(ALeffectState, State)->Process = VerbProcess; + STATIC_CAST(ALeffectState, State)->Process = VerbProcess; isEAX = AL_FALSE; } @@ -1173,7 +1173,7 @@ static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff // slot has a different (or no) effect loaded over the reverb effect. static ALvoid ReverbDestroy(ALeffectState *effect) { - ALverbState *State = GET_PARENT_TYPE(ALverbState, ALeffectState, effect); + ALverbState *State = STATIC_UPCAST(ALverbState, ALeffectState, effect); if(State) { free(State->SampleBuffer); @@ -1193,10 +1193,10 @@ ALeffectState *ReverbCreate(void) if(!State) return NULL; - GET_DERIVED_TYPE(ALeffectState, State)->Destroy = ReverbDestroy; - GET_DERIVED_TYPE(ALeffectState, State)->DeviceUpdate = ReverbDeviceUpdate; - GET_DERIVED_TYPE(ALeffectState, State)->Update = ReverbUpdate; - GET_DERIVED_TYPE(ALeffectState, State)->Process = VerbProcess; + 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->TotalSamples = 0; State->SampleBuffer = NULL; @@ -1278,7 +1278,7 @@ ALeffectState *ReverbCreate(void) State->Gain = State->Late.PanGain; - return GET_DERIVED_TYPE(ALeffectState, State); + return STATIC_CAST(ALeffectState, State); } void eaxreverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index a1a90b2f..4cdaf783 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -62,9 +62,9 @@ static const union { #define COUNTOF(x) (sizeof((x))/sizeof((x)[0])) -#define DERIVE_FROM_TYPE(t) t t##_parent -#define GET_DERIVED_TYPE(t, o) (&(o)->t##_parent) -#define GET_PARENT_TYPE(t1, t2, o) ((t1*)((char*)(o) - offsetof(t1, t2##_parent))) +#define DERIVE_FROM_TYPE(t) t t##_parent +#define STATIC_CAST(to, obj) (&(obj)->to##_parent) +#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent))) #ifdef _WIN32 -- cgit v1.2.3 From 5516d8df0b21722c96189b946a8a10e9cbb0c001 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 May 2013 04:18:02 -0700 Subject: Use macros to help define vtables for effect states --- Alc/alcChorus.c | 19 +++---- Alc/alcDedicated.c | 19 +++---- Alc/alcDistortion.c | 19 +++---- Alc/alcEcho.c | 19 +++---- Alc/alcEqualizer.c | 19 +++---- Alc/alcFlanger.c | 19 +++---- Alc/alcModulator.c | 19 +++---- Alc/alcReverb.c | 108 ++++++++++++++++++------------------- OpenAL32/Include/alAuxEffectSlot.h | 45 +++++++++++----- OpenAL32/alAuxEffectSlot.c | 48 +++++++++-------- 10 files changed, 168 insertions(+), 166 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index f02544c4..c34396eb 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -50,7 +50,7 @@ typedef struct ALchorusState { ALfloat feedback; } ALchorusState; -static ALvoid ChorusDestroy(ALeffectState *effect) +static ALvoid ALchorusState_Destroy(ALeffectState *effect) { ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); @@ -63,7 +63,7 @@ static ALvoid ChorusDestroy(ALeffectState *effect) free(state); } -static ALboolean ChorusDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALchorusState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); ALuint maxlen; @@ -96,7 +96,7 @@ static ALboolean ChorusDeviceUpdate(ALeffectState *effect, ALCdevice *Device) return AL_TRUE; } -static ALvoid ChorusUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALchorusState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); ALfloat frequency = Device->Frequency; @@ -234,7 +234,7 @@ DECL_TEMPLATE(Sinusoid) #undef DECL_TEMPLATE -static ALvoid ChorusProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALchorusState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); @@ -244,18 +244,15 @@ static ALvoid ChorusProcess(ALeffectState *effect, ALuint SamplesToDo, const ALf ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); } +DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); + ALeffectState *ChorusCreate(void) { ALchorusState *state; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = ChorusDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = ChorusDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = ChorusUpdate; - STATIC_CAST(ALeffectState, state)->Process = ChorusProcess; + if(!state) return NULL; + SET_VTABLE2(ALchorusState, ALeffectState, state); state->BufferLength = 0; state->SampleBufferLeft = NULL; diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index 35de345f..a3267509 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -36,20 +36,20 @@ typedef struct ALdedicatedState { } ALdedicatedState; -static ALvoid DedicatedDestroy(ALeffectState *effect) +static ALvoid ALdedicatedState_Destroy(ALeffectState *effect) { ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); free(state); } -static ALboolean DedicatedDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALdedicatedState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { (void)effect; (void)Device; return AL_TRUE; } -static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot) +static ALvoid ALdedicatedState_Update(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot) { ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); ALfloat Gain; @@ -65,7 +65,7 @@ static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const AL state->gains[LFE] = Gain; } -static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALdedicatedState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); const ALfloat *gains = state->gains; @@ -81,19 +81,16 @@ static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const } } +DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); + ALeffectState *DedicatedCreate(void) { ALdedicatedState *state; ALsizei s; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = DedicatedDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = DedicatedDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = DedicatedUpdate; - STATIC_CAST(ALeffectState, state)->Process = DedicatedProcess; + if(!state) return NULL; + SET_VTABLE2(ALdedicatedState, ALeffectState, state); for(s = 0;s < MaxChannels;s++) state->gains[s] = 0.0f; diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 0b0c9c93..50627093 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -59,20 +59,20 @@ typedef struct ALdistortionState { ALfloat edge_coeff; } ALdistortionState; -static ALvoid DistortionDestroy(ALeffectState *effect) +static ALvoid ALdistortionState_Destroy(ALeffectState *effect) { ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); free(state); } -static ALboolean DistortionDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALdistortionState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { return AL_TRUE; (void)effect; (void)Device; } -static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALdistortionState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; @@ -126,7 +126,7 @@ static ALvoid DistortionUpdate(ALeffectState *effect, ALCdevice *Device, const A state->bandpass.a[2] = 1.0f - alpha; } -static ALvoid DistortionProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALdistortionState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); const ALfloat fc = state->edge_coeff; @@ -229,18 +229,15 @@ static ALvoid DistortionProcess(ALeffectState *effect, ALuint SamplesToDo, const } } +DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); + ALeffectState *DistortionCreate(void) { ALdistortionState *state; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = DistortionDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = DistortionDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = DistortionUpdate; - STATIC_CAST(ALeffectState, state)->Process = DistortionProcess; + if(!state) return NULL; + SET_VTABLE2(ALdistortionState, ALeffectState, state); state->bandpass.type = BANDPASS; state->lowpass.type = LOWPASS; diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index b4663ade..3fbd5232 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -51,7 +51,7 @@ typedef struct ALechoState { ALfloat history[2]; } ALechoState; -static ALvoid EchoDestroy(ALeffectState *effect) +static ALvoid ALechoState_Destroy(ALeffectState *effect) { ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); @@ -61,7 +61,7 @@ static ALvoid EchoDestroy(ALeffectState *effect) free(state); } -static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALechoState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); ALuint maxlen, i; @@ -88,7 +88,7 @@ static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device) return AL_TRUE; } -static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALechoState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); ALuint frequency = Device->Frequency; @@ -124,7 +124,7 @@ static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffec ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); } -static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALechoState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); const ALuint mask = state->BufferLength-1; @@ -176,18 +176,15 @@ static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo state->Offset = offset; } +DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); + ALeffectState *EchoCreate(void) { ALechoState *state; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = EchoDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = EchoDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = EchoUpdate; - STATIC_CAST(ALeffectState, state)->Process = EchoProcess; + if(!state) return NULL; + SET_VTABLE2(ALechoState, ALeffectState, state); state->BufferLength = 0; state->SampleBuffer = NULL; diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index 62097cd5..50a83c9a 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -95,13 +95,13 @@ typedef struct ALequalizerState { ALfloat frequency; } ALequalizerState; -static ALvoid EqualizerDestroy(ALeffectState *effect) +static ALvoid ALequalizerState_Destroy(ALeffectState *effect) { ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); free(state); } -static ALboolean EqualizerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALequalizerState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); @@ -110,7 +110,7 @@ static ALboolean EqualizerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) return AL_TRUE; } -static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALequalizerState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; @@ -215,7 +215,7 @@ static ALvoid EqualizerUpdate(ALeffectState *effect, ALCdevice *Device, const AL } } -static ALvoid EqualizerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALequalizerState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); ALuint base; @@ -267,19 +267,16 @@ static ALvoid EqualizerProcess(ALeffectState *effect, ALuint SamplesToDo, const } } +DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); + ALeffectState *EqualizerCreate(void) { ALequalizerState *state; int it; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = EqualizerDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = EqualizerDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = EqualizerUpdate; - STATIC_CAST(ALeffectState, state)->Process = EqualizerProcess; + if(!state) return NULL; + SET_VTABLE2(ALequalizerState, ALeffectState, state); state->bandfilter[0].type = LOW_SHELF; state->bandfilter[1].type = PEAKING; diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index d7a59f3a..a69d7006 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -50,7 +50,7 @@ typedef struct ALflangerState { ALfloat feedback; } ALflangerState; -static ALvoid FlangerDestroy(ALeffectState *effect) +static ALvoid ALflangerState_Destroy(ALeffectState *effect) { ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); @@ -63,7 +63,7 @@ static ALvoid FlangerDestroy(ALeffectState *effect) free(state); } -static ALboolean FlangerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALflangerState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); ALuint maxlen; @@ -96,7 +96,7 @@ static ALboolean FlangerDeviceUpdate(ALeffectState *effect, ALCdevice *Device) return AL_TRUE; } -static ALvoid FlangerUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALflangerState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); ALfloat frequency = Device->Frequency; @@ -234,7 +234,7 @@ DECL_TEMPLATE(Sinusoid) #undef DECL_TEMPLATE -static ALvoid FlangerProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALflangerState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); @@ -244,18 +244,15 @@ static ALvoid FlangerProcess(ALeffectState *effect, ALuint SamplesToDo, const AL ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); } +DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); + ALeffectState *FlangerCreate(void) { ALflangerState *state; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = FlangerDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = FlangerDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = FlangerUpdate; - STATIC_CAST(ALeffectState, state)->Process = FlangerProcess; + if(!state) return NULL; + SET_VTABLE2(ALflangerState, ALeffectState, state); state->BufferLength = 0; state->SampleBufferLeft = NULL; diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index daf5416c..b2ea6642 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -129,20 +129,20 @@ DECL_TEMPLATE(Square) #undef DECL_TEMPLATE -static ALvoid ModulatorDestroy(ALeffectState *effect) +static ALvoid ALmodulatorState_Destroy(ALeffectState *effect) { ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); free(state); } -static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALmodulatorState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) { return AL_TRUE; (void)effect; (void)Device; } -static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALmodulatorState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) { ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); ALfloat gain, cw, a = 0.0f; @@ -175,7 +175,7 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const AL } } -static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALmodulatorState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); @@ -195,18 +195,15 @@ static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const } } +DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); + ALeffectState *ModulatorCreate(void) { ALmodulatorState *state; state = malloc(sizeof(*state)); - if(!state) - return NULL; - - STATIC_CAST(ALeffectState, state)->Destroy = ModulatorDestroy; - STATIC_CAST(ALeffectState, state)->DeviceUpdate = ModulatorDeviceUpdate; - STATIC_CAST(ALeffectState, state)->Update = ModulatorUpdate; - STATIC_CAST(ALeffectState, state)->Process = ModulatorProcess; + if(!state) return NULL; + SET_VTABLE2(ALmodulatorState, ALeffectState, state); state->index = 0; state->step = 1; 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; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index c19eb7b3..a891b52a 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -8,15 +8,36 @@ extern "C" { #endif -typedef struct ALeffectState { - ALvoid (*Destroy)(struct ALeffectState *State); - ALboolean (*DeviceUpdate)(struct ALeffectState *State, ALCdevice *Device); - ALvoid (*Update)(struct ALeffectState *State, ALCdevice *Device, const struct ALeffectslot *Slot); - ALvoid (*Process)(struct ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]); -} ALeffectState; +typedef struct ALeffectState ALeffectState; +typedef struct ALeffectslot ALeffectslot; + +struct ALeffectStateVtable { + ALvoid (*const Destroy)(ALeffectState *State); + ALboolean (*const DeviceUpdate)(ALeffectState *State, ALCdevice *Device); + ALvoid (*const Update)(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot); + ALvoid (*const Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]); +}; + +struct ALeffectState { + const struct ALeffectStateVtable *vtbl; +}; + +#define DEFINE_ALEFFECTSTATE_VTABLE(T) \ +static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ + T##_Destroy, \ + T##_DeviceUpdate, \ + T##_Update, \ + T##_Process \ +} + +#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable)) +#define SET_VTABLE2(T1, T2, obj) do { \ + STATIC_CAST(T2, (obj))->vtbl = &(T1##_##T2##_vtable); \ + /*SET_VTABLE1(T1, obj);*/ \ +} while(0) -typedef struct ALeffectslot +struct ALeffectslot { ALeffect effect; @@ -35,7 +56,7 @@ typedef struct ALeffectslot /* Self ID */ ALuint id; -} ALeffectslot; +}; ALenum InitEffectSlot(ALeffectslot *slot); @@ -51,10 +72,10 @@ ALeffectState *FlangerCreate(void); ALeffectState *EqualizerCreate(void); ALeffectState *DistortionCreate(void); -#define ALeffectState_Destroy(a) ((a)->Destroy((a))) -#define ALeffectState_DeviceUpdate(a,b) ((a)->DeviceUpdate((a),(b))) -#define ALeffectState_Update(a,b,c) ((a)->Update((a),(b),(c))) -#define ALeffectState_Process(a,b,c,d) ((a)->Process((a),(b),(c),(d))) +#define ALeffectState_Destroy(a) ((a)->vtbl->Destroy((a))) +#define ALeffectState_DeviceUpdate(a,b) ((a)->vtbl->DeviceUpdate((a),(b))) +#define ALeffectState_Update(a,b,c) ((a)->vtbl->Update((a),(b),(c))) +#define ALeffectState_Process(a,b,c,d) ((a)->vtbl->Process((a),(b),(c),(d))) ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 7df6bca4..0932376d 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -393,41 +393,43 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p } -static ALvoid NoneDestroy(ALeffectState *State) -{ free(State); } -static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device) +typedef struct ALnoneState { + DERIVE_FROM_TYPE(ALeffectState); +} ALnoneState; + +static ALvoid ALnoneState_Destroy(ALeffectState *state) +{ free(state); } +static ALboolean ALnoneState_DeviceUpdate(ALeffectState *state, ALCdevice *device) { return AL_TRUE; - (void)State; - (void)Device; + (void)state; + (void)device; } -static ALvoid NoneUpdate(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALnoneState_Update(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot) { - (void)State; - (void)Device; - (void)Slot; + (void)state; + (void)device; + (void)slot; } -static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALnoneState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) { - (void)State; - (void)SamplesToDo; - (void)SamplesIn; - (void)SamplesOut; + (void)state; + (void)samplesToDo; + (void)samplesIn; + (void)samplesOut; } + +DEFINE_ALEFFECTSTATE_VTABLE(ALnoneState); + ALeffectState *NoneCreate(void) { - ALeffectState *state; + ALnoneState *state; state = calloc(1, sizeof(*state)); - if(!state) - return NULL; - - state->Destroy = NoneDestroy; - state->DeviceUpdate = NoneDeviceUpdate; - state->Update = NoneUpdate; - state->Process = NoneProcess; + if(!state) return NULL; + SET_VTABLE2(ALnoneState, ALeffectState, state); - return state; + return STATIC_CAST(ALeffectState, state); } void null_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -- cgit v1.2.3 From 5c8c40afefc4e42635da91a876232cfc0975f6fd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 May 2013 05:02:25 -0700 Subject: Auto-generate wrappers to upcast objects before calling user methods --- Alc/alcChorus.c | 14 ++++---------- Alc/alcDedicated.c | 15 ++++++--------- Alc/alcDistortion.c | 13 +++++-------- Alc/alcEcho.c | 13 ++++--------- Alc/alcEqualizer.c | 14 ++++---------- Alc/alcFlanger.c | 14 ++++---------- Alc/alcModulator.c | 14 +++++--------- Alc/alcReverb.c | 15 +++++---------- OpenAL32/Include/alAuxEffectSlot.h | 25 +++++++++++++++++-------- OpenAL32/alAuxEffectSlot.c | 8 ++++---- 10 files changed, 58 insertions(+), 87 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index c34396eb..ff1c9492 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -50,10 +50,8 @@ typedef struct ALchorusState { ALfloat feedback; } ALchorusState; -static ALvoid ALchorusState_Destroy(ALeffectState *effect) +static ALvoid ALchorusState_Destroy(ALchorusState *state) { - ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); - free(state->SampleBufferLeft); state->SampleBufferLeft = NULL; @@ -63,9 +61,8 @@ static ALvoid ALchorusState_Destroy(ALeffectState *effect) free(state); } -static ALboolean ALchorusState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALchorusState_DeviceUpdate(ALchorusState *state, ALCdevice *Device) { - ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); ALuint maxlen; ALuint it; @@ -96,9 +93,8 @@ static ALboolean ALchorusState_DeviceUpdate(ALeffectState *effect, ALCdevice *De return AL_TRUE; } -static ALvoid ALchorusState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALchorusState_Update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot) { - ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); ALfloat frequency = Device->Frequency; ALfloat rate; ALint phase; @@ -234,10 +230,8 @@ DECL_TEMPLATE(Sinusoid) #undef DECL_TEMPLATE -static ALvoid ALchorusState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); - if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); else if(state->waveform == AL_CHORUS_WAVEFORM_SINUSOID) diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index a3267509..7d32c153 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -36,22 +36,20 @@ typedef struct ALdedicatedState { } ALdedicatedState; -static ALvoid ALdedicatedState_Destroy(ALeffectState *effect) +static ALvoid ALdedicatedState_Destroy(ALdedicatedState *state) { - ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); free(state); } -static ALboolean ALdedicatedState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALdedicatedState_DeviceUpdate(ALdedicatedState *state, ALCdevice *Device) { - (void)effect; - (void)Device; return AL_TRUE; + (void)state; + (void)Device; } -static ALvoid ALdedicatedState_Update(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot) +static ALvoid ALdedicatedState_Update(ALdedicatedState *state, ALCdevice *device, const ALeffectslot *Slot) { - ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); ALfloat Gain; ALsizei s; @@ -65,9 +63,8 @@ static ALvoid ALdedicatedState_Update(ALeffectState *effect, ALCdevice *device, state->gains[LFE] = Gain; } -static ALvoid ALdedicatedState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); const ALfloat *gains = state->gains; ALuint i, c; diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 50627093..8c0f5e97 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -59,22 +59,20 @@ typedef struct ALdistortionState { ALfloat edge_coeff; } ALdistortionState; -static ALvoid ALdistortionState_Destroy(ALeffectState *effect) +static ALvoid ALdistortionState_Destroy(ALdistortionState *state) { - ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); free(state); } -static ALboolean ALdistortionState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *Device) { return AL_TRUE; - (void)effect; + (void)state; (void)Device; } -static ALvoid ALdistortionState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALdistortionState_Update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot) { - ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; ALfloat frequency = (ALfloat)Device->Frequency; ALuint it; @@ -126,9 +124,8 @@ static ALvoid ALdistortionState_Update(ALeffectState *effect, ALCdevice *Device, state->bandpass.a[2] = 1.0f - alpha; } -static ALvoid ALdistortionState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); const ALfloat fc = state->edge_coeff; float oversample_buffer[64][4]; ALfloat tempsmp; diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index 3fbd5232..ada61c96 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -51,19 +51,16 @@ typedef struct ALechoState { ALfloat history[2]; } ALechoState; -static ALvoid ALechoState_Destroy(ALeffectState *effect) +static ALvoid ALechoState_Destroy(ALechoState *state) { - ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); - free(state->SampleBuffer); state->SampleBuffer = NULL; free(state); } -static ALboolean ALechoState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALechoState_DeviceUpdate(ALechoState *state, ALCdevice *Device) { - ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); ALuint maxlen, i; // Use the next power of 2 for the buffer length, so the tap offsets can be @@ -88,9 +85,8 @@ static ALboolean ALechoState_DeviceUpdate(ALeffectState *effect, ALCdevice *Devi return AL_TRUE; } -static ALvoid ALechoState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALechoState_Update(ALechoState *state, ALCdevice *Device, const ALeffectslot *Slot) { - ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); ALuint frequency = Device->Frequency; ALfloat lrpan, cw, g, gain; ALfloat dirGain; @@ -124,9 +120,8 @@ static ALvoid ALechoState_Update(ALeffectState *effect, ALCdevice *Device, const ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); } -static ALvoid ALechoState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; const ALuint tap2 = state->Tap[1].delay; diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index 50a83c9a..6bc4ed12 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -95,24 +95,19 @@ typedef struct ALequalizerState { ALfloat frequency; } ALequalizerState; -static ALvoid ALequalizerState_Destroy(ALeffectState *effect) +static ALvoid ALequalizerState_Destroy(ALequalizerState *state) { - ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); free(state); } -static ALboolean ALequalizerState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALequalizerState_DeviceUpdate(ALequalizerState *state, ALCdevice *Device) { - ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); - state->frequency = (ALfloat)Device->Frequency; - return AL_TRUE; } -static ALvoid ALequalizerState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALequalizerState_Update(ALequalizerState *state, ALCdevice *Device, const ALeffectslot *Slot) { - ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; ALuint it; @@ -215,9 +210,8 @@ static ALvoid ALequalizerState_Update(ALeffectState *effect, ALCdevice *Device, } } -static ALvoid ALequalizerState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); ALuint base; ALuint it; ALuint kt; diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index a69d7006..574fa9d7 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -50,10 +50,8 @@ typedef struct ALflangerState { ALfloat feedback; } ALflangerState; -static ALvoid ALflangerState_Destroy(ALeffectState *effect) +static ALvoid ALflangerState_Destroy(ALflangerState *state) { - ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); - free(state->SampleBufferLeft); state->SampleBufferLeft = NULL; @@ -63,9 +61,8 @@ static ALvoid ALflangerState_Destroy(ALeffectState *effect) free(state); } -static ALboolean ALflangerState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALflangerState_DeviceUpdate(ALflangerState *state, ALCdevice *Device) { - ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); ALuint maxlen; ALuint it; @@ -96,9 +93,8 @@ static ALboolean ALflangerState_DeviceUpdate(ALeffectState *effect, ALCdevice *D return AL_TRUE; } -static ALvoid ALflangerState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALflangerState_Update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot) { - ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); ALfloat frequency = Device->Frequency; ALfloat rate; ALint phase; @@ -234,10 +230,8 @@ DECL_TEMPLATE(Sinusoid) #undef DECL_TEMPLATE -static ALvoid ALflangerState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALflangerState_Process(ALflangerState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); - if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); else if(state->waveform == AL_FLANGER_WAVEFORM_SINUSOID) diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index b2ea6642..5d4fdab8 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -129,22 +129,20 @@ DECL_TEMPLATE(Square) #undef DECL_TEMPLATE -static ALvoid ALmodulatorState_Destroy(ALeffectState *effect) +static ALvoid ALmodulatorState_Destroy(ALmodulatorState *state) { - ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); free(state); } -static ALboolean ALmodulatorState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALmodulatorState_DeviceUpdate(ALmodulatorState *state, ALCdevice *Device) { return AL_TRUE; - (void)effect; + (void)state; (void)Device; } -static ALvoid ALmodulatorState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALmodulatorState_Update(ALmodulatorState *state, ALCdevice *Device, const ALeffectslot *Slot) { - ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); ALfloat gain, cw, a = 0.0f; ALuint index; @@ -175,10 +173,8 @@ static ALvoid ALmodulatorState_Update(ALeffectState *effect, ALCdevice *Device, } } -static ALvoid ALmodulatorState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) { - ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); - switch(state->Waveform) { case SINUSOID: diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index b84dad96..2bed00a5 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -606,9 +606,8 @@ static ALvoid ALreverbState_ProcessEax(ALreverbState *State, ALuint SamplesToDo, } } -static ALvoid ALreverbState_Process(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALreverbState_Process(ALreverbState *State, 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 @@ -732,9 +731,8 @@ static ALboolean AllocLines(ALuint frequency, ALreverbState *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 ALreverbState_DeviceUpdate(ALeffectState *effect, ALCdevice *Device) +static ALboolean ALreverbState_DeviceUpdate(ALreverbState *State, ALCdevice *Device) { - ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect); ALuint frequency = Device->Frequency, index; // Allocate the delay lines. @@ -1084,9 +1082,8 @@ 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 ALreverbState_Update(ALeffectState *effect, ALCdevice *Device, const ALeffectslot *Slot) +static ALvoid ALreverbState_Update(ALreverbState *State, ALCdevice *Device, const ALeffectslot *Slot) { - ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect); ALuint frequency = Device->Frequency; ALfloat cw, x, y, hfRatio; @@ -1174,10 +1171,8 @@ static ALvoid ALreverbState_Update(ALeffectState *effect, ALCdevice *Device, con // 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 ALreverbState_Destroy(ALeffectState *effect) +static ALvoid ALreverbState_Destroy(ALreverbState *State) { - ALreverbState *State = STATIC_UPCAST(ALreverbState, ALeffectState, effect); - free(State->SampleBuffer); State->SampleBuffer = NULL; @@ -1190,7 +1185,7 @@ DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState); // effect is loaded into a slot that doesn't already have a reverb effect. ALeffectState *ReverbCreate(void) { - ALreverbState *State = NULL; + ALreverbState *State; ALuint index; State = malloc(sizeof(ALreverbState)); diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index a891b52a..ed0d1887 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -12,10 +12,10 @@ typedef struct ALeffectState ALeffectState; typedef struct ALeffectslot ALeffectslot; struct ALeffectStateVtable { - ALvoid (*const Destroy)(ALeffectState *State); - ALboolean (*const DeviceUpdate)(ALeffectState *State, ALCdevice *Device); - ALvoid (*const Update)(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot); - ALvoid (*const Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]); + ALvoid (*const Destroy)(ALeffectState *state); + ALboolean (*const DeviceUpdate)(ALeffectState *state, ALCdevice *device); + ALvoid (*const Update)(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot); + ALvoid (*const Process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]); }; struct ALeffectState { @@ -23,11 +23,20 @@ struct ALeffectState { }; #define DEFINE_ALEFFECTSTATE_VTABLE(T) \ +static ALvoid T##_ALeffectState_Destroy(ALeffectState *state) \ +{ T##_Destroy(STATIC_UPCAST(T, ALeffectState, state)); } \ +static ALboolean T##_ALeffectState_DeviceUpdate(ALeffectState *state, ALCdevice *device) \ +{ return T##_DeviceUpdate(STATIC_UPCAST(T, ALeffectState, state), device); } \ +static ALvoid T##_ALeffectState_Update(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot) \ +{ T##_Update(STATIC_UPCAST(T, ALeffectState, state), device, slot); } \ +static ALvoid T##_ALeffectState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) \ +{ T##_Process(STATIC_UPCAST(T, ALeffectState, state), samplesToDo, samplesIn, samplesOut); } \ + \ static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ - T##_Destroy, \ - T##_DeviceUpdate, \ - T##_Update, \ - T##_Process \ + T##_ALeffectState_Destroy, \ + T##_ALeffectState_DeviceUpdate, \ + T##_ALeffectState_Update, \ + T##_ALeffectState_Process \ } #define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable)) diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 0932376d..3c31ecb8 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -397,21 +397,21 @@ typedef struct ALnoneState { DERIVE_FROM_TYPE(ALeffectState); } ALnoneState; -static ALvoid ALnoneState_Destroy(ALeffectState *state) +static ALvoid ALnoneState_Destroy(ALnoneState *state) { free(state); } -static ALboolean ALnoneState_DeviceUpdate(ALeffectState *state, ALCdevice *device) +static ALboolean ALnoneState_DeviceUpdate(ALnoneState *state, ALCdevice *device) { return AL_TRUE; (void)state; (void)device; } -static ALvoid ALnoneState_Update(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot) +static ALvoid ALnoneState_Update(ALnoneState *state, ALCdevice *device, const ALeffectslot *slot) { (void)state; (void)device; (void)slot; } -static ALvoid ALnoneState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) +static ALvoid ALnoneState_Process(ALnoneState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) { (void)state; (void)samplesToDo; -- cgit v1.2.3 From e4186f49039a17916dedaa536143761d0a6caa87 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 May 2013 07:10:24 -0700 Subject: Use a properly-defined history for the FILTER struct --- Alc/ALu.c | 14 +++++++++----- Alc/alcEcho.c | 3 +-- Alc/alcModulator.c | 7 +++---- Alc/alcReverb.c | 5 ++--- Alc/mixer.c | 12 ++++++------ OpenAL32/Include/alFilter.h | 14 +++++--------- OpenAL32/Include/alSource.h | 6 ++---- 7 files changed, 28 insertions(+), 33 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index 1288f7b2..6b6917bf 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -254,6 +254,7 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) ALboolean DirectChannels; ALfloat hwidth = 0.0f; ALfloat Pitch; + ALfloat coeff; ALfloat cw; ALint i, c; @@ -459,11 +460,14 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) /* We use two chained one-pole filters, so we need to take the * square root of the squared gain, which is the same as the base * gain. */ - ALSource->Params.Direct.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw); + coeff = lpCoeffCalc(DryGainHF, cw); + for(c = 0;c < num_channels;c++) + ALSource->Params.Direct.Filter[c].coeff = lpCoeffCalc(DryGainHF, cw); for(i = 0;i < NumSends;i++) { - ALfloat a = lpCoeffCalc(WetGainHF[i], cw); - ALSource->Params.Send[i].iirFilter.coeff = a; + coeff = lpCoeffCalc(WetGainHF[i], cw); + for(c = 0;c < num_channels;c++) + ALSource->Params.Send[i].Filter[c].coeff = coeff; } } @@ -903,11 +907,11 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) /* Update filter coefficients. */ cw = cosf(F_PI*2.0f * LOWPASSFREQREF / Frequency); - ALSource->Params.Direct.iirFilter.coeff = lpCoeffCalc(DryGainHF, cw); + ALSource->Params.Direct.Filter[0].coeff = lpCoeffCalc(DryGainHF, cw); for(i = 0;i < NumSends;i++) { ALfloat a = lpCoeffCalc(WetGainHF[i], cw); - ALSource->Params.Send[i].iirFilter.coeff = a; + ALSource->Params.Send[i].Filter[0].coeff = a; } } diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index ada61c96..1aab9870 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -48,7 +48,6 @@ typedef struct ALechoState { ALfloat FeedGain; FILTER iirFilter; - ALfloat history[2]; } ALechoState; static ALvoid ALechoState_Destroy(ALechoState *state) @@ -144,7 +143,7 @@ static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const // Apply damping and feedback gain to the second tap, and mix in the // new sample - smp = lpFilter2P(&state->iirFilter, 0, temps[i][1]+SamplesIn[i]); + smp = lpFilter2P(&state->iirFilter, temps[i][1]+SamplesIn[i]); state->SampleBuffer[offset&mask] = smp * state->FeedGain; } diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index 5d4fdab8..bb90d646 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -45,7 +45,6 @@ typedef struct ALmodulatorState { ALfloat Gain[MaxChannels]; FILTER iirFilter; - ALfloat history[1]; } ALmodulatorState; #define WAVEFORM_FRACBITS 24 @@ -68,9 +67,9 @@ static __inline ALfloat Square(ALuint index) } -static __inline ALfloat hpFilter1P(FILTER *iir, ALuint offset, ALfloat input) +static __inline ALfloat hpFilter1P(FILTER *iir, ALfloat input) { - ALfloat *history = &iir->history[offset]; + ALfloat *history = iir->history; ALfloat a = iir->coeff; ALfloat output = input; @@ -100,7 +99,7 @@ static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ { \ ALfloat samp; \ samp = SamplesIn[base+i]; \ - samp = hpFilter1P(&state->iirFilter, 0, samp); \ + samp = hpFilter1P(&state->iirFilter, samp); \ \ index += step; \ index &= WAVEFORM_FRACMASK; \ diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index 2bed00a5..01f4ab83 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -51,7 +51,6 @@ typedef struct ALreverbState { // Master effect low-pass filter (2 chained 1-pole filters). FILTER LpFilter; - ALfloat LpHistory[2]; struct { // Modulator delay line. @@ -483,7 +482,7 @@ static __inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *RESTR ALfloat feed, late[4], taps[4]; // Low-pass filter the incoming sample. - in = lpFilter2P(&State->LpFilter, 0, in); + in = lpFilter2P(&State->LpFilter, in); // Feed the initial delay line. DelayLineIn(&State->Delay, State->Offset, in); @@ -522,7 +521,7 @@ static __inline ALvoid EAXVerbPass(ALreverbState *State, ALfloat in, ALfloat *RE ALfloat feed, taps[4]; // Low-pass filter the incoming sample. - in = lpFilter2P(&State->LpFilter, 0, in); + in = lpFilter2P(&State->LpFilter, in); // Perform any modulation on the input. in = EAXModulation(State, in); diff --git a/Alc/mixer.c b/Alc/mixer.c index f75a7803..84f48094 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -84,13 +84,13 @@ static void SilenceData(ALfloat *dst, ALuint samples) } -static void Filter2P(FILTER *filter, ALuint chan, ALfloat *RESTRICT dst, - const ALfloat *RESTRICT src, ALuint numsamples) +static void Filter2P(FILTER *filter, ALfloat *RESTRICT dst, const ALfloat *RESTRICT src, + ALuint numsamples) { ALuint i; for(i = 0;i < numsamples;i++) - dst[i] = lpFilter2P(filter, chan, src[i]); - dst[i] = lpFilter2PC(filter, chan, src[i]); + dst[i] = lpFilter2P(filter, src[i]); + dst[i] = lpFilter2PC(filter, src[i]); } @@ -328,7 +328,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) { DirectParams *directparms = &Source->Params.Direct; - Filter2P(&directparms->iirFilter, chan, SrcData, ResampledData, + Filter2P(&directparms->Filter[chan], SrcData, ResampledData, DstBufferSize); Source->Params.DryMix(directparms, SrcData, chan, OutPos, SamplesToDo, DstBufferSize); @@ -340,7 +340,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) if(!sendparms->Slot) continue; - Filter2P(&sendparms->iirFilter, chan, SrcData, ResampledData, + Filter2P(&sendparms->Filter[chan], SrcData, ResampledData, DstBufferSize); Source->Params.WetMix(sendparms, SrcData, OutPos, SamplesToDo, DstBufferSize); diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h index 09cef93c..94feb3ee 100644 --- a/OpenAL32/Include/alFilter.h +++ b/OpenAL32/Include/alFilter.h @@ -11,16 +11,12 @@ extern "C" { typedef struct { ALfloat coeff; -#ifndef _MSC_VER - ALfloat history[0]; -#else - ALfloat history[1]; -#endif + ALfloat history[2]; } FILTER; -static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input) +static __inline ALfloat lpFilter2P(FILTER *iir, ALfloat input) { - ALfloat *history = &iir->history[offset*2]; + ALfloat *history = iir->history; ALfloat a = iir->coeff; ALfloat output = input; @@ -32,9 +28,9 @@ static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input) return output; } -static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat input) +static __inline ALfloat lpFilter2PC(const FILTER *iir, ALfloat input) { - const ALfloat *history = &iir->history[offset*2]; + const ALfloat *history = iir->history; ALfloat a = iir->coeff; ALfloat output = input; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index d8ffc9aa..bd1b2931 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -62,8 +62,7 @@ typedef struct DirectParams { ALfloat Gains[MaxChannels][MaxChannels]; /* A low-pass filter, using 2 chained one-pole filters. */ - FILTER iirFilter; - ALfloat history[MaxChannels*2]; + FILTER Filter[MaxChannels]; } DirectParams; typedef struct SendParams { @@ -74,8 +73,7 @@ typedef struct SendParams { ALfloat Gain; /* A low-pass filter, using 2 chained one-pole filters. */ - FILTER iirFilter; - ALfloat history[MaxChannels*2]; + FILTER Filter[MaxChannels]; } SendParams; -- cgit v1.2.3 From a5d94f5d09be24bf34cbf8433a288cfd9ca396fb Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 May 2013 12:47:18 -0700 Subject: Use factories to create and destroy effect states --- Alc/ALc.c | 4 + Alc/alcChorus.c | 40 ++++++++- Alc/alcDedicated.c | 40 ++++++++- Alc/alcDistortion.c | 45 +++++++++- Alc/alcEcho.c | 40 ++++++++- Alc/alcEqualizer.c | 41 ++++++++- Alc/alcFlanger.c | 40 ++++++++- Alc/alcModulator.c | 40 ++++++++- Alc/alcReverb.c | 177 ++++++++++++++++++++++--------------- OpenAL32/Include/alAuxEffectSlot.h | 65 ++++++++++---- OpenAL32/Include/alMain.h | 5 ++ OpenAL32/alAuxEffectSlot.c | 119 +++++++++++++++++-------- 12 files changed, 513 insertions(+), 143 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 24c2fbe5..aaddfea8 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1038,6 +1038,8 @@ static void alc_initconfig(void) } while(next++); } + InitEffectFactoryMap(); + InitEffect(&DefaultEffect); str = getenv("ALSOFT_DEFAULT_REVERB"); if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str)) @@ -1071,6 +1073,8 @@ static void alc_cleanup(void) } while((dev=dev->next) != NULL); ERR("%u device%s not closed\n", num, (num>1)?"s":""); } + + DeinitEffectFactoryMap(); } static void alc_deinit_safe(void) diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index ff1c9492..018caac5 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -30,6 +30,13 @@ #include "alu.h" +typedef struct ALchorusStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALchorusStateFactory; + +static ALchorusStateFactory ChorusFactory; + + typedef struct ALchorusState { DERIVE_FROM_TYPE(ALeffectState); @@ -57,8 +64,6 @@ static ALvoid ALchorusState_Destroy(ALchorusState *state) free(state->SampleBufferRight); state->SampleBufferRight = NULL; - - free(state); } static ALboolean ALchorusState_DeviceUpdate(ALchorusState *state, ALCdevice *Device) @@ -238,9 +243,15 @@ static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, co ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); } +static ALeffectStateFactory *ALchorusState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); -ALeffectState *ChorusCreate(void) + +static ALeffectState *ALchorusStateFactory_create(void) { ALchorusState *state; @@ -256,6 +267,29 @@ ALeffectState *ChorusCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALchorusStateFactory_destroy(ALeffectState *effect) +{ + ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); + ALchorusState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALchorusStateFactory); + + +static void init_chorus_factory(void) +{ + SET_VTABLE2(ALchorusStateFactory, ALeffectStateFactory, &ChorusFactory); +} + +ALeffectStateFactory *ALchorusStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_chorus_factory); + return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); +} + + void chorus_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { switch(param) diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index 7d32c153..fbe2a5f1 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -29,6 +29,13 @@ #include "alu.h" +typedef struct ALdedicatedStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALdedicatedStateFactory; + +static ALdedicatedStateFactory DedicatedFactory; + + typedef struct ALdedicatedState { DERIVE_FROM_TYPE(ALeffectState); @@ -38,7 +45,7 @@ typedef struct ALdedicatedState { static ALvoid ALdedicatedState_Destroy(ALdedicatedState *state) { - free(state); + (void)state; } static ALboolean ALdedicatedState_DeviceUpdate(ALdedicatedState *state, ALCdevice *Device) @@ -78,9 +85,15 @@ static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesTo } } +static ALeffectStateFactory *ALdedicatedState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); -ALeffectState *DedicatedCreate(void) + +ALeffectState *ALdedicatedStateFactory_create(void) { ALdedicatedState *state; ALsizei s; @@ -95,6 +108,29 @@ ALeffectState *DedicatedCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALdedicatedStateFactory_destroy(ALeffectState *effect) +{ + ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); + ALdedicatedState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdedicatedStateFactory); + + +static void init_dedicated_factory(void) +{ + SET_VTABLE2(ALdedicatedStateFactory, ALeffectStateFactory, &DedicatedFactory); +} + +ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_dedicated_factory); + return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); +} + + void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } void ded_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 8c0f5e97..ec48ad03 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -29,6 +29,14 @@ #include "alError.h" #include "alu.h" + +typedef struct ALdistortionStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALdistortionStateFactory; + +static ALdistortionStateFactory DistortionFactory; + + /* Filters implementation is based on the "Cookbook formulae for audio * * EQ biquad filter coefficients" by Robert Bristow-Johnson * * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ @@ -61,14 +69,14 @@ typedef struct ALdistortionState { static ALvoid ALdistortionState_Destroy(ALdistortionState *state) { - free(state); + (void)state; } -static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *Device) +static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *device) { return AL_TRUE; (void)state; - (void)Device; + (void)device; } static ALvoid ALdistortionState_Update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot) @@ -226,9 +234,15 @@ static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint Samples } } +static ALeffectStateFactory *ALdistortionState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); -ALeffectState *DistortionCreate(void) + +static ALeffectState *ALdistortionStateFactory_create(void) { ALdistortionState *state; @@ -249,6 +263,29 @@ ALeffectState *DistortionCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALdistortionStateFactory_destroy(ALeffectState *effect) +{ + ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); + ALdistortionState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdistortionStateFactory); + + +static void init_distortion_factory(void) +{ + SET_VTABLE2(ALdistortionStateFactory, ALeffectStateFactory, &DistortionFactory); +} + +ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_distortion_factory); + return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); +} + + void distortion_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { effect=effect; diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index 1aab9870..e38e1457 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -30,6 +30,13 @@ #include "alu.h" +typedef struct ALechoStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALechoStateFactory; + +static ALechoStateFactory EchoFactory; + + typedef struct ALechoState { DERIVE_FROM_TYPE(ALeffectState); @@ -54,8 +61,6 @@ static ALvoid ALechoState_Destroy(ALechoState *state) { free(state->SampleBuffer); state->SampleBuffer = NULL; - - free(state); } static ALboolean ALechoState_DeviceUpdate(ALechoState *state, ALCdevice *Device) @@ -170,9 +175,15 @@ static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const state->Offset = offset; } +static ALeffectStateFactory *ALechoState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &EchoFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); -ALeffectState *EchoCreate(void) + +ALeffectState *ALechoStateFactory_create(void) { ALechoState *state; @@ -194,6 +205,29 @@ ALeffectState *EchoCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALechoStateFactory_destroy(ALeffectState *effect) +{ + ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); + ALechoState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALechoStateFactory); + + +static void init_echo_factory(void) +{ + SET_VTABLE2(ALechoStateFactory, ALeffectStateFactory, &EchoFactory); +} + +ALeffectStateFactory *ALechoStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_echo_factory); + return STATIC_CAST(ALeffectStateFactory, &EchoFactory); +} + + void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } void echo_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index 318593ee..5a1d8841 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -29,6 +29,14 @@ #include "alError.h" #include "alu.h" + +typedef struct ALequalizerStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALequalizerStateFactory; + +static ALequalizerStateFactory EqualizerFactory; + + /* The document "Effects Extension Guide.pdf" says that low and high * * frequencies are cutoff frequencies. This is not fully correct, they * * are corner frequencies for low and high shelf filters. If they were * @@ -96,7 +104,7 @@ typedef struct ALequalizerState { static ALvoid ALequalizerState_Destroy(ALequalizerState *state) { - free(state); + (void)state; } static ALboolean ALequalizerState_DeviceUpdate(ALequalizerState *state, ALCdevice *device) @@ -262,9 +270,15 @@ static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesTo } } +static ALeffectStateFactory *ALequalizerState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); -ALeffectState *EqualizerCreate(void) + +ALeffectState *ALequalizerStateFactory_create(void) { ALequalizerState *state; int it; @@ -291,6 +305,29 @@ ALeffectState *EqualizerCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALequalizerStateFactory_destroy(ALeffectState *effect) +{ + ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); + ALequalizerState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALequalizerStateFactory); + + +static void init_equalizer_factory(void) +{ + SET_VTABLE2(ALequalizerStateFactory, ALeffectStateFactory, &EqualizerFactory); +} + +ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_equalizer_factory); + return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); +} + + void equalizer_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { effect=effect; diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index 574fa9d7..953828f6 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -30,6 +30,13 @@ #include "alu.h" +typedef struct ALflangerStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALflangerStateFactory; + +static ALflangerStateFactory FlangerFactory; + + typedef struct ALflangerState { DERIVE_FROM_TYPE(ALeffectState); @@ -57,8 +64,6 @@ static ALvoid ALflangerState_Destroy(ALflangerState *state) free(state->SampleBufferRight); state->SampleBufferRight = NULL; - - free(state); } static ALboolean ALflangerState_DeviceUpdate(ALflangerState *state, ALCdevice *Device) @@ -238,9 +243,15 @@ static ALvoid ALflangerState_Process(ALflangerState *state, ALuint SamplesToDo, ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); } +static ALeffectStateFactory *ALflangerState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); -ALeffectState *FlangerCreate(void) + +ALeffectState *ALflangerStateFactory_create(void) { ALflangerState *state; @@ -256,6 +267,29 @@ ALeffectState *FlangerCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALflangerStateFactory_destroy(ALeffectState *effect) +{ + ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); + ALflangerState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALflangerStateFactory); + + +static void init_flanger_factory(void) +{ + SET_VTABLE2(ALflangerStateFactory, ALeffectStateFactory, &FlangerFactory); +} + +ALeffectStateFactory *ALflangerStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_flanger_factory); + return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); +} + + void flanger_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { switch(param) diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index bb90d646..25b5bcc4 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -30,6 +30,13 @@ #include "alu.h" +typedef struct ALmodulatorStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALmodulatorStateFactory; + +static ALmodulatorStateFactory ModulatorFactory; + + typedef struct ALmodulatorState { DERIVE_FROM_TYPE(ALeffectState); @@ -130,7 +137,7 @@ DECL_TEMPLATE(Square) static ALvoid ALmodulatorState_Destroy(ALmodulatorState *state) { - free(state); + (void)state; } static ALboolean ALmodulatorState_DeviceUpdate(ALmodulatorState *state, ALCdevice *Device) @@ -190,9 +197,15 @@ static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesTo } } +static ALeffectStateFactory *ALmodulatorState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); +} + DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); -ALeffectState *ModulatorCreate(void) + +static ALeffectState *ALmodulatorStateFactory_create(void) { ALmodulatorState *state; @@ -209,6 +222,29 @@ ALeffectState *ModulatorCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALmodulatorStateFactory_destroy(ALeffectState *effect) +{ + ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); + ALmodulatorState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALmodulatorStateFactory); + + +static void init_modulator_factory(void) +{ + SET_VTABLE2(ALmodulatorStateFactory, ALeffectStateFactory, &ModulatorFactory); +} + +ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_modulator_factory); + return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); +} + + void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { switch(param) diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index 01f4ab83..b3de2fad 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -31,6 +31,14 @@ #include "alFilter.h" #include "alError.h" + +typedef struct ALreverbStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALreverbStateFactory; + +static ALreverbStateFactory ReverbFactory; + + typedef struct DelayLine { // The delay lines use sample lengths that are powers of 2 to allow the @@ -1174,106 +1182,131 @@ static ALvoid ALreverbState_Destroy(ALreverbState *State) { free(State->SampleBuffer); State->SampleBuffer = NULL; +} - free(State); +static ALeffectStateFactory *ALreverbState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &ReverbFactory); } 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) + +static ALeffectState *ALreverbStateFactory_create(void) { - ALreverbState *State; + ALreverbState *state; ALuint index; - State = malloc(sizeof(ALreverbState)); - if(!State) return NULL; - SET_VTABLE2(ALreverbState, ALeffectState, State); + state = malloc(sizeof(ALreverbState)); + if(!state) return NULL; + SET_VTABLE2(ALreverbState, ALeffectState, state); - State->TotalSamples = 0; - State->SampleBuffer = NULL; + state->TotalSamples = 0; + state->SampleBuffer = NULL; - State->LpFilter.coeff = 0.0f; - State->LpFilter.history[0] = 0.0f; - State->LpFilter.history[1] = 0.0f; + state->LpFilter.coeff = 0.0f; + state->LpFilter.history[0] = 0.0f; + state->LpFilter.history[1] = 0.0f; - State->Mod.Delay.Mask = 0; - State->Mod.Delay.Line = NULL; - State->Mod.Index = 0; - State->Mod.Range = 1; - State->Mod.Depth = 0.0f; - State->Mod.Coeff = 0.0f; - State->Mod.Filter = 0.0f; + state->Mod.Delay.Mask = 0; + state->Mod.Delay.Line = NULL; + state->Mod.Index = 0; + state->Mod.Range = 1; + state->Mod.Depth = 0.0f; + state->Mod.Coeff = 0.0f; + state->Mod.Filter = 0.0f; - State->Delay.Mask = 0; - State->Delay.Line = NULL; - State->DelayTap[0] = 0; - State->DelayTap[1] = 0; + state->Delay.Mask = 0; + state->Delay.Line = NULL; + state->DelayTap[0] = 0; + state->DelayTap[1] = 0; - State->Early.Gain = 0.0f; + state->Early.Gain = 0.0f; for(index = 0;index < 4;index++) { - State->Early.Coeff[index] = 0.0f; - State->Early.Delay[index].Mask = 0; - State->Early.Delay[index].Line = NULL; - State->Early.Offset[index] = 0; + state->Early.Coeff[index] = 0.0f; + state->Early.Delay[index].Mask = 0; + state->Early.Delay[index].Line = NULL; + state->Early.Offset[index] = 0; } - State->Decorrelator.Mask = 0; - State->Decorrelator.Line = NULL; - State->DecoTap[0] = 0; - State->DecoTap[1] = 0; - State->DecoTap[2] = 0; + state->Decorrelator.Mask = 0; + state->Decorrelator.Line = NULL; + state->DecoTap[0] = 0; + state->DecoTap[1] = 0; + state->DecoTap[2] = 0; - State->Late.Gain = 0.0f; - State->Late.DensityGain = 0.0f; - State->Late.ApFeedCoeff = 0.0f; - State->Late.MixCoeff = 0.0f; + 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 = 0; - State->Late.ApDelay[index].Line = NULL; - State->Late.ApOffset[index] = 0; - - State->Late.Coeff[index] = 0.0f; - State->Late.Delay[index].Mask = 0; - State->Late.Delay[index].Line = NULL; - State->Late.Offset[index] = 0; - - State->Late.LpCoeff[index] = 0.0f; - State->Late.LpSample[index] = 0.0f; + state->Late.ApCoeff[index] = 0.0f; + state->Late.ApDelay[index].Mask = 0; + state->Late.ApDelay[index].Line = NULL; + state->Late.ApOffset[index] = 0; + + state->Late.Coeff[index] = 0.0f; + state->Late.Delay[index].Mask = 0; + state->Late.Delay[index].Line = NULL; + state->Late.Offset[index] = 0; + + state->Late.LpCoeff[index] = 0.0f; + state->Late.LpSample[index] = 0.0f; } for(index = 0;index < MaxChannels;index++) { - State->Early.PanGain[index] = 0.0f; - State->Late.PanGain[index] = 0.0f; + state->Early.PanGain[index] = 0.0f; + state->Late.PanGain[index] = 0.0f; } - State->Echo.DensityGain = 0.0f; - State->Echo.Delay.Mask = 0; - State->Echo.Delay.Line = NULL; - State->Echo.ApDelay.Mask = 0; - State->Echo.ApDelay.Line = NULL; - State->Echo.Coeff = 0.0f; - State->Echo.ApFeedCoeff = 0.0f; - State->Echo.ApCoeff = 0.0f; - State->Echo.Offset = 0; - State->Echo.ApOffset = 0; - State->Echo.LpCoeff = 0.0f; - State->Echo.LpSample = 0.0f; - State->Echo.MixCoeff[0] = 0.0f; - State->Echo.MixCoeff[1] = 0.0f; - - State->Offset = 0; - - State->Gain = State->Late.PanGain; - - return STATIC_CAST(ALeffectState, State); + state->Echo.DensityGain = 0.0f; + state->Echo.Delay.Mask = 0; + state->Echo.Delay.Line = NULL; + state->Echo.ApDelay.Mask = 0; + state->Echo.ApDelay.Line = NULL; + state->Echo.Coeff = 0.0f; + state->Echo.ApFeedCoeff = 0.0f; + state->Echo.ApCoeff = 0.0f; + state->Echo.Offset = 0; + state->Echo.ApOffset = 0; + state->Echo.LpCoeff = 0.0f; + state->Echo.LpSample = 0.0f; + state->Echo.MixCoeff[0] = 0.0f; + state->Echo.MixCoeff[1] = 0.0f; + + state->Offset = 0; + + state->Gain = state->Late.PanGain; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALreverbStateFactory_destroy(ALeffectState *effect) +{ + ALreverbState *state = STATIC_UPCAST(ALreverbState, ALeffectState, effect); + ALreverbState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALreverbStateFactory); + + +static void init_reverb_factory(void) +{ + SET_VTABLE2(ALreverbStateFactory, ALeffectStateFactory, &ReverbFactory); } +ALeffectStateFactory *ALreverbStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_reverb_factory); + return STATIC_CAST(ALeffectStateFactory, &ReverbFactory); +} + + void eaxreverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { switch(param) diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 547e7040..6d5ad8bb 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -8,6 +8,8 @@ extern "C" { #endif +typedef struct ALeffectStateFactory ALeffectStateFactory; + typedef struct ALeffectState ALeffectState; typedef struct ALeffectslot ALeffectslot; @@ -16,12 +18,19 @@ struct ALeffectStateVtable { ALboolean (*const DeviceUpdate)(ALeffectState *state, ALCdevice *device); ALvoid (*const Update)(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot); ALvoid (*const Process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]); + ALeffectStateFactory *(*const getCreator)(void); }; struct ALeffectState { const struct ALeffectStateVtable *vtbl; }; +#define ALeffectState_Destroy(a) ((a)->vtbl->Destroy((a))) +#define ALeffectState_DeviceUpdate(a,b) ((a)->vtbl->DeviceUpdate((a),(b))) +#define ALeffectState_Update(a,b,c) ((a)->vtbl->Update((a),(b),(c))) +#define ALeffectState_Process(a,b,c,d) ((a)->vtbl->Process((a),(b),(c),(d))) +#define ALeffectState_getCreator(a) ((a)->vtbl->getCreator()) + #define DEFINE_ALEFFECTSTATE_VTABLE(T) \ static ALvoid T##_ALeffectState_Destroy(ALeffectState *state) \ { T##_Destroy(STATIC_UPCAST(T, ALeffectState, state)); } \ @@ -31,16 +40,40 @@ static ALvoid T##_ALeffectState_Update(ALeffectState *state, ALCdevice *device, { T##_Update(STATIC_UPCAST(T, ALeffectState, state), device, slot); } \ static ALvoid T##_ALeffectState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) \ { T##_Process(STATIC_UPCAST(T, ALeffectState, state), samplesToDo, samplesIn, samplesOut); } \ +static ALeffectStateFactory* T##_ALeffectState_getCreator(void) \ +{ return T##_getCreator(); } \ \ static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ T##_ALeffectState_Destroy, \ T##_ALeffectState_DeviceUpdate, \ T##_ALeffectState_Update, \ - T##_ALeffectState_Process \ + T##_ALeffectState_Process, \ + T##_ALeffectState_getCreator, \ } -#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable)) -#define SET_VTABLE2(T1, T2, obj) SET_VTABLE1(T1##_##T2, STATIC_CAST(T2, (obj))) + +struct ALeffectStateFactoryVtable { + ALeffectState *(*const create)(void); + ALvoid (*const destroy)(ALeffectState *state); +}; + +struct ALeffectStateFactory { + const struct ALeffectStateFactoryVtable *vtbl; +}; + +#define ALeffectStateFactory_create(p) ((p)->vtbl->create()) +#define ALeffectStateFactory_destroy(p,a) ((p)->vtbl->destroy((a))) + +#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \ +static ALeffectState* T##_ALeffectStateFactory_create(void) \ +{ return T##_create(); } \ +static ALvoid T##_ALeffectStateFactory_destroy(ALeffectState *state) \ +{ T##_destroy(state); } \ + \ +static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \ + T##_ALeffectStateFactory_create, \ + T##_ALeffectStateFactory_destroy \ +} struct ALeffectslot @@ -68,23 +101,23 @@ struct ALeffectslot ALenum InitEffectSlot(ALeffectslot *slot); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); -ALeffectState *NoneCreate(void); -ALeffectState *ReverbCreate(void); -ALeffectState *EchoCreate(void); -ALeffectState *ModulatorCreate(void); -ALeffectState *DedicatedCreate(void); -ALeffectState *ChorusCreate(void); -ALeffectState *FlangerCreate(void); -ALeffectState *EqualizerCreate(void); -ALeffectState *DistortionCreate(void); -#define ALeffectState_Destroy(a) ((a)->vtbl->Destroy((a))) -#define ALeffectState_DeviceUpdate(a,b) ((a)->vtbl->DeviceUpdate((a),(b))) -#define ALeffectState_Update(a,b,c) ((a)->vtbl->Update((a),(b),(c))) -#define ALeffectState_Process(a,b,c,d) ((a)->vtbl->Process((a),(b),(c),(d))) +ALeffectStateFactory *ALreverbStateFactory_getFactory(void); +ALeffectStateFactory *ALchorusStateFactory_getFactory(void); +ALeffectStateFactory *ALdistortionStateFactory_getFactory(void); +ALeffectStateFactory *ALechoStateFactory_getFactory(void); +ALeffectStateFactory *ALequalizerStateFactory_getFactory(void); +ALeffectStateFactory *ALflangerStateFactory_getFactory(void); +ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void); + +ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void); + ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect); +void InitEffectFactoryMap(void); +void DeinitEffectFactoryMap(void); + #ifdef __cplusplus } #endif diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 4cdaf783..fc078175 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -62,10 +62,15 @@ static const union { #define COUNTOF(x) (sizeof((x))/sizeof((x)[0])) + #define DERIVE_FROM_TYPE(t) t t##_parent #define STATIC_CAST(to, obj) (&(obj)->to##_parent) #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent))) +#define SET_VTABLE1(T1, obj) ((obj)->vtbl = &(T1##_vtable)) +#define SET_VTABLE2(T1, T2, obj) SET_VTABLE1(T1##_##T2, STATIC_CAST(T2, (obj))) + + #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 3c31ecb8..0daeaeb1 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -35,7 +35,12 @@ static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots); static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot); -static ALeffectState *CreateStateByType(ALenum type); + +static UIntMap EffectStateFactoryMap; +static __inline ALeffectStateFactory *getFactoryByType(ALenum type) +{ + return LookupUIntMapKey(&EffectStateFactoryMap, type); +} AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) @@ -69,7 +74,8 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(err != AL_NO_ERROR) { FreeThunkEntry(slot->id); - ALeffectState_Destroy(slot->EffectState); + ALeffectStateFactory_destroy(ALeffectState_getCreator(slot->EffectState), + slot->EffectState); al_free(slot); alDeleteAuxiliaryEffectSlots(cur, effectslots); @@ -118,7 +124,8 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * FreeThunkEntry(slot->id); RemoveEffectSlotArray(Context, slot); - ALeffectState_Destroy(slot->EffectState); + ALeffectStateFactory_destroy(ALeffectState_getCreator(slot->EffectState), + slot->EffectState); memset(slot, 0, sizeof(*slot)); al_free(slot); @@ -393,12 +400,21 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p } +typedef struct ALnoneStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALnoneStateFactory; + +static ALnoneStateFactory NoneFactory; + + typedef struct ALnoneState { DERIVE_FROM_TYPE(ALeffectState); } ALnoneState; static ALvoid ALnoneState_Destroy(ALnoneState *state) -{ free(state); } +{ + (void)state; +} static ALboolean ALnoneState_DeviceUpdate(ALnoneState *state, ALCdevice *device) { return AL_TRUE; @@ -418,10 +434,15 @@ static ALvoid ALnoneState_Process(ALnoneState *state, ALuint samplesToDo, const (void)samplesIn; (void)samplesOut; } +static ALeffectStateFactory *ALnoneState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &NoneFactory); +} DEFINE_ALEFFECTSTATE_VTABLE(ALnoneState); -ALeffectState *NoneCreate(void) + +ALeffectState *ALnoneStateFactory_create(void) { ALnoneState *state; @@ -432,6 +453,29 @@ ALeffectState *NoneCreate(void) return STATIC_CAST(ALeffectState, state); } +static ALvoid ALnoneStateFactory_destroy(ALeffectState *effect) +{ + ALnoneState *state = STATIC_UPCAST(ALnoneState, ALeffectState, effect); + ALnoneState_Destroy(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALnoneStateFactory); + + +static void init_none_factory(void) +{ + SET_VTABLE2(ALnoneStateFactory, ALeffectStateFactory, &NoneFactory); +} + +ALeffectStateFactory *ALnoneStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_none_factory); + return STATIC_CAST(ALeffectStateFactory, &NoneFactory); +} + + void null_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } void null_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) @@ -504,46 +548,46 @@ static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuin } -static ALeffectState *CreateStateByType(ALenum type) +void InitEffectFactoryMap(void) { - switch(type) - { - case AL_EFFECT_NULL: - return NoneCreate(); - case AL_EFFECT_EAXREVERB: - case AL_EFFECT_REVERB: - return ReverbCreate(); - case AL_EFFECT_CHORUS: - return ChorusCreate(); - case AL_EFFECT_DISTORTION: - return DistortionCreate(); - case AL_EFFECT_ECHO: - return EchoCreate(); - case AL_EFFECT_EQUALIZER: - return EqualizerCreate(); - case AL_EFFECT_FLANGER: - return FlangerCreate(); - case AL_EFFECT_RING_MODULATOR: - return ModulatorCreate(); - case AL_EFFECT_DEDICATED_DIALOGUE: - case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT: - return DedicatedCreate(); - } + InitUIntMap(&EffectStateFactoryMap, ~0); + + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnoneStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_REVERB, ALreverbStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_ECHO, ALechoStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EQUALIZER, ALequalizerStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_FLANGER, ALflangerStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_RING_MODULATOR, ALmodulatorStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_DIALOGUE, ALdedicatedStateFactory_getFactory()); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, ALdedicatedStateFactory_getFactory()); +} - ERR("Unexpected effect type: 0x%04x\n", type); - return NULL; +void DeinitEffectFactoryMap(void) +{ + ResetUIntMap(&EffectStateFactoryMap); } + ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); + ALeffectStateFactory *factory; if(newtype != EffectSlot->effect.type) { ALeffectState *State; FPUCtl oldMode; - State = CreateStateByType(newtype); + factory = getFactoryByType(newtype); + if(!factory) + { + ERR("Failed to find factory for effect type 0x%04x\n", newtype); + return AL_INVALID_ENUM; + } + State = ALeffectStateFactory_create(factory); if(!State) return AL_OUT_OF_MEMORY; @@ -554,7 +598,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e { ALCdevice_Unlock(Device); RestoreFPUMode(&oldMode); - ALeffectState_Destroy(State); + ALeffectStateFactory_destroy(ALeffectState_getCreator(State), State); return AL_OUT_OF_MEMORY; } @@ -573,7 +617,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e RestoreFPUMode(&oldMode); - ALeffectState_Destroy(State); + ALeffectStateFactory_destroy(ALeffectState_getCreator(State), State); State = NULL; } else @@ -593,9 +637,11 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALenum InitEffectSlot(ALeffectslot *slot) { + ALeffectStateFactory *factory; ALint i, c; - if(!(slot->EffectState=NoneCreate())) + factory = getFactoryByType(AL_EFFECT_NULL); + if(!(slot->EffectState=ALeffectStateFactory_create(factory))) return AL_OUT_OF_MEMORY; slot->Gain = 1.0; @@ -621,7 +667,8 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; Context->EffectSlotMap.array[pos].value = NULL; - ALeffectState_Destroy(temp->EffectState); + ALeffectStateFactory_destroy(ALeffectState_getCreator(temp->EffectState), + temp->EffectState); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALeffectslot)); -- cgit v1.2.3 From eaccaa50284da45401d841a867a7a10daa00dbd0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 May 2013 13:02:56 -0700 Subject: Rename the effect state's Destroy method to Destruct --- Alc/ALc.c | 8 +++++--- Alc/alcChorus.c | 4 ++-- Alc/alcDedicated.c | 4 ++-- Alc/alcDistortion.c | 4 ++-- Alc/alcEcho.c | 4 ++-- Alc/alcEqualizer.c | 4 ++-- Alc/alcFlanger.c | 4 ++-- Alc/alcModulator.c | 4 ++-- Alc/alcReverb.c | 4 ++-- OpenAL32/Include/alAuxEffectSlot.h | 10 +++++----- OpenAL32/alAuxEffectSlot.c | 4 ++-- 11 files changed, 28 insertions(+), 26 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index aaddfea8..a3012650 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1777,8 +1777,9 @@ static ALCvoid FreeDevice(ALCdevice *device) if(device->DefaultSlot) { - ALeffectState_Destroy(device->DefaultSlot->EffectState); - device->DefaultSlot->EffectState = NULL; + ALeffectState *state = device->DefaultSlot->EffectState; + device->DefaultSlot = NULL; + ALeffectStateFactory_destroy(ALeffectState_getCreator(state), state); } if(device->BufferMap.size > 0) @@ -2899,8 +2900,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) } else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) { - ALeffectState_Destroy(device->DefaultSlot->EffectState); + ALeffectState *state = device->DefaultSlot->EffectState; device->DefaultSlot = NULL; + ALeffectStateFactory_destroy(ALeffectState_getCreator(state), state); ERR("Failed to initialize the default effect\n"); } } diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index 018caac5..cf414bbd 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -57,7 +57,7 @@ typedef struct ALchorusState { ALfloat feedback; } ALchorusState; -static ALvoid ALchorusState_Destroy(ALchorusState *state) +static ALvoid ALchorusState_Destruct(ALchorusState *state) { free(state->SampleBufferLeft); state->SampleBufferLeft = NULL; @@ -270,7 +270,7 @@ static ALeffectState *ALchorusStateFactory_create(void) static ALvoid ALchorusStateFactory_destroy(ALeffectState *effect) { ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); - ALchorusState_Destroy(state); + ALchorusState_Destruct(state); free(state); } diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index fbe2a5f1..dd59c2c5 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -43,7 +43,7 @@ typedef struct ALdedicatedState { } ALdedicatedState; -static ALvoid ALdedicatedState_Destroy(ALdedicatedState *state) +static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state) { (void)state; } @@ -111,7 +111,7 @@ ALeffectState *ALdedicatedStateFactory_create(void) static ALvoid ALdedicatedStateFactory_destroy(ALeffectState *effect) { ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); - ALdedicatedState_Destroy(state); + ALdedicatedState_Destruct(state); free(state); } diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index ec48ad03..8f52ab5d 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -67,7 +67,7 @@ typedef struct ALdistortionState { ALfloat edge_coeff; } ALdistortionState; -static ALvoid ALdistortionState_Destroy(ALdistortionState *state) +static ALvoid ALdistortionState_Destruct(ALdistortionState *state) { (void)state; } @@ -266,7 +266,7 @@ static ALeffectState *ALdistortionStateFactory_create(void) static ALvoid ALdistortionStateFactory_destroy(ALeffectState *effect) { ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); - ALdistortionState_Destroy(state); + ALdistortionState_Destruct(state); free(state); } diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index e38e1457..4270c863 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -57,7 +57,7 @@ typedef struct ALechoState { FILTER iirFilter; } ALechoState; -static ALvoid ALechoState_Destroy(ALechoState *state) +static ALvoid ALechoState_Destruct(ALechoState *state) { free(state->SampleBuffer); state->SampleBuffer = NULL; @@ -208,7 +208,7 @@ ALeffectState *ALechoStateFactory_create(void) static ALvoid ALechoStateFactory_destroy(ALeffectState *effect) { ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); - ALechoState_Destroy(state); + ALechoState_Destruct(state); free(state); } diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index 5a1d8841..2c8eb131 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -102,7 +102,7 @@ typedef struct ALequalizerState { ALEQFilter bandfilter[4]; } ALequalizerState; -static ALvoid ALequalizerState_Destroy(ALequalizerState *state) +static ALvoid ALequalizerState_Destruct(ALequalizerState *state) { (void)state; } @@ -308,7 +308,7 @@ ALeffectState *ALequalizerStateFactory_create(void) static ALvoid ALequalizerStateFactory_destroy(ALeffectState *effect) { ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); - ALequalizerState_Destroy(state); + ALequalizerState_Destruct(state); free(state); } diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index 953828f6..b3f09018 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -57,7 +57,7 @@ typedef struct ALflangerState { ALfloat feedback; } ALflangerState; -static ALvoid ALflangerState_Destroy(ALflangerState *state) +static ALvoid ALflangerState_Destruct(ALflangerState *state) { free(state->SampleBufferLeft); state->SampleBufferLeft = NULL; @@ -270,7 +270,7 @@ ALeffectState *ALflangerStateFactory_create(void) static ALvoid ALflangerStateFactory_destroy(ALeffectState *effect) { ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); - ALflangerState_Destroy(state); + ALflangerState_Destruct(state); free(state); } diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index 25b5bcc4..847027e6 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -135,7 +135,7 @@ DECL_TEMPLATE(Square) #undef DECL_TEMPLATE -static ALvoid ALmodulatorState_Destroy(ALmodulatorState *state) +static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state) { (void)state; } @@ -225,7 +225,7 @@ static ALeffectState *ALmodulatorStateFactory_create(void) static ALvoid ALmodulatorStateFactory_destroy(ALeffectState *effect) { ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); - ALmodulatorState_Destroy(state); + ALmodulatorState_Destruct(state); free(state); } diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index b3de2fad..e7dad6bb 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -1178,7 +1178,7 @@ static ALvoid ALreverbState_Update(ALreverbState *State, ALCdevice *Device, cons // 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 ALreverbState_Destroy(ALreverbState *State) +static ALvoid ALreverbState_Destruct(ALreverbState *State) { free(State->SampleBuffer); State->SampleBuffer = NULL; @@ -1287,7 +1287,7 @@ static ALeffectState *ALreverbStateFactory_create(void) static ALvoid ALreverbStateFactory_destroy(ALeffectState *effect) { ALreverbState *state = STATIC_UPCAST(ALreverbState, ALeffectState, effect); - ALreverbState_Destroy(state); + ALreverbState_Destruct(state); free(state); } diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 6d5ad8bb..537f0a8a 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -14,7 +14,7 @@ typedef struct ALeffectState ALeffectState; typedef struct ALeffectslot ALeffectslot; struct ALeffectStateVtable { - ALvoid (*const Destroy)(ALeffectState *state); + ALvoid (*const Destruct)(ALeffectState *state); ALboolean (*const DeviceUpdate)(ALeffectState *state, ALCdevice *device); ALvoid (*const Update)(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot); ALvoid (*const Process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]); @@ -25,15 +25,15 @@ struct ALeffectState { const struct ALeffectStateVtable *vtbl; }; -#define ALeffectState_Destroy(a) ((a)->vtbl->Destroy((a))) +#define ALeffectState_Destruct(a) ((a)->vtbl->Destruct((a))) #define ALeffectState_DeviceUpdate(a,b) ((a)->vtbl->DeviceUpdate((a),(b))) #define ALeffectState_Update(a,b,c) ((a)->vtbl->Update((a),(b),(c))) #define ALeffectState_Process(a,b,c,d) ((a)->vtbl->Process((a),(b),(c),(d))) #define ALeffectState_getCreator(a) ((a)->vtbl->getCreator()) #define DEFINE_ALEFFECTSTATE_VTABLE(T) \ -static ALvoid T##_ALeffectState_Destroy(ALeffectState *state) \ -{ T##_Destroy(STATIC_UPCAST(T, ALeffectState, state)); } \ +static ALvoid T##_ALeffectState_Destruct(ALeffectState *state) \ +{ T##_Destruct(STATIC_UPCAST(T, ALeffectState, state)); } \ static ALboolean T##_ALeffectState_DeviceUpdate(ALeffectState *state, ALCdevice *device) \ { return T##_DeviceUpdate(STATIC_UPCAST(T, ALeffectState, state), device); } \ static ALvoid T##_ALeffectState_Update(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot) \ @@ -44,7 +44,7 @@ static ALeffectStateFactory* T##_ALeffectState_getCreator(void) \ { return T##_getCreator(); } \ \ static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ - T##_ALeffectState_Destroy, \ + T##_ALeffectState_Destruct, \ T##_ALeffectState_DeviceUpdate, \ T##_ALeffectState_Update, \ T##_ALeffectState_Process, \ diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 0daeaeb1..4003d440 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -411,7 +411,7 @@ typedef struct ALnoneState { DERIVE_FROM_TYPE(ALeffectState); } ALnoneState; -static ALvoid ALnoneState_Destroy(ALnoneState *state) +static ALvoid ALnoneState_Destruct(ALnoneState *state) { (void)state; } @@ -456,7 +456,7 @@ ALeffectState *ALnoneStateFactory_create(void) static ALvoid ALnoneStateFactory_destroy(ALeffectState *effect) { ALnoneState *state = STATIC_UPCAST(ALnoneState, ALeffectState, effect); - ALnoneState_Destroy(state); + ALnoneState_Destruct(state); free(state); } -- cgit v1.2.3 From 52efb8d7f43e85659bc84455361f8685a5f493ed Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 22 May 2013 15:11:39 -0700 Subject: Use restrict instead of RESTRICT --- Alc/ALu.c | 10 +++++----- Alc/alcChorus.c | 6 +++--- Alc/alcDedicated.c | 2 +- Alc/alcDistortion.c | 2 +- Alc/alcEcho.c | 2 +- Alc/alcEqualizer.c | 2 +- Alc/alcFlanger.c | 6 +++--- Alc/alcModulator.c | 6 +++--- Alc/alcReverb.c | 22 +++++++++++----------- Alc/mixer.c | 2 +- Alc/mixer_c.c | 30 +++++++++++++++--------------- Alc/mixer_defs.h | 22 +++++++++++----------- Alc/mixer_inc.c | 30 +++++++++++++++--------------- Alc/mixer_neon.c | 10 +++++----- Alc/mixer_sse.c | 26 +++++++++++++------------- CMakeLists.txt | 9 ++++----- OpenAL32/Include/alAuxEffectSlot.h | 4 ++-- OpenAL32/Include/alu.h | 6 +++--- OpenAL32/alAuxEffectSlot.c | 2 +- config.h.in | 3 --- 20 files changed, 99 insertions(+), 103 deletions(-) (limited to 'Alc/alcModulator.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index 6b6917bf..3c1e4ad5 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -130,7 +130,7 @@ static __inline void aluNormalize(ALfloat *inVector) } } -static __inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat (*RESTRICT matrix)[4]) +static __inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat (*restrict matrix)[4]) { ALfloat temp[4] = { vector[0], vector[1], vector[2], w @@ -589,7 +589,7 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) /* Transform source to listener space (convert to head relative) */ if(ALSource->HeadRelative == AL_FALSE) { - ALfloat (*RESTRICT Matrix)[4] = ALContext->Listener->Params.Matrix; + ALfloat (*restrict Matrix)[4] = ALContext->Listener->Params.Matrix; /* Transform source vectors */ aluMatrixVector(Position, 1.0f, Matrix); aluMatrixVector(Direction, 0.0f, Matrix); @@ -941,17 +941,17 @@ static __inline ALubyte aluF2UB(ALfloat val) { return aluF2B(val)+128; } #define DECL_TEMPLATE(T, func) \ -static int Write_##T(ALCdevice *device, T *RESTRICT buffer, \ +static int Write_##T(ALCdevice *device, T *restrict buffer, \ ALuint SamplesToDo) \ { \ - ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = device->DryBuffer; \ + ALfloat (*restrict DryBuffer)[BUFFERSIZE] = device->DryBuffer; \ ALuint numchans = ChannelsFromDevFmt(device->FmtChans); \ const ALuint *offsets = device->ChannelOffsets; \ ALuint i, j; \ \ for(j = 0;j < MaxChannels;j++) \ { \ - T *RESTRICT out; \ + T *restrict out; \ \ if(offsets[j] == INVALID_OFFSET) \ continue; \ diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c index ab46243d..e5a20b5d 100644 --- a/Alc/alcChorus.c +++ b/Alc/alcChorus.c @@ -178,8 +178,8 @@ static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offse #define DECL_TEMPLATE(func) \ static void Process##func(ALchorusState *state, ALuint SamplesToDo, \ - const ALfloat *RESTRICT SamplesIn, \ - ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ { \ const ALint mask = state->BufferLength-1; \ ALint offset = state->offset; \ @@ -235,7 +235,7 @@ DECL_TEMPLATE(Sinusoid) #undef DECL_TEMPLATE -static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c index dd59c2c5..bd266b0e 100644 --- a/Alc/alcDedicated.c +++ b/Alc/alcDedicated.c @@ -70,7 +70,7 @@ static ALvoid ALdedicatedState_Update(ALdedicatedState *state, ALCdevice *device state->gains[LFE] = Gain; } -static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { const ALfloat *gains = state->gains; ALuint i, c; diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c index 8f52ab5d..7828377c 100644 --- a/Alc/alcDistortion.c +++ b/Alc/alcDistortion.c @@ -132,7 +132,7 @@ static ALvoid ALdistortionState_Update(ALdistortionState *state, ALCdevice *Devi state->bandpass.a[2] = 1.0f - alpha; } -static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { const ALfloat fc = state->edge_coeff; float oversample_buffer[64][4]; diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c index 4270c863..d5915295 100644 --- a/Alc/alcEcho.c +++ b/Alc/alcEcho.c @@ -124,7 +124,7 @@ static ALvoid ALechoState_Update(ALechoState *state, ALCdevice *Device, const AL ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); } -static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { const ALuint mask = state->BufferLength-1; const ALuint tap1 = state->Tap[0].delay; diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c index 2c8eb131..d397a9ba 100644 --- a/Alc/alcEqualizer.c +++ b/Alc/alcEqualizer.c @@ -219,7 +219,7 @@ static ALvoid ALequalizerState_Update(ALequalizerState *state, ALCdevice *device } } -static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { ALuint base; ALuint it; diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c index 88e2d625..a0f94a46 100644 --- a/Alc/alcFlanger.c +++ b/Alc/alcFlanger.c @@ -178,8 +178,8 @@ static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offse #define DECL_TEMPLATE(func) \ static void Process##func(ALflangerState *state, ALuint SamplesToDo, \ - const ALfloat *RESTRICT SamplesIn, \ - ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ { \ const ALint mask = state->BufferLength-1; \ ALint offset = state->offset; \ @@ -235,7 +235,7 @@ DECL_TEMPLATE(Sinusoid) #undef DECL_TEMPLATE -static ALvoid ALflangerState_Process(ALflangerState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALflangerState_Process(ALflangerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c index 847027e6..ec99bd53 100644 --- a/Alc/alcModulator.c +++ b/Alc/alcModulator.c @@ -89,8 +89,8 @@ static __inline ALfloat hpFilter1P(FILTER *iir, ALfloat input) #define DECL_TEMPLATE(func) \ static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ - const ALfloat *RESTRICT SamplesIn, \ - ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ { \ const ALuint step = state->step; \ ALuint index = state->index; \ @@ -179,7 +179,7 @@ static ALvoid ALmodulatorState_Update(ALmodulatorState *state, ALCdevice *Device } } -static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { switch(state->Waveform) { diff --git a/Alc/alcReverb.c b/Alc/alcReverb.c index e7dad6bb..a13a5693 100644 --- a/Alc/alcReverb.c +++ b/Alc/alcReverb.c @@ -309,7 +309,7 @@ static __inline ALfloat EarlyDelayLineOut(ALreverbState *State, ALuint index) // Given an input sample, this function produces four-channel output for the // early reflections. -static __inline ALvoid EarlyReflection(ALreverbState *State, ALfloat in, ALfloat *RESTRICT out) +static __inline ALvoid EarlyReflection(ALreverbState *State, ALfloat in, ALfloat *restrict out) { ALfloat d[4], v, f[4]; @@ -380,7 +380,7 @@ static __inline ALfloat LateLowPassInOut(ALreverbState *State, ALuint index, ALf // Given four decorrelated input samples, this function produces four-channel // output for the late reverb. -static __inline ALvoid LateReverb(ALreverbState *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]; @@ -451,7 +451,7 @@ static __inline ALvoid LateReverb(ALreverbState *State, const ALfloat *RESTRICT // Given an input sample, this function mixes echo into the four-channel late // reverb. -static __inline ALvoid EAXEcho(ALreverbState *State, ALfloat in, ALfloat *RESTRICT late) +static __inline ALvoid EAXEcho(ALreverbState *State, ALfloat in, ALfloat *restrict late) { ALfloat out, feed; @@ -485,7 +485,7 @@ static __inline ALvoid EAXEcho(ALreverbState *State, ALfloat in, ALfloat *RESTRI // Perform the non-EAX reverb pass on a given input sample, resulting in // four-channel output. -static __inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *RESTRICT out) +static __inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *restrict out) { ALfloat feed, late[4], taps[4]; @@ -524,7 +524,7 @@ static __inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *RESTR // Perform the EAX reverb pass on a given input sample, resulting in four- // channel output. -static __inline ALvoid EAXVerbPass(ALreverbState *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]; @@ -563,9 +563,9 @@ static __inline ALvoid EAXVerbPass(ALreverbState *State, ALfloat in, ALfloat *RE // 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]) +static ALvoid ALreverbState_ProcessStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { - ALfloat (*RESTRICT out)[4] = State->ReverbSamples; + ALfloat (*restrict out)[4] = State->ReverbSamples; ALuint index, c; /* Process reverb for these samples. */ @@ -585,10 +585,10 @@ static ALvoid ALreverbState_ProcessStandard(ALreverbState *State, ALuint Samples // This processes the EAX reverb state, given the input samples and an output // buffer. -static ALvoid ALreverbState_ProcessEax(ALreverbState *State, 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]) { - ALfloat (*RESTRICT early)[4] = State->EarlySamples; - ALfloat (*RESTRICT late)[4] = State->ReverbSamples; + ALfloat (*restrict early)[4] = State->EarlySamples; + ALfloat (*restrict late)[4] = State->ReverbSamples; ALuint index, c; /* Process reverb for these samples. */ @@ -613,7 +613,7 @@ static ALvoid ALreverbState_ProcessEax(ALreverbState *State, ALuint SamplesToDo, } } -static ALvoid ALreverbState_Process(ALreverbState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) +static ALvoid ALreverbState_Process(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) { if(State->IsEax) ALreverbState_ProcessEax(State, SamplesToDo, SamplesIn, SamplesOut); diff --git a/Alc/mixer.c b/Alc/mixer.c index 84f48094..58e3a535 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -84,7 +84,7 @@ static void SilenceData(ALfloat *dst, ALuint samples) } -static void Filter2P(FILTER *filter, ALfloat *RESTRICT dst, const ALfloat *RESTRICT src, +static void Filter2P(FILTER *filter, ALfloat *restrict dst, const ALfloat *restrict src, ALuint numsamples) { ALuint i; diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c index d9c8ca25..94257504 100644 --- a/Alc/mixer_c.c +++ b/Alc/mixer_c.c @@ -16,7 +16,7 @@ static __inline ALfloat cubic32(const ALfloat *vals, ALuint frac) { return cubic(vals[-1], vals[0], vals[1], vals[2], frac * (1.0f/FRACTIONONE)); } void Resample_copy32_C(const ALfloat *data, ALuint frac, - ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize) + ALuint increment, ALfloat *restrict OutBuffer, ALuint BufferSize) { (void)frac; assert(increment==FRACTIONONE); @@ -25,7 +25,7 @@ void Resample_copy32_C(const ALfloat *data, ALuint frac, #define DECL_TEMPLATE(Sampler) \ void Resample_##Sampler##_C(const ALfloat *data, ALuint frac, \ - ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize) \ + ALuint increment, ALfloat *restrict OutBuffer, ALuint BufferSize) \ { \ ALuint pos = 0; \ ALuint i; \ @@ -47,10 +47,10 @@ DECL_TEMPLATE(cubic32) #undef DECL_TEMPLATE -static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, - ALfloat (*RESTRICT Coeffs)[2], - const ALfloat (*RESTRICT CoeffStep)[2], + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2], ALfloat left, ALfloat right) { ALuint c; @@ -64,9 +64,9 @@ static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2 } } -static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, - ALfloat (*RESTRICT Coeffs)[2], + ALfloat (*restrict Coeffs)[2], ALfloat left, ALfloat right) { ALuint c; @@ -83,12 +83,12 @@ static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], #undef SUFFIX -void MixDirect_C(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, +void MixDirect_C(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) { - ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer; - ALfloat *RESTRICT ClickRemoval = params->ClickRemoval; - ALfloat *RESTRICT PendingClicks = params->PendingClicks; + ALfloat (*restrict DryBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; ALfloat DrySend; ALuint pos; ALuint c; @@ -109,13 +109,13 @@ void MixDirect_C(const DirectParams *params, const ALfloat *RESTRICT data, ALuin } -void MixSend_C(const SendParams *params, const ALfloat *RESTRICT data, +void MixSend_C(const SendParams *params, const ALfloat *restrict data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) { ALeffectslot *Slot = params->Slot; - ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer; - ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval; - ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks; + ALfloat (*restrict WetBuffer)[BUFFERSIZE] = Slot->WetBuffer; + ALfloat *restrict WetClickRemoval = Slot->ClickRemoval; + ALfloat *restrict WetPendingClicks = Slot->PendingClicks; ALfloat WetSend = params->Gain; ALuint pos; diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h index 6d3390c8..5e43af15 100644 --- a/Alc/mixer_defs.h +++ b/Alc/mixer_defs.h @@ -9,23 +9,23 @@ struct DirectParams; struct SendParams; /* C resamplers */ -void Resample_copy32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen); -void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen); -void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen); -void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen); +void Resample_copy32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); +void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); +void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); +void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); /* C mixers */ -void MixDirect_Hrtf_C(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint); -void MixDirect_C(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint); -void MixSend_C(const struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint); +void MixDirect_Hrtf_C(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixDirect_C(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixSend_C(const struct SendParams*,const ALfloat*restrict,ALuint,ALuint,ALuint); /* SSE mixers */ -void MixDirect_Hrtf_SSE(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint); -void MixDirect_SSE(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint); -void MixSend_SSE(const struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint); +void MixDirect_Hrtf_SSE(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixDirect_SSE(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); +void MixSend_SSE(const struct SendParams*,const ALfloat*restrict,ALuint,ALuint,ALuint); /* Neon mixers */ -void MixDirect_Hrtf_Neon(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint); +void MixDirect_Hrtf_Neon(const struct DirectParams*,const ALfloat*restrict,ALuint,ALuint,ALuint,ALuint); #endif /* MIXER_DEFS_H */ diff --git a/Alc/mixer_inc.c b/Alc/mixer_inc.c index 97266d40..08387220 100644 --- a/Alc/mixer_inc.c +++ b/Alc/mixer_inc.c @@ -18,30 +18,30 @@ #define MixDirect_Hrtf MERGE2(MixDirect_Hrtf_,SUFFIX) -static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint irSize, - ALfloat (*RESTRICT Coeffs)[2], - const ALfloat (*RESTRICT CoeffStep)[2], + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2], ALfloat left, ALfloat right); -static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint irSize, - ALfloat (*RESTRICT Coeffs)[2], + ALfloat (*restrict Coeffs)[2], ALfloat left, ALfloat right); -void MixDirect_Hrtf(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, +void MixDirect_Hrtf(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) { - ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer; - ALfloat *RESTRICT ClickRemoval = params->ClickRemoval; - ALfloat *RESTRICT PendingClicks = params->PendingClicks; + ALfloat (*restrict DryBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; const ALuint IrSize = params->Hrtf.Params.IrSize; - const ALint *RESTRICT DelayStep = params->Hrtf.Params.DelayStep; - const ALfloat (*RESTRICT CoeffStep)[2] = params->Hrtf.Params.CoeffStep; - const ALfloat (*RESTRICT TargetCoeffs)[2] = params->Hrtf.Params.Coeffs[srcchan]; - const ALuint *RESTRICT TargetDelay = params->Hrtf.Params.Delay[srcchan]; - ALfloat *RESTRICT History = params->Hrtf.State->History[srcchan]; - ALfloat (*RESTRICT Values)[2] = params->Hrtf.State->Values[srcchan]; + const ALint *restrict DelayStep = params->Hrtf.Params.DelayStep; + const ALfloat (*restrict CoeffStep)[2] = params->Hrtf.Params.CoeffStep; + const ALfloat (*restrict TargetCoeffs)[2] = params->Hrtf.Params.Coeffs[srcchan]; + const ALuint *restrict TargetDelay = params->Hrtf.Params.Delay[srcchan]; + ALfloat *restrict History = params->Hrtf.State->History[srcchan]; + ALfloat (*restrict Values)[2] = params->Hrtf.State->Values[srcchan]; ALint Counter = maxu(params->Hrtf.State->Counter, OutPos) - OutPos; ALuint Offset = params->Hrtf.State->Offset + OutPos; ALIGN(16) ALfloat Coeffs[HRIR_LENGTH][2]; diff --git a/Alc/mixer_neon.c b/Alc/mixer_neon.c index 23dc792c..3006194c 100644 --- a/Alc/mixer_neon.c +++ b/Alc/mixer_neon.c @@ -10,10 +10,10 @@ #include "alu.h" -static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, - ALfloat (*RESTRICT Coeffs)[2], - const ALfloat (*RESTRICT CoeffStep)[2], + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2], ALfloat left, ALfloat right) { ALuint c; @@ -27,9 +27,9 @@ static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2 } } -static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, - ALfloat (*RESTRICT Coeffs)[2], + ALfloat (*restrict Coeffs)[2], ALfloat left, ALfloat right) { ALuint c; diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c index 3c45fd21..2cb3db98 100644 --- a/Alc/mixer_sse.c +++ b/Alc/mixer_sse.c @@ -14,10 +14,10 @@ #include "mixer_defs.h" -static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, - ALfloat (*RESTRICT Coeffs)[2], - const ALfloat (*RESTRICT CoeffStep)[2], + ALfloat (*restrict Coeffs)[2], + const ALfloat (*restrict CoeffStep)[2], ALfloat left, ALfloat right) { const __m128 lrlr = { left, right, left, right }; @@ -76,9 +76,9 @@ static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2 } } -static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], +static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, - ALfloat (*RESTRICT Coeffs)[2], + ALfloat (*restrict Coeffs)[2], ALfloat left, ALfloat right) { const __m128 lrlr = { left, right, left, right }; @@ -133,12 +133,12 @@ static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], #undef SUFFIX -void MixDirect_SSE(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan, +void MixDirect_SSE(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) { - ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer; - ALfloat *RESTRICT ClickRemoval = params->ClickRemoval; - ALfloat *RESTRICT PendingClicks = params->PendingClicks; + ALfloat (*restrict DryBuffer)[BUFFERSIZE] = params->OutBuffer; + ALfloat *restrict ClickRemoval = params->ClickRemoval; + ALfloat *restrict PendingClicks = params->PendingClicks; ALfloat DrySend; ALuint pos; ALuint c; @@ -171,13 +171,13 @@ void MixDirect_SSE(const DirectParams *params, const ALfloat *RESTRICT data, ALu } -void MixSend_SSE(const SendParams *params, const ALfloat *RESTRICT data, +void MixSend_SSE(const SendParams *params, const ALfloat *restrict data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) { ALeffectslot *Slot = params->Slot; - ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer; - ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval; - ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks; + ALfloat (*restrict WetBuffer)[BUFFERSIZE] = Slot->WetBuffer; + ALfloat *restrict WetClickRemoval = Slot->ClickRemoval; + ALfloat *restrict WetPendingClicks = Slot->PendingClicks; const ALfloat WetGain = params->Gain; __m128 gain; ALuint pos; diff --git a/CMakeLists.txt b/CMakeLists.txt index b86de3d3..8c85be15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,6 @@ SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}") SET(EXPORT_DECL "") SET(ALIGN_DECL "") -SET(RESTRICT_DECL "") CHECK_TYPE_SIZE("long" SIZEOF_LONG) @@ -104,13 +103,13 @@ CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG) CHECK_C_SOURCE_COMPILES("int *restrict foo; int main() {return 0;}" HAVE_RESTRICT) -IF(HAVE_RESTRICT) - SET(RESTRICT_DECL "restrict") -ELSE() +IF(NOT HAVE_RESTRICT) CHECK_C_SOURCE_COMPILES("int *__restrict foo; int main() {return 0;}" HAVE___RESTRICT) IF(HAVE___RESTRICT) - SET(RESTRICT_DECL "__restrict") + ADD_DEFINITIONS(-Drestrict=__restrict) + ELSE() + ADD_DEFINITIONS(-Drestrict=) ENDIF() ENDIF() diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 537f0a8a..a81c1326 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -17,7 +17,7 @@ struct ALeffectStateVtable { ALvoid (*const Destruct)(ALeffectState *state); ALboolean (*const DeviceUpdate)(ALeffectState *state, ALCdevice *device); ALvoid (*const Update)(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot); - ALvoid (*const Process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]); + ALvoid (*const Process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE]); ALeffectStateFactory *(*const getCreator)(void); }; @@ -38,7 +38,7 @@ static ALboolean T##_ALeffectState_DeviceUpdate(ALeffectState *state, ALCdevice { return T##_DeviceUpdate(STATIC_UPCAST(T, ALeffectState, state), device); } \ static ALvoid T##_ALeffectState_Update(ALeffectState *state, ALCdevice *device, const ALeffectslot *slot) \ { T##_Update(STATIC_UPCAST(T, ALeffectState, state), device, slot); } \ -static ALvoid T##_ALeffectState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) \ +static ALvoid T##_ALeffectState_Process(ALeffectState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE]) \ { T##_Process(STATIC_UPCAST(T, ALeffectState, state), samplesToDo, samplesIn, samplesOut); } \ static ALeffectStateFactory* T##_ALeffectState_getCreator(void) \ { return T##_getCreator(); } \ diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 01d3ca29..f323b0d0 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -31,14 +31,14 @@ struct DirectParams; struct SendParams; typedef void (*ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment, - ALfloat *RESTRICT dst, ALuint dstlen); + ALfloat *restrict dst, ALuint dstlen); typedef ALvoid (*DryMixerFunc)(const struct DirectParams *params, - const ALfloat *RESTRICT data, ALuint srcchan, + const ALfloat *restrict data, ALuint srcchan, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize); typedef ALvoid (*WetMixerFunc)(const struct SendParams *params, - const ALfloat *RESTRICT data, + const ALfloat *restrict data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 5d0d7a18..ed82b00b 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -425,7 +425,7 @@ static ALvoid ALnoneState_Update(ALnoneState *state, ALCdevice *device, const AL (void)device; (void)slot; } -static ALvoid ALnoneState_Process(ALnoneState *state, ALuint samplesToDo, const ALfloat *RESTRICT samplesIn, ALfloat (*RESTRICT samplesOut)[BUFFERSIZE]) +static ALvoid ALnoneState_Process(ALnoneState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE]) { (void)state; (void)samplesToDo; diff --git a/config.h.in b/config.h.in index 6f45fa84..9b6092fc 100644 --- a/config.h.in +++ b/config.h.in @@ -11,9 +11,6 @@ #define align(x) aligned(x) #endif -/* Define to the appropriate 'restrict' keyword */ -#define RESTRICT ${RESTRICT_DECL} - /* Define if we have the C11 aligned_alloc function */ #cmakedefine HAVE_ALIGNED_ALLOC -- cgit v1.2.3 From 357cf72ab33ef1807da8ea6ce4633fd8e2a89553 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 23 May 2013 21:33:16 -0700 Subject: Move remaining effects to the effects subdir --- Alc/alcChorus.c | 411 -------------------------------------- Alc/alcDedicated.c | 183 ----------------- Alc/alcDistortion.c | 402 -------------------------------------- Alc/alcEcho.c | 324 ------------------------------ Alc/alcEqualizer.c | 499 ----------------------------------------------- Alc/alcFlanger.c | 411 -------------------------------------- Alc/alcModulator.c | 343 -------------------------------- Alc/effects/chorus.c | 411 ++++++++++++++++++++++++++++++++++++++ Alc/effects/dedicated.c | 183 +++++++++++++++++ Alc/effects/distortion.c | 402 ++++++++++++++++++++++++++++++++++++++ Alc/effects/echo.c | 324 ++++++++++++++++++++++++++++++ Alc/effects/equalizer.c | 499 +++++++++++++++++++++++++++++++++++++++++++++++ Alc/effects/flanger.c | 411 ++++++++++++++++++++++++++++++++++++++ Alc/effects/modulator.c | 343 ++++++++++++++++++++++++++++++++ CMakeLists.txt | 20 +- 15 files changed, 2583 insertions(+), 2583 deletions(-) delete mode 100644 Alc/alcChorus.c delete mode 100644 Alc/alcDedicated.c delete mode 100644 Alc/alcDistortion.c delete mode 100644 Alc/alcEcho.c delete mode 100644 Alc/alcEqualizer.c delete mode 100644 Alc/alcFlanger.c delete mode 100644 Alc/alcModulator.c create mode 100644 Alc/effects/chorus.c create mode 100644 Alc/effects/dedicated.c create mode 100644 Alc/effects/distortion.c create mode 100644 Alc/effects/echo.c create mode 100644 Alc/effects/equalizer.c create mode 100644 Alc/effects/flanger.c create mode 100644 Alc/effects/modulator.c (limited to 'Alc/alcModulator.c') diff --git a/Alc/alcChorus.c b/Alc/alcChorus.c deleted file mode 100644 index e5a20b5d..00000000 --- a/Alc/alcChorus.c +++ /dev/null @@ -1,411 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2013 by Mike Gorchak - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALchorusStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALchorusStateFactory; - -static ALchorusStateFactory ChorusFactory; - - -typedef struct ALchorusState { - DERIVE_FROM_TYPE(ALeffectState); - - ALfloat *SampleBufferLeft; - ALfloat *SampleBufferRight; - ALuint BufferLength; - ALint offset; - ALfloat lfo_coeff; - ALint lfo_disp; - - /* Gains for left and right sides */ - ALfloat Gain[2][MaxChannels]; - - /* effect parameters */ - ALint waveform; - ALint delay; - ALfloat depth; - ALfloat feedback; -} ALchorusState; - -static ALvoid ALchorusState_Destruct(ALchorusState *state) -{ - free(state->SampleBufferLeft); - state->SampleBufferLeft = NULL; - - free(state->SampleBufferRight); - state->SampleBufferRight = NULL; -} - -static ALboolean ALchorusState_DeviceUpdate(ALchorusState *state, ALCdevice *Device) -{ - ALuint maxlen; - ALuint it; - - maxlen = fastf2u(AL_CHORUS_MAX_DELAY * 3.0f * Device->Frequency) + 1; - maxlen = NextPowerOf2(maxlen); - - if(maxlen != state->BufferLength) - { - void *temp; - - temp = realloc(state->SampleBufferLeft, maxlen * sizeof(ALfloat)); - if(!temp) return AL_FALSE; - state->SampleBufferLeft = temp; - - temp = realloc(state->SampleBufferRight, maxlen * sizeof(ALfloat)); - if(!temp) return AL_FALSE; - state->SampleBufferRight = temp; - - state->BufferLength = maxlen; - } - - for(it = 0;it < state->BufferLength;it++) - { - state->SampleBufferLeft[it] = 0.0f; - state->SampleBufferRight[it] = 0.0f; - } - - return AL_TRUE; -} - -static ALvoid ALchorusState_Update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot) -{ - ALfloat frequency = (ALfloat)Device->Frequency; - ALfloat rate; - ALint phase; - ALuint it; - - for (it = 0; it < MaxChannels; it++) - { - state->Gain[0][it] = 0.0f; - state->Gain[1][it] = 0.0f; - } - - state->waveform = Slot->effect.Chorus.Waveform; - state->depth = Slot->effect.Chorus.Depth; - state->feedback = Slot->effect.Chorus.Feedback; - state->delay = fastf2i(Slot->effect.Chorus.Delay * frequency); - - /* Gains for left and right sides */ - ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); - ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); - - phase = Slot->effect.Chorus.Phase; - rate = Slot->effect.Chorus.Rate; - - /* Calculate LFO coefficient */ - switch (state->waveform) - { - case AL_CHORUS_WAVEFORM_TRIANGLE: - if(rate == 0.0f) - state->lfo_coeff = 0.0f; - else - state->lfo_coeff = 1.0f / (frequency / rate); - break; - case AL_CHORUS_WAVEFORM_SINUSOID: - if(rate == 0.0f) - state->lfo_coeff = 0.0f; - else - state->lfo_coeff = F_PI*2.0f / (frequency / rate); - break; - } - - /* Calculate lfo phase displacement */ - if(phase == 0 || rate == 0.0f) - state->lfo_disp = 0; - else - state->lfo_disp = fastf2i(frequency / rate / (360.0f/phase)); -} - -static __inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) -{ - ALfloat lfo_value; - - lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff*offset*4.0f, 4.0f)); - lfo_value *= state->depth * state->delay; - *delay_left = fastf2i(lfo_value) + state->delay; - - lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff * - (offset+state->lfo_disp)*4.0f, - 4.0f)); - lfo_value *= state->depth * state->delay; - *delay_right = fastf2i(lfo_value) + state->delay; -} - -static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) -{ - ALfloat lfo_value; - - lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff*offset, 2.0f*F_PI)); - lfo_value *= state->depth * state->delay; - *delay_left = fastf2i(lfo_value) + state->delay; - - lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff*(offset+state->lfo_disp), - 2.0f*F_PI)); - lfo_value *= state->depth * state->delay; - *delay_right = fastf2i(lfo_value) + state->delay; -} - -#define DECL_TEMPLATE(func) \ -static void Process##func(ALchorusState *state, ALuint SamplesToDo, \ - const ALfloat *restrict SamplesIn, \ - ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ -{ \ - const ALint mask = state->BufferLength-1; \ - ALint offset = state->offset; \ - ALuint it, kt; \ - ALuint base; \ - \ - for(base = 0;base < SamplesToDo;) \ - { \ - ALfloat temps[64][2]; \ - ALuint td = minu(SamplesToDo-base, 64); \ - \ - for(it = 0;it < td;it++,offset++) \ - { \ - ALint delay_left, delay_right; \ - (func)(&delay_left, &delay_right, offset, state); \ - \ - temps[it][0] = state->SampleBufferLeft[(offset-delay_left)&mask]; \ - state->SampleBufferLeft[offset&mask] = (temps[it][0] + \ - SamplesIn[it+base]) * \ - state->feedback; \ - \ - temps[it][1] = state->SampleBufferRight[(offset-delay_right)&mask];\ - state->SampleBufferRight[offset&mask] = (temps[it][1] + \ - SamplesIn[it+base]) * \ - state->feedback; \ - } \ - \ - for(kt = 0;kt < MaxChannels;kt++) \ - { \ - ALfloat gain = state->Gain[0][kt]; \ - if(gain > 0.00001f) \ - { \ - for(it = 0;it < td;it++) \ - SamplesOut[kt][it+base] += temps[it][0] * gain; \ - } \ - \ - gain = state->Gain[1][kt]; \ - if(gain > 0.00001f) \ - { \ - for(it = 0;it < td;it++) \ - SamplesOut[kt][it+base] += temps[it][1] * gain; \ - } \ - } \ - \ - base += td; \ - } \ - \ - state->offset = offset; \ -} - -DECL_TEMPLATE(Triangle) -DECL_TEMPLATE(Sinusoid) - -#undef DECL_TEMPLATE - -static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) - ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); - else if(state->waveform == AL_CHORUS_WAVEFORM_SINUSOID) - ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); -} - -static ALeffectStateFactory *ALchorusState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); - - -static ALeffectState *ALchorusStateFactory_create(void) -{ - ALchorusState *state; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALchorusState, ALeffectState, state); - - state->BufferLength = 0; - state->SampleBufferLeft = NULL; - state->SampleBufferRight = NULL; - state->offset = 0; - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALchorusStateFactory_destroy(ALeffectState *effect) -{ - ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); - ALchorusState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALchorusStateFactory); - - -static void init_chorus_factory(void) -{ - SET_VTABLE2(ALchorusStateFactory, ALeffectStateFactory, &ChorusFactory); -} - -ALeffectStateFactory *ALchorusStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_chorus_factory); - return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); -} - - -void chorus_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_CHORUS_WAVEFORM: - if(val >= AL_CHORUS_MIN_WAVEFORM && val <= AL_CHORUS_MAX_WAVEFORM) - effect->Chorus.Waveform = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_CHORUS_PHASE: - if(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE) - effect->Chorus.Phase = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void chorus_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - chorus_SetParami(effect, context, param, vals[0]); -} -void chorus_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_CHORUS_RATE: - if(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE) - effect->Chorus.Rate = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_CHORUS_DEPTH: - if(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH) - effect->Chorus.Depth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_CHORUS_FEEDBACK: - if(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK) - effect->Chorus.Feedback = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_CHORUS_DELAY: - if(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY) - effect->Chorus.Delay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void chorus_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - chorus_SetParamf(effect, context, param, vals[0]); -} - -void chorus_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_CHORUS_WAVEFORM: - *val = effect->Chorus.Waveform; - break; - - case AL_CHORUS_PHASE: - *val = effect->Chorus.Phase; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void chorus_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - chorus_GetParami(effect, context, param, vals); -} -void chorus_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_CHORUS_RATE: - *val = effect->Chorus.Rate; - break; - - case AL_CHORUS_DEPTH: - *val = effect->Chorus.Depth; - break; - - case AL_CHORUS_FEEDBACK: - *val = effect->Chorus.Feedback; - break; - - case AL_CHORUS_DELAY: - *val = effect->Chorus.Delay; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void chorus_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - chorus_GetParamf(effect, context, param, vals); -} diff --git a/Alc/alcDedicated.c b/Alc/alcDedicated.c deleted file mode 100644 index bd266b0e..00000000 --- a/Alc/alcDedicated.c +++ /dev/null @@ -1,183 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2011 by Chris Robinson. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALdedicatedStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALdedicatedStateFactory; - -static ALdedicatedStateFactory DedicatedFactory; - - -typedef struct ALdedicatedState { - DERIVE_FROM_TYPE(ALeffectState); - - ALfloat gains[MaxChannels]; -} ALdedicatedState; - - -static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state) -{ - (void)state; -} - -static ALboolean ALdedicatedState_DeviceUpdate(ALdedicatedState *state, ALCdevice *Device) -{ - return AL_TRUE; - (void)state; - (void)Device; -} - -static ALvoid ALdedicatedState_Update(ALdedicatedState *state, ALCdevice *device, const ALeffectslot *Slot) -{ - ALfloat Gain; - ALsizei s; - - Gain = Slot->Gain * Slot->effect.Dedicated.Gain; - for(s = 0;s < MaxChannels;s++) - state->gains[s] = 0.0f; - - if(Slot->effect.type == AL_EFFECT_DEDICATED_DIALOGUE) - ComputeAngleGains(device, atan2f(0.0f, 1.0f), 0.0f, Gain, state->gains); - else if(Slot->effect.type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) - state->gains[LFE] = Gain; -} - -static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - const ALfloat *gains = state->gains; - ALuint i, c; - - for(c = 0;c < MaxChannels;c++) - { - if(!(gains[c] > 0.00001f)) - continue; - - for(i = 0;i < SamplesToDo;i++) - SamplesOut[c][i] = SamplesIn[i] * gains[c]; - } -} - -static ALeffectStateFactory *ALdedicatedState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); - - -ALeffectState *ALdedicatedStateFactory_create(void) -{ - ALdedicatedState *state; - ALsizei s; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALdedicatedState, ALeffectState, state); - - for(s = 0;s < MaxChannels;s++) - state->gains[s] = 0.0f; - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALdedicatedStateFactory_destroy(ALeffectState *effect) -{ - ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); - ALdedicatedState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdedicatedStateFactory); - - -static void init_dedicated_factory(void) -{ - SET_VTABLE2(ALdedicatedStateFactory, ALeffectStateFactory, &DedicatedFactory); -} - -ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_dedicated_factory); - return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); -} - - -void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -void ded_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ded_SetParami(effect, context, param, vals[0]); -} -void ded_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_DEDICATED_GAIN: - if(val >= 0.0f && isfinite(val)) - effect->Dedicated.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void ded_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ded_SetParamf(effect, context, param, vals[0]); -} - -void ded_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -void ded_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ded_GetParami(effect, context, param, vals); -} -void ded_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_DEDICATED_GAIN: - *val = effect->Dedicated.Gain; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void ded_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ded_GetParamf(effect, context, param, vals); -} diff --git a/Alc/alcDistortion.c b/Alc/alcDistortion.c deleted file mode 100644 index 7828377c..00000000 --- a/Alc/alcDistortion.c +++ /dev/null @@ -1,402 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2013 by Mike Gorchak - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALdistortionStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALdistortionStateFactory; - -static ALdistortionStateFactory DistortionFactory; - - -/* Filters implementation is based on the "Cookbook formulae for audio * - * EQ biquad filter coefficients" by Robert Bristow-Johnson * - * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ - -typedef enum ALEQFilterType { - LOWPASS, - BANDPASS, -} ALEQFilterType; - -typedef struct ALEQFilter { - ALEQFilterType type; - ALfloat x[2]; /* History of two last input samples */ - ALfloat y[2]; /* History of two last output samples */ - ALfloat a[3]; /* Transfer function coefficients "a" */ - ALfloat b[3]; /* Transfer function coefficients "b" */ -} ALEQFilter; - -typedef struct ALdistortionState { - DERIVE_FROM_TYPE(ALeffectState); - - /* Effect gains for each channel */ - ALfloat Gain[MaxChannels]; - - /* Effect parameters */ - ALEQFilter bandpass; - ALEQFilter lowpass; - ALfloat attenuation; - ALfloat edge_coeff; -} ALdistortionState; - -static ALvoid ALdistortionState_Destruct(ALdistortionState *state) -{ - (void)state; -} - -static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *device) -{ - return AL_TRUE; - (void)state; - (void)device; -} - -static ALvoid ALdistortionState_Update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot) -{ - ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; - ALfloat frequency = (ALfloat)Device->Frequency; - ALuint it; - ALfloat w0; - ALfloat alpha; - ALfloat bandwidth; - ALfloat cutoff; - ALfloat edge; - - for(it = 0;it < MaxChannels;it++) - state->Gain[it] = 0.0f; - for(it = 0;it < Device->NumChan;it++) - { - enum Channel chan = Device->Speaker2Chan[it]; - state->Gain[chan] = gain; - } - - /* Store distorted signal attenuation settings */ - state->attenuation = Slot->effect.Distortion.Gain; - - /* Store waveshaper edge settings */ - edge = sinf(Slot->effect.Distortion.Edge * (F_PI/2.0f)); - state->edge_coeff = 2.0f * edge / (1.0f-edge); - - /* Lowpass filter */ - cutoff = Slot->effect.Distortion.LowpassCutoff; - /* Bandwidth value is constant in octaves */ - bandwidth = (cutoff / 2.0f) / (cutoff * 0.67f); - w0 = 2.0f*F_PI * cutoff / (frequency*4.0f); - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); - state->lowpass.b[0] = (1.0f - cosf(w0)) / 2.0f; - state->lowpass.b[1] = 1.0f - cosf(w0); - state->lowpass.b[2] = (1.0f - cosf(w0)) / 2.0f; - state->lowpass.a[0] = 1.0f + alpha; - state->lowpass.a[1] = -2.0f * cosf(w0); - state->lowpass.a[2] = 1.0f - alpha; - - /* Bandpass filter */ - cutoff = Slot->effect.Distortion.EQCenter; - /* Convert bandwidth in Hz to octaves */ - bandwidth = Slot->effect.Distortion.EQBandwidth / (cutoff * 0.67f); - w0 = 2.0f*F_PI * cutoff / (frequency*4.0f); - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); - state->bandpass.b[0] = alpha; - state->bandpass.b[1] = 0; - state->bandpass.b[2] = -alpha; - state->bandpass.a[0] = 1.0f + alpha; - state->bandpass.a[1] = -2.0f * cosf(w0); - state->bandpass.a[2] = 1.0f - alpha; -} - -static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - const ALfloat fc = state->edge_coeff; - float oversample_buffer[64][4]; - ALfloat tempsmp; - ALuint base; - ALuint it; - ALuint ot; - ALuint kt; - - for(base = 0;base < SamplesToDo;) - { - ALfloat temps[64]; - ALuint td = minu(SamplesToDo-base, 64); - - /* Perform 4x oversampling to avoid aliasing. */ - /* Oversampling greatly improves distortion */ - /* quality and allows to implement lowpass and */ - /* bandpass filters using high frequencies, at */ - /* which classic IIR filters became unstable. */ - - /* Fill oversample buffer using zero stuffing */ - for(it = 0;it < td;it++) - { - oversample_buffer[it][0] = SamplesIn[it+base]; - oversample_buffer[it][1] = 0.0f; - oversample_buffer[it][2] = 0.0f; - oversample_buffer[it][3] = 0.0f; - } - - /* First step, do lowpass filtering of original signal, */ - /* additionally perform buffer interpolation and lowpass */ - /* cutoff for oversampling (which is fortunately first */ - /* step of distortion). So combine three operations into */ - /* the one. */ - for(it = 0;it < td;it++) - { - for(ot = 0;ot < 4;ot++) - { - tempsmp = state->lowpass.b[0] / state->lowpass.a[0] * oversample_buffer[it][ot] + - state->lowpass.b[1] / state->lowpass.a[0] * state->lowpass.x[0] + - state->lowpass.b[2] / state->lowpass.a[0] * state->lowpass.x[1] - - state->lowpass.a[1] / state->lowpass.a[0] * state->lowpass.y[0] - - state->lowpass.a[2] / state->lowpass.a[0] * state->lowpass.y[1]; - - state->lowpass.x[1] = state->lowpass.x[0]; - state->lowpass.x[0] = oversample_buffer[it][ot]; - state->lowpass.y[1] = state->lowpass.y[0]; - state->lowpass.y[0] = tempsmp; - /* Restore signal power by multiplying sample by amount of oversampling */ - oversample_buffer[it][ot] = tempsmp * 4.0f; - } - } - - for(it = 0;it < td;it++) - { - /* Second step, do distortion using waveshaper function */ - /* to emulate signal processing during tube overdriving. */ - /* Three steps of waveshaping are intended to modify */ - /* waveform without boost/clipping/attenuation process. */ - for(ot = 0;ot < 4;ot++) - { - ALfloat smp = oversample_buffer[it][ot]; - - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)) * -1.0f; - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); - - /* Third step, do bandpass filtering of distorted signal */ - tempsmp = state->bandpass.b[0] / state->bandpass.a[0] * smp + - state->bandpass.b[1] / state->bandpass.a[0] * state->bandpass.x[0] + - state->bandpass.b[2] / state->bandpass.a[0] * state->bandpass.x[1] - - state->bandpass.a[1] / state->bandpass.a[0] * state->bandpass.y[0] - - state->bandpass.a[2] / state->bandpass.a[0] * state->bandpass.y[1]; - - state->bandpass.x[1] = state->bandpass.x[0]; - state->bandpass.x[0] = smp; - state->bandpass.y[1] = state->bandpass.y[0]; - state->bandpass.y[0] = tempsmp; - - oversample_buffer[it][ot] = tempsmp; - } - - /* Fourth step, final, do attenuation and perform decimation, */ - /* store only one sample out of 4. */ - temps[it] = oversample_buffer[it][0] * state->attenuation; - } - - for(kt = 0;kt < MaxChannels;kt++) - { - ALfloat gain = state->Gain[kt]; - if(!(gain > 0.00001f)) - continue; - - for(it = 0;it < td;it++) - SamplesOut[kt][base+it] += gain * temps[it]; - } - - base += td; - } -} - -static ALeffectStateFactory *ALdistortionState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); - - -static ALeffectState *ALdistortionStateFactory_create(void) -{ - ALdistortionState *state; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALdistortionState, ALeffectState, state); - - state->bandpass.type = BANDPASS; - state->lowpass.type = LOWPASS; - - /* Initialize sample history only on filter creation to avoid */ - /* sound clicks if filter settings were changed in runtime. */ - state->bandpass.x[0] = 0.0f; - state->bandpass.x[1] = 0.0f; - state->lowpass.y[0] = 0.0f; - state->lowpass.y[1] = 0.0f; - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALdistortionStateFactory_destroy(ALeffectState *effect) -{ - ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); - ALdistortionState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdistortionStateFactory); - - -static void init_distortion_factory(void) -{ - SET_VTABLE2(ALdistortionStateFactory, ALeffectStateFactory, &DistortionFactory); -} - -ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_distortion_factory); - return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); -} - - -void distortion_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - effect=effect; - val=val; - - switch(param) - { - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void distortion_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - distortion_SetParami(effect, context, param, vals[0]); -} -void distortion_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_DISTORTION_EDGE: - if(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE) - effect->Distortion.Edge = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_DISTORTION_GAIN: - if(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN) - effect->Distortion.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_DISTORTION_LOWPASS_CUTOFF: - if(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF) - effect->Distortion.LowpassCutoff = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_DISTORTION_EQCENTER: - if(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER) - effect->Distortion.EQCenter = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_DISTORTION_EQBANDWIDTH: - if(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH) - effect->Distortion.EQBandwidth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void distortion_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - distortion_SetParamf(effect, context, param, vals[0]); -} - -void distortion_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - effect=effect; - val=val; - - switch(param) - { - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void distortion_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - distortion_GetParami(effect, context, param, vals); -} -void distortion_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_DISTORTION_EDGE: - *val = effect->Distortion.Edge; - break; - - case AL_DISTORTION_GAIN: - *val = effect->Distortion.Gain; - break; - - case AL_DISTORTION_LOWPASS_CUTOFF: - *val = effect->Distortion.LowpassCutoff; - break; - - case AL_DISTORTION_EQCENTER: - *val = effect->Distortion.EQCenter; - break; - - case AL_DISTORTION_EQBANDWIDTH: - *val = effect->Distortion.EQBandwidth; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void distortion_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - distortion_GetParamf(effect, context, param, vals); -} diff --git a/Alc/alcEcho.c b/Alc/alcEcho.c deleted file mode 100644 index d5915295..00000000 --- a/Alc/alcEcho.c +++ /dev/null @@ -1,324 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2009 by Chris Robinson. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALechoStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALechoStateFactory; - -static ALechoStateFactory EchoFactory; - - -typedef struct ALechoState { - DERIVE_FROM_TYPE(ALeffectState); - - ALfloat *SampleBuffer; - ALuint BufferLength; - - // The echo is two tap. The delay is the number of samples from before the - // current offset - struct { - ALuint delay; - } Tap[2]; - ALuint Offset; - /* The panning gains for the two taps */ - ALfloat Gain[2][MaxChannels]; - - ALfloat FeedGain; - - FILTER iirFilter; -} ALechoState; - -static ALvoid ALechoState_Destruct(ALechoState *state) -{ - free(state->SampleBuffer); - state->SampleBuffer = NULL; -} - -static ALboolean ALechoState_DeviceUpdate(ALechoState *state, ALCdevice *Device) -{ - ALuint maxlen, i; - - // Use the next power of 2 for the buffer length, so the tap offsets can be - // wrapped using a mask instead of a modulo - maxlen = fastf2u(AL_ECHO_MAX_DELAY * Device->Frequency) + 1; - maxlen += fastf2u(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1; - maxlen = NextPowerOf2(maxlen); - - if(maxlen != state->BufferLength) - { - void *temp; - - temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat)); - if(!temp) - return AL_FALSE; - state->SampleBuffer = temp; - state->BufferLength = maxlen; - } - for(i = 0;i < state->BufferLength;i++) - state->SampleBuffer[i] = 0.0f; - - return AL_TRUE; -} - -static ALvoid ALechoState_Update(ALechoState *state, ALCdevice *Device, const ALeffectslot *Slot) -{ - ALuint frequency = Device->Frequency; - ALfloat lrpan, cw, g, gain; - ALfloat dirGain; - ALuint i; - - state->Tap[0].delay = fastf2u(Slot->effect.Echo.Delay * frequency) + 1; - state->Tap[1].delay = fastf2u(Slot->effect.Echo.LRDelay * frequency); - state->Tap[1].delay += state->Tap[0].delay; - - lrpan = Slot->effect.Echo.Spread; - - state->FeedGain = Slot->effect.Echo.Feedback; - - cw = cosf(F_PI*2.0f * LOWPASSFREQREF / frequency); - g = 1.0f - Slot->effect.Echo.Damping; - state->iirFilter.coeff = lpCoeffCalc(g, cw); - - gain = Slot->Gain; - for(i = 0;i < MaxChannels;i++) - { - state->Gain[0][i] = 0.0f; - state->Gain[1][i] = 0.0f; - } - - dirGain = fabsf(lrpan); - - /* First tap panning */ - ComputeAngleGains(Device, atan2f(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]); - - /* Second tap panning */ - ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); -} - -static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - const ALuint mask = state->BufferLength-1; - const ALuint tap1 = state->Tap[0].delay; - const ALuint tap2 = state->Tap[1].delay; - ALuint offset = state->Offset; - ALfloat smp; - ALuint base; - ALuint i, k; - - for(base = 0;base < SamplesToDo;) - { - ALfloat temps[64][2]; - ALuint td = minu(SamplesToDo-base, 64); - - for(i = 0;i < td;i++) - { - /* First tap */ - temps[i][0] = state->SampleBuffer[(offset-tap1) & mask]; - /* Second tap */ - temps[i][1] = state->SampleBuffer[(offset-tap2) & mask]; - - // Apply damping and feedback gain to the second tap, and mix in the - // new sample - smp = lpFilter2P(&state->iirFilter, temps[i][1]+SamplesIn[i]); - state->SampleBuffer[offset&mask] = smp * state->FeedGain; - } - - for(k = 0;k < MaxChannels;k++) - { - ALfloat gain = state->Gain[0][k]; - if(gain > 0.00001f) - { - for(i = 0;i < td;i++) - SamplesOut[k][i+base] += temps[i][0] * gain; - } - - gain = state->Gain[1][k]; - if(gain > 0.00001f) - { - for(i = 0;i < td;i++) - SamplesOut[k][i+base] += temps[i][1] * gain; - } - } - - base += td; - } - - state->Offset = offset; -} - -static ALeffectStateFactory *ALechoState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &EchoFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); - - -ALeffectState *ALechoStateFactory_create(void) -{ - ALechoState *state; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALechoState, ALeffectState, state); - - state->BufferLength = 0; - state->SampleBuffer = NULL; - - state->Tap[0].delay = 0; - state->Tap[1].delay = 0; - state->Offset = 0; - - state->iirFilter.coeff = 0.0f; - state->iirFilter.history[0] = 0.0f; - state->iirFilter.history[1] = 0.0f; - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALechoStateFactory_destroy(ALeffectState *effect) -{ - ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); - ALechoState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALechoStateFactory); - - -static void init_echo_factory(void) -{ - SET_VTABLE2(ALechoStateFactory, ALeffectStateFactory, &EchoFactory); -} - -ALeffectStateFactory *ALechoStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_echo_factory); - return STATIC_CAST(ALeffectStateFactory, &EchoFactory); -} - - -void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -void echo_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - echo_SetParami(effect, context, param, vals[0]); -} -void echo_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_ECHO_DELAY: - if(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY) - effect->Echo.Delay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_LRDELAY: - if(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY) - effect->Echo.LRDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_DAMPING: - if(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING) - effect->Echo.Damping = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_FEEDBACK: - if(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK) - effect->Echo.Feedback = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_SPREAD: - if(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD) - effect->Echo.Spread = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void echo_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - echo_SetParamf(effect, context, param, vals[0]); -} - -void echo_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -void echo_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - echo_GetParami(effect, context, param, vals); -} -void echo_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_ECHO_DELAY: - *val = effect->Echo.Delay; - break; - - case AL_ECHO_LRDELAY: - *val = effect->Echo.LRDelay; - break; - - case AL_ECHO_DAMPING: - *val = effect->Echo.Damping; - break; - - case AL_ECHO_FEEDBACK: - *val = effect->Echo.Feedback; - break; - - case AL_ECHO_SPREAD: - *val = effect->Echo.Spread; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void echo_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - echo_GetParamf(effect, context, param, vals); -} diff --git a/Alc/alcEqualizer.c b/Alc/alcEqualizer.c deleted file mode 100644 index d397a9ba..00000000 --- a/Alc/alcEqualizer.c +++ /dev/null @@ -1,499 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2013 by Mike Gorchak - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALequalizerStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALequalizerStateFactory; - -static ALequalizerStateFactory EqualizerFactory; - - -/* The document "Effects Extension Guide.pdf" says that low and high * - * frequencies are cutoff frequencies. This is not fully correct, they * - * are corner frequencies for low and high shelf filters. If they were * - * just cutoff frequencies, there would be no need in cutoff frequency * - * gains, which are present. Documentation for "Creative Proteus X2" * - * software describes 4-band equalizer functionality in a much better * - * way. This equalizer seems to be a predecessor of OpenAL 4-band * - * equalizer. With low and high shelf filters we are able to cutoff * - * frequencies below and/or above corner frequencies using attenuation * - * gains (below 1.0) and amplify all low and/or high frequencies using * - * gains above 1.0. * - * * - * Low-shelf Low Mid Band High Mid Band High-shelf * - * corner center center corner * - * frequency frequency frequency frequency * - * 50Hz..800Hz 200Hz..3000Hz 1000Hz..8000Hz 4000Hz..16000Hz * - * * - * | | | | * - * | | | | * - * B -----+ /--+--\ /--+--\ +----- * - * O |\ | | | | | | /| * - * O | \ - | - - | - / | * - * S + | \ | | | | | | / | * - * T | | | | | | | | | | * - * ---------+---------------+------------------+---------------+-------- * - * C | | | | | | | | | | * - * U - | / | | | | | | \ | * - * T | / - | - - | - \ | * - * O |/ | | | | | | \| * - * F -----+ \--+--/ \--+--/ +----- * - * F | | | | * - * | | | | * - * * - * Gains vary from 0.126 up to 7.943, which means from -18dB attenuation * - * up to +18dB amplification. Band width varies from 0.01 up to 1.0 in * - * octaves for two mid bands. * - * * - * Implementation is based on the "Cookbook formulae for audio EQ biquad * - * filter coefficients" by Robert Bristow-Johnson * - * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ - -typedef enum ALEQFilterType { - LOW_SHELF, - HIGH_SHELF, - PEAKING -} ALEQFilterType; - -typedef struct ALEQFilter { - ALEQFilterType type; - ALfloat x[2]; /* History of two last input samples */ - ALfloat y[2]; /* History of two last output samples */ - ALfloat a[3]; /* Transfer function coefficients "a" */ - ALfloat b[3]; /* Transfer function coefficients "b" */ -} ALEQFilter; - -typedef struct ALequalizerState { - DERIVE_FROM_TYPE(ALeffectState); - - /* Effect gains for each channel */ - ALfloat Gain[MaxChannels]; - - /* Effect parameters */ - ALEQFilter bandfilter[4]; -} ALequalizerState; - -static ALvoid ALequalizerState_Destruct(ALequalizerState *state) -{ - (void)state; -} - -static ALboolean ALequalizerState_DeviceUpdate(ALequalizerState *state, ALCdevice *device) -{ - return AL_TRUE; - (void)state; - (void)device; -} - -static ALvoid ALequalizerState_Update(ALequalizerState *state, ALCdevice *device, const ALeffectslot *slot) -{ - ALfloat frequency = (ALfloat)device->Frequency; - ALfloat gain = sqrtf(1.0f / device->NumChan) * slot->Gain; - ALuint it; - - for(it = 0;it < MaxChannels;it++) - state->Gain[it] = 0.0f; - for(it = 0; it < device->NumChan; it++) - { - enum Channel chan = device->Speaker2Chan[it]; - state->Gain[chan] = gain; - } - - /* Calculate coefficients for the each type of filter */ - for(it = 0; it < 4; it++) - { - ALfloat gain; - ALfloat filter_frequency; - ALfloat bandwidth = 0.0f; - ALfloat w0; - ALfloat alpha = 0.0f; - - /* convert linear gains to filter gains */ - switch (it) - { - case 0: /* Low Shelf */ - gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.LowGain)) / 40.0f); - filter_frequency = slot->effect.Equalizer.LowCutoff; - break; - case 1: /* Peaking */ - gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.Mid1Gain)) / 40.0f); - filter_frequency = slot->effect.Equalizer.Mid1Center; - bandwidth = slot->effect.Equalizer.Mid1Width; - break; - case 2: /* Peaking */ - gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.Mid2Gain)) / 40.0f); - filter_frequency = slot->effect.Equalizer.Mid2Center; - bandwidth = slot->effect.Equalizer.Mid2Width; - break; - case 3: /* High Shelf */ - gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.HighGain)) / 40.0f); - filter_frequency = slot->effect.Equalizer.HighCutoff; - break; - } - - w0 = 2.0f*F_PI * filter_frequency / frequency; - - /* Calculate filter coefficients depending on filter type */ - switch(state->bandfilter[it].type) - { - case LOW_SHELF: - alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * - (1.0f / 0.75f - 1.0f) + 2.0f); - state->bandfilter[it].b[0] = gain * ((gain + 1.0f) - - (gain - 1.0f) * cosf(w0) + - 2.0f * sqrtf(gain) * alpha); - state->bandfilter[it].b[1] = 2.0f * gain * ((gain - 1.0f) - - (gain + 1.0f) * cosf(w0)); - state->bandfilter[it].b[2] = gain * ((gain + 1.0f) - - (gain - 1.0f) * cosf(w0) - - 2.0f * sqrtf(gain) * alpha); - state->bandfilter[it].a[0] = (gain + 1.0f) + - (gain - 1.0f) * cosf(w0) + - 2.0f * sqrtf(gain) * alpha; - state->bandfilter[it].a[1] = -2.0f * ((gain - 1.0f) + - (gain + 1.0f) * cosf(w0)); - state->bandfilter[it].a[2] = (gain + 1.0f) + - (gain - 1.0f) * cosf(w0) - - 2.0f * sqrtf(gain) * alpha; - break; - case HIGH_SHELF: - alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * - (1.0f / 0.75f - 1.0f) + 2.0f); - state->bandfilter[it].b[0] = gain * ((gain + 1.0f) + - (gain - 1.0f) * cosf(w0) + - 2.0f * sqrtf(gain) * alpha); - state->bandfilter[it].b[1] = -2.0f * gain * ((gain - 1.0f) + - (gain + 1.0f) * - cosf(w0)); - state->bandfilter[it].b[2] = gain * ((gain + 1.0f) + - (gain - 1.0f) * cosf(w0) - - 2.0f * sqrtf(gain) * alpha); - state->bandfilter[it].a[0] = (gain + 1.0f) - - (gain - 1.0f) * cosf(w0) + - 2.0f * sqrtf(gain) * alpha; - state->bandfilter[it].a[1] = 2.0f * ((gain - 1.0f) - - (gain + 1.0f) * cosf(w0)); - state->bandfilter[it].a[2] = (gain + 1.0f) - - (gain - 1.0f) * cosf(w0) - - 2.0f * sqrtf(gain) * alpha; - break; - case PEAKING: - alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); - state->bandfilter[it].b[0] = 1.0f + alpha * gain; - state->bandfilter[it].b[1] = -2.0f * cosf(w0); - state->bandfilter[it].b[2] = 1.0f - alpha * gain; - state->bandfilter[it].a[0] = 1.0f + alpha / gain; - state->bandfilter[it].a[1] = -2.0f * cosf(w0); - state->bandfilter[it].a[2] = 1.0f - alpha / gain; - break; - } - } -} - -static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - ALuint base; - ALuint it; - ALuint kt; - ALuint ft; - - for(base = 0;base < SamplesToDo;) - { - ALfloat temps[64]; - ALuint td = minu(SamplesToDo-base, 64); - - for(it = 0;it < td;it++) - { - ALfloat smp = SamplesIn[base+it]; - ALfloat tempsmp; - - for(ft = 0;ft < 4;ft++) - { - ALEQFilter *filter = &state->bandfilter[ft]; - - tempsmp = filter->b[0] / filter->a[0] * smp + - filter->b[1] / filter->a[0] * filter->x[0] + - filter->b[2] / filter->a[0] * filter->x[1] - - filter->a[1] / filter->a[0] * filter->y[0] - - filter->a[2] / filter->a[0] * filter->y[1]; - - filter->x[1] = filter->x[0]; - filter->x[0] = smp; - filter->y[1] = filter->y[0]; - filter->y[0] = tempsmp; - smp = tempsmp; - } - - temps[it] = smp; - } - - for(kt = 0;kt < MaxChannels;kt++) - { - ALfloat gain = state->Gain[kt]; - if(!(gain > 0.00001f)) - continue; - - for(it = 0;it < td;it++) - SamplesOut[kt][base+it] += gain * temps[it]; - } - - base += td; - } -} - -static ALeffectStateFactory *ALequalizerState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); - - -ALeffectState *ALequalizerStateFactory_create(void) -{ - ALequalizerState *state; - int it; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALequalizerState, ALeffectState, state); - - state->bandfilter[0].type = LOW_SHELF; - state->bandfilter[1].type = PEAKING; - state->bandfilter[2].type = PEAKING; - state->bandfilter[3].type = HIGH_SHELF; - - /* Initialize sample history only on filter creation to avoid */ - /* sound clicks if filter settings were changed in runtime. */ - for(it = 0; it < 4; it++) - { - state->bandfilter[it].x[0] = 0.0f; - state->bandfilter[it].x[1] = 0.0f; - state->bandfilter[it].y[0] = 0.0f; - state->bandfilter[it].y[1] = 0.0f; - } - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALequalizerStateFactory_destroy(ALeffectState *effect) -{ - ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); - ALequalizerState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALequalizerStateFactory); - - -static void init_equalizer_factory(void) -{ - SET_VTABLE2(ALequalizerStateFactory, ALeffectStateFactory, &EqualizerFactory); -} - -ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_equalizer_factory); - return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); -} - - -void equalizer_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - effect=effect; - val=val; - - switch(param) - { - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void equalizer_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - equalizer_SetParami(effect, context, param, vals[0]); -} -void equalizer_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_EQUALIZER_LOW_GAIN: - if(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN) - effect->Equalizer.LowGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_LOW_CUTOFF: - if(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF) - effect->Equalizer.LowCutoff = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_MID1_GAIN: - if(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN) - effect->Equalizer.Mid1Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_MID1_CENTER: - if(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER) - effect->Equalizer.Mid1Center = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_MID1_WIDTH: - if(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH) - effect->Equalizer.Mid1Width = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_MID2_GAIN: - if(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN) - effect->Equalizer.Mid2Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_MID2_CENTER: - if(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER) - effect->Equalizer.Mid2Center = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_MID2_WIDTH: - if(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH) - effect->Equalizer.Mid2Width = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_HIGH_GAIN: - if(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN) - effect->Equalizer.HighGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EQUALIZER_HIGH_CUTOFF: - if(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF) - effect->Equalizer.HighCutoff = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void equalizer_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - equalizer_SetParamf(effect, context, param, vals[0]); -} - -void equalizer_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - effect=effect; - val=val; - - switch(param) - { - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void equalizer_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - equalizer_GetParami(effect, context, param, vals); -} -void equalizer_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_EQUALIZER_LOW_GAIN: - *val = effect->Equalizer.LowGain; - break; - - case AL_EQUALIZER_LOW_CUTOFF: - *val = effect->Equalizer.LowCutoff; - break; - - case AL_EQUALIZER_MID1_GAIN: - *val = effect->Equalizer.Mid1Gain; - break; - - case AL_EQUALIZER_MID1_CENTER: - *val = effect->Equalizer.Mid1Center; - break; - - case AL_EQUALIZER_MID1_WIDTH: - *val = effect->Equalizer.Mid1Width; - break; - - case AL_EQUALIZER_MID2_GAIN: - *val = effect->Equalizer.Mid2Gain; - break; - - case AL_EQUALIZER_MID2_CENTER: - *val = effect->Equalizer.Mid2Center; - break; - - case AL_EQUALIZER_MID2_WIDTH: - *val = effect->Equalizer.Mid2Width; - break; - - case AL_EQUALIZER_HIGH_GAIN: - *val = effect->Equalizer.HighGain; - break; - - case AL_EQUALIZER_HIGH_CUTOFF: - *val = effect->Equalizer.HighCutoff; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void equalizer_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - equalizer_GetParamf(effect, context, param, vals); -} diff --git a/Alc/alcFlanger.c b/Alc/alcFlanger.c deleted file mode 100644 index a0f94a46..00000000 --- a/Alc/alcFlanger.c +++ /dev/null @@ -1,411 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2013 by Mike Gorchak - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALflangerStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALflangerStateFactory; - -static ALflangerStateFactory FlangerFactory; - - -typedef struct ALflangerState { - DERIVE_FROM_TYPE(ALeffectState); - - ALfloat *SampleBufferLeft; - ALfloat *SampleBufferRight; - ALuint BufferLength; - ALint offset; - ALfloat lfo_coeff; - ALint lfo_disp; - - /* Gains for left and right sides */ - ALfloat Gain[2][MaxChannels]; - - /* effect parameters */ - ALint waveform; - ALint delay; - ALfloat depth; - ALfloat feedback; -} ALflangerState; - -static ALvoid ALflangerState_Destruct(ALflangerState *state) -{ - free(state->SampleBufferLeft); - state->SampleBufferLeft = NULL; - - free(state->SampleBufferRight); - state->SampleBufferRight = NULL; -} - -static ALboolean ALflangerState_DeviceUpdate(ALflangerState *state, ALCdevice *Device) -{ - ALuint maxlen; - ALuint it; - - maxlen = fastf2u(AL_FLANGER_MAX_DELAY * 3.0f * Device->Frequency) + 1; - maxlen = NextPowerOf2(maxlen); - - if(maxlen != state->BufferLength) - { - void *temp; - - temp = realloc(state->SampleBufferLeft, maxlen * sizeof(ALfloat)); - if(!temp) return AL_FALSE; - state->SampleBufferLeft = temp; - - temp = realloc(state->SampleBufferRight, maxlen * sizeof(ALfloat)); - if(!temp) return AL_FALSE; - state->SampleBufferRight = temp; - - state->BufferLength = maxlen; - } - - for(it = 0;it < state->BufferLength;it++) - { - state->SampleBufferLeft[it] = 0.0f; - state->SampleBufferRight[it] = 0.0f; - } - - return AL_TRUE; -} - -static ALvoid ALflangerState_Update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot) -{ - ALfloat frequency = (ALfloat)Device->Frequency; - ALfloat rate; - ALint phase; - ALuint it; - - for(it = 0;it < MaxChannels;it++) - { - state->Gain[0][it] = 0.0f; - state->Gain[1][it] = 0.0f; - } - - state->waveform = Slot->effect.Flanger.Waveform; - state->depth = Slot->effect.Flanger.Depth; - state->feedback = Slot->effect.Flanger.Feedback; - state->delay = fastf2i(Slot->effect.Flanger.Delay * frequency); - - /* Gains for left and right sides */ - ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); - ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); - - phase = Slot->effect.Flanger.Phase; - rate = Slot->effect.Flanger.Rate; - - /* Calculate LFO coefficient */ - switch(state->waveform) - { - case AL_FLANGER_WAVEFORM_TRIANGLE: - if(rate == 0.0f) - state->lfo_coeff = 0.0f; - else - state->lfo_coeff = 1.0f / (frequency / rate); - break; - case AL_FLANGER_WAVEFORM_SINUSOID: - if(rate == 0.0f) - state->lfo_coeff = 0.0f; - else - state->lfo_coeff = F_PI * 2.0f / (frequency / rate); - break; - } - - /* Calculate lfo phase displacement */ - if(phase == 0 || rate == 0.0f) - state->lfo_disp = 0; - else - state->lfo_disp = fastf2i(frequency / rate / (360.0f/phase)); -} - -static __inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) -{ - ALfloat lfo_value; - - lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff * offset * 4.0f, 4.0f)); - lfo_value *= state->depth * state->delay; - *delay_left = fastf2i(lfo_value) + state->delay; - - lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff * - (offset+state->lfo_disp) * 4.0f, - 4.0f)); - lfo_value *= state->depth * state->delay; - *delay_right = fastf2i(lfo_value) + state->delay; -} - -static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) -{ - ALfloat lfo_value; - - lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff * offset, 2.0f*F_PI)); - lfo_value *= state->depth * state->delay; - *delay_left = fastf2i(lfo_value) + state->delay; - - lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff * (offset+state->lfo_disp), - 2.0f*F_PI)); - lfo_value *= state->depth * state->delay; - *delay_right = fastf2i(lfo_value) + state->delay; -} - -#define DECL_TEMPLATE(func) \ -static void Process##func(ALflangerState *state, ALuint SamplesToDo, \ - const ALfloat *restrict SamplesIn, \ - ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ -{ \ - const ALint mask = state->BufferLength-1; \ - ALint offset = state->offset; \ - ALuint it, kt; \ - ALuint base; \ - \ - for(base = 0;base < SamplesToDo;) \ - { \ - ALfloat temps[64][2]; \ - ALuint td = minu(SamplesToDo-base, 64); \ - \ - for(it = 0;it < td;it++,offset++) \ - { \ - ALint delay_left, delay_right; \ - (func)(&delay_left, &delay_right, offset, state); \ - \ - temps[it][0] = state->SampleBufferLeft[(offset-delay_left)&mask]; \ - state->SampleBufferLeft[offset&mask] = (temps[it][0] + \ - SamplesIn[it+base]) * \ - state->feedback; \ - \ - temps[it][1] = state->SampleBufferRight[(offset-delay_right)&mask];\ - state->SampleBufferRight[offset&mask] = (temps[it][1] + \ - SamplesIn[it+base]) * \ - state->feedback; \ - } \ - \ - for(kt = 0;kt < MaxChannels;kt++) \ - { \ - ALfloat gain = state->Gain[0][kt]; \ - if(gain > 0.00001f) \ - { \ - for(it = 0;it < td;it++) \ - SamplesOut[kt][it+base] += temps[it][0] * gain; \ - } \ - \ - gain = state->Gain[1][kt]; \ - if(gain > 0.00001f) \ - { \ - for(it = 0;it < td;it++) \ - SamplesOut[kt][it+base] += temps[it][1] * gain; \ - } \ - } \ - \ - base += td; \ - } \ - \ - 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]) -{ - if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) - ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); - else if(state->waveform == AL_FLANGER_WAVEFORM_SINUSOID) - ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); -} - -static ALeffectStateFactory *ALflangerState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); - - -ALeffectState *ALflangerStateFactory_create(void) -{ - ALflangerState *state; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALflangerState, ALeffectState, state); - - state->BufferLength = 0; - state->SampleBufferLeft = NULL; - state->SampleBufferRight = NULL; - state->offset = 0; - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALflangerStateFactory_destroy(ALeffectState *effect) -{ - ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); - ALflangerState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALflangerStateFactory); - - -static void init_flanger_factory(void) -{ - SET_VTABLE2(ALflangerStateFactory, ALeffectStateFactory, &FlangerFactory); -} - -ALeffectStateFactory *ALflangerStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_flanger_factory); - return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); -} - - -void flanger_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_FLANGER_WAVEFORM: - if(val >= AL_FLANGER_MIN_WAVEFORM && val <= AL_FLANGER_MAX_WAVEFORM) - effect->Flanger.Waveform = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_FLANGER_PHASE: - if(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE) - effect->Flanger.Phase = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void flanger_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - flanger_SetParami(effect, context, param, vals[0]); -} -void flanger_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_FLANGER_RATE: - if(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE) - effect->Flanger.Rate = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_FLANGER_DEPTH: - if(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH) - effect->Flanger.Depth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_FLANGER_FEEDBACK: - if(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK) - effect->Flanger.Feedback = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_FLANGER_DELAY: - if(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY) - effect->Flanger.Delay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void flanger_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - flanger_SetParamf(effect, context, param, vals[0]); -} - -void flanger_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_FLANGER_WAVEFORM: - *val = effect->Flanger.Waveform; - break; - - case AL_FLANGER_PHASE: - *val = effect->Flanger.Phase; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void flanger_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - flanger_GetParami(effect, context, param, vals); -} -void flanger_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_FLANGER_RATE: - *val = effect->Flanger.Rate; - break; - - case AL_FLANGER_DEPTH: - *val = effect->Flanger.Depth; - break; - - case AL_FLANGER_FEEDBACK: - *val = effect->Flanger.Feedback; - break; - - case AL_FLANGER_DELAY: - *val = effect->Flanger.Delay; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void flanger_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - flanger_GetParamf(effect, context, param, vals); -} diff --git a/Alc/alcModulator.c b/Alc/alcModulator.c deleted file mode 100644 index ec99bd53..00000000 --- a/Alc/alcModulator.c +++ /dev/null @@ -1,343 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2009 by Chris Robinson. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alFilter.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alu.h" - - -typedef struct ALmodulatorStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALmodulatorStateFactory; - -static ALmodulatorStateFactory ModulatorFactory; - - -typedef struct ALmodulatorState { - DERIVE_FROM_TYPE(ALeffectState); - - enum { - SINUSOID, - SAWTOOTH, - SQUARE - } Waveform; - - ALuint index; - ALuint step; - - ALfloat Gain[MaxChannels]; - - FILTER iirFilter; -} ALmodulatorState; - -#define WAVEFORM_FRACBITS 24 -#define WAVEFORM_FRACONE (1<> (WAVEFORM_FRACBITS - 1)) & 1); -} - - -static __inline ALfloat hpFilter1P(FILTER *iir, ALfloat input) -{ - ALfloat *history = iir->history; - ALfloat a = iir->coeff; - ALfloat output = input; - - output = output + (history[0]-output)*a; - history[0] = output; - - return input - output; -} - - -#define DECL_TEMPLATE(func) \ -static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ - const ALfloat *restrict SamplesIn, \ - ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ -{ \ - const ALuint step = state->step; \ - ALuint index = state->index; \ - ALuint base; \ - \ - for(base = 0;base < SamplesToDo;) \ - { \ - ALfloat temps[64]; \ - ALuint td = minu(SamplesToDo-base, 64); \ - ALuint i, k; \ - \ - for(i = 0;i < td;i++) \ - { \ - ALfloat samp; \ - samp = SamplesIn[base+i]; \ - samp = hpFilter1P(&state->iirFilter, samp); \ - \ - index += step; \ - index &= WAVEFORM_FRACMASK; \ - temps[i] = samp * func(index); \ - } \ - \ - for(k = 0;k < MaxChannels;k++) \ - { \ - ALfloat gain = state->Gain[k]; \ - if(!(gain > 0.00001f)) \ - continue; \ - \ - for(i = 0;i < td;i++) \ - SamplesOut[k][base+i] += gain * temps[i]; \ - } \ - \ - base += td; \ - } \ - state->index = index; \ -} - -DECL_TEMPLATE(Sin) -DECL_TEMPLATE(Saw) -DECL_TEMPLATE(Square) - -#undef DECL_TEMPLATE - - -static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state) -{ - (void)state; -} - -static ALboolean ALmodulatorState_DeviceUpdate(ALmodulatorState *state, ALCdevice *Device) -{ - return AL_TRUE; - (void)state; - (void)Device; -} - -static ALvoid ALmodulatorState_Update(ALmodulatorState *state, ALCdevice *Device, const ALeffectslot *Slot) -{ - ALfloat gain, cw, a = 0.0f; - ALuint index; - - if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID) - state->Waveform = SINUSOID; - else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH) - state->Waveform = SAWTOOTH; - else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SQUARE) - state->Waveform = SQUARE; - - state->step = fastf2u(Slot->effect.Modulator.Frequency*WAVEFORM_FRACONE / - Device->Frequency); - if(state->step == 0) state->step = 1; - - cw = cosf(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff / - Device->Frequency); - a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f); - state->iirFilter.coeff = a; - - gain = sqrtf(1.0f/Device->NumChan); - gain *= Slot->Gain; - for(index = 0;index < MaxChannels;index++) - state->Gain[index] = 0.0f; - for(index = 0;index < Device->NumChan;index++) - { - enum Channel chan = Device->Speaker2Chan[index]; - state->Gain[chan] = gain; - } -} - -static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - switch(state->Waveform) - { - case SINUSOID: - ProcessSin(state, SamplesToDo, SamplesIn, SamplesOut); - break; - - case SAWTOOTH: - ProcessSaw(state, SamplesToDo, SamplesIn, SamplesOut); - break; - - case SQUARE: - ProcessSquare(state, SamplesToDo, SamplesIn, SamplesOut); - break; - } -} - -static ALeffectStateFactory *ALmodulatorState_getCreator(void) -{ - return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); -} - -DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); - - -static ALeffectState *ALmodulatorStateFactory_create(void) -{ - ALmodulatorState *state; - - state = malloc(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALmodulatorState, ALeffectState, state); - - state->index = 0; - state->step = 1; - - state->iirFilter.coeff = 0.0f; - state->iirFilter.history[0] = 0.0f; - - return STATIC_CAST(ALeffectState, state); -} - -static ALvoid ALmodulatorStateFactory_destroy(ALeffectState *effect) -{ - ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); - ALmodulatorState_Destruct(state); - free(state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALmodulatorStateFactory); - - -static void init_modulator_factory(void) -{ - SET_VTABLE2(ALmodulatorStateFactory, ALeffectStateFactory, &ModulatorFactory); -} - -ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void) -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, init_modulator_factory); - return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); -} - - -void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - if(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY) - effect->Modulator.Frequency = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - if(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF) - effect->Modulator.HighPassCutoff = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void mod_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - mod_SetParamf(effect, context, param, vals[0]); -} -void mod_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - mod_SetParamf(effect, context, param, (ALfloat)val); - break; - - case AL_RING_MODULATOR_WAVEFORM: - if(val >= AL_RING_MODULATOR_MIN_WAVEFORM && val <= AL_RING_MODULATOR_MAX_WAVEFORM) - effect->Modulator.Waveform = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void mod_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - mod_SetParami(effect, context, param, vals[0]); -} - -void mod_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - *val = (ALint)effect->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = (ALint)effect->Modulator.HighPassCutoff; - break; - case AL_RING_MODULATOR_WAVEFORM: - *val = effect->Modulator.Waveform; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void mod_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - mod_GetParami(effect, context, param, vals); -} -void mod_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - *val = effect->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = effect->Modulator.HighPassCutoff; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -void mod_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - mod_GetParamf(effect, context, param, vals); -} diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c new file mode 100644 index 00000000..e5a20b5d --- /dev/null +++ b/Alc/effects/chorus.c @@ -0,0 +1,411 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALchorusStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALchorusStateFactory; + +static ALchorusStateFactory ChorusFactory; + + +typedef struct ALchorusState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat *SampleBufferLeft; + ALfloat *SampleBufferRight; + ALuint BufferLength; + ALint offset; + ALfloat lfo_coeff; + ALint lfo_disp; + + /* Gains for left and right sides */ + ALfloat Gain[2][MaxChannels]; + + /* effect parameters */ + ALint waveform; + ALint delay; + ALfloat depth; + ALfloat feedback; +} ALchorusState; + +static ALvoid ALchorusState_Destruct(ALchorusState *state) +{ + free(state->SampleBufferLeft); + state->SampleBufferLeft = NULL; + + free(state->SampleBufferRight); + state->SampleBufferRight = NULL; +} + +static ALboolean ALchorusState_DeviceUpdate(ALchorusState *state, ALCdevice *Device) +{ + ALuint maxlen; + ALuint it; + + maxlen = fastf2u(AL_CHORUS_MAX_DELAY * 3.0f * Device->Frequency) + 1; + maxlen = NextPowerOf2(maxlen); + + if(maxlen != state->BufferLength) + { + void *temp; + + temp = realloc(state->SampleBufferLeft, maxlen * sizeof(ALfloat)); + if(!temp) return AL_FALSE; + state->SampleBufferLeft = temp; + + temp = realloc(state->SampleBufferRight, maxlen * sizeof(ALfloat)); + if(!temp) return AL_FALSE; + state->SampleBufferRight = temp; + + state->BufferLength = maxlen; + } + + for(it = 0;it < state->BufferLength;it++) + { + state->SampleBufferLeft[it] = 0.0f; + state->SampleBufferRight[it] = 0.0f; + } + + return AL_TRUE; +} + +static ALvoid ALchorusState_Update(ALchorusState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat frequency = (ALfloat)Device->Frequency; + ALfloat rate; + ALint phase; + ALuint it; + + for (it = 0; it < MaxChannels; it++) + { + state->Gain[0][it] = 0.0f; + state->Gain[1][it] = 0.0f; + } + + state->waveform = Slot->effect.Chorus.Waveform; + state->depth = Slot->effect.Chorus.Depth; + state->feedback = Slot->effect.Chorus.Feedback; + state->delay = fastf2i(Slot->effect.Chorus.Delay * frequency); + + /* Gains for left and right sides */ + ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); + ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); + + phase = Slot->effect.Chorus.Phase; + rate = Slot->effect.Chorus.Rate; + + /* Calculate LFO coefficient */ + switch (state->waveform) + { + case AL_CHORUS_WAVEFORM_TRIANGLE: + if(rate == 0.0f) + state->lfo_coeff = 0.0f; + else + state->lfo_coeff = 1.0f / (frequency / rate); + break; + case AL_CHORUS_WAVEFORM_SINUSOID: + if(rate == 0.0f) + state->lfo_coeff = 0.0f; + else + state->lfo_coeff = F_PI*2.0f / (frequency / rate); + break; + } + + /* Calculate lfo phase displacement */ + if(phase == 0 || rate == 0.0f) + state->lfo_disp = 0; + else + state->lfo_disp = fastf2i(frequency / rate / (360.0f/phase)); +} + +static __inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) +{ + ALfloat lfo_value; + + lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff*offset*4.0f, 4.0f)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff * + (offset+state->lfo_disp)*4.0f, + 4.0f)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALchorusState *state) +{ + ALfloat lfo_value; + + lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff*offset, 2.0f*F_PI)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff*(offset+state->lfo_disp), + 2.0f*F_PI)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +#define DECL_TEMPLATE(func) \ +static void Process##func(ALchorusState *state, ALuint SamplesToDo, \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ +{ \ + const ALint mask = state->BufferLength-1; \ + ALint offset = state->offset; \ + ALuint it, kt; \ + ALuint base; \ + \ + for(base = 0;base < SamplesToDo;) \ + { \ + ALfloat temps[64][2]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + \ + for(it = 0;it < td;it++,offset++) \ + { \ + ALint delay_left, delay_right; \ + (func)(&delay_left, &delay_right, offset, state); \ + \ + temps[it][0] = state->SampleBufferLeft[(offset-delay_left)&mask]; \ + state->SampleBufferLeft[offset&mask] = (temps[it][0] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + \ + temps[it][1] = state->SampleBufferRight[(offset-delay_right)&mask];\ + state->SampleBufferRight[offset&mask] = (temps[it][1] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + } \ + \ + for(kt = 0;kt < MaxChannels;kt++) \ + { \ + ALfloat gain = state->Gain[0][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][0] * gain; \ + } \ + \ + gain = state->Gain[1][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][1] * gain; \ + } \ + } \ + \ + base += td; \ + } \ + \ + state->offset = offset; \ +} + +DECL_TEMPLATE(Triangle) +DECL_TEMPLATE(Sinusoid) + +#undef DECL_TEMPLATE + +static ALvoid ALchorusState_Process(ALchorusState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + if(state->waveform == AL_CHORUS_WAVEFORM_TRIANGLE) + ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); + else if(state->waveform == AL_CHORUS_WAVEFORM_SINUSOID) + ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); +} + +static ALeffectStateFactory *ALchorusState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); + + +static ALeffectState *ALchorusStateFactory_create(void) +{ + ALchorusState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALchorusState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBufferLeft = NULL; + state->SampleBufferRight = NULL; + state->offset = 0; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALchorusStateFactory_destroy(ALeffectState *effect) +{ + ALchorusState *state = STATIC_UPCAST(ALchorusState, ALeffectState, effect); + ALchorusState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALchorusStateFactory); + + +static void init_chorus_factory(void) +{ + SET_VTABLE2(ALchorusStateFactory, ALeffectStateFactory, &ChorusFactory); +} + +ALeffectStateFactory *ALchorusStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_chorus_factory); + return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); +} + + +void chorus_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + switch(param) + { + case AL_CHORUS_WAVEFORM: + if(val >= AL_CHORUS_MIN_WAVEFORM && val <= AL_CHORUS_MAX_WAVEFORM) + effect->Chorus.Waveform = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_CHORUS_PHASE: + if(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE) + effect->Chorus.Phase = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void chorus_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + chorus_SetParami(effect, context, param, vals[0]); +} +void chorus_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_CHORUS_RATE: + if(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE) + effect->Chorus.Rate = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_CHORUS_DEPTH: + if(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH) + effect->Chorus.Depth = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_CHORUS_FEEDBACK: + if(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK) + effect->Chorus.Feedback = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_CHORUS_DELAY: + if(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY) + effect->Chorus.Delay = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void chorus_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + chorus_SetParamf(effect, context, param, vals[0]); +} + +void chorus_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + switch(param) + { + case AL_CHORUS_WAVEFORM: + *val = effect->Chorus.Waveform; + break; + + case AL_CHORUS_PHASE: + *val = effect->Chorus.Phase; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void chorus_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + chorus_GetParami(effect, context, param, vals); +} +void chorus_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_CHORUS_RATE: + *val = effect->Chorus.Rate; + break; + + case AL_CHORUS_DEPTH: + *val = effect->Chorus.Depth; + break; + + case AL_CHORUS_FEEDBACK: + *val = effect->Chorus.Feedback; + break; + + case AL_CHORUS_DELAY: + *val = effect->Chorus.Delay; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void chorus_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + chorus_GetParamf(effect, context, param, vals); +} diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c new file mode 100644 index 00000000..bd266b0e --- /dev/null +++ b/Alc/effects/dedicated.c @@ -0,0 +1,183 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2011 by Chris Robinson. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALdedicatedStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALdedicatedStateFactory; + +static ALdedicatedStateFactory DedicatedFactory; + + +typedef struct ALdedicatedState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat gains[MaxChannels]; +} ALdedicatedState; + + +static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state) +{ + (void)state; +} + +static ALboolean ALdedicatedState_DeviceUpdate(ALdedicatedState *state, ALCdevice *Device) +{ + return AL_TRUE; + (void)state; + (void)Device; +} + +static ALvoid ALdedicatedState_Update(ALdedicatedState *state, ALCdevice *device, const ALeffectslot *Slot) +{ + ALfloat Gain; + ALsizei s; + + Gain = Slot->Gain * Slot->effect.Dedicated.Gain; + for(s = 0;s < MaxChannels;s++) + state->gains[s] = 0.0f; + + if(Slot->effect.type == AL_EFFECT_DEDICATED_DIALOGUE) + ComputeAngleGains(device, atan2f(0.0f, 1.0f), 0.0f, Gain, state->gains); + else if(Slot->effect.type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) + state->gains[LFE] = Gain; +} + +static ALvoid ALdedicatedState_Process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + const ALfloat *gains = state->gains; + ALuint i, c; + + for(c = 0;c < MaxChannels;c++) + { + if(!(gains[c] > 0.00001f)) + continue; + + for(i = 0;i < SamplesToDo;i++) + SamplesOut[c][i] = SamplesIn[i] * gains[c]; + } +} + +static ALeffectStateFactory *ALdedicatedState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); + + +ALeffectState *ALdedicatedStateFactory_create(void) +{ + ALdedicatedState *state; + ALsizei s; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALdedicatedState, ALeffectState, state); + + for(s = 0;s < MaxChannels;s++) + state->gains[s] = 0.0f; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALdedicatedStateFactory_destroy(ALeffectState *effect) +{ + ALdedicatedState *state = STATIC_UPCAST(ALdedicatedState, ALeffectState, effect); + ALdedicatedState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdedicatedStateFactory); + + +static void init_dedicated_factory(void) +{ + SET_VTABLE2(ALdedicatedStateFactory, ALeffectStateFactory, &DedicatedFactory); +} + +ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_dedicated_factory); + return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); +} + + +void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } +void ded_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ded_SetParami(effect, context, param, vals[0]); +} +void ded_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_DEDICATED_GAIN: + if(val >= 0.0f && isfinite(val)) + effect->Dedicated.Gain = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void ded_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ded_SetParamf(effect, context, param, vals[0]); +} + +void ded_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } +void ded_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ded_GetParami(effect, context, param, vals); +} +void ded_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_DEDICATED_GAIN: + *val = effect->Dedicated.Gain; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void ded_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ded_GetParamf(effect, context, param, vals); +} diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c new file mode 100644 index 00000000..7828377c --- /dev/null +++ b/Alc/effects/distortion.c @@ -0,0 +1,402 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALdistortionStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALdistortionStateFactory; + +static ALdistortionStateFactory DistortionFactory; + + +/* Filters implementation is based on the "Cookbook formulae for audio * + * EQ biquad filter coefficients" by Robert Bristow-Johnson * + * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ + +typedef enum ALEQFilterType { + LOWPASS, + BANDPASS, +} ALEQFilterType; + +typedef struct ALEQFilter { + ALEQFilterType type; + ALfloat x[2]; /* History of two last input samples */ + ALfloat y[2]; /* History of two last output samples */ + ALfloat a[3]; /* Transfer function coefficients "a" */ + ALfloat b[3]; /* Transfer function coefficients "b" */ +} ALEQFilter; + +typedef struct ALdistortionState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MaxChannels]; + + /* Effect parameters */ + ALEQFilter bandpass; + ALEQFilter lowpass; + ALfloat attenuation; + ALfloat edge_coeff; +} ALdistortionState; + +static ALvoid ALdistortionState_Destruct(ALdistortionState *state) +{ + (void)state; +} + +static ALboolean ALdistortionState_DeviceUpdate(ALdistortionState *state, ALCdevice *device) +{ + return AL_TRUE; + (void)state; + (void)device; +} + +static ALvoid ALdistortionState_Update(ALdistortionState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat gain = sqrtf(1.0f / Device->NumChan) * Slot->Gain; + ALfloat frequency = (ALfloat)Device->Frequency; + ALuint it; + ALfloat w0; + ALfloat alpha; + ALfloat bandwidth; + ALfloat cutoff; + ALfloat edge; + + for(it = 0;it < MaxChannels;it++) + state->Gain[it] = 0.0f; + for(it = 0;it < Device->NumChan;it++) + { + enum Channel chan = Device->Speaker2Chan[it]; + state->Gain[chan] = gain; + } + + /* Store distorted signal attenuation settings */ + state->attenuation = Slot->effect.Distortion.Gain; + + /* Store waveshaper edge settings */ + edge = sinf(Slot->effect.Distortion.Edge * (F_PI/2.0f)); + state->edge_coeff = 2.0f * edge / (1.0f-edge); + + /* Lowpass filter */ + cutoff = Slot->effect.Distortion.LowpassCutoff; + /* Bandwidth value is constant in octaves */ + bandwidth = (cutoff / 2.0f) / (cutoff * 0.67f); + w0 = 2.0f*F_PI * cutoff / (frequency*4.0f); + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + state->lowpass.b[0] = (1.0f - cosf(w0)) / 2.0f; + state->lowpass.b[1] = 1.0f - cosf(w0); + state->lowpass.b[2] = (1.0f - cosf(w0)) / 2.0f; + state->lowpass.a[0] = 1.0f + alpha; + state->lowpass.a[1] = -2.0f * cosf(w0); + state->lowpass.a[2] = 1.0f - alpha; + + /* Bandpass filter */ + cutoff = Slot->effect.Distortion.EQCenter; + /* Convert bandwidth in Hz to octaves */ + bandwidth = Slot->effect.Distortion.EQBandwidth / (cutoff * 0.67f); + w0 = 2.0f*F_PI * cutoff / (frequency*4.0f); + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + state->bandpass.b[0] = alpha; + state->bandpass.b[1] = 0; + state->bandpass.b[2] = -alpha; + state->bandpass.a[0] = 1.0f + alpha; + state->bandpass.a[1] = -2.0f * cosf(w0); + state->bandpass.a[2] = 1.0f - alpha; +} + +static ALvoid ALdistortionState_Process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + const ALfloat fc = state->edge_coeff; + float oversample_buffer[64][4]; + ALfloat tempsmp; + ALuint base; + ALuint it; + ALuint ot; + ALuint kt; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); + + /* Perform 4x oversampling to avoid aliasing. */ + /* Oversampling greatly improves distortion */ + /* quality and allows to implement lowpass and */ + /* bandpass filters using high frequencies, at */ + /* which classic IIR filters became unstable. */ + + /* Fill oversample buffer using zero stuffing */ + for(it = 0;it < td;it++) + { + oversample_buffer[it][0] = SamplesIn[it+base]; + oversample_buffer[it][1] = 0.0f; + oversample_buffer[it][2] = 0.0f; + oversample_buffer[it][3] = 0.0f; + } + + /* First step, do lowpass filtering of original signal, */ + /* additionally perform buffer interpolation and lowpass */ + /* cutoff for oversampling (which is fortunately first */ + /* step of distortion). So combine three operations into */ + /* the one. */ + for(it = 0;it < td;it++) + { + for(ot = 0;ot < 4;ot++) + { + tempsmp = state->lowpass.b[0] / state->lowpass.a[0] * oversample_buffer[it][ot] + + state->lowpass.b[1] / state->lowpass.a[0] * state->lowpass.x[0] + + state->lowpass.b[2] / state->lowpass.a[0] * state->lowpass.x[1] - + state->lowpass.a[1] / state->lowpass.a[0] * state->lowpass.y[0] - + state->lowpass.a[2] / state->lowpass.a[0] * state->lowpass.y[1]; + + state->lowpass.x[1] = state->lowpass.x[0]; + state->lowpass.x[0] = oversample_buffer[it][ot]; + state->lowpass.y[1] = state->lowpass.y[0]; + state->lowpass.y[0] = tempsmp; + /* Restore signal power by multiplying sample by amount of oversampling */ + oversample_buffer[it][ot] = tempsmp * 4.0f; + } + } + + for(it = 0;it < td;it++) + { + /* Second step, do distortion using waveshaper function */ + /* to emulate signal processing during tube overdriving. */ + /* Three steps of waveshaping are intended to modify */ + /* waveform without boost/clipping/attenuation process. */ + for(ot = 0;ot < 4;ot++) + { + ALfloat smp = oversample_buffer[it][ot]; + + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)) * -1.0f; + smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); + + /* Third step, do bandpass filtering of distorted signal */ + tempsmp = state->bandpass.b[0] / state->bandpass.a[0] * smp + + state->bandpass.b[1] / state->bandpass.a[0] * state->bandpass.x[0] + + state->bandpass.b[2] / state->bandpass.a[0] * state->bandpass.x[1] - + state->bandpass.a[1] / state->bandpass.a[0] * state->bandpass.y[0] - + state->bandpass.a[2] / state->bandpass.a[0] * state->bandpass.y[1]; + + state->bandpass.x[1] = state->bandpass.x[0]; + state->bandpass.x[0] = smp; + state->bandpass.y[1] = state->bandpass.y[0]; + state->bandpass.y[0] = tempsmp; + + oversample_buffer[it][ot] = tempsmp; + } + + /* Fourth step, final, do attenuation and perform decimation, */ + /* store only one sample out of 4. */ + temps[it] = oversample_buffer[it][0] * state->attenuation; + } + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > 0.00001f)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; + } +} + +static ALeffectStateFactory *ALdistortionState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); + + +static ALeffectState *ALdistortionStateFactory_create(void) +{ + ALdistortionState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALdistortionState, ALeffectState, state); + + state->bandpass.type = BANDPASS; + state->lowpass.type = LOWPASS; + + /* Initialize sample history only on filter creation to avoid */ + /* sound clicks if filter settings were changed in runtime. */ + state->bandpass.x[0] = 0.0f; + state->bandpass.x[1] = 0.0f; + state->lowpass.y[0] = 0.0f; + state->lowpass.y[1] = 0.0f; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALdistortionStateFactory_destroy(ALeffectState *effect) +{ + ALdistortionState *state = STATIC_UPCAST(ALdistortionState, ALeffectState, effect); + ALdistortionState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdistortionStateFactory); + + +static void init_distortion_factory(void) +{ + SET_VTABLE2(ALdistortionStateFactory, ALeffectStateFactory, &DistortionFactory); +} + +ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_distortion_factory); + return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); +} + + +void distortion_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + effect=effect; + val=val; + + switch(param) + { + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void distortion_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + distortion_SetParami(effect, context, param, vals[0]); +} +void distortion_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_DISTORTION_EDGE: + if(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE) + effect->Distortion.Edge = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_DISTORTION_GAIN: + if(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN) + effect->Distortion.Gain = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_DISTORTION_LOWPASS_CUTOFF: + if(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF) + effect->Distortion.LowpassCutoff = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_DISTORTION_EQCENTER: + if(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER) + effect->Distortion.EQCenter = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_DISTORTION_EQBANDWIDTH: + if(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH) + effect->Distortion.EQBandwidth = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void distortion_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + distortion_SetParamf(effect, context, param, vals[0]); +} + +void distortion_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + effect=effect; + val=val; + + switch(param) + { + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void distortion_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + distortion_GetParami(effect, context, param, vals); +} +void distortion_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_DISTORTION_EDGE: + *val = effect->Distortion.Edge; + break; + + case AL_DISTORTION_GAIN: + *val = effect->Distortion.Gain; + break; + + case AL_DISTORTION_LOWPASS_CUTOFF: + *val = effect->Distortion.LowpassCutoff; + break; + + case AL_DISTORTION_EQCENTER: + *val = effect->Distortion.EQCenter; + break; + + case AL_DISTORTION_EQBANDWIDTH: + *val = effect->Distortion.EQBandwidth; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void distortion_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + distortion_GetParamf(effect, context, param, vals); +} diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c new file mode 100644 index 00000000..d5915295 --- /dev/null +++ b/Alc/effects/echo.c @@ -0,0 +1,324 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2009 by Chris Robinson. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALechoStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALechoStateFactory; + +static ALechoStateFactory EchoFactory; + + +typedef struct ALechoState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat *SampleBuffer; + ALuint BufferLength; + + // The echo is two tap. The delay is the number of samples from before the + // current offset + struct { + ALuint delay; + } Tap[2]; + ALuint Offset; + /* The panning gains for the two taps */ + ALfloat Gain[2][MaxChannels]; + + ALfloat FeedGain; + + FILTER iirFilter; +} ALechoState; + +static ALvoid ALechoState_Destruct(ALechoState *state) +{ + free(state->SampleBuffer); + state->SampleBuffer = NULL; +} + +static ALboolean ALechoState_DeviceUpdate(ALechoState *state, ALCdevice *Device) +{ + ALuint maxlen, i; + + // Use the next power of 2 for the buffer length, so the tap offsets can be + // wrapped using a mask instead of a modulo + maxlen = fastf2u(AL_ECHO_MAX_DELAY * Device->Frequency) + 1; + maxlen += fastf2u(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1; + maxlen = NextPowerOf2(maxlen); + + if(maxlen != state->BufferLength) + { + void *temp; + + temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfloat)); + if(!temp) + return AL_FALSE; + state->SampleBuffer = temp; + state->BufferLength = maxlen; + } + for(i = 0;i < state->BufferLength;i++) + state->SampleBuffer[i] = 0.0f; + + return AL_TRUE; +} + +static ALvoid ALechoState_Update(ALechoState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALuint frequency = Device->Frequency; + ALfloat lrpan, cw, g, gain; + ALfloat dirGain; + ALuint i; + + state->Tap[0].delay = fastf2u(Slot->effect.Echo.Delay * frequency) + 1; + state->Tap[1].delay = fastf2u(Slot->effect.Echo.LRDelay * frequency); + state->Tap[1].delay += state->Tap[0].delay; + + lrpan = Slot->effect.Echo.Spread; + + state->FeedGain = Slot->effect.Echo.Feedback; + + cw = cosf(F_PI*2.0f * LOWPASSFREQREF / frequency); + g = 1.0f - Slot->effect.Echo.Damping; + state->iirFilter.coeff = lpCoeffCalc(g, cw); + + gain = Slot->Gain; + for(i = 0;i < MaxChannels;i++) + { + state->Gain[0][i] = 0.0f; + state->Gain[1][i] = 0.0f; + } + + dirGain = fabsf(lrpan); + + /* First tap panning */ + ComputeAngleGains(Device, atan2f(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]); + + /* Second tap panning */ + ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]); +} + +static ALvoid ALechoState_Process(ALechoState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + const ALuint mask = state->BufferLength-1; + const ALuint tap1 = state->Tap[0].delay; + const ALuint tap2 = state->Tap[1].delay; + ALuint offset = state->Offset; + ALfloat smp; + ALuint base; + ALuint i, k; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64][2]; + ALuint td = minu(SamplesToDo-base, 64); + + for(i = 0;i < td;i++) + { + /* First tap */ + temps[i][0] = state->SampleBuffer[(offset-tap1) & mask]; + /* Second tap */ + temps[i][1] = state->SampleBuffer[(offset-tap2) & mask]; + + // Apply damping and feedback gain to the second tap, and mix in the + // new sample + smp = lpFilter2P(&state->iirFilter, temps[i][1]+SamplesIn[i]); + state->SampleBuffer[offset&mask] = smp * state->FeedGain; + } + + for(k = 0;k < MaxChannels;k++) + { + ALfloat gain = state->Gain[0][k]; + if(gain > 0.00001f) + { + for(i = 0;i < td;i++) + SamplesOut[k][i+base] += temps[i][0] * gain; + } + + gain = state->Gain[1][k]; + if(gain > 0.00001f) + { + for(i = 0;i < td;i++) + SamplesOut[k][i+base] += temps[i][1] * gain; + } + } + + base += td; + } + + state->Offset = offset; +} + +static ALeffectStateFactory *ALechoState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &EchoFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); + + +ALeffectState *ALechoStateFactory_create(void) +{ + ALechoState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALechoState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer = NULL; + + state->Tap[0].delay = 0; + state->Tap[1].delay = 0; + state->Offset = 0; + + state->iirFilter.coeff = 0.0f; + state->iirFilter.history[0] = 0.0f; + state->iirFilter.history[1] = 0.0f; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALechoStateFactory_destroy(ALeffectState *effect) +{ + ALechoState *state = STATIC_UPCAST(ALechoState, ALeffectState, effect); + ALechoState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALechoStateFactory); + + +static void init_echo_factory(void) +{ + SET_VTABLE2(ALechoStateFactory, ALeffectStateFactory, &EchoFactory); +} + +ALeffectStateFactory *ALechoStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_echo_factory); + return STATIC_CAST(ALeffectStateFactory, &EchoFactory); +} + + +void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } +void echo_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + echo_SetParami(effect, context, param, vals[0]); +} +void echo_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_ECHO_DELAY: + if(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY) + effect->Echo.Delay = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_ECHO_LRDELAY: + if(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY) + effect->Echo.LRDelay = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_ECHO_DAMPING: + if(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING) + effect->Echo.Damping = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_ECHO_FEEDBACK: + if(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK) + effect->Echo.Feedback = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_ECHO_SPREAD: + if(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD) + effect->Echo.Spread = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void echo_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + echo_SetParamf(effect, context, param, vals[0]); +} + +void echo_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } +void echo_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + echo_GetParami(effect, context, param, vals); +} +void echo_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_ECHO_DELAY: + *val = effect->Echo.Delay; + break; + + case AL_ECHO_LRDELAY: + *val = effect->Echo.LRDelay; + break; + + case AL_ECHO_DAMPING: + *val = effect->Echo.Damping; + break; + + case AL_ECHO_FEEDBACK: + *val = effect->Echo.Feedback; + break; + + case AL_ECHO_SPREAD: + *val = effect->Echo.Spread; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void echo_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + echo_GetParamf(effect, context, param, vals); +} diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c new file mode 100644 index 00000000..d397a9ba --- /dev/null +++ b/Alc/effects/equalizer.c @@ -0,0 +1,499 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALequalizerStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALequalizerStateFactory; + +static ALequalizerStateFactory EqualizerFactory; + + +/* The document "Effects Extension Guide.pdf" says that low and high * + * frequencies are cutoff frequencies. This is not fully correct, they * + * are corner frequencies for low and high shelf filters. If they were * + * just cutoff frequencies, there would be no need in cutoff frequency * + * gains, which are present. Documentation for "Creative Proteus X2" * + * software describes 4-band equalizer functionality in a much better * + * way. This equalizer seems to be a predecessor of OpenAL 4-band * + * equalizer. With low and high shelf filters we are able to cutoff * + * frequencies below and/or above corner frequencies using attenuation * + * gains (below 1.0) and amplify all low and/or high frequencies using * + * gains above 1.0. * + * * + * Low-shelf Low Mid Band High Mid Band High-shelf * + * corner center center corner * + * frequency frequency frequency frequency * + * 50Hz..800Hz 200Hz..3000Hz 1000Hz..8000Hz 4000Hz..16000Hz * + * * + * | | | | * + * | | | | * + * B -----+ /--+--\ /--+--\ +----- * + * O |\ | | | | | | /| * + * O | \ - | - - | - / | * + * S + | \ | | | | | | / | * + * T | | | | | | | | | | * + * ---------+---------------+------------------+---------------+-------- * + * C | | | | | | | | | | * + * U - | / | | | | | | \ | * + * T | / - | - - | - \ | * + * O |/ | | | | | | \| * + * F -----+ \--+--/ \--+--/ +----- * + * F | | | | * + * | | | | * + * * + * Gains vary from 0.126 up to 7.943, which means from -18dB attenuation * + * up to +18dB amplification. Band width varies from 0.01 up to 1.0 in * + * octaves for two mid bands. * + * * + * Implementation is based on the "Cookbook formulae for audio EQ biquad * + * filter coefficients" by Robert Bristow-Johnson * + * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ + +typedef enum ALEQFilterType { + LOW_SHELF, + HIGH_SHELF, + PEAKING +} ALEQFilterType; + +typedef struct ALEQFilter { + ALEQFilterType type; + ALfloat x[2]; /* History of two last input samples */ + ALfloat y[2]; /* History of two last output samples */ + ALfloat a[3]; /* Transfer function coefficients "a" */ + ALfloat b[3]; /* Transfer function coefficients "b" */ +} ALEQFilter; + +typedef struct ALequalizerState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MaxChannels]; + + /* Effect parameters */ + ALEQFilter bandfilter[4]; +} ALequalizerState; + +static ALvoid ALequalizerState_Destruct(ALequalizerState *state) +{ + (void)state; +} + +static ALboolean ALequalizerState_DeviceUpdate(ALequalizerState *state, ALCdevice *device) +{ + return AL_TRUE; + (void)state; + (void)device; +} + +static ALvoid ALequalizerState_Update(ALequalizerState *state, ALCdevice *device, const ALeffectslot *slot) +{ + ALfloat frequency = (ALfloat)device->Frequency; + ALfloat gain = sqrtf(1.0f / device->NumChan) * slot->Gain; + ALuint it; + + for(it = 0;it < MaxChannels;it++) + state->Gain[it] = 0.0f; + for(it = 0; it < device->NumChan; it++) + { + enum Channel chan = device->Speaker2Chan[it]; + state->Gain[chan] = gain; + } + + /* Calculate coefficients for the each type of filter */ + for(it = 0; it < 4; it++) + { + ALfloat gain; + ALfloat filter_frequency; + ALfloat bandwidth = 0.0f; + ALfloat w0; + ALfloat alpha = 0.0f; + + /* convert linear gains to filter gains */ + switch (it) + { + case 0: /* Low Shelf */ + gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.LowGain)) / 40.0f); + filter_frequency = slot->effect.Equalizer.LowCutoff; + break; + case 1: /* Peaking */ + gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.Mid1Gain)) / 40.0f); + filter_frequency = slot->effect.Equalizer.Mid1Center; + bandwidth = slot->effect.Equalizer.Mid1Width; + break; + case 2: /* Peaking */ + gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.Mid2Gain)) / 40.0f); + filter_frequency = slot->effect.Equalizer.Mid2Center; + bandwidth = slot->effect.Equalizer.Mid2Width; + break; + case 3: /* High Shelf */ + gain = powf(10.0f, (20.0f * log10f(slot->effect.Equalizer.HighGain)) / 40.0f); + filter_frequency = slot->effect.Equalizer.HighCutoff; + break; + } + + w0 = 2.0f*F_PI * filter_frequency / frequency; + + /* Calculate filter coefficients depending on filter type */ + switch(state->bandfilter[it].type) + { + case LOW_SHELF: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * + (1.0f / 0.75f - 1.0f) + 2.0f); + state->bandfilter[it].b[0] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + state->bandfilter[it].b[1] = 2.0f * gain * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + state->bandfilter[it].b[2] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + state->bandfilter[it].a[0] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + state->bandfilter[it].a[1] = -2.0f * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + state->bandfilter[it].a[2] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case HIGH_SHELF: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * + (1.0f / 0.75f - 1.0f) + 2.0f); + state->bandfilter[it].b[0] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + state->bandfilter[it].b[1] = -2.0f * gain * ((gain - 1.0f) + + (gain + 1.0f) * + cosf(w0)); + state->bandfilter[it].b[2] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + state->bandfilter[it].a[0] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + state->bandfilter[it].a[1] = 2.0f * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + state->bandfilter[it].a[2] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case PEAKING: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + state->bandfilter[it].b[0] = 1.0f + alpha * gain; + state->bandfilter[it].b[1] = -2.0f * cosf(w0); + state->bandfilter[it].b[2] = 1.0f - alpha * gain; + state->bandfilter[it].a[0] = 1.0f + alpha / gain; + state->bandfilter[it].a[1] = -2.0f * cosf(w0); + state->bandfilter[it].a[2] = 1.0f - alpha / gain; + break; + } + } +} + +static ALvoid ALequalizerState_Process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + ALuint base; + ALuint it; + ALuint kt; + ALuint ft; + + for(base = 0;base < SamplesToDo;) + { + ALfloat temps[64]; + ALuint td = minu(SamplesToDo-base, 64); + + for(it = 0;it < td;it++) + { + ALfloat smp = SamplesIn[base+it]; + ALfloat tempsmp; + + for(ft = 0;ft < 4;ft++) + { + ALEQFilter *filter = &state->bandfilter[ft]; + + tempsmp = filter->b[0] / filter->a[0] * smp + + filter->b[1] / filter->a[0] * filter->x[0] + + filter->b[2] / filter->a[0] * filter->x[1] - + filter->a[1] / filter->a[0] * filter->y[0] - + filter->a[2] / filter->a[0] * filter->y[1]; + + filter->x[1] = filter->x[0]; + filter->x[0] = smp; + filter->y[1] = filter->y[0]; + filter->y[0] = tempsmp; + smp = tempsmp; + } + + temps[it] = smp; + } + + for(kt = 0;kt < MaxChannels;kt++) + { + ALfloat gain = state->Gain[kt]; + if(!(gain > 0.00001f)) + continue; + + for(it = 0;it < td;it++) + SamplesOut[kt][base+it] += gain * temps[it]; + } + + base += td; + } +} + +static ALeffectStateFactory *ALequalizerState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); + + +ALeffectState *ALequalizerStateFactory_create(void) +{ + ALequalizerState *state; + int it; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALequalizerState, ALeffectState, state); + + state->bandfilter[0].type = LOW_SHELF; + state->bandfilter[1].type = PEAKING; + state->bandfilter[2].type = PEAKING; + state->bandfilter[3].type = HIGH_SHELF; + + /* Initialize sample history only on filter creation to avoid */ + /* sound clicks if filter settings were changed in runtime. */ + for(it = 0; it < 4; it++) + { + state->bandfilter[it].x[0] = 0.0f; + state->bandfilter[it].x[1] = 0.0f; + state->bandfilter[it].y[0] = 0.0f; + state->bandfilter[it].y[1] = 0.0f; + } + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALequalizerStateFactory_destroy(ALeffectState *effect) +{ + ALequalizerState *state = STATIC_UPCAST(ALequalizerState, ALeffectState, effect); + ALequalizerState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALequalizerStateFactory); + + +static void init_equalizer_factory(void) +{ + SET_VTABLE2(ALequalizerStateFactory, ALeffectStateFactory, &EqualizerFactory); +} + +ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_equalizer_factory); + return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); +} + + +void equalizer_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + effect=effect; + val=val; + + switch(param) + { + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void equalizer_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + equalizer_SetParami(effect, context, param, vals[0]); +} +void equalizer_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_EQUALIZER_LOW_GAIN: + if(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN) + effect->Equalizer.LowGain = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_LOW_CUTOFF: + if(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF) + effect->Equalizer.LowCutoff = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_MID1_GAIN: + if(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN) + effect->Equalizer.Mid1Gain = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_MID1_CENTER: + if(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER) + effect->Equalizer.Mid1Center = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_MID1_WIDTH: + if(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH) + effect->Equalizer.Mid1Width = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_MID2_GAIN: + if(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN) + effect->Equalizer.Mid2Gain = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_MID2_CENTER: + if(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER) + effect->Equalizer.Mid2Center = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_MID2_WIDTH: + if(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH) + effect->Equalizer.Mid2Width = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_HIGH_GAIN: + if(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN) + effect->Equalizer.HighGain = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_EQUALIZER_HIGH_CUTOFF: + if(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF) + effect->Equalizer.HighCutoff = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void equalizer_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + equalizer_SetParamf(effect, context, param, vals[0]); +} + +void equalizer_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + effect=effect; + val=val; + + switch(param) + { + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void equalizer_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + equalizer_GetParami(effect, context, param, vals); +} +void equalizer_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_EQUALIZER_LOW_GAIN: + *val = effect->Equalizer.LowGain; + break; + + case AL_EQUALIZER_LOW_CUTOFF: + *val = effect->Equalizer.LowCutoff; + break; + + case AL_EQUALIZER_MID1_GAIN: + *val = effect->Equalizer.Mid1Gain; + break; + + case AL_EQUALIZER_MID1_CENTER: + *val = effect->Equalizer.Mid1Center; + break; + + case AL_EQUALIZER_MID1_WIDTH: + *val = effect->Equalizer.Mid1Width; + break; + + case AL_EQUALIZER_MID2_GAIN: + *val = effect->Equalizer.Mid2Gain; + break; + + case AL_EQUALIZER_MID2_CENTER: + *val = effect->Equalizer.Mid2Center; + break; + + case AL_EQUALIZER_MID2_WIDTH: + *val = effect->Equalizer.Mid2Width; + break; + + case AL_EQUALIZER_HIGH_GAIN: + *val = effect->Equalizer.HighGain; + break; + + case AL_EQUALIZER_HIGH_CUTOFF: + *val = effect->Equalizer.HighCutoff; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void equalizer_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + equalizer_GetParamf(effect, context, param, vals); +} diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c new file mode 100644 index 00000000..a0f94a46 --- /dev/null +++ b/Alc/effects/flanger.c @@ -0,0 +1,411 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2013 by Mike Gorchak + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALflangerStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALflangerStateFactory; + +static ALflangerStateFactory FlangerFactory; + + +typedef struct ALflangerState { + DERIVE_FROM_TYPE(ALeffectState); + + ALfloat *SampleBufferLeft; + ALfloat *SampleBufferRight; + ALuint BufferLength; + ALint offset; + ALfloat lfo_coeff; + ALint lfo_disp; + + /* Gains for left and right sides */ + ALfloat Gain[2][MaxChannels]; + + /* effect parameters */ + ALint waveform; + ALint delay; + ALfloat depth; + ALfloat feedback; +} ALflangerState; + +static ALvoid ALflangerState_Destruct(ALflangerState *state) +{ + free(state->SampleBufferLeft); + state->SampleBufferLeft = NULL; + + free(state->SampleBufferRight); + state->SampleBufferRight = NULL; +} + +static ALboolean ALflangerState_DeviceUpdate(ALflangerState *state, ALCdevice *Device) +{ + ALuint maxlen; + ALuint it; + + maxlen = fastf2u(AL_FLANGER_MAX_DELAY * 3.0f * Device->Frequency) + 1; + maxlen = NextPowerOf2(maxlen); + + if(maxlen != state->BufferLength) + { + void *temp; + + temp = realloc(state->SampleBufferLeft, maxlen * sizeof(ALfloat)); + if(!temp) return AL_FALSE; + state->SampleBufferLeft = temp; + + temp = realloc(state->SampleBufferRight, maxlen * sizeof(ALfloat)); + if(!temp) return AL_FALSE; + state->SampleBufferRight = temp; + + state->BufferLength = maxlen; + } + + for(it = 0;it < state->BufferLength;it++) + { + state->SampleBufferLeft[it] = 0.0f; + state->SampleBufferRight[it] = 0.0f; + } + + return AL_TRUE; +} + +static ALvoid ALflangerState_Update(ALflangerState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat frequency = (ALfloat)Device->Frequency; + ALfloat rate; + ALint phase; + ALuint it; + + for(it = 0;it < MaxChannels;it++) + { + state->Gain[0][it] = 0.0f; + state->Gain[1][it] = 0.0f; + } + + state->waveform = Slot->effect.Flanger.Waveform; + state->depth = Slot->effect.Flanger.Depth; + state->feedback = Slot->effect.Flanger.Feedback; + state->delay = fastf2i(Slot->effect.Flanger.Delay * frequency); + + /* Gains for left and right sides */ + ComputeAngleGains(Device, atan2f(-1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[0]); + ComputeAngleGains(Device, atan2f(+1.0f, 0.0f), 0.0f, Slot->Gain, state->Gain[1]); + + phase = Slot->effect.Flanger.Phase; + rate = Slot->effect.Flanger.Rate; + + /* Calculate LFO coefficient */ + switch(state->waveform) + { + case AL_FLANGER_WAVEFORM_TRIANGLE: + if(rate == 0.0f) + state->lfo_coeff = 0.0f; + else + state->lfo_coeff = 1.0f / (frequency / rate); + break; + case AL_FLANGER_WAVEFORM_SINUSOID: + if(rate == 0.0f) + state->lfo_coeff = 0.0f; + else + state->lfo_coeff = F_PI * 2.0f / (frequency / rate); + break; + } + + /* Calculate lfo phase displacement */ + if(phase == 0 || rate == 0.0f) + state->lfo_disp = 0; + else + state->lfo_disp = fastf2i(frequency / rate / (360.0f/phase)); +} + +static __inline void Triangle(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) +{ + ALfloat lfo_value; + + lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff * offset * 4.0f, 4.0f)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + lfo_value = 2.0f - fabsf(2.0f - fmodf(state->lfo_coeff * + (offset+state->lfo_disp) * 4.0f, + 4.0f)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +static __inline void Sinusoid(ALint *delay_left, ALint *delay_right, ALint offset, const ALflangerState *state) +{ + ALfloat lfo_value; + + lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff * offset, 2.0f*F_PI)); + lfo_value *= state->depth * state->delay; + *delay_left = fastf2i(lfo_value) + state->delay; + + lfo_value = 1.0f + sinf(fmodf(state->lfo_coeff * (offset+state->lfo_disp), + 2.0f*F_PI)); + lfo_value *= state->depth * state->delay; + *delay_right = fastf2i(lfo_value) + state->delay; +} + +#define DECL_TEMPLATE(func) \ +static void Process##func(ALflangerState *state, ALuint SamplesToDo, \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ +{ \ + const ALint mask = state->BufferLength-1; \ + ALint offset = state->offset; \ + ALuint it, kt; \ + ALuint base; \ + \ + for(base = 0;base < SamplesToDo;) \ + { \ + ALfloat temps[64][2]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + \ + for(it = 0;it < td;it++,offset++) \ + { \ + ALint delay_left, delay_right; \ + (func)(&delay_left, &delay_right, offset, state); \ + \ + temps[it][0] = state->SampleBufferLeft[(offset-delay_left)&mask]; \ + state->SampleBufferLeft[offset&mask] = (temps[it][0] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + \ + temps[it][1] = state->SampleBufferRight[(offset-delay_right)&mask];\ + state->SampleBufferRight[offset&mask] = (temps[it][1] + \ + SamplesIn[it+base]) * \ + state->feedback; \ + } \ + \ + for(kt = 0;kt < MaxChannels;kt++) \ + { \ + ALfloat gain = state->Gain[0][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][0] * gain; \ + } \ + \ + gain = state->Gain[1][kt]; \ + if(gain > 0.00001f) \ + { \ + for(it = 0;it < td;it++) \ + SamplesOut[kt][it+base] += temps[it][1] * gain; \ + } \ + } \ + \ + base += td; \ + } \ + \ + 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]) +{ + if(state->waveform == AL_FLANGER_WAVEFORM_TRIANGLE) + ProcessTriangle(state, SamplesToDo, SamplesIn, SamplesOut); + else if(state->waveform == AL_FLANGER_WAVEFORM_SINUSOID) + ProcessSinusoid(state, SamplesToDo, SamplesIn, SamplesOut); +} + +static ALeffectStateFactory *ALflangerState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); + + +ALeffectState *ALflangerStateFactory_create(void) +{ + ALflangerState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALflangerState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBufferLeft = NULL; + state->SampleBufferRight = NULL; + state->offset = 0; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALflangerStateFactory_destroy(ALeffectState *effect) +{ + ALflangerState *state = STATIC_UPCAST(ALflangerState, ALeffectState, effect); + ALflangerState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALflangerStateFactory); + + +static void init_flanger_factory(void) +{ + SET_VTABLE2(ALflangerStateFactory, ALeffectStateFactory, &FlangerFactory); +} + +ALeffectStateFactory *ALflangerStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_flanger_factory); + return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); +} + + +void flanger_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + switch(param) + { + case AL_FLANGER_WAVEFORM: + if(val >= AL_FLANGER_MIN_WAVEFORM && val <= AL_FLANGER_MAX_WAVEFORM) + effect->Flanger.Waveform = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_FLANGER_PHASE: + if(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE) + effect->Flanger.Phase = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void flanger_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + flanger_SetParami(effect, context, param, vals[0]); +} +void flanger_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_FLANGER_RATE: + if(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE) + effect->Flanger.Rate = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_FLANGER_DEPTH: + if(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH) + effect->Flanger.Depth = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_FLANGER_FEEDBACK: + if(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK) + effect->Flanger.Feedback = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_FLANGER_DELAY: + if(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY) + effect->Flanger.Delay = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void flanger_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + flanger_SetParamf(effect, context, param, vals[0]); +} + +void flanger_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + switch(param) + { + case AL_FLANGER_WAVEFORM: + *val = effect->Flanger.Waveform; + break; + + case AL_FLANGER_PHASE: + *val = effect->Flanger.Phase; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void flanger_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + flanger_GetParami(effect, context, param, vals); +} +void flanger_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_FLANGER_RATE: + *val = effect->Flanger.Rate; + break; + + case AL_FLANGER_DEPTH: + *val = effect->Flanger.Depth; + break; + + case AL_FLANGER_FEEDBACK: + *val = effect->Flanger.Feedback; + break; + + case AL_FLANGER_DELAY: + *val = effect->Flanger.Delay; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void flanger_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + flanger_GetParamf(effect, context, param, vals); +} diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c new file mode 100644 index 00000000..ec99bd53 --- /dev/null +++ b/Alc/effects/modulator.c @@ -0,0 +1,343 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2009 by Chris Robinson. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alFilter.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" + + +typedef struct ALmodulatorStateFactory { + DERIVE_FROM_TYPE(ALeffectStateFactory); +} ALmodulatorStateFactory; + +static ALmodulatorStateFactory ModulatorFactory; + + +typedef struct ALmodulatorState { + DERIVE_FROM_TYPE(ALeffectState); + + enum { + SINUSOID, + SAWTOOTH, + SQUARE + } Waveform; + + ALuint index; + ALuint step; + + ALfloat Gain[MaxChannels]; + + FILTER iirFilter; +} ALmodulatorState; + +#define WAVEFORM_FRACBITS 24 +#define WAVEFORM_FRACONE (1<> (WAVEFORM_FRACBITS - 1)) & 1); +} + + +static __inline ALfloat hpFilter1P(FILTER *iir, ALfloat input) +{ + ALfloat *history = iir->history; + ALfloat a = iir->coeff; + ALfloat output = input; + + output = output + (history[0]-output)*a; + history[0] = output; + + return input - output; +} + + +#define DECL_TEMPLATE(func) \ +static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \ + const ALfloat *restrict SamplesIn, \ + ALfloat (*restrict SamplesOut)[BUFFERSIZE]) \ +{ \ + const ALuint step = state->step; \ + ALuint index = state->index; \ + ALuint base; \ + \ + for(base = 0;base < SamplesToDo;) \ + { \ + ALfloat temps[64]; \ + ALuint td = minu(SamplesToDo-base, 64); \ + ALuint i, k; \ + \ + for(i = 0;i < td;i++) \ + { \ + ALfloat samp; \ + samp = SamplesIn[base+i]; \ + samp = hpFilter1P(&state->iirFilter, samp); \ + \ + index += step; \ + index &= WAVEFORM_FRACMASK; \ + temps[i] = samp * func(index); \ + } \ + \ + for(k = 0;k < MaxChannels;k++) \ + { \ + ALfloat gain = state->Gain[k]; \ + if(!(gain > 0.00001f)) \ + continue; \ + \ + for(i = 0;i < td;i++) \ + SamplesOut[k][base+i] += gain * temps[i]; \ + } \ + \ + base += td; \ + } \ + state->index = index; \ +} + +DECL_TEMPLATE(Sin) +DECL_TEMPLATE(Saw) +DECL_TEMPLATE(Square) + +#undef DECL_TEMPLATE + + +static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state) +{ + (void)state; +} + +static ALboolean ALmodulatorState_DeviceUpdate(ALmodulatorState *state, ALCdevice *Device) +{ + return AL_TRUE; + (void)state; + (void)Device; +} + +static ALvoid ALmodulatorState_Update(ALmodulatorState *state, ALCdevice *Device, const ALeffectslot *Slot) +{ + ALfloat gain, cw, a = 0.0f; + ALuint index; + + if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID) + state->Waveform = SINUSOID; + else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH) + state->Waveform = SAWTOOTH; + else if(Slot->effect.Modulator.Waveform == AL_RING_MODULATOR_SQUARE) + state->Waveform = SQUARE; + + state->step = fastf2u(Slot->effect.Modulator.Frequency*WAVEFORM_FRACONE / + Device->Frequency); + if(state->step == 0) state->step = 1; + + cw = cosf(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff / + Device->Frequency); + a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f); + state->iirFilter.coeff = a; + + gain = sqrtf(1.0f/Device->NumChan); + gain *= Slot->Gain; + for(index = 0;index < MaxChannels;index++) + state->Gain[index] = 0.0f; + for(index = 0;index < Device->NumChan;index++) + { + enum Channel chan = Device->Speaker2Chan[index]; + state->Gain[chan] = gain; + } +} + +static ALvoid ALmodulatorState_Process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) +{ + switch(state->Waveform) + { + case SINUSOID: + ProcessSin(state, SamplesToDo, SamplesIn, SamplesOut); + break; + + case SAWTOOTH: + ProcessSaw(state, SamplesToDo, SamplesIn, SamplesOut); + break; + + case SQUARE: + ProcessSquare(state, SamplesToDo, SamplesIn, SamplesOut); + break; + } +} + +static ALeffectStateFactory *ALmodulatorState_getCreator(void) +{ + return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); +} + +DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); + + +static ALeffectState *ALmodulatorStateFactory_create(void) +{ + ALmodulatorState *state; + + state = malloc(sizeof(*state)); + if(!state) return NULL; + SET_VTABLE2(ALmodulatorState, ALeffectState, state); + + state->index = 0; + state->step = 1; + + state->iirFilter.coeff = 0.0f; + state->iirFilter.history[0] = 0.0f; + + return STATIC_CAST(ALeffectState, state); +} + +static ALvoid ALmodulatorStateFactory_destroy(ALeffectState *effect) +{ + ALmodulatorState *state = STATIC_UPCAST(ALmodulatorState, ALeffectState, effect); + ALmodulatorState_Destruct(state); + free(state); +} + +DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALmodulatorStateFactory); + + +static void init_modulator_factory(void) +{ + SET_VTABLE2(ALmodulatorStateFactory, ALeffectStateFactory, &ModulatorFactory); +} + +ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, init_modulator_factory); + return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); +} + + +void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + if(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY) + effect->Modulator.Frequency = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + if(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF) + effect->Modulator.HighPassCutoff = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + mod_SetParamf(effect, context, param, vals[0]); +} +void mod_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + mod_SetParamf(effect, context, param, (ALfloat)val); + break; + + case AL_RING_MODULATOR_WAVEFORM: + if(val >= AL_RING_MODULATOR_MIN_WAVEFORM && val <= AL_RING_MODULATOR_MAX_WAVEFORM) + effect->Modulator.Waveform = val; + else + alSetError(context, AL_INVALID_VALUE); + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + mod_SetParami(effect, context, param, vals[0]); +} + +void mod_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + *val = (ALint)effect->Modulator.Frequency; + break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + *val = (ALint)effect->Modulator.HighPassCutoff; + break; + case AL_RING_MODULATOR_WAVEFORM: + *val = effect->Modulator.Waveform; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + mod_GetParami(effect, context, param, vals); +} +void mod_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + switch(param) + { + case AL_RING_MODULATOR_FREQUENCY: + *val = effect->Modulator.Frequency; + break; + case AL_RING_MODULATOR_HIGHPASS_CUTOFF: + *val = effect->Modulator.HighPassCutoff; + break; + + default: + alSetError(context, AL_INVALID_ENUM); + break; + } +} +void mod_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + mod_GetParamf(effect, context, param, vals); +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fb8811f..d4fa325f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -439,22 +439,22 @@ SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c ) SET(ALC_OBJS Alc/ALc.c Alc/ALu.c - Alc/effects/null.c - Alc/alcChorus.c Alc/alcConfig.c - Alc/alcDedicated.c - Alc/alcDistortion.c - Alc/alcEcho.c - Alc/alcEqualizer.c - Alc/alcFlanger.c - Alc/alcModulator.c - Alc/effects/reverb.c Alc/alcRing.c Alc/alcThread.c Alc/bs2b.c + Alc/effects/chorus.c + Alc/effects/dedicated.c + Alc/effects/distortion.c + Alc/effects/echo.c + Alc/effects/equalizer.c + Alc/effects/flanger.c + Alc/effects/modulator.c + Alc/effects/null.c + Alc/effects/reverb.c Alc/helpers.c - Alc/panning.c Alc/hrtf.c + Alc/panning.c Alc/mixer.c Alc/mixer_c.c ) -- cgit v1.2.3