diff options
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 50 | ||||
-rw-r--r-- | OpenAL32/Include/alEffect.h | 57 | ||||
-rw-r--r-- | OpenAL32/Include/alFilter.h | 55 | ||||
-rw-r--r-- | OpenAL32/Include/alListener.h | 3 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 1 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 33 | ||||
-rw-r--r-- | OpenAL32/OpenAL32.c | 6 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 422 | ||||
-rw-r--r-- | OpenAL32/alEffect.c | 383 | ||||
-rw-r--r-- | OpenAL32/alExtension.c | 82 | ||||
-rw-r--r-- | OpenAL32/alFilter.c | 421 | ||||
-rw-r--r-- | OpenAL32/alListener.c | 22 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 137 |
13 files changed, 1671 insertions, 1 deletions
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h new file mode 100644 index 00000000..e34d787d --- /dev/null +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -0,0 +1,50 @@ +#ifndef _AL_AUXEFFECTSLOT_H_ +#define _AL_AUXEFFECTSLOT_H_ + +#include "alEffect.h" +#include "AL/al.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AL_EFFECTSLOT_EFFECT 0x0001 +#define AL_EFFECTSLOT_GAIN 0x0002 +#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003 + +#define AL_EFFECTSLOT_NULL 0x0000 + +typedef struct ALeffectslot_struct +{ + ALeffect effect; + + ALfloat Gain; + ALboolean AuxSendAuto; + + // Index to itself + ALuint effectslot; + + struct ALeffectslot_struct *next; +} ALeffectslot; + +AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots); +AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots); +AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot); + +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue); +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues); + +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue); +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues); + +ALvoid ReleaseALAuxiliaryEffectSlots(ALvoid); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h new file mode 100644 index 00000000..d42f5adc --- /dev/null +++ b/OpenAL32/Include/alEffect.h @@ -0,0 +1,57 @@ +#ifndef _AL_EFFECT_H_ +#define _AL_EFFECT_H_ + +#include "AL/al.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AL_EFFECT_TYPE 0x8001 + +#define AL_EFFECT_NULL 0x0000 +#define AL_EFFECT_REVERB 0x0001 +#define AL_EFFECT_CHORUS 0x0002 +#define AL_EFFECT_DISTORTION 0x0003 +#define AL_EFFECT_ECHO 0x0004 +#define AL_EFFECT_FLANGER 0x0005 +#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006 +#define AL_EFFECT_VOCAL_MORPHER 0x0007 +#define AL_EFFECT_PITCH_SHIFTER 0x0008 +#define AL_EFFECT_RING_MODULATOR 0x0009 +#define AL_EFFECT_AUTOWAH 0x000A +#define AL_EFFECT_COMPRESSOR 0x000B +#define AL_EFFECT_EQUALIZER 0x000C + +typedef struct ALeffect_struct +{ + // Effect type (AL_EFFECT_NULL, ...) + ALenum type; + + // Index to itself + ALuint effect; + + struct ALeffect_struct *next; +} ALeffect; + +AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects); +AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects); +AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect); + +AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue); +AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue); +AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues); + +AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue); +AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue); +AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues); + +ALvoid ReleaseALEffects(ALvoid); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h new file mode 100644 index 00000000..038304e8 --- /dev/null +++ b/OpenAL32/Include/alFilter.h @@ -0,0 +1,55 @@ +#ifndef _AL_FILTER_H_ +#define _AL_FILTER_H_ + +#include "AL/al.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AL_FILTER_TYPE 0x8001 + +#define AL_FILTER_NULL 0x0000 +#define AL_FILTER_LOWPASS 0x0001 +#define AL_FILTER_HIGHPASS 0x0002 +#define AL_FILTER_BANDPASS 0x0003 + +#define AL_LOWPASS_GAIN 0x0001 +#define AL_LOWPASS_GAINHF 0x0002 + + +typedef struct ALfilter_struct +{ + // Filter type (AL_FILTER_NULL, ...) + ALenum type; + + ALfloat Gain; + ALfloat GainHF; + + // Index to itself + ALuint filter; + + struct ALfilter_struct *next; +} ALfilter; + +AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters); +AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters); +AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter); + +AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue); +AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue); +AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues); + +AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue); +AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues); +AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue); +AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues); + +ALvoid ReleaseALFilters(ALvoid); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index 2075e612..d22261fa 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -7,6 +7,8 @@ extern "C" { #endif +#define AL_METERS_PER_UNIT 0x20004 + typedef struct ALlistener_struct { ALfloat Position[3]; @@ -14,6 +16,7 @@ typedef struct ALlistener_struct ALfloat Forward[3]; ALfloat Up[3]; ALfloat Gain; + ALfloat MetersPerUnit; } ALlistener; #ifdef __cplusplus diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 71e29e47..168991b7 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -98,6 +98,7 @@ extern char _alDebug[256]; //#define OUTPUT_BUFFER_SIZE (32768*SWMIXER_OUTPUT_RATE/22050) #define SPEEDOFSOUNDMETRESPERSEC (343.3f) +#define AIRABSORBGAINHF (0.994f) typedef struct { ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 499ddcf4..f54d4721 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -3,8 +3,22 @@ #define AL_NUM_SOURCE_PARAMS 128 +/* This cannot be changed without working on the code! */ +#define MAX_SENDS 1 + +#include "alFilter.h" +#include "alAuxEffectSlot.h" #include "AL/al.h" +#define AL_DIRECT_FILTER 0x20005 +#define AL_AUXILIARY_SEND_FILTER 0x20006 +#define AL_AIR_ABSORPTION_FACTOR 0x20007 +#define AL_ROOM_ROLLOFF_FACTOR 0x20008 +#define AL_CONE_OUTER_GAINHF 0x20009 +#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A +#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B +#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C + #ifdef __cplusplus extern "C" { #endif @@ -50,6 +64,25 @@ typedef struct ALsource_struct ALuint BuffersPlayed; // Number of buffers played on this loop ALuint BufferPosition; // Read position in audio data of current buffer + ALfilter DirectFilter; + + struct { + ALeffectslot Slot; + ALfilter WetFilter; + } Send[MAX_SENDS]; + + ALfloat LastDrySample; + ALfloat LastWetSample; + + ALboolean DryGainHFAuto; + ALboolean WetGainAuto; + ALboolean WetGainHFAuto; + ALfloat OuterGainHF; + + ALfloat AirAbsorptionFactor; + + ALfloat RoomRolloffFactor; + // Index to itself ALuint source; diff --git a/OpenAL32/OpenAL32.c b/OpenAL32/OpenAL32.c index 678888b0..8510c7cb 100644 --- a/OpenAL32/OpenAL32.c +++ b/OpenAL32/OpenAL32.c @@ -20,6 +20,9 @@ #include "alMain.h" #include "alBuffer.h" +#include "alFilter.h" +#include "alEffect.h" +#include "alAuxEffectSlot.h" #include "alThunk.h" CRITICAL_SECTION _alMutex; @@ -55,6 +58,9 @@ static void my_deinit() once = AL_TRUE; ReleaseALBuffers(); + ReleaseALAuxiliaryEffectSlots(); + ReleaseALEffects(); + ReleaseALFilters(); FreeALConfig(); ALTHUNK_EXIT(); DeleteCriticalSection(&_alMutex); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c new file mode 100644 index 00000000..6b8a335c --- /dev/null +++ b/OpenAL32/alAuxEffectSlot.c @@ -0,0 +1,422 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * 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 <stdlib.h> + +#include "config.h" + +#include "AL/al.h" +#include "AL/alc.h" + +#include "alMain.h" +#include "alAuxEffectSlot.h" + +static ALeffectslot *g_AuxiliaryEffectSlotList; +static ALuint g_AuxiliaryEffectSlotCount; + + +AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) +{ + ALCcontext *Context; + ALsizei i; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (n > 0) + { + /* NOTE: We only support one slot currently */ + if(n == 1 && g_AuxiliaryEffectSlotCount == 0) + { + // Check that enough memory has been allocted in the 'sources' array for n Sources + if (!IsBadWritePtr((void*)effectslots, n * sizeof(ALuint))) + { + ALeffectslot **list = &g_AuxiliaryEffectSlotList; + while(*list) + list = &(*list)->next; + + i = 0; + while(i < n) + { + *list = calloc(1, sizeof(ALeffectslot)); + if(!(*list)) + { + // We must have run out or memory + alDeleteAuxiliaryEffectSlots(i, effectslots); + alSetError(AL_OUT_OF_MEMORY); + break; + } + + (*list)->Gain = 1.0; + (*list)->AuxSendAuto = AL_TRUE; + + effectslots[i] = (ALuint)ALTHUNK_ADDENTRY(*list); + (*list)->effectslot = effectslots[i]; + + g_AuxiliaryEffectSlotCount++; + i++; + } + } + } + else + alSetError(AL_INVALID_OPERATION); + } + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) +{ + ALCcontext *Context; + ALeffectslot *ALAuxiliaryEffectSlot; + ALsizei i; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (n >= 0) + { + // Check that all effectslots are valid + for (i = 0; i < n; i++) + { + if (!alIsAuxiliaryEffectSlot(effectslots[i])) + { + alSetError(AL_INVALID_NAME); + break; + } + } + + if (i == n) + { + // All effectslots are valid + for (i = 0; i < n; i++) + { + // Recheck that the effectslot is valid, because there could be duplicated names + if (alIsAuxiliaryEffectSlot(effectslots[i])) + { + ALeffectslot **list; + + ALAuxiliaryEffectSlot = ((ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslots[i])); + + // Remove Source from list of Sources + list = &g_AuxiliaryEffectSlotList; + while(*list && *list != ALAuxiliaryEffectSlot) + list = &(*list)->next; + + if(*list) + *list = (*list)->next; + ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot); + + memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot)); + free(ALAuxiliaryEffectSlot); + + g_AuxiliaryEffectSlotCount--; + } + } + } + } + else + alSetError(AL_INVALID_VALUE); + + ProcessContext(Context); +} + +AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot) +{ + ALCcontext *Context; + ALeffectslot **list; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + list = &g_AuxiliaryEffectSlotList; + while(*list && (*list)->effectslot != effectslot) + list = &(*list)->next; + + ProcessContext(Context); + + return (*list ? AL_TRUE : AL_FALSE); +} + +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); + + switch(param) + { + case AL_EFFECTSLOT_EFFECT: + if(alIsEffect(iValue)) + { + ALeffect *effect = (ALeffect*)ALTHUNK_LOOKUPENTRY(iValue); + if(!effect) + { + ALEffectSlot->effect.type = AL_EFFECT_NULL; + ALEffectSlot->effect.effect = 0; + } + else + memcpy(&ALEffectSlot->effect, effect, sizeof(*effect)); + } + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + if(iValue == AL_TRUE || iValue == AL_FALSE) + ALEffectSlot->AuxSendAuto = iValue; + else + alSetError(AL_INVALID_VALUE); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + switch(param) + { + case AL_EFFECTSLOT_EFFECT: + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + alAuxiliaryEffectSloti(effectslot, param, piValues[0]); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue) +{ + ALCcontext *Context; + + (void)flValue; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); + + switch(param) + { + case AL_EFFECTSLOT_GAIN: + if(flValue >= 0.0f && flValue <= 1.0f) + ALEffectSlot->Gain = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + switch(param) + { + case AL_EFFECTSLOT_GAIN: + alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); + + switch(param) + { + case AL_EFFECTSLOT_EFFECT: + *piValue = ALEffectSlot->effect.effect; + break; + + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + *piValue = ALEffectSlot->AuxSendAuto; + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + switch(param) + { + case AL_EFFECTSLOT_EFFECT: + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + alGetAuxiliaryEffectSloti(effectslot, param, piValues); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); + + switch(param) + { + case AL_EFFECTSLOT_GAIN: + *pflValue = ALEffectSlot->Gain; + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (alIsAuxiliaryEffectSlot(effectslot)) + { + switch(param) + { + case AL_EFFECTSLOT_GAIN: + alGetAuxiliaryEffectSlotf(effectslot, param, pflValues); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + + +ALvoid ReleaseALAuxiliaryEffectSlots(ALvoid) +{ +#ifdef _DEBUG + if(g_AuxiliaryEffectSlotCount > 0) + AL_PRINT("exit() %d AuxiliaryEffectSlot(s) NOT deleted\n", g_AuxiliaryEffectSlotCount); +#endif + + while(g_AuxiliaryEffectSlotList) + { + ALeffectslot *temp = g_AuxiliaryEffectSlotList; + g_AuxiliaryEffectSlotList = g_AuxiliaryEffectSlotList->next; + + // Release effectslot structure + memset(temp, 0, sizeof(ALeffectslot)); + free(temp); + } + g_AuxiliaryEffectSlotCount = 0; +} diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c new file mode 100644 index 00000000..823d09ae --- /dev/null +++ b/OpenAL32/alEffect.c @@ -0,0 +1,383 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * 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 <stdlib.h> + +#include "config.h" + +#include "AL/al.h" +#include "AL/alc.h" + +#include "alMain.h" +#include "alEffect.h" + +static ALeffect *g_EffectList; +static ALuint g_EffectCount; + +static void InitEffectParams(ALeffect *effect, ALenum type); + + +AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) +{ + ALCcontext *Context; + ALsizei i; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (n > 0) + { + // Check that enough memory has been allocted in the 'sources' array for n Sources + if (!IsBadWritePtr((void*)effects, n * sizeof(ALuint))) + { + ALeffect **list = &g_EffectList; + while(*list) + list = &(*list)->next; + + i = 0; + while(i < n) + { + *list = calloc(1, sizeof(ALeffect)); + if(!(*list)) + { + // We must have run out or memory + alDeleteEffects(i, effects); + alSetError(AL_OUT_OF_MEMORY); + break; + } + + effects[i] = (ALuint)ALTHUNK_ADDENTRY(*list); + (*list)->effect = effects[i]; + + InitEffectParams(*list, AL_EFFECT_NULL); + g_EffectCount++; + i++; + } + } + } + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects) +{ + ALCcontext *Context; + ALeffect *ALEffect; + ALsizei i; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (n >= 0) + { + // Check that all effects are valid + for (i = 0; i < n; i++) + { + if (!alIsEffect(effects[i])) + { + alSetError(AL_INVALID_NAME); + break; + } + } + + if (i == n) + { + // All effects are valid + for (i = 0; i < n; i++) + { + // Recheck that the effect is valid, because there could be duplicated names + if (effects[i] && alIsEffect(effects[i])) + { + ALeffect **list; + + ALEffect = ((ALeffect*)ALTHUNK_LOOKUPENTRY(effects[i])); + + // Remove Source from list of Sources + list = &g_EffectList; + while(*list && *list != ALEffect) + list = &(*list)->next; + + if(*list) + *list = (*list)->next; + ALTHUNK_REMOVEENTRY(ALEffect->effect); + + memset(ALEffect, 0, sizeof(ALeffect)); + free(ALEffect); + + g_EffectCount--; + } + } + } + } + else + alSetError(AL_INVALID_VALUE); + + ProcessContext(Context); +} + +AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) +{ + ALCcontext *Context; + ALeffect **list; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + list = &g_EffectList; + while(*list && (*list)->effect != effect) + list = &(*list)->next; + + ProcessContext(Context); + + return ((*list || !effect) ? AL_TRUE : AL_FALSE); +} + +AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); + + switch(param) + { + case AL_EFFECT_TYPE: + if(iValue == AL_EFFECT_NULL) + InitEffectParams(ALEffect, iValue); + else + alSetError(AL_INVALID_VALUE); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + switch(param) + { + case AL_EFFECT_TYPE: + alEffecti(effect, param, piValues[0]); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue) +{ + ALCcontext *Context; + + (void)flValue; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) +{ + ALCcontext *Context; + + (void)pflValues; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); + + switch(param) + { + case AL_EFFECT_TYPE: + *piValue = ALEffect->type; + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + switch(param) + { + case AL_EFFECT_TYPE: + alGetEffecti(effect, param, piValues); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue) +{ + ALCcontext *Context; + + (void)pflValue; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) +{ + ALCcontext *Context; + + (void)pflValues; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (effect && alIsEffect(effect)) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + + +ALvoid ReleaseALEffects(ALvoid) +{ +#ifdef _DEBUG + if(g_EffectCount > 0) + AL_PRINT("exit() %d Effect(s) NOT deleted\n", g_EffectCount); +#endif + + while(g_EffectList) + { + ALeffect *temp = g_EffectList; + g_EffectList = g_EffectList->next; + + // Release effect structure + memset(temp, 0, sizeof(ALeffect)); + free(temp); + } + g_EffectCount = 0; +} + + +static void InitEffectParams(ALeffect *effect, ALenum type) +{ + effect->type = type; +} diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c index 269590e9..54371ff4 100644 --- a/OpenAL32/alExtension.c +++ b/OpenAL32/alExtension.c @@ -24,6 +24,9 @@ #include "alExtension.h" #include "alError.h" #include "alMain.h" +#include "alFilter.h" +#include "alEffect.h" +#include "alAuxEffectSlot.h" #include "AL/al.h" #include "AL/alc.h" @@ -101,6 +104,43 @@ static ALfunction function[]= { { "alDopplerVelocity", (ALvoid *) alDopplerVelocity }, { "alSpeedOfSound", (ALvoid *) alSpeedOfSound }, { "alDistanceModel", (ALvoid *) alDistanceModel }, + + { "alGenFilters", (ALvoid *) alGenFilters }, + { "alDeleteFilters", (ALvoid *) alDeleteFilters }, + { "alIsFilter", (ALvoid *) alIsFilter }, + { "alFilteri", (ALvoid *) alFilteri }, + { "alFilteriv", (ALvoid *) alFilteriv }, + { "alFilterf", (ALvoid *) alFilterf }, + { "alFilterfv", (ALvoid *) alFilterfv }, + { "alGetFilteri", (ALvoid *) alGetFilteri }, + { "alGetFilteriv", (ALvoid *) alGetFilteriv }, + { "alGetFilterf", (ALvoid *) alGetFilterf }, + { "alGetFilterfv", (ALvoid *) alGetFilterfv }, + + { "alGenEffects", (ALvoid *) alGenEffects }, + { "alDeleteEffects", (ALvoid *) alDeleteEffects }, + { "alIsEffect", (ALvoid *) alIsEffect }, + { "alEffecti", (ALvoid *) alEffecti }, + { "alEffectiv", (ALvoid *) alEffectiv }, + { "alEffectf", (ALvoid *) alEffectf }, + { "alEffectfv", (ALvoid *) alEffectfv }, + { "alGetEffecti", (ALvoid *) alGetEffecti }, + { "alGetEffectiv", (ALvoid *) alGetEffectiv }, + { "alGetEffectf", (ALvoid *) alGetEffectf }, + { "alGetEffectfv", (ALvoid *) alGetEffectfv }, + + { "alGenAuxiliaryEffectSlots", (ALvoid *) alGenAuxiliaryEffectSlots }, + { "alDeleteAuxiliaryEffectSlots",(ALvoid *) alDeleteAuxiliaryEffectSlots}, + { "alIsAuxiliaryEffectSlot", (ALvoid *) alIsAuxiliaryEffectSlot }, + { "alAuxiliaryEffectSloti", (ALvoid *) alAuxiliaryEffectSloti }, + { "alAuxiliaryEffectSlotiv", (ALvoid *) alAuxiliaryEffectSlotiv }, + { "alAuxiliaryEffectSlotf", (ALvoid *) alAuxiliaryEffectSlotf }, + { "alAuxiliaryEffectSlotfv", (ALvoid *) alAuxiliaryEffectSlotfv }, + { "alGetAuxiliaryEffectSloti", (ALvoid *) alGetAuxiliaryEffectSloti }, + { "alGetAuxiliaryEffectSlotiv", (ALvoid *) alGetAuxiliaryEffectSlotiv}, + { "alGetAuxiliaryEffectSlotf", (ALvoid *) alGetAuxiliaryEffectSlotf }, + { "alGetAuxiliaryEffectSlotfv", (ALvoid *) alGetAuxiliaryEffectSlotfv}, + { NULL, (ALvoid *) NULL } }; static ALenums enumeration[]={ @@ -135,6 +175,18 @@ static ALenums enumeration[]={ { (ALchar *)"AL_STATIC", AL_STATIC }, { (ALchar *)"AL_STREAMING", AL_STREAMING }, { (ALchar *)"AL_UNDETERMINED", AL_UNDETERMINED }, + { (ALchar *)"AL_METERS_PER_UNIT", AL_METERS_PER_UNIT }, + + // Source EFX Properties + { (ALchar *)"AL_DIRECT_FILTER", AL_DIRECT_FILTER }, + { (ALchar *)"AL_AUXILIARY_SEND_FILTER", AL_AUXILIARY_SEND_FILTER }, + { (ALchar *)"AL_AIR_ABSORPTION_FACTOR", AL_AIR_ABSORPTION_FACTOR }, + { (ALchar *)"AL_ROOM_ROLLOFF_FACTOR", AL_ROOM_ROLLOFF_FACTOR }, + { (ALchar *)"AL_CONE_OUTER_GAINHF", AL_CONE_OUTER_GAINHF }, + { (ALchar *)"AL_DIRECT_FILTER_GAINHF_AUTO", AL_DIRECT_FILTER_GAINHF_AUTO }, + { (ALchar *)"AL_AUXILIARY_SEND_FILTER_GAIN_AUTO", AL_AUXILIARY_SEND_FILTER_GAIN_AUTO }, + { (ALchar *)"AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO", AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO}, + // Source State information { (ALchar *)"AL_SOURCE_STATE", AL_SOURCE_STATE }, @@ -196,8 +248,36 @@ static ALenums enumeration[]={ { (ALchar *)"AL_EXPONENT_DISTANCE", AL_EXPONENT_DISTANCE }, { (ALchar *)"AL_EXPONENT_DISTANCE_CLAMPED", AL_EXPONENT_DISTANCE_CLAMPED }, + // Filter types + { (ALchar *)"AL_FILTER_TYPE", AL_FILTER_TYPE }, + { (ALchar *)"AL_FILTER_NULL", AL_FILTER_NULL }, + { (ALchar *)"AL_FILTER_LOWPASS", AL_FILTER_LOWPASS }, + { (ALchar *)"AL_FILTER_HIGHPASS", AL_FILTER_HIGHPASS }, + { (ALchar *)"AL_FILTER_BANDPASS", AL_FILTER_BANDPASS }, + + // Filter params + { (ALchar *)"AL_LOWPASS_GAIN", AL_LOWPASS_GAIN }, + { (ALchar *)"AL_LOWPASS_GAINHF", AL_LOWPASS_GAINHF }, + + // Effect types + { (ALchar *)"AL_EFFECT_TYPE", AL_EFFECT_TYPE }, + { (ALchar *)"AL_EFFECT_NULL", AL_EFFECT_NULL }, + { (ALchar *)"AL_EFFECT_REVERB", AL_EFFECT_REVERB }, + { (ALchar *)"AL_EFFECT_CHORUS", AL_EFFECT_CHORUS }, + { (ALchar *)"AL_EFFECT_DISTORTION", AL_EFFECT_DISTORTION }, + { (ALchar *)"AL_EFFECT_ECHO", AL_EFFECT_ECHO }, + { (ALchar *)"AL_EFFECT_FLANGER", AL_EFFECT_FLANGER }, + { (ALchar *)"AL_EFFECT_FREQUENCY_SHIFTER", AL_EFFECT_FREQUENCY_SHIFTER }, + { (ALchar *)"AL_EFFECT_VOCAL_MORPHER", AL_EFFECT_VOCAL_MORPHER }, + { (ALchar *)"AL_EFFECT_PITCH_SHIFTER", AL_EFFECT_PITCH_SHIFTER }, + { (ALchar *)"AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR }, + { (ALchar *)"AL_EFFECT_AUTOWAH", AL_EFFECT_AUTOWAH }, + { (ALchar *)"AL_EFFECT_COMPRESSOR", AL_EFFECT_COMPRESSOR }, + { (ALchar *)"AL_EFFECT_EQUALIZER", AL_EFFECT_EQUALIZER }, + // Default - { (ALchar *)NULL, (ALenum ) 0 } }; + { (ALchar *)NULL, (ALenum)0 } +}; diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c new file mode 100644 index 00000000..80da100a --- /dev/null +++ b/OpenAL32/alFilter.c @@ -0,0 +1,421 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * 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 <stdlib.h> + +#include "config.h" + +#include "AL/al.h" +#include "AL/alc.h" + +#include "alMain.h" +#include "alFilter.h" + +static ALfilter *g_FilterList; +static ALuint g_FilterCount; + +static void InitFilterParams(ALfilter *filter, ALenum type); + + +AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) +{ + ALCcontext *Context; + ALsizei i; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (n > 0) + { + // Check that enough memory has been allocted in the 'sources' array for n Sources + if (!IsBadWritePtr((void*)filters, n * sizeof(ALuint))) + { + ALfilter **list = &g_FilterList; + while(*list) + list = &(*list)->next; + + i = 0; + while(i < n) + { + *list = calloc(1, sizeof(ALfilter)); + if(!(*list)) + { + // We must have run out or memory + alDeleteFilters(i, filters); + alSetError(AL_OUT_OF_MEMORY); + break; + } + + filters[i] = (ALuint)ALTHUNK_ADDENTRY(*list); + (*list)->filter = filters[i]; + + InitFilterParams(*list, AL_FILTER_NULL); + g_FilterCount++; + i++; + } + } + } + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters) +{ + ALCcontext *Context; + ALfilter *ALFilter; + ALsizei i; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (n >= 0) + { + // Check that all filters are valid + for (i = 0; i < n; i++) + { + if (!alIsFilter(filters[i])) + { + alSetError(AL_INVALID_NAME); + break; + } + } + + if (i == n) + { + // All filters are valid + for (i = 0; i < n; i++) + { + // Recheck that the filter is valid, because there could be duplicated names + if (filters[i] && alIsFilter(filters[i])) + { + ALfilter **list; + + ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i])); + + // Remove Source from list of Sources + list = &g_FilterList; + while(*list && *list != ALFilter) + list = &(*list)->next; + + if(*list) + *list = (*list)->next; + ALTHUNK_REMOVEENTRY(ALFilter->filter); + + memset(ALFilter, 0, sizeof(ALfilter)); + free(ALFilter); + + g_FilterCount--; + } + } + } + } + else + alSetError(AL_INVALID_VALUE); + + ProcessContext(Context); +} + +AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter) +{ + ALCcontext *Context; + ALfilter **list; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + list = &g_FilterList; + while(*list && (*list)->filter != filter) + list = &(*list)->next; + + ProcessContext(Context); + + return ((*list || !filter) ? AL_TRUE : AL_FALSE); +} + +AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter); + + switch(param) + { + case AL_FILTER_TYPE: + if(iValue == AL_FILTER_NULL || + iValue == AL_FILTER_LOWPASS) + InitFilterParams(ALFilter, iValue); + else + alSetError(AL_INVALID_VALUE); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + switch(param) + { + case AL_FILTER_TYPE: + alFilteri(filter, param, piValues[0]); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter); + + switch(param) + { + case AL_LOWPASS_GAIN: + if(ALFilter->type == AL_FILTER_LOWPASS) + { + if(flValue >= 0.0f && flValue <= 1.0f) + ALFilter->Gain = flValue; + } + else + alSetError(AL_INVALID_ENUM); + break; + + case AL_LOWPASS_GAINHF: + if(ALFilter->type == AL_FILTER_LOWPASS) + { + if(flValue >= 0.0f && flValue <= 1.0f) + ALFilter->GainHF = flValue; + } + else + alSetError(AL_INVALID_ENUM); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + switch(param) + { + case AL_LOWPASS_GAIN: + case AL_LOWPASS_GAINHF: + alFilterf(filter, param, pflValues[0]); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue) +{ + ALCcontext *Context; + + (void)piValue; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues) +{ + ALCcontext *Context; + + (void)piValues; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + switch(param) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter); + + switch(param) + { + case AL_LOWPASS_GAIN: + if(ALFilter->type == AL_FILTER_LOWPASS) + *pflValue = ALFilter->Gain; + else + alSetError(AL_INVALID_ENUM); + break; + + case AL_LOWPASS_GAINHF: + if(ALFilter->type == AL_FILTER_LOWPASS) + *pflValue = ALFilter->GainHF; + else + alSetError(AL_INVALID_ENUM); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + +AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues) +{ + ALCcontext *Context; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + if (filter && alIsFilter(filter)) + { + switch(param) + { + case AL_LOWPASS_GAIN: + case AL_LOWPASS_GAINHF: + alGetFilterf(filter, param, pflValues); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + alSetError(AL_INVALID_NAME); + + ProcessContext(Context); +} + + +ALvoid ReleaseALFilters(ALvoid) +{ +#ifdef _DEBUG + if(g_FilterCount > 0) + AL_PRINT("exit() %d Filter(s) NOT deleted\n", g_FilterCount); +#endif + + while(g_FilterList) + { + ALfilter *temp = g_FilterList; + g_FilterList = g_FilterList->next; + + // Release filter structure + memset(temp, 0, sizeof(ALfilter)); + free(temp); + } + g_FilterCount = 0; +} + + +static void InitFilterParams(ALfilter *filter, ALenum type) +{ + filter->type = type; + + filter->Gain = 1.0; + filter->GainHF = 1.0; +} diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 97fc593c..1e02622a 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -41,6 +41,13 @@ ALAPI ALvoid ALAPIENTRY alListenerf(ALenum eParam, ALfloat flValue) alSetError(AL_INVALID_VALUE); break; + case AL_METERS_PER_UNIT: + if (flValue > 0.0f) + pContext->Listener.MetersPerUnit = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + default: alSetError(AL_INVALID_ENUM); break; @@ -112,6 +119,13 @@ ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues) alSetError(AL_INVALID_VALUE); break; + case AL_METERS_PER_UNIT: + if (pflValues[0] > 0.0f) + pContext->Listener.MetersPerUnit = pflValues[0]; + else + alSetError(AL_INVALID_VALUE); + break; + case AL_POSITION: pContext->Listener.Position[0] = pflValues[0]; pContext->Listener.Position[1] = pflValues[1]; @@ -274,6 +288,10 @@ ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue) *pflValue = pContext->Listener.Gain; break; + case AL_METERS_PER_UNIT: + *pflValue = pContext->Listener.MetersPerUnit; + break; + default: alSetError(AL_INVALID_ENUM); break; @@ -350,6 +368,10 @@ ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues) pflValues[0] = pContext->Listener.Gain; break; + case AL_METERS_PER_UNIT: + pflValues[0] = pContext->Listener.MetersPerUnit; + break; + case AL_POSITION: pflValues[0] = pContext->Listener.Position[0]; pflValues[1] = pContext->Listener.Position[1]; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index ec8783c3..5b40f7eb 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -341,6 +341,27 @@ ALAPI ALvoid ALAPIENTRY alSourcef(ALuint source, ALenum eParam, ALfloat flValue) alSetError(AL_INVALID_VALUE); break; + case AL_CONE_OUTER_GAINHF: + if ((flValue >= 0.0f) && (flValue <= 1.0f)) + pSource->OuterGainHF = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_AIR_ABSORPTION_FACTOR: + if (flValue >= 0.0f && flValue <= 10.0f) + pSource->AirAbsorptionFactor = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_ROOM_ROLLOFF_FACTOR: + if (flValue >= 0.0f && flValue <= 1.0f) + pSource->RoomRolloffFactor = flValue; + else + alSetError(AL_INVALID_VALUE); + break; + case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: @@ -461,9 +482,12 @@ ALAPI ALvoid ALAPIENTRY alSourcefv(ALuint source, ALenum eParam, const ALfloat * case AL_MIN_GAIN: case AL_MAX_GAIN: case AL_CONE_OUTER_GAIN: + case AL_CONE_OUTER_GAINHF: case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: + case AL_AIR_ABSORPTION_FACTOR: + case AL_ROOM_ROLLOFF_FACTOR: alSourcef(source, eParam, pflValues[0]); break; @@ -636,6 +660,43 @@ ALAPI ALvoid ALAPIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue) alSetError(AL_INVALID_VALUE); break; + case AL_DIRECT_FILTER: + if(alIsFilter(lValue)) + { + ALfilter *filter = (ALfilter*)ALTHUNK_LOOKUPENTRY(lValue); + if(!filter) + { + pSource->DirectFilter.type = AL_FILTER_NULL; + pSource->DirectFilter.filter = 0; + } + else + memcpy(&pSource->DirectFilter, filter, sizeof(*filter)); + } + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_DIRECT_FILTER_GAINHF_AUTO: + if(lValue == AL_TRUE || lValue == AL_FALSE) + pSource->DryGainHFAuto = lValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + if(lValue == AL_TRUE || lValue == AL_FALSE) + pSource->WetGainAuto = lValue; + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + if(lValue == AL_TRUE || lValue == AL_FALSE) + pSource->WetGainHFAuto = lValue; + else + alSetError(AL_INVALID_VALUE); + break; + default: alSetError(AL_INVALID_ENUM); break; @@ -664,6 +725,8 @@ ALAPI void ALAPIENTRY alSource3i(ALuint source, ALenum eParam, ALint lValue1, AL if (alIsSource(source)) { + ALsource *pSource = ((ALsource *)ALTHUNK_LOOKUPENTRY(source)); + switch (eParam) { case AL_POSITION: @@ -672,6 +735,35 @@ ALAPI void ALAPIENTRY alSource3i(ALuint source, ALenum eParam, ALint lValue1, AL alSource3f(source, eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3); break; + case AL_AUXILIARY_SEND_FILTER: + if(lValue2 >= 0 && lValue2 < MAX_SENDS && + (alIsAuxiliaryEffectSlot(lValue1) || lValue1 == 0) && + alIsFilter(lValue3)) + { + ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(lValue1); + ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(lValue3); + + if(!ALEffectSlot) + { + /* Disable slot */ + pSource->Send[lValue2].Slot.effectslot = 0; + } + else + memcpy(&pSource->Send[lValue2].Slot, ALEffectSlot, sizeof(*ALEffectSlot)); + + if(!ALFilter) + { + /* Disable filter */ + pSource->Send[lValue2].WetFilter.type = 0; + pSource->Send[lValue2].WetFilter.filter = 0; + } + else + memcpy(&pSource->Send[lValue2].WetFilter, ALFilter, sizeof(*ALFilter)); + } + else + alSetError(AL_INVALID_VALUE); + break; + default: alSetError(AL_INVALID_ENUM); break; @@ -716,12 +808,17 @@ ALAPI void ALAPIENTRY alSourceiv(ALuint source, ALenum eParam, const ALint* plVa case AL_MAX_DISTANCE: case AL_ROLLOFF_FACTOR: case AL_REFERENCE_DISTANCE: + case AL_DIRECT_FILTER: + case AL_DIRECT_FILTER_GAINHF_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: alSourcei(source, eParam, plValues[0]); break; case AL_POSITION: case AL_VELOCITY: case AL_DIRECTION: + case AL_AUXILIARY_SEND_FILTER: alSource3i(source, eParam, plValues[0], plValues[1], plValues[2]); break; @@ -792,6 +889,10 @@ ALAPI ALvoid ALAPIENTRY alGetSourcef(ALuint source, ALenum eParam, ALfloat *pflV *pflValue = pSource->flOuterGain; break; + case AL_CONE_OUTER_GAINHF: + *pflValue = pSource->OuterGainHF; + break; + case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: @@ -813,6 +914,14 @@ ALAPI ALvoid ALAPIENTRY alGetSourcef(ALuint source, ALenum eParam, ALfloat *pflV *pflValue = pSource->flRefDistance; break; + case AL_AIR_ABSORPTION_FACTOR: + *pflValue = pSource->AirAbsorptionFactor; + break; + + case AL_ROOM_ROLLOFF_FACTOR: + *pflValue = pSource->RoomRolloffFactor; + break; + default: alSetError(AL_INVALID_ENUM); break; @@ -920,6 +1029,9 @@ ALAPI ALvoid ALAPIENTRY alGetSourcefv(ALuint source, ALenum eParam, ALfloat *pfl case AL_CONE_INNER_ANGLE: case AL_CONE_OUTER_ANGLE: case AL_REFERENCE_DISTANCE: + case AL_CONE_OUTER_GAINHF: + case AL_AIR_ABSORPTION_FACTOR: + case AL_ROOM_ROLLOFF_FACTOR: alGetSourcef(source, eParam, pflValues); break; @@ -1044,6 +1156,22 @@ ALAPI ALvoid ALAPIENTRY alGetSourcei(ALuint source, ALenum eParam, ALint *plValu alSetError(AL_INVALID_OPERATION); break; + case AL_DIRECT_FILTER: + *plValue = pSource->DirectFilter.filter; + break; + + case AL_DIRECT_FILTER_GAINHF_AUTO: + *plValue = pSource->DryGainHFAuto; + break; + + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + *plValue = pSource->WetGainAuto; + break; + + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: + *plValue = pSource->WetGainHFAuto; + break; + default: alSetError(AL_INVALID_ENUM); break; @@ -1153,6 +1281,10 @@ ALAPI void ALAPIENTRY alGetSourceiv(ALuint source, ALenum eParam, ALint* plValue case AL_ROLLOFF_FACTOR: case AL_REFERENCE_DISTANCE: case AL_SOURCE_TYPE: + case AL_DIRECT_FILTER: + case AL_DIRECT_FILTER_GAINHF_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: + case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: alGetSourcei(source, eParam, plValues); break; @@ -1830,6 +1962,11 @@ static ALvoid InitSourceParams(ALsource *pSource) pSource->flMaxGain = 1.0f; pSource->flOuterGain = 0.0f; + pSource->DryGainHFAuto = AL_TRUE; + pSource->WetGainAuto = AL_TRUE; + pSource->WetGainHFAuto = AL_TRUE; + pSource->AirAbsorptionFactor = 0.0f; + pSource->state = AL_INITIAL; pSource->lSourceType = AL_UNDETERMINED; |