From 55c790c9ff28acad5e5da365bee8a6f693d21796 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 12 Apr 2009 16:01:10 -0700 Subject: Add the Echo effect --- OpenAL32/Include/alAuxEffectSlot.h | 2 + OpenAL32/Include/alEcho.h | 24 ++++++ OpenAL32/Include/alEffect.h | 34 +++++++++ OpenAL32/alAuxEffectSlot.c | 20 +++++ OpenAL32/alEffect.c | 153 ++++++++++++++++++++++++++++++++++++- 5 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 OpenAL32/Include/alEcho.h (limited to 'OpenAL32') diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index a818bb47..8dfa9418 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -5,6 +5,7 @@ #include "alEffect.h" #include "alFilter.h" #include "alReverb.h" +#include "alEcho.h" #ifdef __cplusplus extern "C" { @@ -24,6 +25,7 @@ typedef struct ALeffectslot ALboolean AuxSendAuto; ALverbState *ReverbState; + ALechoState *EchoState; ALfloat WetBuffer[BUFFERSIZE]; diff --git a/OpenAL32/Include/alEcho.h b/OpenAL32/Include/alEcho.h new file mode 100644 index 00000000..34896ea7 --- /dev/null +++ b/OpenAL32/Include/alEcho.h @@ -0,0 +1,24 @@ +#ifndef AL_ECHO_H +#define AL_ECHO_H + +#include "AL/al.h" +#include "AL/alc.h" +#include "alMain.h" +#include "alEffect.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ALechoState ALechoState; + +ALechoState *EchoCreate(ALCcontext *Context); +ALvoid EchoDestroy(ALechoState *State); +ALvoid EchoUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect); +ALvoid EchoProcess(ALechoState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index 5f6723bc..6dd1b766 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -37,9 +37,33 @@ extern "C" { #define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C #define AL_REVERB_DECAY_HFLIMIT 0x000D +#define AL_ECHO_DELAY 0x0001 +#define AL_ECHO_LRDELAY 0x0002 +#define AL_ECHO_DAMPING 0x0003 +#define AL_ECHO_FEEDBACK 0x0004 +#define AL_ECHO_SPREAD 0x0005 + +#define AL_ECHO_MIN_DELAY (0.0f) +#define AL_ECHO_MAX_DELAY (0.207f) +#define AL_ECHO_DEFAULT_DELAY (0.1f) +#define AL_ECHO_MIN_LRDELAY (0.0f) +#define AL_ECHO_MAX_LRDELAY (0.404f) +#define AL_ECHO_DEFAULT_LRDELAY (0.1f) +#define AL_ECHO_MIN_DAMPING (0.0f) +#define AL_ECHO_MAX_DAMPING (0.99f) +#define AL_ECHO_DEFAULT_DAMPING (0.5f) +#define AL_ECHO_MIN_FEEDBACK (0.0f) +#define AL_ECHO_MAX_FEEDBACK (1.0f) +#define AL_ECHO_DEFAULT_FEEDBACK (0.5f) +#define AL_ECHO_MIN_SPREAD (-1.0f) +#define AL_ECHO_MAX_SPREAD (1.0f) +#define AL_ECHO_DEFAULT_SPREAD (-1.0f) + enum { REVERB = 0, + ECHO, + MAX_EFFECTS }; extern ALboolean DisabledEffects[MAX_EFFECTS]; @@ -67,6 +91,16 @@ typedef struct ALeffect_struct ALboolean DecayHFLimit; } Reverb; + struct { + ALfloat Delay; + ALfloat LRDelay; + + ALfloat Damping; + ALfloat Feedback; + + ALfloat Spread; + } Echo; + // Index to itself ALuint effect; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 85a7c6ee..810b380e 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -151,6 +151,7 @@ ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot); VerbDestroy(ALAuxiliaryEffectSlot->ReverbState); + EchoDestroy(ALAuxiliaryEffectSlot->EchoState); memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot)); free(ALAuxiliaryEffectSlot); @@ -474,14 +475,32 @@ static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, memset(&ALEffectSlot->effect, 0, sizeof(ALEffectSlot->effect)); VerbDestroy(ALEffectSlot->ReverbState); ALEffectSlot->ReverbState = NULL; + EchoDestroy(ALEffectSlot->EchoState); + ALEffectSlot->EchoState = NULL; return; } if(effect->type == AL_EFFECT_REVERB) { + if(ALEffectSlot->EchoState) + { + EchoDestroy(ALEffectSlot->EchoState); + ALEffectSlot->EchoState = NULL; + } if(!ALEffectSlot->ReverbState) ALEffectSlot->ReverbState = VerbCreate(Context); VerbUpdate(Context, ALEffectSlot, effect); } + else if(effect->type == AL_EFFECT_ECHO) + { + if(ALEffectSlot->ReverbState) + { + VerbDestroy(ALEffectSlot->ReverbState); + ALEffectSlot->ReverbState = NULL; + } + if(!ALEffectSlot->EchoState) + ALEffectSlot->EchoState = EchoCreate(Context); + EchoUpdate(Context, ALEffectSlot, effect); + } memcpy(&ALEffectSlot->effect, effect, sizeof(*effect)); } @@ -500,6 +519,7 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) // Release effectslot structure VerbDestroy(temp->ReverbState); + EchoDestroy(temp->EchoState); ALTHUNK_REMOVEENTRY(temp->effectslot); memset(temp, 0, sizeof(ALeffectslot)); diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 939b663f..4455a230 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -170,7 +170,8 @@ ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) if(param == AL_EFFECT_TYPE) { ALboolean isOk = (iValue == AL_EFFECT_NULL || - (iValue == AL_EFFECT_REVERB && !DisabledEffects[REVERB])); + (iValue == AL_EFFECT_REVERB && !DisabledEffects[REVERB]) || + (iValue == AL_EFFECT_ECHO && !DisabledEffects[ECHO])); if(isOk) InitEffectParams(ALEffect, iValue); @@ -193,6 +194,15 @@ ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -230,6 +240,15 @@ ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -343,6 +362,50 @@ ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + case AL_ECHO_DELAY: + if(flValue >= AL_ECHO_MIN_DELAY && flValue <= AL_ECHO_MAX_DELAY) + ALEffect->Echo.Delay = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_ECHO_LRDELAY: + if(flValue >= AL_ECHO_MIN_LRDELAY && flValue <= AL_ECHO_MAX_LRDELAY) + ALEffect->Echo.LRDelay = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_ECHO_DAMPING: + if(flValue >= AL_ECHO_MIN_DAMPING && flValue <= AL_ECHO_MAX_DAMPING) + ALEffect->Echo.Damping = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_ECHO_FEEDBACK: + if(flValue >= AL_ECHO_MIN_FEEDBACK && flValue <= AL_ECHO_MAX_FEEDBACK) + ALEffect->Echo.Feedback = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_ECHO_SPREAD: + if(flValue >= AL_ECHO_MIN_SPREAD && flValue <= AL_ECHO_MAX_SPREAD) + ALEffect->Echo.Spread = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -387,6 +450,23 @@ ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + case AL_ECHO_DELAY: + case AL_ECHO_LRDELAY: + case AL_ECHO_DAMPING: + case AL_ECHO_FEEDBACK: + case AL_ECHO_SPREAD: + alEffectf(effect, param, pflValues[0]); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -424,6 +504,15 @@ ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -461,6 +550,15 @@ ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -538,6 +636,35 @@ ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue) break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + case AL_ECHO_DELAY: + *pflValue = ALEffect->Echo.Delay; + break; + + case AL_ECHO_LRDELAY: + *pflValue = ALEffect->Echo.LRDelay; + break; + + case AL_ECHO_DAMPING: + *pflValue = ALEffect->Echo.Damping; + break; + + case AL_ECHO_FEEDBACK: + *pflValue = ALEffect->Echo.Feedback; + break; + + case AL_ECHO_SPREAD: + *pflValue = ALEffect->Echo.Spread; + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -582,6 +709,23 @@ ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues break; } } + else if(ALEffect->type == AL_EFFECT_ECHO) + { + switch(param) + { + case AL_ECHO_DELAY: + case AL_ECHO_LRDELAY: + case AL_ECHO_DAMPING: + case AL_ECHO_FEEDBACK: + case AL_ECHO_SPREAD: + alGetEffectf(effect, param, pflValues); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } else alSetError(AL_INVALID_ENUM); } @@ -632,5 +776,12 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Reverb.RoomRolloffFactor = 0.0f; effect->Reverb.DecayHFLimit = AL_TRUE; break; + case AL_EFFECT_ECHO: + effect->Echo.Delay = AL_ECHO_DEFAULT_DELAY; + effect->Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY; + effect->Echo.Damping = AL_ECHO_DEFAULT_DAMPING; + effect->Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; + effect->Echo.Spread = AL_ECHO_DEFAULT_SPREAD; + break; } } -- cgit v1.2.3