From c1f87414c5452f595f78b7a52a7063a023ce2982 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 28 Jan 2016 00:02:46 -0800 Subject: Mix to multichannel for effects This mixes to a 4-channel first-order ambisonics buffer. With ACN ordering and N3D scaling, this makes it easy to remain compatible with effects that only care about mono input since channel 0 is an unattenuated mono signal. --- OpenAL32/alAuxEffectSlot.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index c1314301..b0dba25d 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -90,6 +90,8 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo SET_ERROR_AND_GOTO(context, err, done); } + aluInitEffectPanning(slot); + VECTOR_PUSH_BACK(slotvec, slot); effectslots[cur] = slot->id; -- cgit v1.2.3 From ce575718ef495c3c146d7a1b443ce556014e057f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 17 Mar 2016 10:10:26 -0700 Subject: Store the effect's output buffer in the effect state --- Alc/ALc.c | 7 ++++++- Alc/ALu.c | 10 +++++----- OpenAL32/Include/alAuxEffectSlot.h | 3 +++ OpenAL32/alAuxEffectSlot.c | 2 ++ 4 files changed, 16 insertions(+), 6 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index f22cb7c1..091a5473 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2170,6 +2170,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALeffectslot *slot = context->EffectSlotMap.array[pos].value; + slot->EffectState->OutBuffer = device->Dry.Buffer; + slot->EffectState->OutChannels = device->Dry.NumChannels; if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); @@ -2217,8 +2219,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(device->DefaultSlot) { ALeffectslot *slot = device->DefaultSlot; + ALeffectState *state = slot->EffectState; - if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE) + state->OutBuffer = device->Dry.Buffer; + state->OutChannels = device->Dry.NumChannels; + if(V(state,deviceUpdate)(device) == AL_FALSE) { V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); diff --git a/Alc/ALu.c b/Alc/ALu.c index 5064a588..55ed84dc 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1417,8 +1417,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { const ALeffectslot *slot = VECTOR_ELEM(ctx->ActiveAuxSlots, i); ALeffectState *state = slot->EffectState; - V(state,process)(SamplesToDo, slot->WetBuffer, device->Dry.Buffer, - device->Dry.NumChannels); + V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer, + state->OutChannels); } ctx = ctx->next; @@ -1428,8 +1428,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { const ALeffectslot *slot = device->DefaultSlot; ALeffectState *state = slot->EffectState; - V(state,process)(SamplesToDo, slot->WetBuffer, device->Dry.Buffer, - device->Dry.NumChannels); + V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer, + state->OutChannels); } /* Increment the clock time. Every second's worth of samples is @@ -1503,7 +1503,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) if(buffer) { ALfloat (*OutBuffer)[BUFFERSIZE] = device->RealOut.Buffer; - ALuint OutChannels = device->RealOut.NumChannels;; + ALuint OutChannels = device->RealOut.NumChannels; #define WRITE(T, a, b, c, d) do { \ Write_##T((a), (b), (c), (d)); \ diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 3f677fd1..2c9a83e5 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -15,6 +15,9 @@ struct ALeffectslot; typedef struct ALeffectState { const struct ALeffectStateVtable *vtbl; + + ALfloat (*OutBuffer)[BUFFERSIZE]; + ALuint OutChannels; } ALeffectState; struct ALeffectStateVtable { diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index b0dba25d..c80bab22 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -464,6 +464,8 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e SetMixerFPUMode(&oldMode); ALCdevice_Lock(Device); + State->OutBuffer = Device->Dry.Buffer; + State->OutChannels = Device->Dry.NumChannels; if(V(State,deviceUpdate)(Device) == AL_FALSE) { ALCdevice_Unlock(Device); -- cgit v1.2.3 From 2ccc1d1d8a6ecc5c025e99518038fcc7a001d949 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 29 Mar 2016 00:44:58 -0700 Subject: Move the aligned malloc functions to the common lib --- Alc/ALc.c | 1 + Alc/alcRing.c | 1 + Alc/bformatdec.c | 1 + Alc/helpers.c | 50 ------------------------------------- CMakeLists.txt | 3 ++- OpenAL32/Include/alMain.h | 6 +---- OpenAL32/alAuxEffectSlot.c | 2 ++ OpenAL32/alSource.c | 1 + OpenAL32/alThunk.c | 2 ++ common/almalloc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ include/almalloc.h | 18 ++++++++++++++ 11 files changed, 91 insertions(+), 56 deletions(-) create mode 100644 common/almalloc.c create mode 100644 include/almalloc.h (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 6389270c..43ec7cf9 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -44,6 +44,7 @@ #include "compat.h" #include "threads.h" #include "alstring.h" +#include "almalloc.h" #include "backends/base.h" diff --git a/Alc/alcRing.c b/Alc/alcRing.c index e9a40a12..05db7bc3 100644 --- a/Alc/alcRing.c +++ b/Alc/alcRing.c @@ -25,6 +25,7 @@ #include "alMain.h" #include "threads.h" +#include "almalloc.h" #include "compat.h" diff --git a/Alc/bformatdec.c b/Alc/bformatdec.c index 6dd5ce9a..e4c6da49 100644 --- a/Alc/bformatdec.c +++ b/Alc/bformatdec.c @@ -6,6 +6,7 @@ #include "alu.h" #include "threads.h" +#include "almalloc.h" typedef struct BandSplitter { diff --git a/Alc/helpers.c b/Alc/helpers.c index f596c0d9..c8983c11 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -243,56 +243,6 @@ void FillCPUCaps(ALuint capfilter) } -void *al_malloc(size_t alignment, size_t size) -{ -#if defined(HAVE_ALIGNED_ALLOC) - size = (size+(alignment-1))&~(alignment-1); - return aligned_alloc(alignment, size); -#elif defined(HAVE_POSIX_MEMALIGN) - void *ret; - if(posix_memalign(&ret, alignment, size) == 0) - return ret; - return NULL; -#elif defined(HAVE__ALIGNED_MALLOC) - return _aligned_malloc(size, alignment); -#else - char *ret = malloc(size+alignment); - if(ret != NULL) - { - *(ret++) = 0x00; - while(((ptrdiff_t)ret&(alignment-1)) != 0) - *(ret++) = 0x55; - } - return ret; -#endif -} - -void *al_calloc(size_t alignment, size_t size) -{ - void *ret = al_malloc(alignment, size); - if(ret) memset(ret, 0, size); - return ret; -} - -void al_free(void *ptr) -{ -#if defined(HAVE_ALIGNED_ALLOC) || defined(HAVE_POSIX_MEMALIGN) - free(ptr); -#elif defined(HAVE__ALIGNED_MALLOC) - _aligned_free(ptr); -#else - if(ptr != NULL) - { - char *finder = ptr; - do { - --finder; - } while(*finder == 0x55); - free(finder); - } -#endif -} - - void SetMixerFPUMode(FPUCtl *ctl) { #ifdef HAVE_FENV_H diff --git a/CMakeLists.txt b/CMakeLists.txt index c3e17967..8c89a0d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -607,7 +607,8 @@ IF(NOT HAVE_STDINT_H) ENDIF() -SET(COMMON_OBJS common/atomic.c +SET(COMMON_OBJS common/almalloc.c + common/atomic.c common/rwlock.c common/threads.c common/uintmap.c diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 4c737f02..17edd7fc 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -36,6 +36,7 @@ #include "uintmap.h" #include "vector.h" #include "alstring.h" +#include "almalloc.h" #include "hrtf.h" @@ -637,11 +638,6 @@ inline void UnlockContext(ALCcontext *context) { ALCdevice_Unlock(context->Device); } -void *al_malloc(size_t alignment, size_t size); -void *al_calloc(size_t alignment, size_t size); -void al_free(void *ptr); - - typedef struct { #ifdef HAVE_FENV_H DERIVE_FROM_TYPE(fenv_t); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index c80bab22..0364c33c 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -31,6 +31,8 @@ #include "alError.h" #include "alSource.h" +#include "almalloc.h" + extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index d7b68185..03eae080 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -37,6 +37,7 @@ #include "backends/base.h" #include "threads.h" +#include "almalloc.h" extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); diff --git a/OpenAL32/alThunk.c b/OpenAL32/alThunk.c index 0cebad42..29da9bbd 100644 --- a/OpenAL32/alThunk.c +++ b/OpenAL32/alThunk.c @@ -25,6 +25,8 @@ #include "alMain.h" #include "alThunk.h" +#include "almalloc.h" + static ATOMIC(ALenum) *ThunkArray; static ALuint ThunkArraySize; diff --git a/common/almalloc.c b/common/almalloc.c new file mode 100644 index 00000000..8c1c5794 --- /dev/null +++ b/common/almalloc.c @@ -0,0 +1,62 @@ + +#include "config.h" + +#include "almalloc.h" + +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_WINDOWS_H +#include +#endif + +void *al_malloc(size_t alignment, size_t size) +{ +#if defined(HAVE_ALIGNED_ALLOC) + size = (size+(alignment-1))&~(alignment-1); + return aligned_alloc(alignment, size); +#elif defined(HAVE_POSIX_MEMALIGN) + void *ret; + if(posix_memalign(&ret, alignment, size) == 0) + return ret; + return NULL; +#elif defined(HAVE__ALIGNED_MALLOC) + return _aligned_malloc(size, alignment); +#else + char *ret = malloc(size+alignment); + if(ret != NULL) + { + *(ret++) = 0x00; + while(((ptrdiff_t)ret&(alignment-1)) != 0) + *(ret++) = 0x55; + } + return ret; +#endif +} + +void *al_calloc(size_t alignment, size_t size) +{ + void *ret = al_malloc(alignment, size); + if(ret) memset(ret, 0, size); + return ret; +} + +void al_free(void *ptr) +{ +#if defined(HAVE_ALIGNED_ALLOC) || defined(HAVE_POSIX_MEMALIGN) + free(ptr); +#elif defined(HAVE__ALIGNED_MALLOC) + _aligned_free(ptr); +#else + if(ptr != NULL) + { + char *finder = ptr; + do { + --finder; + } while(*finder == 0x55); + free(finder); + } +#endif +} diff --git a/include/almalloc.h b/include/almalloc.h new file mode 100644 index 00000000..355db795 --- /dev/null +++ b/include/almalloc.h @@ -0,0 +1,18 @@ +#ifndef AL_MALLOC_H +#define AL_MALLOC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void *al_malloc(size_t alignment, size_t size); +void *al_calloc(size_t alignment, size_t size); +void al_free(void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* AL_MALLOC_H */ -- cgit v1.2.3 From f4ff5fc106f39ad30cdf72eade4bade649777a85 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 15 Apr 2016 12:22:54 -0700 Subject: Shorten VECTOR_ITER_ macros to VECTOR_ --- Alc/backends/alsa.c | 19 ++++++++----------- Alc/backends/dsound.c | 6 +++--- Alc/backends/mmdevapi.c | 6 +++--- Alc/backends/pulseaudio.c | 12 ++++++------ Alc/backends/qsa.c | 4 ++-- Alc/backends/winmm.c | 12 ++++++------ Alc/helpers.c | 42 +++++++++++++++++++++--------------------- Alc/hrtf.c | 6 +++--- Alc/vector.h | 20 ++++++++++---------- OpenAL32/alAuxEffectSlot.c | 6 +++--- 10 files changed, 65 insertions(+), 68 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index 3b37f3ca..7d23ecc3 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -237,16 +237,13 @@ static vector_DevMap CaptureDevices; static void clear_devlist(vector_DevMap *devlist) { - DevMap *iter, *end; - - iter = VECTOR_ITER_BEGIN(*devlist); - end = VECTOR_ITER_END(*devlist); - for(;iter != end;iter++) - { - AL_STRING_DEINIT(iter->name); - AL_STRING_DEINIT(iter->device_name); - } +#define FREE_DEV(i) do { \ + AL_STRING_DEINIT((i)->name); \ + AL_STRING_DEINIT((i)->device_name); \ +} while(0) + VECTOR_FOR_EACH(DevMap, *devlist, FREE_DEV); VECTOR_RESIZE(*devlist, 0); +#undef FREE_DEV } @@ -635,7 +632,7 @@ static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name) #define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, name) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(PlaybackDevices)) + if(iter == VECTOR_END(PlaybackDevices)) return ALC_INVALID_VALUE; driver = al_string_get_cstr(iter->device_name); } @@ -969,7 +966,7 @@ static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name) #define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, name) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(CaptureDevices)) + if(iter == VECTOR_END(CaptureDevices)) return ALC_INVALID_VALUE; driver = al_string_get_cstr(iter->device_name); } diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c index 68ac08f1..454f7fa0 100644 --- a/Alc/backends/dsound.c +++ b/Alc/backends/dsound.c @@ -156,7 +156,7 @@ static BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHA #define MATCH_ENTRY(i) (al_string_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const DevMap, *devices, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(*devices)) break; + if(iter == VECTOR_END(*devices)) break; #undef MATCH_ENTRY count++; } @@ -351,7 +351,7 @@ static ALCenum ALCdsoundPlayback_open(ALCdsoundPlayback *self, const ALCchar *de #define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, deviceName) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(PlaybackDevices)) + if(iter == VECTOR_END(PlaybackDevices)) return ALC_INVALID_VALUE; guid = &iter->guid; } @@ -712,7 +712,7 @@ static ALCenum ALCdsoundCapture_open(ALCdsoundCapture *self, const ALCchar *devi #define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, deviceName) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(CaptureDevices)) + if(iter == VECTOR_END(CaptureDevices)) return ALC_INVALID_VALUE; guid = &iter->guid; } diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c index c47ddee6..8851678b 100644 --- a/Alc/backends/mmdevapi.c +++ b/Alc/backends/mmdevapi.c @@ -211,7 +211,7 @@ static void add_device(IMMDevice *device, LPCWSTR devid, vector_DevMap *list) #define MATCH_ENTRY(i) (al_string_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const DevMap, *list, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(*list)) break; + if(iter == VECTOR_END(*list)) break; #undef MATCH_ENTRY count++; } @@ -696,7 +696,7 @@ static ALCenum ALCmmdevPlayback_open(ALCmmdevPlayback *self, const ALCchar *devi hr = E_FAIL; #define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, deviceName) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_NAME); - if(iter == VECTOR_ITER_END(PlaybackDevices)) + if(iter == VECTOR_END(PlaybackDevices)) WARN("Failed to find device name matching \"%s\"\n", deviceName); else { @@ -1332,7 +1332,7 @@ static ALCenum ALCmmdevCapture_open(ALCmmdevCapture *self, const ALCchar *device hr = E_FAIL; #define MATCH_NAME(i) (al_string_cmp_cstr((i)->name, deviceName) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_NAME); - if(iter == VECTOR_ITER_END(CaptureDevices)) + if(iter == VECTOR_END(CaptureDevices)) WARN("Failed to find device name matching \"%s\"\n", deviceName); else { diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index ca8441aa..ccce2e00 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -527,7 +527,7 @@ static void ALCpulsePlayback_deviceCallback(pa_context *UNUSED(context), const p #define MATCH_INFO_NAME(iter) (al_string_cmp_cstr((iter)->device_name, info->name) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_INFO_NAME); - if(iter != VECTOR_ITER_END(PlaybackDevices)) return; + if(iter != VECTOR_END(PlaybackDevices)) return; #undef MATCH_INFO_NAME AL_STRING_INIT(entry.name); @@ -548,7 +548,7 @@ static void ALCpulsePlayback_deviceCallback(pa_context *UNUSED(context), const p #define MATCH_ENTRY(i) (al_string_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(PlaybackDevices)) break; + if(iter == VECTOR_END(PlaybackDevices)) break; #undef MATCH_ENTRY count++; } @@ -861,7 +861,7 @@ static ALCenum ALCpulsePlayback_open(ALCpulsePlayback *self, const ALCchar *name #define MATCH_NAME(iter) (al_string_cmp_cstr((iter)->name, name) == 0) VECTOR_FIND_IF(iter, const DevMap, PlaybackDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(PlaybackDevices)) + if(iter == VECTOR_END(PlaybackDevices)) return ALC_INVALID_VALUE; pulse_name = al_string_get_cstr(iter->device_name); dev_name = iter->name; @@ -1247,7 +1247,7 @@ static void ALCpulseCapture_deviceCallback(pa_context *UNUSED(context), const pa #define MATCH_INFO_NAME(iter) (al_string_cmp_cstr((iter)->device_name, info->name) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_INFO_NAME); - if(iter != VECTOR_ITER_END(CaptureDevices)) return; + if(iter != VECTOR_END(CaptureDevices)) return; #undef MATCH_INFO_NAME AL_STRING_INIT(entry.name); @@ -1268,7 +1268,7 @@ static void ALCpulseCapture_deviceCallback(pa_context *UNUSED(context), const pa #define MATCH_ENTRY(i) (al_string_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(CaptureDevices)) break; + if(iter == VECTOR_END(CaptureDevices)) break; #undef MATCH_ENTRY count++; } @@ -1439,7 +1439,7 @@ static ALCenum ALCpulseCapture_open(ALCpulseCapture *self, const ALCchar *name) #define MATCH_NAME(iter) (al_string_cmp_cstr((iter)->name, name) == 0) VECTOR_FIND_IF(iter, const DevMap, CaptureDevices, MATCH_NAME); #undef MATCH_NAME - if(iter == VECTOR_ITER_END(CaptureDevices)) + if(iter == VECTOR_END(CaptureDevices)) return ALC_INVALID_VALUE; pulse_name = al_string_get_cstr(iter->device_name); al_string_copy(&device->DeviceName, iter->name); diff --git a/Alc/backends/qsa.c b/Alc/backends/qsa.c index 291e49fc..a1fbce63 100644 --- a/Alc/backends/qsa.c +++ b/Alc/backends/qsa.c @@ -277,7 +277,7 @@ static ALCenum qsa_open_playback(ALCdevice* device, const ALCchar* deviceName) #define MATCH_DEVNAME(iter) ((iter)->name && strcmp(deviceName, (iter)->name)==0) VECTOR_FIND_IF(iter, const DevMap, DeviceNameMap, MATCH_DEVNAME); #undef MATCH_DEVNAME - if(iter == VECTOR_ITER_END(DeviceNameMap)) + if(iter == VECTOR_END(DeviceNameMap)) { free(data); return ALC_INVALID_DEVICE; @@ -624,7 +624,7 @@ static ALCenum qsa_open_capture(ALCdevice* device, const ALCchar* deviceName) #define MATCH_DEVNAME(iter) ((iter)->name && strcmp(deviceName, (iter)->name)==0) VECTOR_FIND_IF(iter, const DevMap, CaptureNameMap, MATCH_DEVNAME); #undef MATCH_DEVNAME - if(iter == VECTOR_ITER_END(CaptureNameMap)) + if(iter == VECTOR_END(CaptureNameMap)) { free(data); return ALC_INVALID_DEVICE; diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c index 0085251d..664b3dfe 100644 --- a/Alc/backends/winmm.c +++ b/Alc/backends/winmm.c @@ -83,7 +83,7 @@ static void ProbePlaybackDevices(void) #define MATCH_ENTRY(i) (al_string_cmp(dname, *(i)) == 0) VECTOR_FIND_IF(iter, const al_string, PlaybackDevices, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(PlaybackDevices)) break; + if(iter == VECTOR_END(PlaybackDevices)) break; #undef MATCH_ENTRY } @@ -126,7 +126,7 @@ static void ProbeCaptureDevices(void) #define MATCH_ENTRY(i) (al_string_cmp(dname, *(i)) == 0) VECTOR_FIND_IF(iter, const al_string, CaptureDevices, MATCH_ENTRY); - if(iter == VECTOR_ITER_END(CaptureDevices)) break; + if(iter == VECTOR_END(CaptureDevices)) break; #undef MATCH_ENTRY } @@ -258,11 +258,11 @@ static ALCenum ALCwinmmPlayback_open(ALCwinmmPlayback *self, const ALCchar *devi #define MATCH_DEVNAME(iter) (!al_string_empty(*(iter)) && \ (!deviceName || al_string_cmp_cstr(*(iter), deviceName) == 0)) VECTOR_FIND_IF(iter, const al_string, PlaybackDevices, MATCH_DEVNAME); - if(iter == VECTOR_ITER_END(PlaybackDevices)) + if(iter == VECTOR_END(PlaybackDevices)) return ALC_INVALID_VALUE; #undef MATCH_DEVNAME - DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(PlaybackDevices)); + DeviceID = (UINT)(iter - VECTOR_BEGIN(PlaybackDevices)); retry_open: memset(&self->Format, 0, sizeof(WAVEFORMATEX)); @@ -544,11 +544,11 @@ static ALCenum ALCwinmmCapture_open(ALCwinmmCapture *self, const ALCchar *name) // Find the Device ID matching the deviceName if valid #define MATCH_DEVNAME(iter) (!al_string_empty(*(iter)) && (!name || al_string_cmp_cstr(*iter, name) == 0)) VECTOR_FIND_IF(iter, const al_string, CaptureDevices, MATCH_DEVNAME); - if(iter == VECTOR_ITER_END(CaptureDevices)) + if(iter == VECTOR_END(CaptureDevices)) return ALC_INVALID_VALUE; #undef MATCH_DEVNAME - DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(CaptureDevices)); + DeviceID = (UINT)(iter - VECTOR_BEGIN(CaptureDevices)); switch(device->FmtChans) { diff --git a/Alc/helpers.c b/Alc/helpers.c index 47851cf9..950a67bf 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -456,7 +456,7 @@ static void DirectorySearch(const char *path, const char *ext, vector_al_string FindClose(hdl); if(VECTOR_SIZE(*results) > base) - qsort(VECTOR_ITER_BEGIN(*results)+base, VECTOR_SIZE(*results)-base, + qsort(VECTOR_BEGIN(*results)+base, VECTOR_SIZE(*results)-base, sizeof(VECTOR_FRONT(*results)), StringSortCompare); } @@ -501,7 +501,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) if(is_slash(VECTOR_BACK(path))) { VECTOR_POP_BACK(path); - *VECTOR_ITER_END(path) = 0; + *VECTOR_END(path) = 0; } } else if(!(cwdbuf=_wgetcwd(NULL, 0))) @@ -512,7 +512,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) if(is_slash(VECTOR_BACK(path))) { VECTOR_POP_BACK(path); - *VECTOR_ITER_END(path) = 0; + *VECTOR_END(path) = 0; } free(cwdbuf); } @@ -629,8 +629,8 @@ static void DirectorySearch(const char *path, const char *ext, vector_al_string closedir(dir); if(VECTOR_SIZE(*results) > base) - qsort(VECTOR_ITER_BEGIN(*results)+base, VECTOR_SIZE(*results)-base, - sizeof(VECTOR_FRONT(*results)), StringSortCompare); + qsort(VECTOR_BEGIN(*results)+base, VECTOR_SIZE(*results)-base, + sizeof(VECTOR_FRONT(*results)), StringSortCompare); } } @@ -673,7 +673,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) if(VECTOR_BACK(path) == '/') { VECTOR_POP_BACK(path); - *VECTOR_ITER_END(path) = 0; + *VECTOR_END(path) = 0; } al_string_append_cstr(&path, "/.local/share/"); al_string_append_cstr(&path, subdir); @@ -826,7 +826,7 @@ void al_string_clear(al_string *str) */ VECTOR_RESERVE(*str, 1); VECTOR_RESIZE(*str, 0); - *VECTOR_ITER_END(*str) = 0; + *VECTOR_END(*str) = 0; } } @@ -858,8 +858,8 @@ void al_string_copy(al_string *str, const_al_string from) size_t len = al_string_length(from); VECTOR_RESERVE(*str, len+1); VECTOR_RESIZE(*str, 0); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), VECTOR_ITER_BEGIN(from), VECTOR_ITER_BEGIN(from)+len); - *VECTOR_ITER_END(*str) = 0; + VECTOR_INSERT(*str, VECTOR_END(*str), VECTOR_BEGIN(from), VECTOR_BEGIN(from)+len); + *VECTOR_END(*str) = 0; } void al_string_copy_cstr(al_string *str, const al_string_char_type *from) @@ -867,8 +867,8 @@ void al_string_copy_cstr(al_string *str, const al_string_char_type *from) size_t len = strlen(from); VECTOR_RESERVE(*str, len+1); VECTOR_RESIZE(*str, 0); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, from+len); - *VECTOR_ITER_END(*str) = 0; + VECTOR_INSERT(*str, VECTOR_END(*str), from, from+len); + *VECTOR_END(*str) = 0; } void al_string_copy_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to) @@ -876,15 +876,15 @@ void al_string_copy_range(al_string *str, const al_string_char_type *from, const size_t len = to - from; VECTOR_RESERVE(*str, len+1); VECTOR_RESIZE(*str, 0); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, to); - *VECTOR_ITER_END(*str) = 0; + VECTOR_INSERT(*str, VECTOR_END(*str), from, to); + *VECTOR_END(*str) = 0; } void al_string_append_char(al_string *str, const al_string_char_type c) { VECTOR_RESERVE(*str, al_string_length(*str)+2); VECTOR_PUSH_BACK(*str, c); - *VECTOR_ITER_END(*str) = 0; + *VECTOR_END(*str) = 0; } void al_string_append_cstr(al_string *str, const al_string_char_type *from) @@ -893,8 +893,8 @@ void al_string_append_cstr(al_string *str, const al_string_char_type *from) if(len != 0) { VECTOR_RESERVE(*str, al_string_length(*str)+len+1); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, from+len); - *VECTOR_ITER_END(*str) = 0; + VECTOR_INSERT(*str, VECTOR_END(*str), from, from+len); + *VECTOR_END(*str) = 0; } } @@ -903,8 +903,8 @@ void al_string_append_range(al_string *str, const al_string_char_type *from, con if(to != from) { VECTOR_RESERVE(*str, al_string_length(*str)+(to-from)+1); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, to); - *VECTOR_ITER_END(*str) = 0; + VECTOR_INSERT(*str, VECTOR_END(*str), from, to); + *VECTOR_END(*str) = 0; } } @@ -917,7 +917,7 @@ void al_string_copy_wcstr(al_string *str, const wchar_t *from) VECTOR_RESERVE(*str, len); VECTOR_RESIZE(*str, len-1); WideCharToMultiByte(CP_UTF8, 0, from, -1, &VECTOR_FRONT(*str), len, NULL, NULL); - *VECTOR_ITER_END(*str) = 0; + *VECTOR_END(*str) = 0; } } @@ -930,7 +930,7 @@ void al_string_append_wcstr(al_string *str, const wchar_t *from) VECTOR_RESERVE(*str, strlen+len); VECTOR_RESIZE(*str, strlen+len-1); WideCharToMultiByte(CP_UTF8, 0, from, -1, &VECTOR_FRONT(*str) + strlen, len, NULL, NULL); - *VECTOR_ITER_END(*str) = 0; + *VECTOR_END(*str) = 0; } } @@ -943,7 +943,7 @@ void al_string_append_wrange(al_string *str, const wchar_t *from, const wchar_t VECTOR_RESERVE(*str, strlen+len+1); VECTOR_RESIZE(*str, strlen+len); WideCharToMultiByte(CP_UTF8, 0, from, (int)(to-from), &VECTOR_FRONT(*str) + strlen, len+1, NULL, NULL); - *VECTOR_ITER_END(*str) = 0; + *VECTOR_END(*str) = 0; } } #endif diff --git a/Alc/hrtf.c b/Alc/hrtf.c index 49c9793b..9549c010 100644 --- a/Alc/hrtf.c +++ b/Alc/hrtf.c @@ -595,7 +595,7 @@ static void AddFileEntry(vector_HrtfEntry *list, al_string *filename) #define MATCH_NAME(i) (al_string_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const HrtfEntry, *list, MATCH_NAME); #undef MATCH_NAME - } while(iter != VECTOR_ITER_END(*list)); + } while(iter != VECTOR_END(*list)); TRACE("Adding entry \"%s\" from file \"%s\"\n", al_string_get_cstr(entry.name), al_string_get_cstr(*filename)); @@ -667,11 +667,11 @@ vector_HrtfEntry EnumerateHrtf(const_al_string devname) /* Find the preferred HRTF and move it to the front of the list. */ #define FIND_ENTRY(i) (al_string_cmp_cstr((i)->name, defaulthrtf) == 0) VECTOR_FIND_IF(iter, const HrtfEntry, list, FIND_ENTRY); - if(iter != VECTOR_ITER_END(list) && iter != VECTOR_ITER_BEGIN(list)) + if(iter != VECTOR_END(list) && iter != VECTOR_BEGIN(list)) { HrtfEntry entry = *iter; memmove(&VECTOR_ELEM(list,1), &VECTOR_ELEM(list,0), - (iter-VECTOR_ITER_BEGIN(list))*sizeof(HrtfEntry)); + (iter-VECTOR_BEGIN(list))*sizeof(HrtfEntry)); VECTOR_ELEM(list,0) = entry; } else diff --git a/Alc/vector.h b/Alc/vector.h index c1fc925d..cb64b5a9 100644 --- a/Alc/vector.h +++ b/Alc/vector.h @@ -39,8 +39,8 @@ ALboolean vector_resize(char *ptr, size_t base_size, size_t obj_size, size_t obj #define VECTOR_CAPACITY(_x) ((_x) ? (_x)->Capacity : 0) #define VECTOR_SIZE(_x) ((_x) ? (_x)->Size : 0) -#define VECTOR_ITER_BEGIN(_x) ((_x) ? (_x)->Data + 0 : NULL) -#define VECTOR_ITER_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL) +#define VECTOR_BEGIN(_x) ((_x) ? (_x)->Data + 0 : NULL) +#define VECTOR_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL) ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_pos, const void *datstart, const void *datend); #ifdef __GNUC__ @@ -67,22 +67,22 @@ ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_ #define VECTOR_ELEM(_x, _o) ((_x)->Data[(_o)]) #define VECTOR_FOR_EACH(_t, _x, _f) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ + _t *_iter = VECTOR_BEGIN((_x)); \ + _t *_end = VECTOR_END((_x)); \ for(;_iter != _end;++_iter) \ _f(_iter); \ } while(0) #define VECTOR_FOR_EACH_PARAMS(_t, _x, _f, ...) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ + _t *_iter = VECTOR_BEGIN((_x)); \ + _t *_end = VECTOR_END((_x)); \ for(;_iter != _end;++_iter) \ _f(__VA_ARGS__, _iter); \ } while(0) #define VECTOR_FIND_IF(_i, _t, _x, _f) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ + _t *_iter = VECTOR_BEGIN((_x)); \ + _t *_end = VECTOR_END((_x)); \ for(;_iter != _end;++_iter) \ { \ if(_f(_iter)) \ @@ -92,8 +92,8 @@ ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_ } while(0) #define VECTOR_FIND_IF_PARMS(_i, _t, _x, _f, ...) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ + _t *_iter = VECTOR_BEGIN((_x)); \ + _t *_end = VECTOR_END((_x)); \ for(;_iter != _end;++_iter) \ { \ if(_f(__VA_ARGS__, _iter)) \ diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 0364c33c..9780cff3 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -98,7 +98,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo effectslots[cur] = slot->id; } - err = AddEffectSlotArray(context, VECTOR_ITER_BEGIN(slotvec), n); + err = AddEffectSlotArray(context, VECTOR_BEGIN(slotvec), n); if(err != AL_NO_ERROR) { alDeleteAuxiliaryEffectSlots(cur, effectslots); @@ -394,7 +394,7 @@ static ALenum AddEffectSlotArray(ALCcontext *context, ALeffectslot **start, ALsi ALenum err = AL_NO_ERROR; LockContext(context); - if(!VECTOR_INSERT(context->ActiveAuxSlots, VECTOR_ITER_END(context->ActiveAuxSlots), start, start+count)) + if(!VECTOR_INSERT(context->ActiveAuxSlots, VECTOR_END(context->ActiveAuxSlots), start, start+count)) err = AL_OUT_OF_MEMORY; UnlockContext(context); @@ -408,7 +408,7 @@ static void RemoveEffectSlotArray(ALCcontext *context, const ALeffectslot *slot) LockContext(context); #define MATCH_SLOT(_i) (slot == *(_i)) VECTOR_FIND_IF(iter, ALeffectslot*, context->ActiveAuxSlots, MATCH_SLOT); - if(iter != VECTOR_ITER_END(context->ActiveAuxSlots)) + if(iter != VECTOR_END(context->ActiveAuxSlots)) { *iter = VECTOR_BACK(context->ActiveAuxSlots); VECTOR_POP_BACK(context->ActiveAuxSlots); -- cgit v1.2.3 From 186b54aa3d5f1398a384fa318aa000210d82437e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 11 May 2016 18:40:17 -0700 Subject: Use a lockless method for updating listener and context properties This uses a separate container to provide the relevant properties to the internal update method, using atomic pointer swaps. A free-list is used to avoid having too many individual containers. This allows the mixer to update the internal listener properties without requiring the lock to protect against async updates. It also allows concurrent read access to the user-facing property values, even the multi-value ones (e.g. the vectors). --- Alc/ALc.c | 35 ++++++++-- Alc/ALu.c | 58 ++++++++++++----- OpenAL32/Include/alListener.h | 30 ++++++++- OpenAL32/Include/alMain.h | 7 +- OpenAL32/alAuxEffectSlot.c | 7 +- OpenAL32/alListener.c | 148 ++++++++++++++++++++++++++++++------------ OpenAL32/alState.c | 27 ++++++-- 7 files changed, 234 insertions(+), 78 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index b8dae07c..058dd242 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2064,7 +2064,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALsizei pos; - ATOMIC_STORE(&context->UpdateSources, AL_FALSE); LockUIntMapRead(&context->EffectSlotMap); for(pos = 0;pos < context->EffectSlotMap.size;pos++) { @@ -2272,11 +2271,16 @@ static ALCboolean VerifyDevice(ALCdevice **device) static ALvoid InitContext(ALCcontext *Context) { ALlistener *listener = Context->Listener; + //Initialise listener listener->Gain = 1.0f; listener->MetersPerUnit = 1.0f; - aluVectorSet(&listener->Position, 0.0f, 0.0f, 0.0f, 1.0f); - aluVectorSet(&listener->Velocity, 0.0f, 0.0f, 0.0f, 0.0f); + listener->Position[0] = 0.0f; + listener->Position[1] = 0.0f; + listener->Position[2] = 0.0f; + listener->Velocity[0] = 0.0f; + listener->Velocity[1] = 0.0f; + listener->Velocity[2] = 0.0f; listener->Forward[0] = 0.0f; listener->Forward[1] = 0.0f; listener->Forward[2] = -1.0f; @@ -2296,9 +2300,12 @@ static ALvoid InitContext(ALCcontext *Context) listener->Params.DopplerFactor = 1.0f; listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; + ATOMIC_INIT(&listener->Update, NULL); + ATOMIC_INIT(&listener->FreeList, NULL); + //Validate Context + RWLockInit(&Context->PropLock); ATOMIC_INIT(&Context->LastError, AL_NO_ERROR); - ATOMIC_INIT(&Context->UpdateSources, AL_FALSE); InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources); InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax); @@ -2321,6 +2328,10 @@ static ALvoid InitContext(ALCcontext *Context) */ static void FreeContext(ALCcontext *context) { + ALlistener *listener = context->Listener; + struct ALlistenerProps *lprops; + size_t count; + TRACE("%p\n", context); if(context->SourceMap.size > 0) @@ -2344,6 +2355,22 @@ static void FreeContext(ALCcontext *context) VECTOR_DEINIT(context->ActiveAuxSlots); + if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL) + { + TRACE("Freed unapplied listener update %p\n", lprops); + al_free(lprops); + } + count = 0; + lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_consume); + while(lprops) + { + struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_consume); + al_free(lprops); + lprops = next; + ++count; + } + TRACE("Freed "SZFMT" listener property object%s\n", count, (count==1)?"":"s"); + ALCdevice_DecRef(context->Device); context->Device = NULL; diff --git a/Alc/ALu.c b/Alc/ALu.c index 709b7127..82553cc7 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -266,19 +266,25 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state) } -static ALvoid CalcListenerParams(ALCcontext *Context) +static ALboolean CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALdouble N[3], V[3], U[3], P[3]; + struct ALlistenerProps *first; + struct ALlistenerProps *props; + aluVector vel; + + props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel); + if(!props) return AL_FALSE; /* AT then UP */ - N[0] = Listener->Forward[0]; - N[1] = Listener->Forward[1]; - N[2] = Listener->Forward[2]; + N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); + N[1] = ATOMIC_LOAD(&props->Forward[1], almemory_order_relaxed); + N[2] = ATOMIC_LOAD(&props->Forward[2], almemory_order_relaxed); aluNormalized(N); - V[0] = Listener->Up[0]; - V[1] = Listener->Up[1]; - V[2] = Listener->Up[2]; + V[0] = ATOMIC_LOAD(&props->Up[0], almemory_order_relaxed); + V[1] = ATOMIC_LOAD(&props->Up[1], almemory_order_relaxed); + V[2] = ATOMIC_LOAD(&props->Up[2], almemory_order_relaxed); aluNormalized(V); /* Build and normalize right-vector */ aluCrossproductd(N, V, U); @@ -291,19 +297,37 @@ static ALvoid CalcListenerParams(ALCcontext *Context) 0.0, 0.0, 0.0, 1.0 ); - P[0] = Listener->Position.v[0]; - P[1] = Listener->Position.v[1]; - P[2] = Listener->Position.v[2]; + P[0] = ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed); + P[1] = ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed); + P[2] = ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed); aluMatrixdDouble3(P, 1.0, &Listener->Params.Matrix); aluMatrixdSetRow(&Listener->Params.Matrix, 3, -P[0], -P[1], -P[2], 1.0f); - Listener->Params.Velocity = aluMatrixdVector(&Listener->Params.Matrix, &Listener->Velocity); + aluVectorSet(&vel, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), + 0.0f); + Listener->Params.Velocity = aluMatrixdVector(&Listener->Params.Matrix, &vel); + + Listener->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); + Listener->Params.MetersPerUnit = ATOMIC_LOAD(&props->MetersPerUnit, almemory_order_relaxed); - Listener->Params.Gain = Listener->Gain; - Listener->Params.MetersPerUnit = Listener->MetersPerUnit; + Listener->Params.DopplerFactor = ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); + Listener->Params.SpeedOfSound = ATOMIC_LOAD(&props->SpeedOfSound, almemory_order_relaxed) * + ATOMIC_LOAD(&props->DopplerVelocity, almemory_order_relaxed); - Listener->Params.DopplerFactor = Context->DopplerFactor; - Listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity; + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&Listener->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, + &Listener->FreeList, &first, props) == 0); + + return AL_TRUE; } ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) @@ -1223,10 +1247,8 @@ void UpdateContextSources(ALCcontext *ctx) ALvoice *voice, *voice_end; ALsource *source; - if(ATOMIC_EXCHANGE(ALenum, &ctx->UpdateSources, AL_FALSE)) + if(CalcListenerParams(ctx)) { - CalcListenerParams(ctx); - voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index f28561fa..75a3fb46 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -8,14 +8,38 @@ extern "C" { #endif +struct ALlistenerProps { + ATOMIC(ALfloat) Position[3]; + ATOMIC(ALfloat) Velocity[3]; + ATOMIC(ALfloat) Forward[3]; + ATOMIC(ALfloat) Up[3]; + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) MetersPerUnit; + + ATOMIC(ALfloat) DopplerFactor; + ATOMIC(ALfloat) DopplerVelocity; + ATOMIC(ALfloat) SpeedOfSound; + + ATOMIC(struct ALlistenerProps*) next; +}; + typedef struct ALlistener { - aluVector Position; - aluVector Velocity; + volatile ALfloat Position[3]; + volatile ALfloat Velocity[3]; volatile ALfloat Forward[3]; volatile ALfloat Up[3]; volatile ALfloat Gain; volatile ALfloat MetersPerUnit; + /* Pointer to the most recent property values that are awaiting an update. + */ + ATOMIC(struct ALlistenerProps*) Update; + + /* A linked list of unused property containers, free to use for future + * updates. + */ + ATOMIC(struct ALlistenerProps*) FreeList; + struct { aluMatrixd Matrix; aluVector Velocity; @@ -28,6 +52,8 @@ typedef struct ALlistener { } Params; } ALlistener; +void UpdateListenerProps(ALCcontext *context); + #ifdef __cplusplus } #endif diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index e818245b..44ce4fe0 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -679,8 +679,7 @@ struct ALCdevice_struct #define RECORD_THREAD_NAME "alsoft-record" -struct ALCcontext_struct -{ +struct ALCcontext_struct { RefCount ref; struct ALlistener *Listener; @@ -690,8 +689,6 @@ struct ALCcontext_struct ATOMIC(ALenum) LastError; - ATOMIC(ALenum) UpdateSources; - volatile enum DistanceModel DistanceModel; volatile ALboolean SourceDistanceModel; @@ -700,6 +697,8 @@ struct ALCcontext_struct volatile ALfloat SpeedOfSound; volatile ALenum DeferUpdates; + RWLock PropLock; + struct ALvoice *Voices; ALsizei VoiceCount; ALsizei MaxVoices; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 9780cff3..7f570ef8 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -29,6 +29,7 @@ #include "alAuxEffectSlot.h" #include "alThunk.h" #include "alError.h" +#include "alListener.h" #include "alSource.h" #include "almalloc.h" @@ -187,7 +188,6 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param err = InitializeEffect(device, slot, effect); if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: @@ -195,12 +195,15 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + /* HACK: Force sources to update by doing a listener update */ + ReadLock(&context->PropLock); + UpdateListenerProps(context); + ReadUnlock(&context->PropLock); done: ALCcontext_DecRef(context); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 66865473..b215f678 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -33,29 +33,28 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); switch(param) { case AL_GAIN: if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - context->Listener->Gain = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; case AL_METERS_PER_UNIT: if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - context->Listener->MetersPerUnit = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateListenerProps(context); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -67,33 +66,32 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); switch(param) { case AL_POSITION: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - LockContext(context); - aluVectorSet(&context->Listener->Position, value1, value2, value3, 1.0f); - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); - UnlockContext(context); + context->Listener->Position[0] = value1; + context->Listener->Position[1] = value2; + context->Listener->Position[2] = value3; break; case AL_VELOCITY: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - LockContext(context); - aluVectorSet(&context->Listener->Velocity, value1, value2, value3, 0.0f); - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); - UnlockContext(context); + context->Listener->Velocity[0] = value1; + context->Listener->Velocity[1] = value2; + context->Listener->Velocity[2] = value3; break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateListenerProps(context); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -121,6 +119,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) @@ -129,8 +128,6 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) if(!(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - LockContext(context); /* AT then UP */ context->Listener->Forward[0] = values[0]; context->Listener->Forward[1] = values[1]; @@ -138,15 +135,15 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) context->Listener->Up[0] = values[3]; context->Listener->Up[1] = values[4]; context->Listener->Up[2] = values[5]; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); - UnlockContext(context); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateListenerProps(context); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -158,13 +155,16 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); switch(param) { default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateListenerProps(context); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -184,13 +184,16 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); switch(param) { default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateListenerProps(context); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -224,6 +227,7 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) @@ -231,8 +235,10 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateListenerProps(context); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -244,6 +250,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) context = GetContextRef(); if(!context) return; + ReadLock(&context->PropLock); if(!(value)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) @@ -261,6 +268,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) } done: + ReadUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -272,24 +280,21 @@ AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat context = GetContextRef(); if(!context) return; + ReadLock(&context->PropLock); if(!(value1 && value2 && value3)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { case AL_POSITION: - LockContext(context); - *value1 = context->Listener->Position.v[0]; - *value2 = context->Listener->Position.v[1]; - *value3 = context->Listener->Position.v[2]; - UnlockContext(context); + *value1 = context->Listener->Position[0]; + *value2 = context->Listener->Position[1]; + *value3 = context->Listener->Position[2]; break; case AL_VELOCITY: - LockContext(context); - *value1 = context->Listener->Velocity.v[0]; - *value2 = context->Listener->Velocity.v[1]; - *value3 = context->Listener->Velocity.v[2]; - UnlockContext(context); + *value1 = context->Listener->Velocity[0]; + *value2 = context->Listener->Velocity[1]; + *value3 = context->Listener->Velocity[2]; break; default: @@ -297,6 +302,7 @@ AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat } done: + ReadUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -321,12 +327,12 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) context = GetContextRef(); if(!context) return; + ReadLock(&context->PropLock); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { case AL_ORIENTATION: - LockContext(context); // AT then UP values[0] = context->Listener->Forward[0]; values[1] = context->Listener->Forward[1]; @@ -334,7 +340,6 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) values[3] = context->Listener->Up[0]; values[4] = context->Listener->Up[1]; values[5] = context->Listener->Up[2]; - UnlockContext(context); break; default: @@ -342,6 +347,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) } done: + ReadUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -353,6 +359,7 @@ AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) context = GetContextRef(); if(!context) return; + ReadLock(&context->PropLock); if(!(value)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) @@ -362,6 +369,7 @@ AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) } done: + ReadUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -373,24 +381,21 @@ AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *valu context = GetContextRef(); if(!context) return; + ReadLock(&context->PropLock); if(!(value1 && value2 && value3)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch (param) { case AL_POSITION: - LockContext(context); - *value1 = (ALint)context->Listener->Position.v[0]; - *value2 = (ALint)context->Listener->Position.v[1]; - *value3 = (ALint)context->Listener->Position.v[2]; - UnlockContext(context); + *value1 = (ALint)context->Listener->Position[0]; + *value2 = (ALint)context->Listener->Position[1]; + *value3 = (ALint)context->Listener->Position[2]; break; case AL_VELOCITY: - LockContext(context); - *value1 = (ALint)context->Listener->Velocity.v[0]; - *value2 = (ALint)context->Listener->Velocity.v[1]; - *value3 = (ALint)context->Listener->Velocity.v[2]; - UnlockContext(context); + *value1 = (ALint)context->Listener->Velocity[0]; + *value2 = (ALint)context->Listener->Velocity[1]; + *value3 = (ALint)context->Listener->Velocity[2]; break; default: @@ -398,6 +403,7 @@ AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *valu } done: + ReadUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -417,12 +423,12 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) context = GetContextRef(); if(!context) return; + ReadLock(&context->PropLock); if(!(values)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(param) { case AL_ORIENTATION: - LockContext(context); // AT then UP values[0] = (ALint)context->Listener->Forward[0]; values[1] = (ALint)context->Listener->Forward[1]; @@ -430,7 +436,6 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) values[3] = (ALint)context->Listener->Up[0]; values[4] = (ALint)context->Listener->Up[1]; values[5] = (ALint)context->Listener->Up[2]; - UnlockContext(context); break; default: @@ -438,5 +443,64 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) } done: + ReadUnlock(&context->PropLock); ALCcontext_DecRef(context); } + + +void UpdateListenerProps(ALCcontext *context) +{ + ALlistener *listener = context->Listener; + struct ALlistenerProps *props; + + /* Get an unused proprty container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire); + if(!props) + props = al_calloc(16, sizeof(*props)); + else + { + struct ALlistenerProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, + &listener->FreeList, &props, next, almemory_order_seq_cst, + almemory_order_consume) == 0); + } + + /* Copy in current property values. */ + ATOMIC_STORE(&props->Position[0], listener->Position[0], almemory_order_relaxed); + ATOMIC_STORE(&props->Position[1], listener->Position[1], almemory_order_relaxed); + ATOMIC_STORE(&props->Position[2], listener->Position[2], almemory_order_relaxed); + + ATOMIC_STORE(&props->Velocity[0], listener->Velocity[0], almemory_order_relaxed); + ATOMIC_STORE(&props->Velocity[1], listener->Velocity[1], almemory_order_relaxed); + ATOMIC_STORE(&props->Velocity[2], listener->Velocity[2], almemory_order_relaxed); + + ATOMIC_STORE(&props->Forward[0], listener->Forward[0], almemory_order_relaxed); + ATOMIC_STORE(&props->Forward[1], listener->Forward[1], almemory_order_relaxed); + ATOMIC_STORE(&props->Forward[2], listener->Forward[2], almemory_order_relaxed); + ATOMIC_STORE(&props->Up[0], listener->Up[0], almemory_order_relaxed); + ATOMIC_STORE(&props->Up[1], listener->Up[1], almemory_order_relaxed); + ATOMIC_STORE(&props->Up[2], listener->Up[2], almemory_order_relaxed); + + ATOMIC_STORE(&props->Gain, listener->Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->MetersPerUnit, listener->MetersPerUnit, almemory_order_relaxed); + + ATOMIC_STORE(&props->DopplerFactor, context->DopplerFactor, almemory_order_relaxed); + ATOMIC_STORE(&props->DopplerVelocity, context->DopplerVelocity, almemory_order_relaxed); + ATOMIC_STORE(&props->SpeedOfSound, context->SpeedOfSound, almemory_order_relaxed); + + /* Set the new container for updating internal parameters. */ + props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &listener->Update, props, almemory_order_acq_rel); + if(props) + { + /* If there was an unused update container, put it back in the + * freelist. + */ + struct ALlistenerProps *first = ATOMIC_LOAD(&listener->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, + &listener->FreeList, &first, props) == 0); + } +} diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index dca41363..899dacd4 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -26,6 +26,7 @@ #include "AL/al.h" #include "AL/alext.h" #include "alError.h" +#include "alListener.h" #include "alSource.h" #include "alAuxEffectSlot.h" @@ -55,12 +56,15 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) { case AL_SOURCE_DISTANCE_MODEL: context->SourceDistanceModel = AL_TRUE; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + /* HACK: Force sources to update by doing a listener update */ + ReadLock(&context->PropLock); + UpdateListenerProps(context); + ReadUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -77,12 +81,15 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) { case AL_SOURCE_DISTANCE_MODEL: context->SourceDistanceModel = AL_FALSE; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + /* HACK: Force sources to update by doing a listener update */ + ReadLock(&context->PropLock); + UpdateListenerProps(context); + ReadUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -547,8 +554,10 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->DopplerFactor = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -564,8 +573,10 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) if(!(value >= 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->DopplerVelocity = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -581,8 +592,10 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) if(!(value > 0.0f && isfinite(value))) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->SpeedOfSound = value; - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); @@ -601,9 +614,11 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) value == AL_NONE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + WriteLock(&context->PropLock); context->DistanceModel = value; if(!context->SourceDistanceModel) - ATOMIC_STORE(&context->UpdateSources, AL_TRUE); + UpdateListenerProps(context); + WriteUnlock(&context->PropLock); done: ALCcontext_DecRef(context); -- cgit v1.2.3 From ef0d4f8210fe6aa65b9df96f3b64bf6f355e845a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 12 May 2016 18:26:33 -0700 Subject: Provide (mostly) lockless updates for effect slots Similar to the listener, separate containers are provided atomically for the mixer thread to apply updates without needing to block, and a free-list is used to reuse container objects. A couple things to note. First, the lock is still used when the effect state's deviceUpdate method is called to prevent asynchronous calls to reset the device from interfering. This can be fixed by using the list lock in ALc.c instead. Secondly, old effect states aren't immediately deleted when the effect type changes (the actual type, not just its properties). This is because the mixer thread is intended to be real-time safe, and so can't be freeing anything. They are cleared away when updates reuse the container they were kept in, and they don't incur any extra processing cost, but there may be cases where the memory is kept around until the effect slot is deleted. --- Alc/ALc.c | 56 ++++++------- Alc/ALu.c | 103 +++++++++++++++-------- Alc/effects/autowah.c | 13 +-- Alc/effects/chorus.c | 17 ++-- Alc/effects/compressor.c | 7 +- Alc/effects/dedicated.c | 9 +- Alc/effects/distortion.c | 15 ++-- Alc/effects/echo.c | 13 +-- Alc/effects/equalizer.c | 29 ++++--- Alc/effects/flanger.c | 17 ++-- Alc/effects/modulator.c | 15 ++-- Alc/effects/null.c | 6 +- Alc/effects/reverb.c | 9 +- OpenAL32/Include/alAuxEffectSlot.h | 44 ++++++++-- OpenAL32/alAuxEffectSlot.c | 166 ++++++++++++++++++++++++++----------- 15 files changed, 332 insertions(+), 187 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 058dd242..b3d7eb38 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1570,12 +1570,6 @@ void ALCcontext_DeferUpdates(ALCcontext *context) /* Make sure all pending updates are performed */ UpdateContextSources(context); -#define UPDATE_SLOT(iter) do { \ - if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \ - V((*iter)->EffectState,update)(device, *iter); \ -} while(0) - VECTOR_FOR_EACH(ALeffectslot*, context->ActiveAuxSlots, UPDATE_SLOT); -#undef UPDATE_SLOT } V0(device->Backend,unlock)(); @@ -2059,6 +2053,22 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) SetMixerFPUMode(&oldMode); V0(device->Backend,lock)(); + if(device->DefaultSlot) + { + ALeffectslot *slot = device->DefaultSlot; + ALeffectState *state = slot->Params.EffectState; + + state->OutBuffer = device->Dry.Buffer; + state->OutChannels = device->Dry.NumChannels; + if(V(state,deviceUpdate)(device) == AL_FALSE) + { + V0(device->Backend,unlock)(); + RestoreFPUMode(&oldMode); + return ALC_INVALID_DEVICE; + } + UpdateEffectSlotProps(slot); + } + context = ATOMIC_LOAD(&device->ContextList); while(context) { @@ -2069,17 +2079,16 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALeffectslot *slot = context->EffectSlotMap.array[pos].value; - slot->EffectState->OutBuffer = device->Dry.Buffer; - slot->EffectState->OutChannels = device->Dry.NumChannels; - if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE) + slot->Params.EffectState->OutBuffer = device->Dry.Buffer; + slot->Params.EffectState->OutChannels = device->Dry.NumChannels; + if(V(slot->Params.EffectState,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } - ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE); - V(slot->EffectState,update)(device, slot); + UpdateEffectSlotProps(slot); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -2126,22 +2135,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) context = context->next; } - if(device->DefaultSlot) - { - ALeffectslot *slot = device->DefaultSlot; - ALeffectState *state = slot->EffectState; - - state->OutBuffer = device->Dry.Buffer; - state->OutChannels = device->Dry.NumChannels; - if(V(state,deviceUpdate)(device) == AL_FALSE) - { - V0(device->Backend,unlock)(); - RestoreFPUMode(&oldMode); - return ALC_INVALID_DEVICE; - } - ATOMIC_STORE(&slot->NeedsUpdate, AL_FALSE); - V(slot->EffectState,update)(device, slot); - } V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); @@ -2170,9 +2163,8 @@ static ALCvoid FreeDevice(ALCdevice *device) if(device->DefaultSlot) { - ALeffectState *state = device->DefaultSlot->EffectState; + DeinitEffectSlot(device->DefaultSlot); device->DefaultSlot = NULL; - DELETE_OBJ(state); } if(device->BufferMap.size > 0) @@ -3497,13 +3489,15 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) } else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) { - ALeffectState *state = device->DefaultSlot->EffectState; + DeinitEffectSlot(device->DefaultSlot); device->DefaultSlot = NULL; - DELETE_OBJ(state); ERR("Failed to initialize the default effect\n"); } else + { aluInitEffectPanning(device->DefaultSlot); + UpdateEffectSlotProps(device->DefaultSlot); + } } { diff --git a/Alc/ALu.c b/Alc/ALu.c index 82553cc7..3b873aa5 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -330,6 +330,55 @@ static ALboolean CalcListenerParams(ALCcontext *Context) return AL_TRUE; } +static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) +{ + struct ALeffectslotProps *first; + struct ALeffectslotProps *props; + + props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); + if(!props) return AL_FALSE; + + slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); + slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); + slot->Params.EffectType = ATOMIC_LOAD(&props->Type, almemory_order_relaxed); + memcpy(&slot->Params.EffectProps, &props->Props, sizeof(props->Props)); + /* If the existing state object is different from the one being set, + * exchange it so it remains in the freelist and isn't leaked. + */ + if(slot->Params.EffectState == ATOMIC_LOAD(&props->State, almemory_order_relaxed)) + slot->Params.EffectState = NULL; + slot->Params.EffectState = ATOMIC_EXCHANGE(ALeffectState*, + &props->State, slot->Params.EffectState, almemory_order_relaxed + ); + if(IsReverbEffect(slot->Params.EffectType)) + { + slot->Params.RoomRolloff = slot->Params.EffectProps.Reverb.RoomRolloffFactor; + slot->Params.DecayTime = slot->Params.EffectProps.Reverb.DecayTime; + slot->Params.AirAbsorptionGainHF = slot->Params.EffectProps.Reverb.AirAbsorptionGainHF; + } + else + { + slot->Params.RoomRolloff = 0.0f; + slot->Params.DecayTime = 0.0f; + slot->Params.AirAbsorptionGainHF = 1.0f; + } + + V(slot->Params.EffectState,update)(device, slot); + + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&slot->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + &slot->FreeList, &first, props) == 0); + + return AL_TRUE; +} + ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { static const struct ChanMap MonoMap[1] = { @@ -415,7 +464,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A SendSlots[i] = ALSource->Send[i].Slot; if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; - if(!SendSlots[i] || SendSlots[i]->EffectType == AL_EFFECT_NULL) + if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) { SendSlots[i] = NULL; voice->Send[i].OutBuffer = NULL; @@ -847,7 +896,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; - if(!SendSlots[i] || SendSlots[i]->EffectType == AL_EFFECT_NULL) + if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) { SendSlots[i] = NULL; RoomRolloff[i] = 0.0f; @@ -856,19 +905,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } else if(SendSlots[i]->AuxSendAuto) { - RoomRolloff[i] = RoomRolloffBase; - if(IsReverbEffect(SendSlots[i]->EffectType)) - { - RoomRolloff[i] += SendSlots[i]->EffectProps.Reverb.RoomRolloffFactor; - DecayDistance[i] = SendSlots[i]->EffectProps.Reverb.DecayTime * - SPEEDOFSOUNDMETRESPERSEC; - RoomAirAbsorption[i] = SendSlots[i]->EffectProps.Reverb.AirAbsorptionGainHF; - } - else - { - DecayDistance[i] = 0.0f; - RoomAirAbsorption[i] = 1.0f; - } + RoomRolloff[i] = SendSlots[i]->Params.RoomRolloff + RoomRolloffBase; + DecayDistance[i] = SendSlots[i]->Params.DecayTime * + SPEEDOFSOUNDMETRESPERSEC; + RoomAirAbsorption[i] = SendSlots[i]->Params.AirAbsorptionGainHF; } else { @@ -1245,9 +1285,18 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer void UpdateContextSources(ALCcontext *ctx) { ALvoice *voice, *voice_end; + ALboolean fullupdate; ALsource *source; - if(CalcListenerParams(ctx)) + fullupdate = CalcListenerParams(ctx); +#define UPDATE_SLOT(iter) do { \ + if(CalcEffectSlotParams(*iter, ctx->Device)) \ + fullupdate = AL_TRUE; \ +} while(0) + VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); +#undef UPDATE_SLOT + + if(fullupdate) { voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; @@ -1388,8 +1437,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) if((slot=device->DefaultSlot) != NULL) { - if(ATOMIC_EXCHANGE(ALenum, &slot->NeedsUpdate, AL_FALSE)) - V(slot->EffectState,update)(device, slot); + CalcEffectSlotParams(device->DefaultSlot, device); for(i = 0;i < slot->NumChannels;i++) memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); } @@ -1398,26 +1446,13 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) while(ctx) { if(!ctx->DeferUpdates) - { UpdateContextSources(ctx); -#define UPDATE_SLOT(iter) do { \ - if(ATOMIC_EXCHANGE(ALenum, &(*iter)->NeedsUpdate, AL_FALSE)) \ - V((*iter)->EffectState,update)(device, *iter); \ - for(i = 0;i < (*iter)->NumChannels;i++) \ - memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \ -} while(0) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); -#undef UPDATE_SLOT - } - else - { #define CLEAR_WET_BUFFER(iter) do { \ for(i = 0;i < (*iter)->NumChannels;i++) \ memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \ } while(0) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, CLEAR_WET_BUFFER); + VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, CLEAR_WET_BUFFER); #undef CLEAR_WET_BUFFER - } /* source processing */ voice = ctx->Voices; @@ -1434,7 +1469,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) for(i = 0;i < c;i++) { const ALeffectslot *slot = VECTOR_ELEM(ctx->ActiveAuxSlots, i); - ALeffectState *state = slot->EffectState; + ALeffectState *state = slot->Params.EffectState; V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer, state->OutChannels); } @@ -1445,7 +1480,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) if(device->DefaultSlot != NULL) { const ALeffectslot *slot = device->DefaultSlot; - ALeffectState *state = slot->EffectState; + ALeffectState *state = slot->Params.EffectState; V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer, state->OutChannels); } diff --git a/Alc/effects/autowah.c b/Alc/effects/autowah.c index 7c5abfb1..1e7a8e29 100644 --- a/Alc/effects/autowah.c +++ b/Alc/effects/autowah.c @@ -53,8 +53,9 @@ typedef struct ALautowahState { ALfilterState LowPass; } ALautowahState; -static ALvoid ALautowahState_Destruct(ALautowahState *UNUSED(state)) +static ALvoid ALautowahState_Destruct(ALautowahState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *device) @@ -67,15 +68,15 @@ static ALvoid ALautowahState_update(ALautowahState *state, const ALCdevice *devi { ALfloat attackTime, releaseTime; - attackTime = slot->EffectProps.Autowah.AttackTime * state->Frequency; - releaseTime = slot->EffectProps.Autowah.ReleaseTime * state->Frequency; + attackTime = slot->Params.EffectProps.Autowah.AttackTime * state->Frequency; + releaseTime = slot->Params.EffectProps.Autowah.ReleaseTime * state->Frequency; state->AttackRate = powf(1.0f/GAIN_SILENCE_THRESHOLD, 1.0f/attackTime); state->ReleaseRate = powf(GAIN_SILENCE_THRESHOLD/1.0f, 1.0f/releaseTime); - state->PeakGain = slot->EffectProps.Autowah.PeakGain; - state->Resonance = slot->EffectProps.Autowah.Resonance; + state->PeakGain = slot->Params.EffectProps.Autowah.PeakGain; + state->Resonance = slot->Params.EffectProps.Autowah.Resonance; - ComputeAmbientGains(device->Dry, slot->Gain, state->Gain); + ComputeAmbientGains(device->Dry, slot->Params.Gain, state->Gain); } static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index 9deb2a1f..3eff95a4 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -60,6 +60,7 @@ static ALvoid ALchorusState_Destruct(ALchorusState *state) free(state->SampleBuffer[0]); state->SampleBuffer[0] = NULL; state->SampleBuffer[1] = NULL; + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Device) @@ -98,7 +99,7 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device ALfloat rate; ALint phase; - switch(Slot->EffectProps.Chorus.Waveform) + switch(Slot->Params.EffectProps.Chorus.Waveform) { case AL_CHORUS_WAVEFORM_TRIANGLE: state->waveform = CWF_Triangle; @@ -107,18 +108,18 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device state->waveform = CWF_Sinusoid; break; } - state->depth = Slot->EffectProps.Chorus.Depth; - state->feedback = Slot->EffectProps.Chorus.Feedback; - state->delay = fastf2i(Slot->EffectProps.Chorus.Delay * frequency); + state->depth = Slot->Params.EffectProps.Chorus.Depth; + state->feedback = Slot->Params.EffectProps.Chorus.Feedback; + state->delay = fastf2i(Slot->Params.EffectProps.Chorus.Delay * frequency); /* Gains for left and right sides */ CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]); + ComputePanningGains(Device->Dry, coeffs, Slot->Params.Gain, state->Gain[0]); CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]); + ComputePanningGains(Device->Dry, coeffs, Slot->Params.Gain, state->Gain[1]); - phase = Slot->EffectProps.Chorus.Phase; - rate = Slot->EffectProps.Chorus.Rate; + phase = Slot->Params.EffectProps.Chorus.Phase; + rate = Slot->Params.EffectProps.Chorus.Rate; if(!(rate > 0.0f)) { state->lfo_scale = 0.0f; diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index bc4955b9..c501b3ba 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -40,8 +40,9 @@ typedef struct ALcompressorState { ALfloat GainCtrl; } ALcompressorState; -static ALvoid ALcompressorState_Destruct(ALcompressorState *UNUSED(state)) +static ALvoid ALcompressorState_Destruct(ALcompressorState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdevice *device) @@ -60,7 +61,7 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice aluMatrixf matrix; ALuint i; - state->Enabled = slot->EffectProps.Compressor.OnOff; + state->Enabled = slot->Params.EffectProps.Compressor.OnOff; aluMatrixfSet(&matrix, 1.0f, 0.0f, 0.0f, 0.0f, @@ -72,7 +73,7 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels; for(i = 0;i < 4;i++) - ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Gain, + ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Params.Gain, state->Gain[i]); } diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index f510e8fe..34e5ed80 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -36,8 +36,9 @@ typedef struct ALdedicatedState { } ALdedicatedState; -static ALvoid ALdedicatedState_Destruct(ALdedicatedState *UNUSED(state)) +static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *UNUSED(state), ALCdevice *UNUSED(device)) @@ -53,8 +54,8 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice * for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) state->gains[i] = 0.0f; - Gain = Slot->Gain * Slot->EffectProps.Dedicated.Gain; - if(Slot->EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) + Gain = Slot->Params.Gain * Slot->Params.EffectProps.Dedicated.Gain; + if(Slot->Params.EffectType == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) { int idx; if((idx=GetChannelIdxByName(device->RealOut, LFE)) != -1) @@ -64,7 +65,7 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice * state->gains[idx] = Gain; } } - else if(Slot->EffectType == AL_EFFECT_DEDICATED_DIALOGUE) + else if(Slot->Params.EffectType == AL_EFFECT_DEDICATED_DIALOGUE) { int idx; /* Dialog goes to the front-center speaker if it exists, otherwise it diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index 7a4c2f62..534a817c 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -43,8 +43,9 @@ typedef struct ALdistortionState { ALfloat edge_coeff; } ALdistortionState; -static ALvoid ALdistortionState_Destruct(ALdistortionState *UNUSED(state)) +static ALvoid ALdistortionState_Destruct(ALdistortionState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *UNUSED(state), ALCdevice *UNUSED(device)) @@ -60,15 +61,15 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCdevice ALfloat edge; /* Store distorted signal attenuation settings */ - state->attenuation = Slot->EffectProps.Distortion.Gain; + state->attenuation = Slot->Params.EffectProps.Distortion.Gain; /* Store waveshaper edge settings */ - edge = sinf(Slot->EffectProps.Distortion.Edge * (F_PI_2)); + edge = sinf(Slot->Params.EffectProps.Distortion.Edge * (F_PI_2)); edge = minf(edge, 0.99f); state->edge_coeff = 2.0f * edge / (1.0f-edge); /* Lowpass filter */ - cutoff = Slot->EffectProps.Distortion.LowpassCutoff; + cutoff = Slot->Params.EffectProps.Distortion.LowpassCutoff; /* Bandwidth value is constant in octaves */ bandwidth = (cutoff / 2.0f) / (cutoff * 0.67f); ALfilterState_setParams(&state->lowpass, ALfilterType_LowPass, 1.0f, @@ -76,14 +77,14 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCdevice ); /* Bandpass filter */ - cutoff = Slot->EffectProps.Distortion.EQCenter; + cutoff = Slot->Params.EffectProps.Distortion.EQCenter; /* Convert bandwidth in Hz to octaves */ - bandwidth = Slot->EffectProps.Distortion.EQBandwidth / (cutoff * 0.67f); + bandwidth = Slot->Params.EffectProps.Distortion.EQBandwidth / (cutoff * 0.67f); ALfilterState_setParams(&state->bandpass, ALfilterType_BandPass, 1.0f, cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) ); - ComputeAmbientGains(Device->Dry, Slot->Gain, state->Gain); + ComputeAmbientGains(Device->Dry, Slot->Params.Gain, state->Gain); } static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index 8600db70..eea86f15 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -54,6 +54,7 @@ static ALvoid ALechoState_Destruct(ALechoState *state) { free(state->SampleBuffer); state->SampleBuffer = NULL; + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device) @@ -87,11 +88,11 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, co ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat gain, lrpan, spread; - state->Tap[0].delay = fastf2u(Slot->EffectProps.Echo.Delay * frequency) + 1; - state->Tap[1].delay = fastf2u(Slot->EffectProps.Echo.LRDelay * frequency); + state->Tap[0].delay = fastf2u(Slot->Params.EffectProps.Echo.Delay * frequency) + 1; + state->Tap[1].delay = fastf2u(Slot->Params.EffectProps.Echo.LRDelay * frequency); state->Tap[1].delay += state->Tap[0].delay; - spread = Slot->EffectProps.Echo.Spread; + spread = Slot->Params.EffectProps.Echo.Spread; if(spread < 0.0f) lrpan = -1.0f; else lrpan = 1.0f; /* Convert echo spread (where 0 = omni, +/-1 = directional) to coverage @@ -99,14 +100,14 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, co */ spread = asinf(1.0f - fabsf(spread))*4.0f; - state->FeedGain = Slot->EffectProps.Echo.Feedback; + state->FeedGain = Slot->Params.EffectProps.Echo.Feedback; - gain = minf(1.0f - Slot->EffectProps.Echo.Damping, 0.01f); + gain = minf(1.0f - Slot->Params.EffectProps.Echo.Damping, 0.01f); ALfilterState_setParams(&state->Filter, ALfilterType_HighShelf, gain, LOWPASSFREQREF/frequency, calc_rcpQ_from_slope(gain, 0.75f)); - gain = Slot->Gain; + gain = Slot->Params.Gain; /* First tap panning */ CalcXYZCoeffs(-lrpan, 0.0f, 0.0f, spread, coeffs); diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index e0fa010e..94ee1853 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -87,8 +87,9 @@ typedef struct ALequalizerState { ALfloat SampleBuffer[4][MAX_EFFECT_CHANNELS][MAX_UPDATE_SAMPLES]; } ALequalizerState; -static ALvoid ALequalizerState_Destruct(ALequalizerState *UNUSED(state)) +static ALvoid ALequalizerState_Destruct(ALequalizerState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *UNUSED(state), ALCdevice *UNUSED(device)) @@ -113,15 +114,15 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice * STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels; for(i = 0;i < MAX_EFFECT_CHANNELS;i++) - ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Gain, + ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Params.Gain, state->Gain[i]); /* Calculate coefficients for the each type of filter. Note that the shelf * filters' gain is for the reference frequency, which is the centerpoint * of the transition band. */ - gain = sqrtf(slot->EffectProps.Equalizer.LowGain); - freq_mult = slot->EffectProps.Equalizer.LowCutoff/frequency; + gain = sqrtf(slot->Params.EffectProps.Equalizer.LowGain); + freq_mult = slot->Params.EffectProps.Equalizer.LowCutoff/frequency; ALfilterState_setParams(&state->filter[0][0], ALfilterType_LowShelf, gain, freq_mult, calc_rcpQ_from_slope(gain, 0.75f) ); @@ -136,10 +137,12 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice * state->filter[0][i].process = state->filter[0][0].process; } - gain = slot->EffectProps.Equalizer.Mid1Gain; - freq_mult = slot->EffectProps.Equalizer.Mid1Center/frequency; + gain = slot->Params.EffectProps.Equalizer.Mid1Gain; + freq_mult = slot->Params.EffectProps.Equalizer.Mid1Center/frequency; ALfilterState_setParams(&state->filter[1][0], ALfilterType_Peaking, - gain, freq_mult, calc_rcpQ_from_bandwidth(freq_mult, slot->EffectProps.Equalizer.Mid1Width) + gain, freq_mult, calc_rcpQ_from_bandwidth( + freq_mult, slot->Params.EffectProps.Equalizer.Mid1Width + ) ); for(i = 1;i < MAX_EFFECT_CHANNELS;i++) { @@ -151,10 +154,12 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice * state->filter[1][i].process = state->filter[1][0].process; } - gain = slot->EffectProps.Equalizer.Mid2Gain; - freq_mult = slot->EffectProps.Equalizer.Mid2Center/frequency; + gain = slot->Params.EffectProps.Equalizer.Mid2Gain; + freq_mult = slot->Params.EffectProps.Equalizer.Mid2Center/frequency; ALfilterState_setParams(&state->filter[2][0], ALfilterType_Peaking, - gain, freq_mult, calc_rcpQ_from_bandwidth(freq_mult, slot->EffectProps.Equalizer.Mid2Width) + gain, freq_mult, calc_rcpQ_from_bandwidth( + freq_mult, slot->Params.EffectProps.Equalizer.Mid2Width + ) ); for(i = 1;i < MAX_EFFECT_CHANNELS;i++) { @@ -166,8 +171,8 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice * state->filter[2][i].process = state->filter[2][0].process; } - gain = sqrtf(slot->EffectProps.Equalizer.HighGain); - freq_mult = slot->EffectProps.Equalizer.HighCutoff/frequency; + gain = sqrtf(slot->Params.EffectProps.Equalizer.HighGain); + freq_mult = slot->Params.EffectProps.Equalizer.HighCutoff/frequency; ALfilterState_setParams(&state->filter[3][0], ALfilterType_HighShelf, gain, freq_mult, calc_rcpQ_from_slope(gain, 0.75f) ); diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c index a71eb9c2..966622e6 100644 --- a/Alc/effects/flanger.c +++ b/Alc/effects/flanger.c @@ -60,6 +60,7 @@ static ALvoid ALflangerState_Destruct(ALflangerState *state) free(state->SampleBuffer[0]); state->SampleBuffer[0] = NULL; state->SampleBuffer[1] = NULL; + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *Device) @@ -98,7 +99,7 @@ static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Devi ALfloat rate; ALint phase; - switch(Slot->EffectProps.Flanger.Waveform) + switch(Slot->Params.EffectProps.Flanger.Waveform) { case AL_FLANGER_WAVEFORM_TRIANGLE: state->waveform = FWF_Triangle; @@ -107,18 +108,18 @@ static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Devi state->waveform = FWF_Sinusoid; break; } - state->depth = Slot->EffectProps.Flanger.Depth; - state->feedback = Slot->EffectProps.Flanger.Feedback; - state->delay = fastf2i(Slot->EffectProps.Flanger.Delay * frequency); + state->depth = Slot->Params.EffectProps.Flanger.Depth; + state->feedback = Slot->Params.EffectProps.Flanger.Feedback; + state->delay = fastf2i(Slot->Params.EffectProps.Flanger.Delay * frequency); /* Gains for left and right sides */ CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]); + ComputePanningGains(Device->Dry, coeffs, Slot->Params.Gain, state->Gain[0]); CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]); + ComputePanningGains(Device->Dry, coeffs, Slot->Params.Gain, state->Gain[1]); - phase = Slot->EffectProps.Flanger.Phase; - rate = Slot->EffectProps.Flanger.Rate; + phase = Slot->Params.EffectProps.Flanger.Phase; + rate = Slot->Params.EffectProps.Flanger.Rate; if(!(rate > 0.0f)) { state->lfo_scale = 0.0f; diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index fb75043a..5a96bb9d 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -82,8 +82,9 @@ DECL_TEMPLATE(Square) #undef DECL_TEMPLATE -static ALvoid ALmodulatorState_Destruct(ALmodulatorState *UNUSED(state)) +static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *UNUSED(state), ALCdevice *UNUSED(device)) @@ -97,19 +98,19 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice * ALfloat cw, a; ALuint i; - if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID) + if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SINUSOID) state->Process = ModulateSin; - else if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH) + else if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH) state->Process = ModulateSaw; - else /*if(Slot->EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/ + else /*if(Slot->Params.EffectProps.Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/ state->Process = ModulateSquare; - state->step = fastf2u(Slot->EffectProps.Modulator.Frequency*WAVEFORM_FRACONE / + state->step = fastf2u(Slot->Params.EffectProps.Modulator.Frequency*WAVEFORM_FRACONE / Device->Frequency); if(state->step == 0) state->step = 1; /* Custom filter coeffs, which match the old version instead of a low-shelf. */ - cw = cosf(F_TAU * Slot->EffectProps.Modulator.HighPassCutoff / Device->Frequency); + cw = cosf(F_TAU * Slot->Params.EffectProps.Modulator.HighPassCutoff / Device->Frequency); a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f); for(i = 0;i < MAX_EFFECT_CHANNELS;i++) @@ -132,7 +133,7 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice * STATIC_CAST(ALeffectState,state)->OutBuffer = Device->FOAOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = Device->FOAOut.NumChannels; for(i = 0;i < MAX_EFFECT_CHANNELS;i++) - ComputeFirstOrderGains(Device->FOAOut, matrix.m[i], Slot->Gain, + ComputeFirstOrderGains(Device->FOAOut, matrix.m[i], Slot->Params.Gain, state->Gain[i]); } diff --git a/Alc/effects/null.c b/Alc/effects/null.c index 0600703d..b90f75c9 100644 --- a/Alc/effects/null.c +++ b/Alc/effects/null.c @@ -15,10 +15,12 @@ typedef struct ALnullState { /* This destructs (not free!) the effect state. It's called only when the - * effect slot is no longer used. + * effect slot is no longer used. Make sure to call the parent Destruct + * function before returning! */ -static ALvoid ALnullState_Destruct(ALnullState* UNUSED(state)) +static ALvoid ALnullState_Destruct(ALnullState *state) { + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } /* This updates the device-dependant effect state. This is called on diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index ef3ab6c3..bd5637e9 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -169,6 +169,7 @@ static ALvoid ALreverbState_Destruct(ALreverbState *State) { free(State->SampleBuffer); State->SampleBuffer = NULL; + ALeffectState_Destruct(STATIC_CAST(ALeffectState,State)); } static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Device); @@ -894,15 +895,15 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device, const ALeffectslot *Slot) { - const ALeffectProps *props = &Slot->EffectProps; + const ALeffectProps *props = &Slot->Params.EffectProps; ALuint frequency = Device->Frequency; ALfloat lfscale, hfscale, hfRatio; ALfloat gain, gainlf, gainhf; ALfloat cw, x, y; - if(Slot->EffectType == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) + if(Slot->Params.EffectType == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) State->IsEax = AL_TRUE; - else if(Slot->EffectType == AL_EFFECT_REVERB || EmulateEAXReverb) + else if(Slot->Params.EffectType == AL_EFFECT_REVERB || EmulateEAXReverb) State->IsEax = AL_FALSE; // Calculate the master filters @@ -952,7 +953,7 @@ static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device props->Reverb.Diffusion, props->Reverb.EchoDepth, hfRatio, cw, frequency, State); - gain = props->Reverb.Gain * Slot->Gain * ReverbBoost; + gain = props->Reverb.Gain * Slot->Params.Gain * ReverbBoost; // Update early and late 3D panning. if(Device->Hrtf || Device->Uhj_Encoder) UpdateMixedPanning(Device, props->Reverb.ReflectionsPan, diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index e521ff82..7f670a95 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -20,6 +20,8 @@ typedef struct ALeffectState { ALuint OutChannels; } ALeffectState; +void ALeffectState_Destruct(ALeffectState *state); + struct ALeffectStateVtable { void (*const Destruct)(ALeffectState *state); @@ -70,18 +72,48 @@ static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = #define MAX_EFFECT_CHANNELS (4) -typedef struct ALeffectslot { - ALenum EffectType; - ALeffectProps EffectProps; +struct ALeffectslotProps { + ATOMIC(ALfloat) Gain; + ATOMIC(ALboolean) AuxSendAuto; + + ATOMIC(ALenum) Type; + ALeffectProps Props; + + ATOMIC(ALeffectState*) State; + + ATOMIC(struct ALeffectslotProps*) next; +}; + +typedef struct ALeffectslot { volatile ALfloat Gain; volatile ALboolean AuxSendAuto; - ATOMIC(ALenum) NeedsUpdate; - ALeffectState *EffectState; + struct { + ALenum Type; + ALeffectProps Props; + + ALeffectState *State; + } Effect; RefCount ref; + ATOMIC(struct ALeffectslotProps*) Update; + ATOMIC(struct ALeffectslotProps*) FreeList; + + struct { + ALfloat Gain; + ALboolean AuxSendAuto; + + ALenum EffectType; + ALeffectProps EffectProps; + ALeffectState *EffectState; + + ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */ + ALfloat DecayTime; + ALfloat AirAbsorptionGainHF; + } Params; + /* Self ID */ ALuint id; @@ -106,6 +138,8 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) { return (struct ALeffectslot*)RemoveUIntMapKey(&context->EffectSlotMap, id); } ALenum InitEffectSlot(ALeffectslot *slot); +void DeinitEffectSlot(ALeffectslot *slot); +void UpdateEffectSlotProps(ALeffectslot *slot); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 7f570ef8..1407e1b1 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -86,7 +86,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(err != AL_NO_ERROR) { FreeThunkEntry(slot->id); - DELETE_OBJ(slot->EffectState); + DELETE_OBJ(slot->Params.EffectState); al_free(slot); alDeleteAuxiliaryEffectSlots(cur, effectslots); @@ -139,7 +139,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * FreeThunkEntry(slot->id); RemoveEffectSlotArray(context, slot); - DELETE_OBJ(slot->EffectState); + DeinitEffectSlot(slot); memset(slot, 0, sizeof(*slot)); al_free(slot); @@ -175,12 +175,13 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param context = GetContextRef(); if(!context) return; - device = context->Device; + WriteLock(&context->PropLock); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) { case AL_EFFECTSLOT_EFFECT: + device = context->Device; effect = (value ? LookupEffect(device, value) : NULL); if(!(value == 0 || effect != NULL)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); @@ -193,19 +194,16 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: if(!(value == AL_TRUE || value == AL_FALSE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - slot->AuxSendAuto = value; break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - /* HACK: Force sources to update by doing a listener update */ - ReadLock(&context->PropLock); - UpdateListenerProps(context); - ReadUnlock(&context->PropLock); + UpdateEffectSlotProps(slot); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -244,6 +242,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param context = GetContextRef(); if(!context) return; + WriteLock(&context->PropLock); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -251,16 +250,16 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param case AL_EFFECTSLOT_GAIN: if(!(value >= 0.0f && value <= 1.0f)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - slot->Gain = value; - ATOMIC_STORE(&slot->NeedsUpdate, AL_TRUE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + UpdateEffectSlotProps(slot); done: + WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -451,7 +450,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); ALeffectStateFactory *factory; - if(newtype != EffectSlot->EffectType) + if(newtype != EffectSlot->Effect.Type) { ALeffectState *State; FPUCtl oldMode; @@ -467,7 +466,9 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e return AL_OUT_OF_MEMORY; SetMixerFPUMode(&oldMode); - + /* FIXME: This just needs to prevent the device from being reset during + * the state's device update, so the list lock in ALc.c should do here. + */ ALCdevice_Lock(Device); State->OutBuffer = Device->Dry.Buffer; State->OutChannels = Device->Dry.NumChannels; @@ -478,70 +479,135 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e DELETE_OBJ(State); return AL_OUT_OF_MEMORY; } - - State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State); - if(!effect) - { - memset(&EffectSlot->EffectProps, 0, sizeof(EffectSlot->EffectProps)); - EffectSlot->EffectType = AL_EFFECT_NULL; - } - else - { - memcpy(&EffectSlot->EffectProps, &effect->Props, sizeof(effect->Props)); - EffectSlot->EffectType = effect->type; - } - - /* FIXME: This should be done asynchronously, but since the EffectState - * object was changed, it needs an update before its Process method can - * be called. */ - ATOMIC_STORE(&EffectSlot->NeedsUpdate, AL_FALSE); - V(EffectSlot->EffectState,update)(Device, EffectSlot); ALCdevice_Unlock(Device); - RestoreFPUMode(&oldMode); - DELETE_OBJ(State); - State = NULL; + EffectSlot->Effect.State = State; + } + + if(!effect) + { + EffectSlot->Effect.Type = AL_EFFECT_NULL; + memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); } else { - if(effect) - { - ALCdevice_Lock(Device); - memcpy(&EffectSlot->EffectProps, &effect->Props, sizeof(effect->Props)); - ALCdevice_Unlock(Device); - ATOMIC_STORE(&EffectSlot->NeedsUpdate, AL_TRUE); - } + EffectSlot->Effect.Type = effect->type; + memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); } return AL_NO_ERROR; } +void ALeffectState_Destruct(ALeffectState *UNUSED(state)) +{ +} + + ALenum InitEffectSlot(ALeffectslot *slot) { ALeffectStateFactory *factory; - ALuint i, c; - slot->EffectType = AL_EFFECT_NULL; + slot->Effect.Type = AL_EFFECT_NULL; factory = getFactoryByType(AL_EFFECT_NULL); - if(!(slot->EffectState=V0(factory,create)())) + if(!(slot->Effect.State=V0(factory,create)())) return AL_OUT_OF_MEMORY; slot->Gain = 1.0; slot->AuxSendAuto = AL_TRUE; - ATOMIC_INIT(&slot->NeedsUpdate, AL_FALSE); - for(c = 0;c < 1;c++) - { - for(i = 0;i < BUFFERSIZE;i++) - slot->WetBuffer[c][i] = 0.0f; - } InitRef(&slot->ref, 0); + ATOMIC_INIT(&slot->Update, NULL); + ATOMIC_INIT(&slot->FreeList, NULL); + + slot->Params.Gain = 1.0f; + slot->Params.AuxSendAuto = AL_TRUE; + slot->Params.EffectState = slot->Effect.State; + slot->Params.RoomRolloff = 0.0f; + slot->Params.DecayTime = 0.0f; + slot->Params.AirAbsorptionGainHF = 1.0f; + return AL_NO_ERROR; } +void DeinitEffectSlot(ALeffectslot *slot) +{ + struct ALeffectslotProps *props; + size_t count = 0; + + props = ATOMIC_LOAD(&slot->Update); + if(props) + { + DELETE_OBJ(props->State); + TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); + al_free(props); + } + props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); + while(props) + { + struct ALeffectslotProps *next; + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + DELETE_OBJ(props->State); + al_free(props); + props = next; + ++count; + } + TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); + + DELETE_OBJ(slot->Params.EffectState); +} + +void UpdateEffectSlotProps(ALeffectslot *slot) +{ + struct ALeffectslotProps *props; + ALeffectState *oldstate; + + /* Get an unused property container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&slot->FreeList, almemory_order_acquire); + if(!props) + props = al_calloc(16, sizeof(*props)); + else + { + struct ALeffectslotProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + &slot->FreeList, &props, next, almemory_order_seq_cst, + almemory_order_consume) == 0); + } + + /* Copy in current property values. */ + ATOMIC_STORE(&props->Gain, slot->Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->AuxSendAuto, slot->AuxSendAuto, almemory_order_relaxed); + + ATOMIC_STORE(&props->Type, slot->Effect.Type, almemory_order_relaxed); + memcpy(&props->Props, &slot->Effect.Props, sizeof(props->Props)); + /* Swap out any stale effect state object there may be in the container, to + * delete it. + */ + oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, + almemory_order_relaxed); + + /* Set the new container for updating internal parameters. */ + props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, + almemory_order_acq_rel); + if(props) + { + /* If there was an unused update container, put it back in the + * freelist. + */ + struct ALeffectslotProps *first = ATOMIC_LOAD(&slot->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + &slot->FreeList, &first, props) == 0); + } + + DELETE_OBJ(oldstate); +} + ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) { ALsizei pos; @@ -550,7 +616,7 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; Context->EffectSlotMap.array[pos].value = NULL; - DELETE_OBJ(temp->EffectState); + DeinitEffectSlot(temp); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALeffectslot)); -- cgit v1.2.3 From 210e150601d9b458d446483f5f16e1e67cc6e3ba Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 12 May 2016 19:05:06 -0700 Subject: Avoid updating the effect state object if it's not changed --- Alc/ALc.c | 24 ++++++++++++------------ Alc/ALu.c | 15 +++++++-------- OpenAL32/Include/alAuxEffectSlot.h | 4 +++- OpenAL32/alAuxEffectSlot.c | 34 +++++++++++++++++++++------------- 4 files changed, 43 insertions(+), 34 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index b3d7eb38..47aa0f04 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2066,7 +2066,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, AL_FALSE); } context = ATOMIC_LOAD(&device->ContextList); @@ -2078,17 +2078,18 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) for(pos = 0;pos < context->EffectSlotMap.size;pos++) { ALeffectslot *slot = context->EffectSlotMap.array[pos].value; + ALeffectState *state = slot->Params.EffectState; - slot->Params.EffectState->OutBuffer = device->Dry.Buffer; - slot->Params.EffectState->OutChannels = device->Dry.NumChannels; - if(V(slot->Params.EffectState,deviceUpdate)(device) == AL_FALSE) + state->OutBuffer = device->Dry.Buffer; + state->OutChannels = device->Dry.NumChannels; + if(V(state,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, AL_FALSE); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -3487,16 +3488,15 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->DefaultSlot = NULL; ERR("Failed to initialize the default effect slot\n"); } - else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) - { - DeinitEffectSlot(device->DefaultSlot); - device->DefaultSlot = NULL; - ERR("Failed to initialize the default effect\n"); - } else { aluInitEffectPanning(device->DefaultSlot); - UpdateEffectSlotProps(device->DefaultSlot); + if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR) + { + DeinitEffectSlot(device->DefaultSlot); + device->DefaultSlot = NULL; + ERR("Failed to initialize the default effect\n"); + } } } diff --git a/Alc/ALu.c b/Alc/ALu.c index 3b873aa5..a555b834 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -342,14 +342,6 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); slot->Params.EffectType = ATOMIC_LOAD(&props->Type, almemory_order_relaxed); memcpy(&slot->Params.EffectProps, &props->Props, sizeof(props->Props)); - /* If the existing state object is different from the one being set, - * exchange it so it remains in the freelist and isn't leaked. - */ - if(slot->Params.EffectState == ATOMIC_LOAD(&props->State, almemory_order_relaxed)) - slot->Params.EffectState = NULL; - slot->Params.EffectState = ATOMIC_EXCHANGE(ALeffectState*, - &props->State, slot->Params.EffectState, almemory_order_relaxed - ); if(IsReverbEffect(slot->Params.EffectType)) { slot->Params.RoomRolloff = slot->Params.EffectProps.Reverb.RoomRolloffFactor; @@ -362,6 +354,13 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; } + /* If the state object is changed, exchange it with the current one so it + * remains in the freelist and isn't leaked. + */ + if(ATOMIC_LOAD(&props->UpdateState, almemory_order_relaxed)) + slot->Params.EffectState = ATOMIC_EXCHANGE(ALeffectState*, + &props->State, slot->Params.EffectState, almemory_order_relaxed + ); V(slot->Params.EffectState,update)(device, slot); diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 7f670a95..85827746 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -79,6 +79,8 @@ struct ALeffectslotProps { ATOMIC(ALenum) Type; ALeffectProps Props; + /* Flag indicates if State should be updated. */ + ATOMIC(ALboolean) UpdateState; ATOMIC(ALeffectState*) State; ATOMIC(struct ALeffectslotProps*) next; @@ -139,7 +141,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); -void UpdateEffectSlotProps(ALeffectslot *slot); +void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 1407e1b1..368a0fb1 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -195,12 +195,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!(value == AL_TRUE || value == AL_FALSE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; + UpdateEffectSlotProps(slot, AL_FALSE); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot); done: WriteUnlock(&context->PropLock); @@ -256,7 +256,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, AL_FALSE); done: WriteUnlock(&context->PropLock); @@ -482,18 +482,24 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALCdevice_Unlock(Device); RestoreFPUMode(&oldMode); - EffectSlot->Effect.State = State; - } + if(!effect) + { + EffectSlot->Effect.Type = AL_EFFECT_NULL; + memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); + } + else + { + EffectSlot->Effect.Type = effect->type; + memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); + } - if(!effect) - { - EffectSlot->Effect.Type = AL_EFFECT_NULL; - memset(&EffectSlot->Effect.Props, 0, sizeof(EffectSlot->Effect.Props)); + EffectSlot->Effect.State = State; + UpdateEffectSlotProps(EffectSlot, AL_TRUE); } - else + else if(effect) { - EffectSlot->Effect.Type = effect->type; memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); + UpdateEffectSlotProps(EffectSlot, AL_FALSE); } return AL_NO_ERROR; @@ -559,7 +565,7 @@ void DeinitEffectSlot(ALeffectslot *slot) DELETE_OBJ(slot->Params.EffectState); } -void UpdateEffectSlotProps(ALeffectslot *slot) +void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate) { struct ALeffectslotProps *props; ALeffectState *oldstate; @@ -587,8 +593,10 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* Swap out any stale effect state object there may be in the container, to * delete it. */ - oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, - almemory_order_relaxed); + ATOMIC_STORE(&props->UpdateState, withstate, almemory_order_relaxed); + oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, + withstate ? slot->Effect.State : NULL, almemory_order_relaxed + ); /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, -- cgit v1.2.3 From 9e6d8342de62df83377b19577268af7106cdc088 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 12 May 2016 23:12:11 -0700 Subject: Hold the effect and filter maps while handling effects and filters --- Alc/effects/reverb.c | 8 -------- OpenAL32/Include/alEffect.h | 13 +++++++++++-- OpenAL32/Include/alFilter.h | 13 +++++++++++-- OpenAL32/alAuxEffectSlot.c | 8 +++++++- OpenAL32/alEffect.c | 27 +++++++++++++++++++++++++-- OpenAL32/alFilter.c | 27 +++++++++++++++++++++++++-- OpenAL32/alSource.c | 11 ++++++++++- 7 files changed, 89 insertions(+), 18 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index bd5637e9..0f851295 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -1652,20 +1652,16 @@ void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, case AL_EAXREVERB_REFLECTIONS_PAN: if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - LockContext(context); props->Reverb.ReflectionsPan[0] = vals[0]; props->Reverb.ReflectionsPan[1] = vals[1]; props->Reverb.ReflectionsPan[2] = vals[2]; - UnlockContext(context); break; case AL_EAXREVERB_LATE_REVERB_PAN: if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - LockContext(context); props->Reverb.LateReverbPan[0] = vals[0]; props->Reverb.LateReverbPan[1] = vals[1]; props->Reverb.LateReverbPan[2] = vals[2]; - UnlockContext(context); break; default: @@ -1786,18 +1782,14 @@ void ALeaxreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum switch(param) { case AL_EAXREVERB_REFLECTIONS_PAN: - LockContext(context); vals[0] = props->Reverb.ReflectionsPan[0]; vals[1] = props->Reverb.ReflectionsPan[1]; vals[2] = props->Reverb.ReflectionsPan[2]; - UnlockContext(context); break; case AL_EAXREVERB_LATE_REVERB_PAN: - LockContext(context); vals[0] = props->Reverb.LateReverbPan[0]; vals[1] = props->Reverb.LateReverbPan[1]; vals[2] = props->Reverb.LateReverbPan[2]; - UnlockContext(context); break; default: diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index 91ee782f..d20ef077 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -176,10 +176,19 @@ typedef struct ALeffect { ALuint id; } ALeffect; +inline void LockEffectsRead(ALCdevice *device) +{ LockUIntMapRead(&device->EffectMap); } +inline void UnlockEffectsRead(ALCdevice *device) +{ UnlockUIntMapRead(&device->EffectMap); } +inline void LockEffectsWrite(ALCdevice *device) +{ LockUIntMapWrite(&device->EffectMap); } +inline void UnlockEffectsWrite(ALCdevice *device) +{ UnlockUIntMapWrite(&device->EffectMap); } + inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id) -{ return (struct ALeffect*)LookupUIntMapKey(&device->EffectMap, id); } +{ return (struct ALeffect*)LookupUIntMapKeyNoLock(&device->EffectMap, id); } inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id) -{ return (struct ALeffect*)RemoveUIntMapKey(&device->EffectMap, id); } +{ return (struct ALeffect*)RemoveUIntMapKeyNoLock(&device->EffectMap, id); } inline ALboolean IsReverbEffect(ALenum type) { return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; } diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h index 6f44e3b7..855bb534 100644 --- a/OpenAL32/Include/alFilter.h +++ b/OpenAL32/Include/alFilter.h @@ -151,10 +151,19 @@ typedef struct ALfilter { #define ALfilter_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v))) #define ALfilter_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v))) +inline void LockFiltersRead(ALCdevice *device) +{ LockUIntMapRead(&device->FilterMap); } +inline void UnlockFiltersRead(ALCdevice *device) +{ UnlockUIntMapRead(&device->FilterMap); } +inline void LockFiltersWrite(ALCdevice *device) +{ LockUIntMapWrite(&device->FilterMap); } +inline void UnlockFiltersWrite(ALCdevice *device) +{ UnlockUIntMapWrite(&device->FilterMap); } + inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id) -{ return (struct ALfilter*)LookupUIntMapKey(&device->FilterMap, id); } +{ return (struct ALfilter*)LookupUIntMapKeyNoLock(&device->FilterMap, id); } inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id) -{ return (struct ALfilter*)RemoveUIntMapKey(&device->FilterMap, id); } +{ return (struct ALfilter*)RemoveUIntMapKeyNoLock(&device->FilterMap, id); } ALvoid ReleaseALFilters(ALCdevice *device); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 368a0fb1..70bb4e43 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -182,11 +182,17 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param { case AL_EFFECTSLOT_EFFECT: device = context->Device; + + LockEffectsRead(device); effect = (value ? LookupEffect(device, value) : NULL); if(!(value == 0 || effect != NULL)) + { + UnlockEffectsRead(device); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - + } err = InitializeEffect(device, slot, effect); + UnlockEffectsRead(device); + if(err != AL_NO_ERROR) SET_ERROR_AND_GOTO(context, err, done); break; diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 0bfe11b9..5a036091 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -34,6 +34,10 @@ ALboolean DisabledEffects[MAX_EFFECTS]; +extern inline void LockEffectsRead(ALCdevice *device); +extern inline void UnlockEffectsRead(ALCdevice *device); +extern inline void LockEffectsWrite(ALCdevice *device); +extern inline void UnlockEffectsWrite(ALCdevice *device); extern inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id); extern inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id); extern inline ALboolean IsReverbEffect(ALenum type); @@ -95,10 +99,10 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) context = GetContextRef(); if(!context) return; + device = context->Device; + LockEffectsWrite(device); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; for(i = 0;i < n;i++) { if(effects[i] && LookupEffect(device, effects[i]) == NULL) @@ -115,6 +119,7 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) } done: + UnlockEffectsWrite(device); ALCcontext_DecRef(context); } @@ -126,8 +131,10 @@ AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) Context = GetContextRef(); if(!Context) return AL_FALSE; + LockEffectsRead(Context->Device); result = ((!effect || LookupEffect(Context->Device, effect)) ? AL_TRUE : AL_FALSE); + UnlockEffectsRead(Context->Device); ALCcontext_DecRef(Context); @@ -144,6 +151,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) if(!Context) return; Device = Context->Device; + LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -170,6 +178,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) V(ALEffect,setParami)(Context, param, value); } } + UnlockEffectsWrite(Device); ALCcontext_DecRef(Context); } @@ -191,6 +200,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v if(!Context) return; Device = Context->Device; + LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -198,6 +208,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v /* Call the appropriate handler */ V(ALEffect,setParamiv)(Context, param, values); } + UnlockEffectsWrite(Device); ALCcontext_DecRef(Context); } @@ -212,6 +223,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) if(!Context) return; Device = Context->Device; + LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -219,6 +231,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) /* Call the appropriate handler */ V(ALEffect,setParamf)(Context, param, value); } + UnlockEffectsWrite(Device); ALCcontext_DecRef(Context); } @@ -233,6 +246,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat if(!Context) return; Device = Context->Device; + LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -240,6 +254,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat /* Call the appropriate handler */ V(ALEffect,setParamfv)(Context, param, values); } + UnlockEffectsWrite(Device); ALCcontext_DecRef(Context); } @@ -254,6 +269,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value if(!Context) return; Device = Context->Device; + LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -266,6 +282,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value V(ALEffect,getParami)(Context, param, value); } } + UnlockEffectsRead(Device); ALCcontext_DecRef(Context); } @@ -287,6 +304,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu if(!Context) return; Device = Context->Device; + LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -294,6 +312,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu /* Call the appropriate handler */ V(ALEffect,getParamiv)(Context, param, values); } + UnlockEffectsRead(Device); ALCcontext_DecRef(Context); } @@ -308,6 +327,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val if(!Context) return; Device = Context->Device; + LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -315,6 +335,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val /* Call the appropriate handler */ V(ALEffect,getParamf)(Context, param, value); } + UnlockEffectsRead(Device); ALCcontext_DecRef(Context); } @@ -329,6 +350,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va if(!Context) return; Device = Context->Device; + LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -336,6 +358,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va /* Call the appropriate handler */ V(ALEffect,getParamfv)(Context, param, values); } + UnlockEffectsRead(Device); ALCcontext_DecRef(Context); } diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 8e04ec2a..7be3e339 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -29,6 +29,10 @@ #include "alError.h" +extern inline void LockFiltersRead(ALCdevice *device); +extern inline void UnlockFiltersRead(ALCdevice *device); +extern inline void LockFiltersWrite(ALCdevice *device); +extern inline void UnlockFiltersWrite(ALCdevice *device); extern inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id); extern inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id); extern inline void ALfilterState_clear(ALfilterState *filter); @@ -94,10 +98,10 @@ AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) context = GetContextRef(); if(!context) return; + device = context->Device; + LockFiltersWrite(device); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; for(i = 0;i < n;i++) { if(filters[i] && LookupFilter(device, filters[i]) == NULL) @@ -114,6 +118,7 @@ AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) } done: + UnlockFiltersWrite(device); ALCcontext_DecRef(context); } @@ -125,8 +130,10 @@ AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter) Context = GetContextRef(); if(!Context) return AL_FALSE; + LockFiltersRead(Context->Device); result = ((!filter || LookupFilter(Context->Device, filter)) ? AL_TRUE : AL_FALSE); + UnlockFiltersRead(Context->Device); ALCcontext_DecRef(Context); @@ -143,6 +150,7 @@ AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value) if(!Context) return; Device = Context->Device; + LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -161,6 +169,7 @@ AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value) ALfilter_SetParami(ALFilter, Context, param, value); } } + UnlockFiltersWrite(Device); ALCcontext_DecRef(Context); } @@ -182,6 +191,7 @@ AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *v if(!Context) return; Device = Context->Device; + LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -189,6 +199,7 @@ AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *v /* Call the appropriate handler */ ALfilter_SetParamiv(ALFilter, Context, param, values); } + UnlockFiltersWrite(Device); ALCcontext_DecRef(Context); } @@ -203,6 +214,7 @@ AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value) if(!Context) return; Device = Context->Device; + LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -210,6 +222,7 @@ AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value) /* Call the appropriate handler */ ALfilter_SetParamf(ALFilter, Context, param, value); } + UnlockFiltersWrite(Device); ALCcontext_DecRef(Context); } @@ -224,6 +237,7 @@ AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat if(!Context) return; Device = Context->Device; + LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -231,6 +245,7 @@ AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat /* Call the appropriate handler */ ALfilter_SetParamfv(ALFilter, Context, param, values); } + UnlockFiltersWrite(Device); ALCcontext_DecRef(Context); } @@ -245,6 +260,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value if(!Context) return; Device = Context->Device; + LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -257,6 +273,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value ALfilter_GetParami(ALFilter, Context, param, value); } } + UnlockFiltersRead(Device); ALCcontext_DecRef(Context); } @@ -278,6 +295,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *valu if(!Context) return; Device = Context->Device; + LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -285,6 +303,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *valu /* Call the appropriate handler */ ALfilter_GetParamiv(ALFilter, Context, param, values); } + UnlockFiltersRead(Device); ALCcontext_DecRef(Context); } @@ -299,6 +318,7 @@ AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *val if(!Context) return; Device = Context->Device; + LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -306,6 +326,7 @@ AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *val /* Call the appropriate handler */ ALfilter_GetParamf(ALFilter, Context, param, value); } + UnlockFiltersRead(Device); ALCcontext_DecRef(Context); } @@ -320,6 +341,7 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *va if(!Context) return; Device = Context->Device; + LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) alSetError(Context, AL_INVALID_NAME); else @@ -327,6 +349,7 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *va /* Call the appropriate handler */ ALfilter_GetParamfv(ALFilter, Context, param, values); } + UnlockFiltersRead(Device); ALCcontext_DecRef(Context); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 8cab5ab3..a62bf59e 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -715,7 +715,12 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_DIRECT_FILTER: - CHECKVAL(*values == 0 || (filter=LookupFilter(device, *values)) != NULL); + LockFiltersRead(device); + if(!(*values == 0 || (filter=LookupFilter(device, *values)) != NULL)) + { + UnlockFiltersRead(device); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } LockContext(Context); if(!filter) @@ -735,6 +740,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Direct.LFReference = filter->LFReference; } UnlockContext(Context); + UnlockFiltersRead(device); ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); return AL_TRUE; @@ -782,12 +788,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_AUXILIARY_SEND_FILTER: + LockFiltersRead(device); LockContext(Context); if(!((ALuint)values[1] < device->NumAuxSends && (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) { UnlockContext(Context); + UnlockFiltersRead(device); SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } @@ -814,6 +822,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].LFReference = filter->LFReference; } UnlockContext(Context); + UnlockFiltersRead(device); ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); return AL_TRUE; -- cgit v1.2.3 From 59cd6230a661d5cee69c0a44c4dde152eed9f865 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 13 May 2016 00:23:03 -0700 Subject: Properly load the effect state pointer from the property container --- OpenAL32/alAuxEffectSlot.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 70bb4e43..98ee9328 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -552,7 +552,9 @@ void DeinitEffectSlot(ALeffectslot *slot) props = ATOMIC_LOAD(&slot->Update); if(props) { - DELETE_OBJ(props->State); + ALeffectState *state; + state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); + DELETE_OBJ(state); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } @@ -560,8 +562,10 @@ void DeinitEffectSlot(ALeffectslot *slot) while(props) { struct ALeffectslotProps *next; + ALeffectState *state; + state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - DELETE_OBJ(props->State); + DELETE_OBJ(state); al_free(props); props = next; ++count; -- cgit v1.2.3 From b3338d25f6d4fd02935ac83d0d3f227b145307d1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 14 May 2016 23:43:40 -0700 Subject: Provide asynchronous property updates for sources This necessitates a change in how source updates are handled. Rather than just being able to update sources when a dependent object state is changed (e.g. a listener gain change), now all source updates must be proactively provided. Consequently, apps that do not utilize any deferring (AL_SOFT_defer_updates or alcSuspendContext/alcProcessContext) may utilize more CPU since it'll be filling out more update containers for the mixer thread to use. The upside is that there's less blocking between the app's calling thread and the mixer thread, particularly for vectors and other multi-value properties (filters and sends). Deferring behavior when used is also improved, since updates that shouldn't be applied yet are simply not provided. And when they are provided, the mixer doesn't have to ignore them, meaning the actual deferring of a context doesn't have to synchrnously force an update -- the process call will send any pending updates, which the mixer will apply even if another deferral occurs before the mixer runs, because it'll still be there waiting on the next mixer invocation. There is one slight bug introduced by this commit. When a listener change is made, or changes to multiple sources while updates are being deferred, it is possible for the mixer to run while the sources are prepping their updates, causing some of the source updates to be seen before the other. This will be fixed in short order. --- Alc/ALc.c | 65 ++----- Alc/ALu.c | 267 +++++++++++++------------- Alc/mixer.c | 2 +- OpenAL32/Include/alMain.h | 2 +- OpenAL32/Include/alSource.h | 104 +++++++--- OpenAL32/Include/alu.h | 5 +- OpenAL32/alAuxEffectSlot.c | 2 + OpenAL32/alListener.c | 36 +++- OpenAL32/alSource.c | 452 +++++++++++++++++++++++++++++++------------- OpenAL32/alState.c | 48 +++-- 10 files changed, 627 insertions(+), 356 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 47aa0f04..e5c18d8c 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1558,22 +1558,7 @@ extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS */ void ALCcontext_DeferUpdates(ALCcontext *context) { - ALCdevice *device = context->Device; - FPUCtl oldMode; - - SetMixerFPUMode(&oldMode); - - V0(device->Backend,lock)(); - if(!context->DeferUpdates) - { - context->DeferUpdates = AL_TRUE; - - /* Make sure all pending updates are performed */ - UpdateContextSources(context); - } - V0(device->Backend,unlock)(); - - RestoreFPUMode(&oldMode); + ATOMIC_STORE(&context->DeferUpdates, AL_TRUE); } /* ALCcontext_ProcessUpdates @@ -1584,14 +1569,15 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) { ALCdevice *device = context->Device; - V0(device->Backend,lock)(); - if(context->DeferUpdates) + ReadLock(&context->PropLock); + if(ATOMIC_EXCHANGE(ALenum, &context->DeferUpdates, AL_FALSE)) { ALsizei pos; - context->DeferUpdates = AL_FALSE; + UpdateListenerProps(context); LockUIntMapRead(&context->SourceMap); + V0(device->Backend,lock)(); for(pos = 0;pos < context->SourceMap.size;pos++) { ALsource *Source = context->SourceMap.array[pos].value; @@ -1610,9 +1596,11 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) if(new_state) SetSourceState(Source, context, new_state); } + V0(device->Backend,unlock)(); UnlockUIntMapRead(&context->SourceMap); + UpdateAllSourceProps(context); } - V0(device->Backend,unlock)(); + ReadUnlock(&context->PropLock); } @@ -2052,7 +2040,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } SetMixerFPUMode(&oldMode); - V0(device->Backend,lock)(); if(device->DefaultSlot) { ALeffectslot *slot = device->DefaultSlot; @@ -2062,7 +2049,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) state->OutChannels = device->Dry.NumChannels; if(V(state,deviceUpdate)(device) == AL_FALSE) { - V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } @@ -2074,6 +2060,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALsizei pos; + ReadLock(&context->PropLock); LockUIntMapRead(&context->EffectSlotMap); for(pos = 0;pos < context->EffectSlotMap.size;pos++) { @@ -2085,10 +2072,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(V(state,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); - V0(device->Backend,unlock)(); + ReadUnlock(&context->PropLock); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } + UpdateEffectSlotProps(slot, AL_FALSE); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -2105,38 +2093,19 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) source->Send[s].Slot = NULL; source->Send[s].Gain = 1.0f; source->Send[s].GainHF = 1.0f; + source->Send[s].HFReference = LOWPASSFREQREF; + source->Send[s].GainLF = 1.0f; + source->Send[s].LFReference = HIGHPASSFREQREF; s++; } - ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE); } UnlockUIntMapRead(&context->SourceMap); - for(pos = 0;pos < context->VoiceCount;pos++) - { - ALvoice *voice = &context->Voices[pos]; - ALsource *source = voice->Source; - ALbufferlistitem *BufferListItem; - - if(!source) - continue; - - BufferListItem = ATOMIC_LOAD(&source->queue); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); - voice->Update(voice, source, buffer, context); - break; - } - BufferListItem = BufferListItem->next; - } - } + UpdateAllSourceProps(context); + ReadUnlock(&context->PropLock); context = context->next; } - V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); if(!(device->Flags&DEVICE_PAUSED)) @@ -2308,7 +2277,7 @@ static ALvoid InitContext(ALCcontext *Context) Context->DopplerFactor = 1.0f; Context->DopplerVelocity = 1.0f; Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; - Context->DeferUpdates = AL_FALSE; + ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE); Context->ExtensionList = alExtList; } diff --git a/Alc/ALu.c b/Alc/ALu.c index 4a9a59cf..2fffdcd9 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -266,7 +266,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state) } -static ALboolean CalcListenerParams(ALCcontext *Context) +static void CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALdouble N[3], V[3], U[3], P[3]; @@ -275,7 +275,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context) aluVector vel; props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel); - if(!props) return AL_FALSE; + if(!props) return; /* AT then UP */ N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); @@ -330,17 +330,15 @@ static ALboolean CalcListenerParams(ALCcontext *Context) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, &Listener->FreeList, &first, props) == 0); - - return AL_TRUE; } -static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) +static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { struct ALeffectslotProps *first; struct ALeffectslotProps *props; props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); - if(!props) return AL_FALSE; + if(!props) return; slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); @@ -377,11 +375,43 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, &slot->FreeList, &first, props) == 0); +} + +static void CalcSourceParams(ALvoice *voice, ALCcontext *context) +{ + ALsource *source = voice->Source; + ALbufferlistitem *BufferListItem; + struct ALsourceProps *first; + struct ALsourceProps *props; + + props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); + if(!props) return; + + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) + { + ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + voice->Update(voice, props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; + } - return AL_TRUE; + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); } -ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +ALvoid CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } @@ -448,22 +478,22 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ListenerGain = Listener->Params.Gain; /* Get source properties */ - SourceVolume = ALSource->Gain; - MinVolume = ALSource->MinGain; - MaxVolume = ALSource->MaxGain; - Pitch = ALSource->Pitch; - Relative = ALSource->HeadRelative; - DirectChannels = ALSource->DirectChannels; + SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); + MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); + MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); + Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); + Relative = ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed); + DirectChannels = ATOMIC_LOAD(&props->DirectChannels, almemory_order_relaxed); /* Convert counter-clockwise to clockwise. */ - StereoMap[0].angle = -ALSource->StereoPan[0]; - StereoMap[1].angle = -ALSource->StereoPan[1]; + StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed); + StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed); voice->Direct.OutBuffer = Device->Dry.Buffer; voice->Direct.OutChannels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ALSource->Send[i].Slot; + SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) @@ -489,15 +519,15 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); - DryGain *= ALSource->Direct.Gain * ListenerGain; - DryGainHF = ALSource->Direct.GainHF; - DryGainLF = ALSource->Direct.GainLF; + DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGainHF = ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); + DryGainLF = ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume); - WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; - WetGainHF[i] = ALSource->Send[i].GainHF; - WetGainLF[i] = ALSource->Send[i].GainLF; + WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGainHF[i] = ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); + WetGainLF[i] = ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); } switch(ALBuffer->FmtChannels) @@ -557,13 +587,13 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ALfloat scale; /* AT then UP */ - N[0] = ALSource->Orientation[0][0]; - N[1] = ALSource->Orientation[0][1]; - N[2] = ALSource->Orientation[0][2]; + N[0] = ATOMIC_LOAD(&props->Orientation[0][0], almemory_order_relaxed); + N[1] = ATOMIC_LOAD(&props->Orientation[0][1], almemory_order_relaxed); + N[2] = ATOMIC_LOAD(&props->Orientation[0][2], almemory_order_relaxed); aluNormalize(N); - V[0] = ALSource->Orientation[1][0]; - V[1] = ALSource->Orientation[1][1]; - V[2] = ALSource->Orientation[1][2]; + V[0] = ATOMIC_LOAD(&props->Orientation[1][0], almemory_order_relaxed); + V[1] = ATOMIC_LOAD(&props->Orientation[1][1], almemory_order_relaxed); + V[2] = ATOMIC_LOAD(&props->Orientation[1][2], almemory_order_relaxed); aluNormalize(V); if(!Relative) { @@ -779,8 +809,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } { - ALfloat hfscale = ALSource->Direct.HFReference / Frequency; - ALfloat lfscale = ALSource->Direct.LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / + Frequency; DryGainHF = maxf(DryGainHF, 0.0001f); DryGainLF = maxf(DryGainLF, 0.0001f); for(c = 0;c < num_channels;c++) @@ -800,8 +832,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } for(i = 0;i < NumSends;i++) { - ALfloat hfscale = ALSource->Send[i].HFReference / Frequency; - ALfloat lfscale = ALSource->Send[i].LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / + Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0001f); WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); for(c = 0;c < num_channels;c++) @@ -821,7 +855,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } } -ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +ALvoid CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; @@ -862,7 +896,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } /* Get context/device properties */ - DopplerFactor = Listener->Params.DopplerFactor * ALSource->DopplerFactor; + DopplerFactor = Listener->Params.DopplerFactor; SpeedOfSound = Listener->Params.SpeedOfSound; NumSends = Device->NumAuxSends; Frequency = Device->Frequency; @@ -872,29 +906,39 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer MetersPerUnit = Listener->Params.MetersPerUnit; /* Get source properties */ - SourceVolume = ALSource->Gain; - MinVolume = ALSource->MinGain; - MaxVolume = ALSource->MaxGain; - Pitch = ALSource->Pitch; - Position = ALSource->Position; - Direction = ALSource->Direction; - Velocity = ALSource->Velocity; - MinDist = ALSource->RefDistance; - MaxDist = ALSource->MaxDistance; - Rolloff = ALSource->RollOffFactor; - InnerAngle = ALSource->InnerAngle; - OuterAngle = ALSource->OuterAngle; - AirAbsorptionFactor = ALSource->AirAbsorptionFactor; - DryGainHFAuto = ALSource->DryGainHFAuto; - WetGainAuto = ALSource->WetGainAuto; - WetGainHFAuto = ALSource->WetGainHFAuto; - RoomRolloffBase = ALSource->RoomRolloffFactor; + SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); + MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); + MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); + Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); + aluVectorSet(&Position, ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed), + 1.0f); + aluVectorSet(&Direction, ATOMIC_LOAD(&props->Direction[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Direction[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Direction[2], almemory_order_relaxed), + 0.0f); + aluVectorSet(&Velocity, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), + 0.0f); + MinDist = ATOMIC_LOAD(&props->RefDistance, almemory_order_relaxed); + MaxDist = ATOMIC_LOAD(&props->MaxDistance, almemory_order_relaxed); + Rolloff = ATOMIC_LOAD(&props->RollOffFactor, almemory_order_relaxed); + DopplerFactor *= ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); + InnerAngle = ATOMIC_LOAD(&props->InnerAngle, almemory_order_relaxed); + OuterAngle = ATOMIC_LOAD(&props->OuterAngle, almemory_order_relaxed); + AirAbsorptionFactor = ATOMIC_LOAD(&props->AirAbsorptionFactor, almemory_order_relaxed); + DryGainHFAuto = ATOMIC_LOAD(&props->DryGainHFAuto, almemory_order_relaxed); + WetGainAuto = ATOMIC_LOAD(&props->WetGainAuto, almemory_order_relaxed); + WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed); + RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed); voice->Direct.OutBuffer = Device->Dry.Buffer; voice->Direct.OutChannels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ALSource->Send[i].Slot; + SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; @@ -905,7 +949,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer DecayDistance[i] = 0.0f; RoomAirAbsorption[i] = 1.0f; } - else if(SendSlots[i]->AuxSendAuto) + else if(SendSlots[i]->Params.AuxSendAuto) { RoomRolloff[i] = SendSlots[i]->Params.RoomRolloff + RoomRolloffBase; DecayDistance[i] = SendSlots[i]->Params.DecayTime * @@ -934,7 +978,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } /* Transform source to listener space (convert to head relative) */ - if(ALSource->HeadRelative == AL_FALSE) + if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE) { const aluMatrixd *Matrix = &Listener->Params.Matrix; /* Transform source vectors */ @@ -964,8 +1008,9 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer Attenuation = 1.0f; for(i = 0;i < NumSends;i++) RoomAttenuation[i] = 1.0f; - switch(Listener->Params.SourceDistanceModel ? ALSource->DistanceModel : - Listener->Params.DistanceModel) + switch(Listener->Params.SourceDistanceModel ? + ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed) : + Listener->Params.DistanceModel) { case InverseDistanceClamped: ClampedDist = clampf(ClampedDist, MinDist, MaxDist); @@ -1059,13 +1104,15 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer if(Angle > InnerAngle && Angle <= OuterAngle) { ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp(1.0f, ALSource->OuterGain, scale); - ConeHF = lerp(1.0f, ALSource->OuterGainHF, scale); + ConeVolume = lerp(1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), + scale); + ConeHF = lerp(1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), + scale); } else if(Angle > OuterAngle) { - ConeVolume = ALSource->OuterGain; - ConeHF = ALSource->OuterGainHF; + ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed); + ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed); } else { @@ -1093,14 +1140,14 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume); /* Apply gain and frequency filters */ - DryGain *= ALSource->Direct.Gain * ListenerGain; - DryGainHF *= ALSource->Direct.GainHF; - DryGainLF *= ALSource->Direct.GainLF; + DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGainHF *= ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); + DryGainLF *= ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); for(i = 0;i < NumSends;i++) { - WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; - WetGainHF[i] *= ALSource->Send[i].GainHF; - WetGainLF[i] *= ALSource->Send[i].GainLF; + WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGainHF[i] *= ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); + WetGainLF[i] *= ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); } /* Calculate velocity-based doppler effect */ @@ -1139,7 +1186,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; ALfloat ev = 0.0f, az = 0.0f; - ALfloat radius = ALSource->Radius; + ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat spread = 0.0f; @@ -1193,7 +1240,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer { /* Non-HRTF rendering. */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; - ALfloat radius = ALSource->Radius; + ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat spread = 0.0f; @@ -1247,8 +1294,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } { - ALfloat hfscale = ALSource->Direct.HFReference / Frequency; - ALfloat lfscale = ALSource->Direct.LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / + Frequency; DryGainHF = maxf(DryGainHF, 0.0001f); DryGainLF = maxf(DryGainLF, 0.0001f); voice->Direct.Filters[0].ActiveType = AF_None; @@ -1265,8 +1314,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } for(i = 0;i < NumSends;i++) { - ALfloat hfscale = ALSource->Send[i].HFReference / Frequency; - ALfloat lfscale = ALSource->Send[i].LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / + Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0001f); WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); voice->Send[i].Filters[0].ActiveType = AF_None; @@ -1287,69 +1338,22 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer void UpdateContextSources(ALCcontext *ctx) { ALvoice *voice, *voice_end; - ALboolean fullupdate; ALsource *source; - fullupdate = CalcListenerParams(ctx); -#define UPDATE_SLOT(iter) do { \ - if(CalcEffectSlotParams(*iter, ctx->Device)) \ - fullupdate = AL_TRUE; \ -} while(0) + CalcListenerParams(ctx); +#define UPDATE_SLOT(iter) CalcEffectSlotParams(*iter, ctx->Device) VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); #undef UPDATE_SLOT - if(fullupdate) + voice = ctx->Voices; + voice_end = voice + ctx->VoiceCount; + for(;voice != voice_end;++voice) { - voice = ctx->Voices; - voice_end = voice + ctx->VoiceCount; - for(;voice != voice_end;++voice) - { - if(!(source=voice->Source)) continue; - if(source->state != AL_PLAYING && source->state != AL_PAUSED) - voice->Source = NULL; - else - { - ALbufferlistitem *BufferListItem; - BufferListItem = ATOMIC_LOAD(&source->queue); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); - voice->Update(voice, source, buffer, ctx); - break; - } - BufferListItem = BufferListItem->next; - } - } - } - } - else - { - voice = ctx->Voices; - voice_end = voice + ctx->VoiceCount; - for(;voice != voice_end;++voice) - { - if(!(source=voice->Source)) continue; - if(source->state != AL_PLAYING && source->state != AL_PAUSED) - voice->Source = NULL; - else if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE)) - { - ALbufferlistitem *BufferListItem; - BufferListItem = ATOMIC_LOAD(&source->queue); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - voice->Update(voice, source, buffer, ctx); - break; - } - BufferListItem = BufferListItem->next; - } - } - } + if(!(source=voice->Source)) continue; + if(source->state != AL_PLAYING && source->state != AL_PAUSED) + voice->Source = NULL; + else + CalcSourceParams(voice, ctx); } } @@ -1447,8 +1451,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) ctx = ATOMIC_LOAD(&device->ContextList); while(ctx) { - if(!ctx->DeferUpdates) - UpdateContextSources(ctx); + UpdateContextSources(ctx); #define CLEAR_WET_BUFFER(iter) do { \ for(i = 0;i < (*iter)->NumChannels;i++) \ memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \ diff --git a/Alc/mixer.c b/Alc/mixer.c index 44495d72..38ec295c 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -388,9 +388,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam BufferListItem = ATOMIC_LOAD(&Source->current_buffer); DataPosInt = Source->position; DataPosFrac = Source->position_fraction; - Looping = Source->Looping; NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; + Looping = voice->Looping; increment = voice->Step; IrSize = (Device->Hrtf ? GetHrtfIrSize(Device->Hrtf) : 0); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 44ce4fe0..a624e078 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -695,7 +695,7 @@ struct ALCcontext_struct { volatile ALfloat DopplerFactor; volatile ALfloat DopplerVelocity; volatile ALfloat SpeedOfSound; - volatile ALenum DeferUpdates; + ATOMIC(ALenum) DeferUpdates; RWLock PropLock; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 187d7e07..6d915153 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -13,6 +13,7 @@ extern "C" { struct ALbuffer; struct ALsource; +struct ALsourceProps; typedef struct ALbufferlistitem { @@ -25,11 +26,13 @@ typedef struct ALvoice { struct ALsource *volatile Source; /** Method to update mixing parameters. */ - ALvoid (*Update)(struct ALvoice *self, const struct ALsource *source, const struct ALbuffer *ALBuffer, const ALCcontext *context); + ALvoid (*Update)(struct ALvoice *self, const struct ALsourceProps *props, const struct ALbuffer *ALBuffer, const ALCcontext *context); /** Current target parameters used for mixing. */ ALint Step; + ALboolean Looping; + /* If not 'moving', gain/coefficients are set directly without fading. */ ALboolean Moving; @@ -46,6 +49,59 @@ typedef struct ALvoice { } ALvoice; +struct ALsourceProps { + ATOMIC(ALfloat) Pitch; + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) OuterGain; + ATOMIC(ALfloat) MinGain; + ATOMIC(ALfloat) MaxGain; + ATOMIC(ALfloat) InnerAngle; + ATOMIC(ALfloat) OuterAngle; + ATOMIC(ALfloat) RefDistance; + ATOMIC(ALfloat) MaxDistance; + ATOMIC(ALfloat) RollOffFactor; + ATOMIC(ALfloat) Position[3]; + ATOMIC(ALfloat) Velocity[3]; + ATOMIC(ALfloat) Direction[3]; + ATOMIC(ALfloat) Orientation[2][3]; + ATOMIC(ALboolean) HeadRelative; + ATOMIC(ALboolean) Looping; + ATOMIC(enum DistanceModel) DistanceModel; + ATOMIC(ALboolean) DirectChannels; + + ATOMIC(ALboolean) DryGainHFAuto; + ATOMIC(ALboolean) WetGainAuto; + ATOMIC(ALboolean) WetGainHFAuto; + ATOMIC(ALfloat) OuterGainHF; + + ATOMIC(ALfloat) AirAbsorptionFactor; + ATOMIC(ALfloat) RoomRolloffFactor; + ATOMIC(ALfloat) DopplerFactor; + + ATOMIC(ALfloat) StereoPan[2]; + + ATOMIC(ALfloat) Radius; + + /** Direct filter and auxiliary send info. */ + struct { + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) GainHF; + ATOMIC(ALfloat) HFReference; + ATOMIC(ALfloat) GainLF; + ATOMIC(ALfloat) LFReference; + } Direct; + struct { + ATOMIC(struct ALeffectslot*) Slot; + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) GainHF; + ATOMIC(ALfloat) HFReference; + ATOMIC(ALfloat) GainLF; + ATOMIC(ALfloat) LFReference; + } Send[MAX_SENDS]; + + ATOMIC(struct ALsourceProps*) next; +}; + typedef struct ALsource { /** Source properties. */ volatile ALfloat Pitch; @@ -58,9 +114,9 @@ typedef struct ALsource { volatile ALfloat RefDistance; volatile ALfloat MaxDistance; volatile ALfloat RollOffFactor; - aluVector Position; - aluVector Velocity; - aluVector Direction; + volatile ALfloat Position[3]; + volatile ALfloat Velocity[3]; + volatile ALfloat Direction[3]; volatile ALfloat Orientation[2][3]; volatile ALboolean HeadRelative; volatile ALboolean Looping; @@ -83,6 +139,23 @@ typedef struct ALsource { volatile ALfloat Radius; + /** Direct filter and auxiliary send info. */ + struct { + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; + } Direct; + struct { + struct ALeffectslot *Slot; + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; + } Send[MAX_SENDS]; + /** * Last user-specified offset, and the offset type (bytes, samples, or * seconds). @@ -114,25 +187,8 @@ typedef struct ALsource { ALuint NumChannels; ALuint SampleSize; - /** Direct filter and auxiliary send info. */ - struct { - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Direct; - struct { - struct ALeffectslot *Slot; - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Send[MAX_SENDS]; - - /** Source needs to update its mixing parameters. */ - ATOMIC(ALenum) NeedsUpdate; + ATOMIC(struct ALsourceProps*) Update; + ATOMIC(struct ALsourceProps*) FreeList; /** Self ID */ ALuint id; @@ -152,6 +208,8 @@ inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) { return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } +void UpdateSourceProps(ALsource *source, ALuint num_sends); +void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index c20c6404..8e93dc6e 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -34,6 +34,7 @@ extern "C" { #endif struct ALsource; +struct ALsourceProps; struct ALvoice; struct ALeffectslot; struct ALbuffer; @@ -375,8 +376,8 @@ void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, c ALvoid UpdateContextSources(ALCcontext *context); -ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext); -ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext); +ALvoid CalcAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); +ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 98ee9328..6d1423db 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -202,6 +202,8 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; UpdateEffectSlotProps(slot, AL_FALSE); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + UpdateAllSourceProps(context); break; default: diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 1c40c399..c59d644b 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -51,7 +51,11 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -88,7 +92,11 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -140,7 +148,11 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -161,7 +173,11 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -190,7 +206,11 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -235,7 +255,11 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a62bf59e..e2d6ca4f 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -48,6 +48,7 @@ extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); static ALvoid InitSourceParams(ALsource *Source); +static ALvoid DeinitSource(ALsource *source); static ALint64 GetSourceSampleOffset(ALsource *Source); static ALdouble GetSourceSecOffset(ALsource *Source); static ALdouble GetSourceOffset(ALsource *Source, ALenum name); @@ -123,6 +124,12 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values); static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values); +static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context) +{ + return (source->state == AL_PLAYING || source->state == AL_PAUSED) && + !ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); +} + static ALint FloatValsByProp(ALenum prop) { if(prop != (ALenum)((SourceProp)prop)) @@ -376,8 +383,14 @@ static ALint Int64ValsByProp(ALenum prop) SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \ } while(0) +#define DO_UPDATEPROPS() do { \ + if(SourceShouldUpdate(Source, Context)) \ + UpdateSourceProps(Source, device->NumAuxSends); \ +} while(0) + static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values) { + ALCdevice *device = Context->Device; ALint ival; switch(prop) @@ -393,98 +406,98 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values >= 0.0f); Source->Pitch = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_INNER_ANGLE: CHECKVAL(*values >= 0.0f && *values <= 360.0f); Source->InnerAngle = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_OUTER_ANGLE: CHECKVAL(*values >= 0.0f && *values <= 360.0f); Source->OuterAngle = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_GAIN: CHECKVAL(*values >= 0.0f); Source->Gain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_MAX_DISTANCE: CHECKVAL(*values >= 0.0f); Source->MaxDistance = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f); Source->RollOffFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_REFERENCE_DISTANCE: CHECKVAL(*values >= 0.0f); Source->RefDistance = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_MIN_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->MinGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_MAX_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->MaxGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_OUTER_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->OuterGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_OUTER_GAINHF: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->OuterGainHF = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AIR_ABSORPTION_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 10.0f); Source->AirAbsorptionFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_ROOM_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 10.0f); Source->RoomRolloffFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DOPPLER_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->DopplerFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_SEC_OFFSET: @@ -492,13 +505,13 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_OFFSET: CHECKVAL(*values >= 0.0f); - LockContext(Context); Source->OffsetType = prop; Source->Offset = *values; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !Context->DeferUpdates) + !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { + LockContext(Context); WriteLock(&Source->queue_lock); if(ApplyOffset(Source) == AL_FALSE) { @@ -507,68 +520,64 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } WriteUnlock(&Source->queue_lock); + UnlockContext(Context); } - UnlockContext(Context); return AL_TRUE; case AL_SOURCE_RADIUS: CHECKVAL(*values >= 0.0f && isfinite(*values)); Source->Radius = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_STEREO_ANGLES: CHECKVAL(isfinite(values[0]) && isfinite(values[1])); - LockContext(Context); Source->StereoPan[0] = values[0]; Source->StereoPan[1] = values[1]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_POSITION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - LockContext(Context); - aluVectorSet(&Source->Position, values[0], values[1], values[2], 1.0f); - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + Source->Position[0] = values[0]; + Source->Position[1] = values[1]; + Source->Position[2] = values[2]; + DO_UPDATEPROPS(); return AL_TRUE; case AL_VELOCITY: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - LockContext(Context); - aluVectorSet(&Source->Velocity, values[0], values[1], values[2], 0.0f); - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + Source->Velocity[0] = values[0]; + Source->Velocity[1] = values[1]; + Source->Velocity[2] = values[2]; + DO_UPDATEPROPS(); return AL_TRUE; case AL_DIRECTION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - LockContext(Context); - aluVectorSet(&Source->Direction, values[0], values[1], values[2], 0.0f); - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + Source->Direction[0] = values[0]; + Source->Direction[1] = values[1]; + Source->Direction[2] = values[2]; + DO_UPDATEPROPS(); return AL_TRUE; case AL_ORIENTATION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5])); - LockContext(Context); Source->Orientation[0][0] = values[0]; Source->Orientation[0][1] = values[1]; Source->Orientation[0][2] = values[2]; Source->Orientation[1][0] = values[3]; Source->Orientation[1][1] = values[4]; Source->Orientation[1][2] = values[5]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; @@ -626,13 +635,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->HeadRelative = (ALboolean)*values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_LOOPING: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->Looping = (ALboolean)*values; + DO_UPDATEPROPS(); return AL_TRUE; case AL_BUFFER: @@ -695,13 +705,13 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_OFFSET: CHECKVAL(*values >= 0); - LockContext(Context); Source->OffsetType = prop; Source->Offset = *values; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !Context->DeferUpdates) + !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { + LockContext(Context); WriteLock(&Source->queue_lock); if(ApplyOffset(Source) == AL_FALSE) { @@ -710,8 +720,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } WriteUnlock(&Source->queue_lock); + UnlockContext(Context); } - UnlockContext(Context); return AL_TRUE; case AL_DIRECT_FILTER: @@ -722,7 +732,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } - LockContext(Context); if(!filter) { Source->Direct.Gain = 1.0f; @@ -739,37 +748,36 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Direct.GainLF = filter->GainLF; Source->Direct.LFReference = filter->LFReference; } - UnlockContext(Context); UnlockFiltersRead(device); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DIRECT_FILTER_GAINHF_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->DryGainHFAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->WetGainAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->WetGainHFAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DIRECT_CHANNELS_SOFT: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->DirectChannels = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DISTANCE_MODEL: @@ -783,27 +791,20 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->DistanceModel = *values; if(Context->SourceDistanceModel) - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AUXILIARY_SEND_FILTER: LockFiltersRead(device); - LockContext(Context); if(!((ALuint)values[1] < device->NumAuxSends && (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) { - UnlockContext(Context); UnlockFiltersRead(device); SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } - /* Add refcount on the new slot, and release the previous slot */ - if(slot) IncrementRef(&slot->ref); - slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); - if(slot) DecrementRef(&slot->ref); - if(!filter) { /* Disable filter */ @@ -821,9 +822,28 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].GainLF = filter->GainLF; Source->Send[values[1]].LFReference = filter->LFReference; } - UnlockContext(Context); UnlockFiltersRead(device); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + + if(slot != Source->Send[values[1]].Slot && + (Source->state == AL_PLAYING || Source->state == AL_PAUSED)) + { + /* Add refcount on the new slot, and release the previous slot */ + if(slot) IncrementRef(&slot->ref); + slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); + if(slot) DecrementRef(&slot->ref); + /* We must force an update if the auxiliary slot changed on a + * playing source, in case the slot is about to be deleted. + */ + UpdateSourceProps(Source, device->NumAuxSends); + } + else + { + if(slot) IncrementRef(&slot->ref); + slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); + if(slot) DecrementRef(&slot->ref); + DO_UPDATEPROPS(); + } + return AL_TRUE; @@ -1078,10 +1098,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_STEREO_ANGLES: - LockContext(Context); values[0] = Source->StereoPan[0]; values[1] = Source->StereoPan[1]; - UnlockContext(Context); return AL_TRUE; case AL_SEC_OFFSET_LATENCY_SOFT: @@ -1093,38 +1111,30 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_POSITION: - LockContext(Context); - values[0] = Source->Position.v[0]; - values[1] = Source->Position.v[1]; - values[2] = Source->Position.v[2]; - UnlockContext(Context); + values[0] = Source->Position[0]; + values[1] = Source->Position[1]; + values[2] = Source->Position[2]; return AL_TRUE; case AL_VELOCITY: - LockContext(Context); - values[0] = Source->Velocity.v[0]; - values[1] = Source->Velocity.v[1]; - values[2] = Source->Velocity.v[2]; - UnlockContext(Context); + values[0] = Source->Velocity[0]; + values[1] = Source->Velocity[1]; + values[2] = Source->Velocity[2]; return AL_TRUE; case AL_DIRECTION: - LockContext(Context); - values[0] = Source->Direction.v[0]; - values[1] = Source->Direction.v[1]; - values[2] = Source->Direction.v[2]; - UnlockContext(Context); + values[0] = Source->Direction[0]; + values[1] = Source->Direction[1]; + values[2] = Source->Direction[2]; return AL_TRUE; case AL_ORIENTATION: - LockContext(Context); values[0] = Source->Orientation[0][0]; values[1] = Source->Orientation[0][1]; values[2] = Source->Orientation[0][2]; values[3] = Source->Orientation[1][0]; values[4] = Source->Orientation[1][1]; values[5] = Source->Orientation[1][2]; - UnlockContext(Context); return AL_TRUE; /* 1x int */ @@ -1522,9 +1532,8 @@ done: AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) { ALCcontext *context; - ALbufferlistitem *BufferList; ALsource *Source; - ALsizei i, j; + ALsizei i; context = GetContextRef(); if(!context) return; @@ -1559,22 +1568,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) } UnlockContext(context); - BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, NULL); - while(BufferList != NULL) - { - ALbufferlistitem *next = BufferList->next; - if(BufferList->buffer != NULL) - DecrementRef(&BufferList->buffer->ref); - free(BufferList); - BufferList = next; - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(Source->Send[j].Slot) - DecrementRef(&Source->Send[j].Slot->ref); - Source->Send[j].Slot = NULL; - } + DeinitSource(Source); memset(Source, 0, sizeof(*Source)); al_free(Source); @@ -1612,6 +1606,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1620,6 +1615,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) else SetSourcefv(Source, Context, param, &value); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1632,6 +1628,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1643,6 +1640,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 SetSourcefv(Source, Context, param, fvals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1655,6 +1653,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1665,6 +1664,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat else SetSourcefv(Source, Context, param, values); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1678,6 +1678,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1689,6 +1690,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va SetSourcefv(Source, Context, param, &fval); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1701,6 +1703,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1712,6 +1715,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v SetSourcefv(Source, Context, param, fvals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1725,6 +1729,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1742,6 +1747,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo SetSourcefv(Source, Context, param, fvals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1755,6 +1761,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1763,6 +1770,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) else SetSourceiv(Source, Context, param, &value); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1775,6 +1783,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1786,6 +1795,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL SetSourceiv(Source, Context, param, ivals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1798,6 +1808,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1808,6 +1819,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val else SetSourceiv(Source, Context, param, values); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1821,6 +1833,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1829,6 +1842,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO else SetSourcei64v(Source, Context, param, &value); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1841,6 +1855,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1852,6 +1867,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF SetSourcei64v(Source, Context, param, i64vals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1864,6 +1880,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1874,6 +1891,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin else SetSourcei64v(Source, Context, param, values); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1887,6 +1905,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1901,6 +1920,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val *value = (ALfloat)dval; } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1914,6 +1934,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1932,6 +1953,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1946,6 +1968,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1964,6 +1987,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1977,6 +2001,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1987,6 +2012,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * else GetSourcedv(Source, Context, param, value); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1999,6 +2025,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2017,6 +2044,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2029,6 +2057,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2039,6 +2068,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble else GetSourcedv(Source, Context, param, values); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2052,6 +2082,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2062,6 +2093,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value else GetSourceiv(Source, Context, param, value); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2075,6 +2107,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2093,6 +2126,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2106,6 +2140,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2116,6 +2151,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values else GetSourceiv(Source, Context, param, values); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2129,6 +2165,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2139,6 +2176,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S else GetSourcei64v(Source, Context, param, value); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2151,6 +2189,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2169,6 +2208,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2181,6 +2221,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2191,6 +2232,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 else GetSourcei64v(Source, Context, param, values); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2241,8 +2283,10 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - if(context->DeferUpdates) source->new_state = AL_PLAYING; - else SetSourceState(source, context, AL_PLAYING); + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + source->new_state = AL_PLAYING; + else + SetSourceState(source, context, AL_PLAYING); } UnlockContext(context); @@ -2277,8 +2321,10 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - if(context->DeferUpdates) source->new_state = AL_PAUSED; - else SetSourceState(source, context, AL_PAUSED); + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + source->new_state = AL_PAUSED; + else + SetSourceState(source, context, AL_PAUSED); } UnlockContext(context); @@ -2594,9 +2640,15 @@ static ALvoid InitSourceParams(ALsource *Source) Source->InnerAngle = 360.0f; Source->OuterAngle = 360.0f; Source->Pitch = 1.0f; - aluVectorSet(&Source->Position, 0.0f, 0.0f, 0.0f, 1.0f); - aluVectorSet(&Source->Velocity, 0.0f, 0.0f, 0.0f, 0.0f); - aluVectorSet(&Source->Direction, 0.0f, 0.0f, 0.0f, 0.0f); + Source->Position[0] = 0.0f; + Source->Position[1] = 0.0f; + Source->Position[2] = 0.0f; + Source->Velocity[0] = 0.0f; + Source->Velocity[1] = 0.0f; + Source->Velocity[2] = 0.0f; + Source->Direction[0] = 0.0f; + Source->Direction[1] = 0.0f; + Source->Direction[2] = 0.0f; Source->Orientation[0][0] = 0.0f; Source->Orientation[0][1] = 0.0f; Source->Orientation[0][2] = -1.0f; @@ -2628,15 +2680,6 @@ static ALvoid InitSourceParams(ALsource *Source) Source->DistanceModel = DefaultDistanceModel; - Source->state = AL_INITIAL; - Source->new_state = AL_NONE; - Source->SourceType = AL_UNDETERMINED; - Source->OffsetType = AL_NONE; - Source->Offset = 0.0; - - ATOMIC_INIT(&Source->queue, NULL); - ATOMIC_INIT(&Source->current_buffer, NULL); - Source->Direct.Gain = 1.0f; Source->Direct.GainHF = 1.0f; Source->Direct.HFReference = LOWPASSFREQREF; @@ -2651,7 +2694,170 @@ static ALvoid InitSourceParams(ALsource *Source) Source->Send[i].LFReference = HIGHPASSFREQREF; } - ATOMIC_INIT(&Source->NeedsUpdate, AL_TRUE); + Source->state = AL_INITIAL; + Source->new_state = AL_NONE; + Source->SourceType = AL_UNDETERMINED; + Source->OffsetType = AL_NONE; + Source->Offset = 0.0; + + ATOMIC_INIT(&Source->queue, NULL); + ATOMIC_INIT(&Source->current_buffer, NULL); + + ATOMIC_INIT(&Source->Update, NULL); + ATOMIC_INIT(&Source->FreeList, NULL); +} + +static ALvoid DeinitSource(ALsource *source) +{ + ALbufferlistitem *BufferList; + struct ALsourceProps *props; + size_t count = 0; + size_t i; + + props = ATOMIC_LOAD(&source->Update); + if(props) al_free(props); + + props = ATOMIC_LOAD(&source->FreeList, almemory_order_relaxed); + while(props) + { + struct ALsourceProps *next; + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + al_free(props); + props = next; + ++count; + } + /* This is excessively spammy if it traces every source destruction, so + * just warn if it was unexpectedly large. + */ + if(count > 3) + WARN("Freed "SZFMT" Source property objects\n", count); + + BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NULL); + while(BufferList != NULL) + { + ALbufferlistitem *next = BufferList->next; + if(BufferList->buffer != NULL) + DecrementRef(&BufferList->buffer->ref); + free(BufferList); + BufferList = next; + } + + for(i = 0;i < MAX_SENDS;++i) + { + if(source->Send[i].Slot) + DecrementRef(&source->Send[i].Slot->ref); + source->Send[i].Slot = NULL; + } +} + +void UpdateSourceProps(ALsource *source, ALuint num_sends) +{ + struct ALsourceProps *props; + size_t i; + + /* Get an unused property container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire); + if(!props) + props = al_calloc(16, sizeof(*props)); + else + { + struct ALsourceProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &props, next, almemory_order_seq_cst, + almemory_order_consume) == 0); + } + + /* Copy in current property values. */ + ATOMIC_STORE(&props->Pitch, source->Pitch, almemory_order_relaxed); + ATOMIC_STORE(&props->Gain, source->Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->OuterGain, source->OuterGain, almemory_order_relaxed); + ATOMIC_STORE(&props->MinGain, source->MinGain, almemory_order_relaxed); + ATOMIC_STORE(&props->MaxGain, source->MaxGain, almemory_order_relaxed); + ATOMIC_STORE(&props->InnerAngle, source->InnerAngle, almemory_order_relaxed); + ATOMIC_STORE(&props->OuterAngle, source->OuterAngle, almemory_order_relaxed); + ATOMIC_STORE(&props->RefDistance, source->RefDistance, almemory_order_relaxed); + ATOMIC_STORE(&props->MaxDistance, source->MaxDistance, almemory_order_relaxed); + ATOMIC_STORE(&props->RollOffFactor, source->RollOffFactor, almemory_order_relaxed); + for(i = 0;i < 3;i++) + ATOMIC_STORE(&props->Position[i], source->Position[i], almemory_order_relaxed); + for(i = 0;i < 3;i++) + ATOMIC_STORE(&props->Velocity[i], source->Velocity[i], almemory_order_relaxed); + for(i = 0;i < 3;i++) + ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed); + for(i = 0;i < 2;i++) + { + size_t j; + for(j = 0;j < 3;j++) + ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j], + almemory_order_relaxed); + } + ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); + ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed); + ATOMIC_STORE(&props->DistanceModel, source->DistanceModel, almemory_order_relaxed); + ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed); + + ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed); + ATOMIC_STORE(&props->WetGainAuto, source->WetGainAuto, almemory_order_relaxed); + ATOMIC_STORE(&props->WetGainHFAuto, source->WetGainHFAuto, almemory_order_relaxed); + ATOMIC_STORE(&props->OuterGainHF, source->OuterGainHF, almemory_order_relaxed); + + ATOMIC_STORE(&props->AirAbsorptionFactor, source->AirAbsorptionFactor, almemory_order_relaxed); + ATOMIC_STORE(&props->RoomRolloffFactor, source->RoomRolloffFactor, almemory_order_relaxed); + ATOMIC_STORE(&props->DopplerFactor, source->DopplerFactor, almemory_order_relaxed); + + ATOMIC_STORE(&props->StereoPan[0], source->StereoPan[0], almemory_order_relaxed); + ATOMIC_STORE(&props->StereoPan[1], source->StereoPan[1], almemory_order_relaxed); + + ATOMIC_STORE(&props->Radius, source->Radius, almemory_order_relaxed); + + ATOMIC_STORE(&props->Direct.Gain, source->Direct.Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.GainHF, source->Direct.GainHF, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.HFReference, source->Direct.HFReference, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.GainLF, source->Direct.GainLF, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.LFReference, source->Direct.LFReference, almemory_order_relaxed); + + for(i = 0;i < num_sends;i++) + { + ATOMIC_STORE(&props->Send[i].Slot, source->Send[i].Slot, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].Gain, source->Send[i].Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].GainHF, source->Send[i].GainHF, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].HFReference, source->Send[i].HFReference, + almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].GainLF, source->Send[i].GainLF, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].LFReference, source->Send[i].LFReference, + almemory_order_relaxed); + } + + /* Set the new container for updating internal parameters. */ + props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, props, almemory_order_acq_rel); + if(props) + { + /* If there was an unused update container, put it back in the + * freelist. + */ + struct ALsourceProps *first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); + } +} + +void UpdateAllSourceProps(ALCcontext *context) +{ + ALuint num_sends = context->Device->NumAuxSends; + ALsizei pos; + for(pos = 0;pos < context->VoiceCount;pos++) + { + ALvoice *voice = &context->Voices[pos]; + ALsource *source = voice->Source; + if(source != NULL && (source->state == AL_PLAYING || + source->state == AL_PAUSED)) + UpdateSourceProps(source, num_sends); + } + } @@ -2749,11 +2955,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } if(BufferList->buffer->FmtChannels == FmtMono) - voice->Update = CalcSourceParams; + voice->Update = CalcAttnSourceParams; else voice->Update = CalcNonAttnSourceParams; - - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + UpdateSourceProps(Source, device->NumAuxSends); } else if(state == AL_PAUSED) { @@ -3084,30 +3289,13 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac) */ ALvoid ReleaseALSources(ALCcontext *Context) { - ALbufferlistitem *item; ALsizei pos; - ALuint j; for(pos = 0;pos < Context->SourceMap.size;pos++) { ALsource *temp = Context->SourceMap.array[pos].value; Context->SourceMap.array[pos].value = NULL; - item = ATOMIC_EXCHANGE(ALbufferlistitem*, &temp->queue, NULL); - while(item != NULL) - { - ALbufferlistitem *next = item->next; - if(item->buffer != NULL) - DecrementRef(&item->buffer->ref); - free(item); - item = next; - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(temp->Send[j].Slot) - DecrementRef(&temp->Send[j].Slot->ref); - temp->Send[j].Slot = NULL; - } + DeinitSource(temp); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(*temp)); diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index c0c2ca82..e8a8d391 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -62,7 +62,11 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -86,7 +90,11 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -148,7 +156,7 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = context->DeferUpdates; + value = ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -188,7 +196,7 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALdouble)context->DeferUpdates; + value = (ALdouble)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -228,7 +236,7 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALfloat)context->DeferUpdates; + value = (ALfloat)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -268,7 +276,7 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALint)context->DeferUpdates; + value = (ALint)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -308,7 +316,7 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALint64SOFT)context->DeferUpdates; + value = (ALint64SOFT)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -554,7 +562,11 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) WriteLock(&context->PropLock); context->DopplerFactor = value; - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } WriteUnlock(&context->PropLock); done: @@ -573,7 +585,11 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) WriteLock(&context->PropLock); context->DopplerVelocity = value; - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } WriteUnlock(&context->PropLock); done: @@ -592,7 +608,11 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) WriteLock(&context->PropLock); context->SpeedOfSound = value; - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } WriteUnlock(&context->PropLock); done: @@ -615,7 +635,13 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) WriteLock(&context->PropLock); context->DistanceModel = value; if(!context->SourceDistanceModel) - UpdateListenerProps(context); + { + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } + } WriteUnlock(&context->PropLock); done: -- cgit v1.2.3 From 576c1116a65bd66effce6d92d1aa7e21d1dee83a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 15 May 2016 01:19:05 -0700 Subject: Avoid using a flag to specify if the effect state needs to be updated This fixes a potential missed state change if an update with a new state got replaced with one that doesn't. --- Alc/ALc.c | 4 ++-- Alc/ALu.c | 12 ++++++++---- OpenAL32/Include/alAuxEffectSlot.h | 4 +--- OpenAL32/alAuxEffectSlot.c | 19 +++++++++---------- 4 files changed, 20 insertions(+), 19 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index e5c18d8c..dfbb6c63 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2052,7 +2052,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } - UpdateEffectSlotProps(slot, AL_FALSE); + UpdateEffectSlotProps(slot); } context = ATOMIC_LOAD(&device->ContextList); @@ -2077,7 +2077,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) return ALC_INVALID_DEVICE; } - UpdateEffectSlotProps(slot, AL_FALSE); + UpdateEffectSlotProps(slot); } UnlockUIntMapRead(&context->EffectSlotMap); diff --git a/Alc/ALu.c b/Alc/ALu.c index 2fffdcd9..329d01eb 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -336,6 +336,7 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { struct ALeffectslotProps *first; struct ALeffectslotProps *props; + ALeffectState *state; props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); if(!props) return; @@ -355,13 +356,16 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; } + state = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); + /* If the state object is changed, exchange it with the current one so it * remains in the freelist and isn't leaked. */ - if(ATOMIC_LOAD(&props->UpdateState, almemory_order_relaxed)) - slot->Params.EffectState = ATOMIC_EXCHANGE(ALeffectState*, - &props->State, slot->Params.EffectState, almemory_order_relaxed - ); + if(state != slot->Params.EffectState) + { + ATOMIC_STORE(&props->State, slot->Params.EffectState, almemory_order_relaxed); + slot->Params.EffectState = state; + } V(slot->Params.EffectState,update)(device, slot, &props->Props); diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 28c0b46f..85d730f8 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -79,8 +79,6 @@ struct ALeffectslotProps { ATOMIC(ALenum) Type; ALeffectProps Props; - /* Flag indicates if State should be updated. */ - ATOMIC(ALboolean) UpdateState; ATOMIC(ALeffectState*) State; ATOMIC(struct ALeffectslotProps*) next; @@ -140,7 +138,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); -void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate); +void UpdateEffectSlotProps(ALeffectslot *slot); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 6d1423db..0dd6a53f 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -201,7 +201,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!(value == AL_TRUE || value == AL_FALSE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; - UpdateEffectSlotProps(slot, AL_FALSE); + UpdateEffectSlotProps(slot); if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) UpdateAllSourceProps(context); break; @@ -264,7 +264,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot, AL_FALSE); + UpdateEffectSlotProps(slot); done: WriteUnlock(&context->PropLock); @@ -502,12 +502,12 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e } EffectSlot->Effect.State = State; - UpdateEffectSlotProps(EffectSlot, AL_TRUE); + UpdateEffectSlotProps(EffectSlot); } else if(effect) { memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); - UpdateEffectSlotProps(EffectSlot, AL_FALSE); + UpdateEffectSlotProps(EffectSlot); } return AL_NO_ERROR; @@ -556,7 +556,8 @@ void DeinitEffectSlot(ALeffectslot *slot) { ALeffectState *state; state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); - DELETE_OBJ(state); + if(state != slot->Params.EffectState) + DELETE_OBJ(state); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } @@ -577,7 +578,7 @@ void DeinitEffectSlot(ALeffectslot *slot) DELETE_OBJ(slot->Params.EffectState); } -void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate) +void UpdateEffectSlotProps(ALeffectslot *slot) { struct ALeffectslotProps *props; ALeffectState *oldstate; @@ -605,10 +606,8 @@ void UpdateEffectSlotProps(ALeffectslot *slot, ALboolean withstate) /* Swap out any stale effect state object there may be in the container, to * delete it. */ - ATOMIC_STORE(&props->UpdateState, withstate, almemory_order_relaxed); - oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, - withstate ? slot->Effect.State : NULL, almemory_order_relaxed - ); + oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, + almemory_order_relaxed); /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, -- cgit v1.2.3 From c522658d19f7e82748400731bddb4633847c2a40 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 15 May 2016 13:44:32 -0700 Subject: Avoid duplicate effect state objects in the freelist If an unapplied update was superceded, it would be placed in the freelist with its effect state object intact. This would cause another update with the same effect state object to be placed into the freelist as well, or worse, cause it to get deleted while in use when the container had its effect state cleared. --- OpenAL32/alAuxEffectSlot.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 0dd6a53f..9cc86563 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -549,12 +549,12 @@ ALenum InitEffectSlot(ALeffectslot *slot) void DeinitEffectSlot(ALeffectslot *slot) { struct ALeffectslotProps *props; + ALeffectState *state; size_t count = 0; props = ATOMIC_LOAD(&slot->Update); if(props) { - ALeffectState *state; state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); if(state != slot->Params.EffectState) DELETE_OBJ(state); @@ -565,7 +565,6 @@ void DeinitEffectSlot(ALeffectslot *slot) while(props) { struct ALeffectslotProps *next; - ALeffectState *state; state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); DELETE_OBJ(state); @@ -583,18 +582,32 @@ void UpdateEffectSlotProps(ALeffectslot *slot) struct ALeffectslotProps *props; ALeffectState *oldstate; - /* Get an unused property container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&slot->FreeList, almemory_order_acquire); - if(!props) - props = al_calloc(16, sizeof(*props)); + props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL); + if(props) + { + /* If there was an unapplied update, check if its state object is the + * same as the current in-use one, or the one that will be set. If + * neither, delete it. + */ + oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); + if(oldstate != slot->Params.EffectState && oldstate != slot->Effect.State) + DELETE_OBJ(oldstate); + } else { - struct ALeffectslotProps *next; - do { - next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, - &slot->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_consume) == 0); + /* Get an unused property container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); + if(!props) + props = al_calloc(16, sizeof(*props)); + else + { + struct ALeffectslotProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + &slot->FreeList, &props, next, almemory_order_seq_cst, + almemory_order_consume) == 0); + } } /* Copy in current property values. */ -- cgit v1.2.3 From 800e38bac68315d372ca1f865c7c448356309f70 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 27 May 2016 19:40:54 -0700 Subject: Use the backend lock for the effectstate's deviceUpdate call --- OpenAL32/alAuxEffectSlot.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 9cc86563..c37ecd58 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -470,24 +470,20 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e return AL_INVALID_ENUM; } State = V0(factory,create)(); - if(!State) - return AL_OUT_OF_MEMORY; + if(!State) return AL_OUT_OF_MEMORY; SetMixerFPUMode(&oldMode); - /* FIXME: This just needs to prevent the device from being reset during - * the state's device update, so the list lock in ALc.c should do here. - */ - ALCdevice_Lock(Device); + almtx_lock(&Device->BackendLock); State->OutBuffer = Device->Dry.Buffer; State->OutChannels = Device->Dry.NumChannels; if(V(State,deviceUpdate)(Device) == AL_FALSE) { - ALCdevice_Unlock(Device); + almtx_unlock(&Device->BackendLock); RestoreFPUMode(&oldMode); DELETE_OBJ(State); return AL_OUT_OF_MEMORY; } - ALCdevice_Unlock(Device); + almtx_unlock(&Device->BackendLock); RestoreFPUMode(&oldMode); if(!effect) -- cgit v1.2.3 From 8aa4a74a7b213f2a8a3e0126a248357e587d34a8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 29 May 2016 01:40:16 -0700 Subject: Use a linked list for active effect slots --- Alc/ALc.c | 8 +---- Alc/ALu.c | 40 ++++++++++++++--------- OpenAL32/Include/alAuxEffectSlot.h | 2 ++ OpenAL32/Include/alMain.h | 2 +- OpenAL32/alAuxEffectSlot.c | 67 ++++++++++++++++++-------------------- 5 files changed, 59 insertions(+), 60 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index e8e5c3ee..b4582b0e 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2324,8 +2324,6 @@ static void FreeContext(ALCcontext *context) context->VoiceCount = 0; context->MaxVoices = 0; - VECTOR_DEINIT(context->ActiveAuxSlots); - if((lprops=ATOMIC_LOAD(&listener->Update, almemory_order_acquire)) != NULL) { TRACE("Freed unapplied listener update %p\n", lprops); @@ -3115,7 +3113,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin InitRef(&ALContext->ref, 1); ALContext->Listener = (ALlistener*)ALContext->_listener_mem; - VECTOR_INIT(ALContext->ActiveAuxSlots); + ATOMIC_INIT(&ALContext->ActiveAuxSlotList, NULL); ALContext->VoiceCount = 0; ALContext->MaxVoices = 256; @@ -3130,8 +3128,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin al_free(ALContext->Voices); ALContext->Voices = NULL; - VECTOR_DEINIT(ALContext->ActiveAuxSlots); - al_free(ALContext); ALContext = NULL; } @@ -3148,8 +3144,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin al_free(ALContext->Voices); ALContext->Voices = NULL; - VECTOR_DEINIT(ALContext->ActiveAuxSlots); - al_free(ALContext); ALContext = NULL; diff --git a/Alc/ALu.c b/Alc/ALu.c index b64cbf49..3ba068a2 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1320,7 +1320,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context) } -static void UpdateContextSources(ALCcontext *ctx) +static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) { ALvoice *voice, *voice_end; ALsource *source; @@ -1329,9 +1329,11 @@ static void UpdateContextSources(ALCcontext *ctx) if(!ATOMIC_LOAD(&ctx->HoldUpdates)) { CalcListenerParams(ctx); -#define UPDATE_SLOT(iter) CalcEffectSlotParams(*iter, ctx->Device) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); -#undef UPDATE_SLOT + while(slot) + { + CalcEffectSlotParams(slot, ctx->Device); + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + } voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; @@ -1440,13 +1442,18 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) ctx = ATOMIC_LOAD(&device->ContextList); while(ctx) { - UpdateContextSources(ctx); -#define CLEAR_WET_BUFFER(iter) do { \ - for(i = 0;i < (*iter)->NumChannels;i++) \ - memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \ -} while(0) - VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, CLEAR_WET_BUFFER); -#undef CLEAR_WET_BUFFER + ALeffectslot *slotroot; + + slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList); + UpdateContextSources(ctx, slotroot); + + slot = slotroot; + while(slot) + { + for(i = 0;i < slot->NumChannels;i++) + memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + } /* source processing */ voice = ctx->Voices; @@ -1459,13 +1466,14 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) } /* effect slot processing */ - c = VECTOR_SIZE(ctx->ActiveAuxSlots); - for(i = 0;i < c;i++) + slot = slotroot; + while(slot) { - const ALeffectslot *slot = VECTOR_ELEM(ctx->ActiveAuxSlots, i); - ALeffectState *state = slot->Params.EffectState; - V(state,process)(SamplesToDo, slot->WetBuffer, state->OutBuffer, + const ALeffectslot *cslot = slot; + ALeffectState *state = cslot->Params.EffectState; + V(state,process)(SamplesToDo, cslot->WetBuffer, state->OutBuffer, state->OutChannels); + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } ctx = ctx->next; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 85d730f8..a9b50387 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -129,6 +129,8 @@ typedef struct ALeffectslot { * first-order device output (FOAOut). */ alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]; + + ATOMIC(struct ALeffectslot*) next; } ALeffectslot; inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 50162b0e..d7b54310 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -711,7 +711,7 @@ struct ALCcontext_struct { ALsizei VoiceCount; ALsizei MaxVoices; - VECTOR(struct ALeffectslot*) ActiveAuxSlots; + ATOMIC(struct ALeffectslot*) ActiveAuxSlotList; ALCdevice *Device; const ALCchar *ExtensionList; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index c37ecd58..8da7aeb2 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -38,8 +38,8 @@ extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); -static ALenum AddEffectSlotArray(ALCcontext *Context, ALeffectslot **start, ALsizei count); -static void RemoveEffectSlotArray(ALCcontext *Context, const ALeffectslot *slot); +static void AddEffectSlotList(ALCcontext *Context, ALeffectslot *first, ALeffectslot *last); +static void RemoveEffectSlotList(ALCcontext *Context, const ALeffectslot *slot); static UIntMap EffectStateFactoryMap; @@ -55,20 +55,17 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *context; - VECTOR(ALeffectslot*) slotvec; + ALeffectslot *first, *last; ALsizei cur; ALenum err; context = GetContextRef(); if(!context) return; - VECTOR_INIT(slotvec); - if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - if(!VECTOR_RESERVE(slotvec, n)) - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + first = last = NULL; for(cur = 0;cur < n;cur++) { ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); @@ -95,20 +92,15 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo aluInitEffectPanning(slot); - VECTOR_PUSH_BACK(slotvec, slot); + if(!first) first = slot; + if(last) ATOMIC_STORE(&last->next, slot); + last = slot; effectslots[cur] = slot->id; } - err = AddEffectSlotArray(context, VECTOR_BEGIN(slotvec), n); - if(err != AL_NO_ERROR) - { - alDeleteAuxiliaryEffectSlots(cur, effectslots); - SET_ERROR_AND_GOTO(context, err, done); - } + AddEffectSlotList(context, first, last); done: - VECTOR_DEINIT(slotvec); - ALCcontext_DecRef(context); } @@ -138,7 +130,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * continue; FreeThunkEntry(slot->id); - RemoveEffectSlotArray(context, slot); + RemoveEffectSlotList(context, slot); DeinitEffectSlot(slot); memset(slot, 0, sizeof(*slot)); @@ -399,32 +391,33 @@ done: } -static ALenum AddEffectSlotArray(ALCcontext *context, ALeffectslot **start, ALsizei count) +static void AddEffectSlotList(ALCcontext *context, ALeffectslot *start, ALeffectslot *last) { - ALenum err = AL_NO_ERROR; - - LockContext(context); - if(!VECTOR_INSERT(context->ActiveAuxSlots, VECTOR_END(context->ActiveAuxSlots), start, start+count)) - err = AL_OUT_OF_MEMORY; - UnlockContext(context); - - return err; + ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList); + do { + ATOMIC_STORE(&last->next, root, almemory_order_relaxed); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList, + &root, start)); } -static void RemoveEffectSlotArray(ALCcontext *context, const ALeffectslot *slot) +static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot) { - ALeffectslot **iter; + ALCdevice *device = context->Device; + const ALeffectslot *root, *next; - LockContext(context); -#define MATCH_SLOT(_i) (slot == *(_i)) - VECTOR_FIND_IF(iter, ALeffectslot*, context->ActiveAuxSlots, MATCH_SLOT); - if(iter != VECTOR_END(context->ActiveAuxSlots)) + root = slot; + next = ATOMIC_LOAD(&slot->next); + if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) { - *iter = VECTOR_BACK(context->ActiveAuxSlots); - VECTOR_POP_BACK(context->ActiveAuxSlots); + const ALeffectslot *cur; + do { + cur = root; + root = slot; + } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next)); } -#undef MATCH_SLOT - UnlockContext(context); + /* Wait for any mix that may be using these effect slots to finish. */ + while((ReadRef(&device->MixCount)&1) != 0) + althrd_yield(); } @@ -539,6 +532,8 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; + ATOMIC_INIT(&slot->next, NULL); + return AL_NO_ERROR; } -- cgit v1.2.3 From 4802465f1a6365051604f38dae9c20c93c0f0a7b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 29 May 2016 02:47:54 -0700 Subject: Hold the effectslot map lock while handling it --- OpenAL32/Include/alAuxEffectSlot.h | 13 +++++++++++-- OpenAL32/alAuxEffectSlot.c | 24 ++++++++++++++++++++++++ OpenAL32/alSource.c | 3 +++ 3 files changed, 38 insertions(+), 2 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index a9b50387..8d2fc3d7 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -133,10 +133,19 @@ typedef struct ALeffectslot { ATOMIC(struct ALeffectslot*) next; } ALeffectslot; +inline void LockEffectSlotsRead(ALCcontext *context) +{ LockUIntMapRead(&context->EffectSlotMap); } +inline void UnlockEffectSlotsRead(ALCcontext *context) +{ UnlockUIntMapRead(&context->EffectSlotMap); } +inline void LockEffectSlotsWrite(ALCcontext *context) +{ LockUIntMapWrite(&context->EffectSlotMap); } +inline void UnlockEffectSlotsWrite(ALCcontext *context) +{ UnlockUIntMapWrite(&context->EffectSlotMap); } + inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) -{ return (struct ALeffectslot*)LookupUIntMapKey(&context->EffectSlotMap, id); } +{ return (struct ALeffectslot*)LookupUIntMapKeyNoLock(&context->EffectSlotMap, id); } inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) -{ return (struct ALeffectslot*)RemoveUIntMapKey(&context->EffectSlotMap, id); } +{ return (struct ALeffectslot*)RemoveUIntMapKeyNoLock(&context->EffectSlotMap, id); } ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 8da7aeb2..b0fd3385 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -35,6 +35,10 @@ #include "almalloc.h" +extern inline void LockEffectSlotsRead(ALCcontext *context); +extern inline void UnlockEffectSlotsRead(ALCcontext *context); +extern inline void LockEffectSlotsWrite(ALCcontext *context); +extern inline void UnlockEffectSlotsWrite(ALCcontext *context); extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); @@ -113,6 +117,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * context = GetContextRef(); if(!context) return; + LockEffectSlotsWrite(context); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) @@ -138,6 +143,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * } done: + UnlockEffectSlotsWrite(context); ALCcontext_DecRef(context); } @@ -149,7 +155,9 @@ AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot) context = GetContextRef(); if(!context) return AL_FALSE; + LockEffectSlotsRead(context); ret = (LookupEffectSlot(context, effectslot) ? AL_TRUE : AL_FALSE); + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); @@ -168,6 +176,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!context) return; WriteLock(&context->PropLock); + LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -203,6 +212,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param } done: + UnlockEffectSlotsRead(context); WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -222,6 +232,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para context = GetContextRef(); if(!context) return; + LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -231,6 +242,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para } done: + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); } @@ -243,6 +255,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param if(!context) return; WriteLock(&context->PropLock); + LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -259,6 +272,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param UpdateEffectSlotProps(slot); done: + UnlockEffectSlotsRead(context); WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -277,6 +291,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum para context = GetContextRef(); if(!context) return; + LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -286,6 +301,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum para } done: + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); } @@ -297,6 +313,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa context = GetContextRef(); if(!context) return; + LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -310,6 +327,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa } done: + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); } @@ -328,6 +346,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p context = GetContextRef(); if(!context) return; + LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -337,6 +356,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p } done: + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); } @@ -348,6 +368,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa context = GetContextRef(); if(!context) return; + LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -361,6 +382,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa } done: + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); } @@ -378,6 +400,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p context = GetContextRef(); if(!context) return; + LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); switch(param) @@ -387,6 +410,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p } done: + UnlockEffectSlotsRead(context); ALCcontext_DecRef(context); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a15b169f..c1824d5b 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -796,12 +796,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_AUXILIARY_SEND_FILTER: + LockEffectSlotsRead(Context); LockFiltersRead(device); if(!((ALuint)values[1] < device->NumAuxSends && (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) { UnlockFiltersRead(device); + UnlockEffectSlotsRead(Context); SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } @@ -846,6 +848,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].Slot = slot; DO_UPDATEPROPS(); } + UnlockEffectSlotsRead(Context); return AL_TRUE; -- cgit v1.2.3 From 8f4d6c48ce6621e2e2b79ada781b9e3dfc9ed38c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 4 Jul 2016 20:35:32 -0700 Subject: Use separate arrays for UIntMap keys and values --- Alc/ALc.c | 6 +-- OpenAL32/alAuxEffectSlot.c | 4 +- OpenAL32/alBuffer.c | 4 +- OpenAL32/alEffect.c | 4 +- OpenAL32/alFilter.c | 4 +- OpenAL32/alSource.c | 4 +- common/uintmap.c | 109 ++++++++++++++++++++++++++++----------------- include/uintmap.h | 10 ++--- 8 files changed, 87 insertions(+), 58 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index ca73bd57..83cd59f5 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1580,7 +1580,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) V0(device->Backend,lock)(); for(pos = 0;pos < context->SourceMap.size;pos++) { - ALsource *Source = context->SourceMap.array[pos].value; + ALsource *Source = context->SourceMap.values[pos]; ALenum new_state; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && @@ -2064,7 +2064,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) LockUIntMapRead(&context->EffectSlotMap); for(pos = 0;pos < context->EffectSlotMap.size;pos++) { - ALeffectslot *slot = context->EffectSlotMap.array[pos].value; + ALeffectslot *slot = context->EffectSlotMap.values[pos]; ALeffectState *state = slot->Effect.State; state->OutBuffer = device->Dry.Buffer; @@ -2084,7 +2084,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) LockUIntMapRead(&context->SourceMap); for(pos = 0;pos < context->SourceMap.size;pos++) { - ALsource *source = context->SourceMap.array[pos].value; + ALsource *source = context->SourceMap.values[pos]; ALuint s = device->NumAuxSends; while(s < MAX_SENDS) { diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index b0fd3385..bbaf0668 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -660,8 +660,8 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) ALsizei pos; for(pos = 0;pos < Context->EffectSlotMap.size;pos++) { - ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; - Context->EffectSlotMap.array[pos].value = NULL; + ALeffectslot *temp = Context->EffectSlotMap.values[pos]; + Context->EffectSlotMap.values[pos] = NULL; DeinitEffectSlot(temp); diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 193ab44f..c52924a9 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -1402,8 +1402,8 @@ ALvoid ReleaseALBuffers(ALCdevice *device) ALsizei i; for(i = 0;i < device->BufferMap.size;i++) { - ALbuffer *temp = device->BufferMap.array[i].value; - device->BufferMap.array[i].value = NULL; + ALbuffer *temp = device->BufferMap.values[i]; + device->BufferMap.values[i] = NULL; al_free(temp->data); diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 5a036091..1057f3c1 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -375,8 +375,8 @@ ALvoid ReleaseALEffects(ALCdevice *device) ALsizei i; for(i = 0;i < device->EffectMap.size;i++) { - ALeffect *temp = device->EffectMap.array[i].value; - device->EffectMap.array[i].value = NULL; + ALeffect *temp = device->EffectMap.values[i]; + device->EffectMap.values[i] = NULL; // Release effect structure FreeThunkEntry(temp->id); diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 7be3e339..7b96263a 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -636,8 +636,8 @@ ALvoid ReleaseALFilters(ALCdevice *device) ALsizei i; for(i = 0;i < device->FilterMap.size;i++) { - ALfilter *temp = device->FilterMap.array[i].value; - device->FilterMap.array[i].value = NULL; + ALfilter *temp = device->FilterMap.values[i]; + device->FilterMap.values[i] = NULL; // Release filter structure FreeThunkEntry(temp->id); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index e79f0fc3..7d34f368 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -3373,8 +3373,8 @@ ALvoid ReleaseALSources(ALCcontext *Context) ALsizei pos; for(pos = 0;pos < Context->SourceMap.size;pos++) { - ALsource *temp = Context->SourceMap.array[pos].value; - Context->SourceMap.array[pos].value = NULL; + ALsource *temp = Context->SourceMap.values[pos]; + Context->SourceMap.values[pos] = NULL; DeinitSource(temp); diff --git a/common/uintmap.c b/common/uintmap.c index 041f46c1..d3b51923 100644 --- a/common/uintmap.c +++ b/common/uintmap.c @@ -17,7 +17,8 @@ extern inline void UnlockUIntMapWrite(UIntMap *map); void InitUIntMap(UIntMap *map, ALsizei limit) { - map->array = NULL; + map->keys = NULL; + map->values = NULL; map->size = 0; map->capacity = 0; map->limit = limit; @@ -27,8 +28,9 @@ void InitUIntMap(UIntMap *map, ALsizei limit) void ResetUIntMap(UIntMap *map) { WriteLock(&map->lock); - al_free(map->array); - map->array = NULL; + al_free(map->keys); + map->keys = NULL; + map->values = NULL; map->size = 0; map->capacity = 0; WriteUnlock(&map->lock); @@ -46,17 +48,17 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) while(low < high) { ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) + if(map->keys[mid] < key) low = mid + 1; else high = mid; } - if(map->array[low].key < key) + if(map->keys[low] < key) low++; pos = low; } - if(pos == map->size || map->array[pos].key != key) + if(pos == map->size || map->keys[pos] != key) { if(map->size == map->limit) { @@ -66,34 +68,53 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) if(map->size == map->capacity) { - ALvoid *temp = NULL; - ALsizei newsize; - - newsize = (map->capacity ? (map->capacity<<1) : 4); - if(map->limit > 0 && newsize > map->limit) - newsize = map->limit; - if(newsize > map->capacity) - temp = al_malloc(16, newsize * sizeof(map->array[0])); - if(!temp) + ALuint *keys = NULL; + ALvoid **values; + ALsizei newcap, keylen; + + newcap = (map->capacity ? (map->capacity<<1) : 4); + if(map->limit > 0 && newcap > map->limit) + newcap = map->limit; + if(newcap > map->capacity) + { + /* Round the memory size for keys up to a multiple of the + * pointer size. + */ + keylen = newcap * sizeof(map->keys[0]); + keylen += sizeof(map->values[0]) - 1; + keylen -= keylen%sizeof(map->values[0]); + + keys = al_malloc(16, keylen + newcap*sizeof(map->values[0])); + } + if(!keys) { WriteUnlock(&map->lock); return AL_OUT_OF_MEMORY; } + values = (ALvoid**)((ALbyte*)keys + keylen); - if(map->array) - memcpy(temp, map->array, map->size*sizeof(map->array[0])); - al_free(map->array); - map->array = temp; - map->capacity = newsize; + if(map->keys) + { + memcpy(keys, map->keys, map->size*sizeof(map->keys[0])); + memcpy(values, map->values, map->size*sizeof(map->values[0])); + } + al_free(map->keys); + map->keys = keys; + map->values = values; + map->capacity = newcap; } if(pos < map->size) - memmove(&map->array[pos+1], &map->array[pos], - (map->size-pos)*sizeof(map->array[0])); + { + memmove(&map->keys[pos+1], &map->keys[pos], + (map->size-pos)*sizeof(map->keys[0])); + memmove(&map->values[pos+1], &map->values[pos], + (map->size-pos)*sizeof(map->values[0])); + } map->size++; } - map->array[pos].key = key; - map->array[pos].value = value; + map->keys[pos] = key; + map->values[pos] = value; WriteUnlock(&map->lock); return AL_NO_ERROR; @@ -110,17 +131,21 @@ ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key) while(low < high) { ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) + if(map->keys[mid] < key) low = mid + 1; else high = mid; } - if(map->array[low].key == key) + if(map->keys[low] == key) { - ptr = map->array[low].value; + ptr = map->values[low]; if(low < map->size-1) - memmove(&map->array[low], &map->array[low+1], - (map->size-1-low)*sizeof(map->array[0])); + { + memmove(&map->keys[low], &map->keys[low+1], + (map->size-1-low)*sizeof(map->keys[0])); + memmove(&map->values[low], &map->values[low+1], + (map->size-1-low)*sizeof(map->values[0])); + } map->size--; } } @@ -137,17 +162,21 @@ ALvoid *RemoveUIntMapKeyNoLock(UIntMap *map, ALuint key) while(low < high) { ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) + if(map->keys[mid] < key) low = mid + 1; else high = mid; } - if(map->array[low].key == key) + if(map->keys[low] == key) { - ALvoid *ptr = map->array[low].value; + ALvoid *ptr = map->values[low]; if(low < map->size-1) - memmove(&map->array[low], &map->array[low+1], - (map->size-1-low)*sizeof(map->array[0])); + { + memmove(&map->keys[low], &map->keys[low+1], + (map->size-1-low)*sizeof(map->keys[0])); + memmove(&map->values[low], &map->values[low+1], + (map->size-1-low)*sizeof(map->values[0])); + } map->size--; return ptr; } @@ -166,13 +195,13 @@ ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key) while(low < high) { ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) + if(map->keys[mid] < key) low = mid + 1; else high = mid; } - if(map->array[low].key == key) - ptr = map->array[low].value; + if(map->keys[low] == key) + ptr = map->values[low]; } ReadUnlock(&map->lock); return ptr; @@ -187,13 +216,13 @@ ALvoid *LookupUIntMapKeyNoLock(UIntMap *map, ALuint key) while(low < high) { ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) + if(map->keys[mid] < key) low = mid + 1; else high = mid; } - if(map->array[low].key == key) - return map->array[low].value; + if(map->keys[low] == key) + return map->values[low]; } return NULL; } diff --git a/include/uintmap.h b/include/uintmap.h index e7c3f93d..acb2749a 100644 --- a/include/uintmap.h +++ b/include/uintmap.h @@ -9,16 +9,16 @@ extern "C" { #endif typedef struct UIntMap { - struct { - ALuint key; - ALvoid *value; - } *array; + ALuint *keys; + /* Shares memory with keys. */ + ALvoid **values; + ALsizei size; ALsizei capacity; ALsizei limit; RWLock lock; } UIntMap; -#define UINTMAP_STATIC_INITIALIZE_N(_n) { NULL, 0, 0, (_n), RWLOCK_STATIC_INITIALIZE } +#define UINTMAP_STATIC_INITIALIZE_N(_n) { NULL, NULL, 0, 0, (_n), RWLOCK_STATIC_INITIALIZE } #define UINTMAP_STATIC_INITIALIZE UINTMAP_STATIC_INITIALIZE_N(~0) void InitUIntMap(UIntMap *map, ALsizei limit); -- cgit v1.2.3 From b495d80f5624328569bd0d8b9478927c0fc32100 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 6 Jul 2016 13:33:40 -0700 Subject: Avoid using memcpy to copy a single struct --- Alc/panning.c | 8 ++++---- OpenAL32/Include/alMain.h | 26 ++++++++++++-------------- OpenAL32/alAuxEffectSlot.c | 6 +++--- 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/panning.c b/Alc/panning.c index 6949c565..c7bc82f8 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -581,7 +581,7 @@ static void InitPanning(ALCdevice *device) device->Dry.CoeffCount = 0; device->Dry.NumChannels = count; - memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.Ambi = device->Dry.Ambi; device->FOAOut.CoeffCount = device->Dry.CoeffCount; } else @@ -708,7 +708,7 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALuin if(bformatdec_getOrder(device->AmbiDecoder) < 2) { - memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.Ambi = device->Dry.Ambi; device->FOAOut.CoeffCount = device->Dry.CoeffCount; } else @@ -763,7 +763,7 @@ static void InitHrtfPanning(ALCdevice *device) &device->Dry.NumChannels, AL_TRUE); device->Dry.CoeffCount = 4; - memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.Ambi = device->Dry.Ambi; device->FOAOut.CoeffCount = device->Dry.CoeffCount; for(i = 0;i < device->Dry.NumChannels;i++) @@ -788,7 +788,7 @@ static void InitUhjPanning(ALCdevice *device) device->Dry.CoeffCount = 0; device->Dry.NumChannels = count; - memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.Ambi = device->Dry.Ambi; device->FOAOut.CoeffCount = device->Dry.CoeffCount; } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index e1411b83..13aadef5 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -504,6 +504,13 @@ typedef struct BFChannelConfig { ALuint Index; } BFChannelConfig; +typedef union AmbiConfig { + /* Ambisonic coefficients for mixing to the dry buffer. */ + ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS]; + /* Coefficient channel mapping for mixing to the dry buffer. */ + BFChannelConfig Map[MAX_OUTPUT_CHANNELS]; +} AmbiConfig; + #define HRTF_HISTORY_BITS (6) #define HRTF_HISTORY_LENGTH (1<Effect.Type = effect->type; - memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); + EffectSlot->Effect.Props = effect->Props; } EffectSlot->Effect.State = State; @@ -519,7 +519,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e } else if(effect) { - memcpy(&EffectSlot->Effect.Props, &effect->Props, sizeof(EffectSlot->Effect.Props)); + EffectSlot->Effect.Props = effect->Props; UpdateEffectSlotProps(EffectSlot); } @@ -630,7 +630,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) ATOMIC_STORE(&props->AuxSendAuto, slot->AuxSendAuto, almemory_order_relaxed); ATOMIC_STORE(&props->Type, slot->Effect.Type, almemory_order_relaxed); - memcpy(&props->Props, &slot->Effect.Props, sizeof(props->Props)); + props->Props = slot->Effect.Props; /* Swap out any stale effect state object there may be in the container, to * delete it. */ -- cgit v1.2.3 From 25d1b7bdba7b0c68e9e8e6f727c991cb69f24f4a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 26 Jul 2016 03:45:25 -0700 Subject: Remove broken autowah effect code It's been disabled forever, and I have no idea how to make it work properly. Better to just redo it when making something that works. --- Alc/ALc.c | 7 - Alc/effects/autowah.c | 271 ------------------------------------- CMakeLists.txt | 1 - OpenAL32/Include/alAuxEffectSlot.h | 1 - OpenAL32/Include/alEffect.h | 9 -- OpenAL32/alAuxEffectSlot.c | 1 - OpenAL32/alEffect.c | 7 - OpenAL32/alExtension.c | 3 - 8 files changed, 300 deletions(-) delete mode 100644 Alc/effects/autowah.c (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index bc6304d7..9d3553c8 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -666,13 +666,6 @@ static const ALCenums enumeration[] = { DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF), DECL(AL_RING_MODULATOR_WAVEFORM), -#if 0 - DECL(AL_AUTOWAH_ATTACK_TIME), - DECL(AL_AUTOWAH_PEAK_GAIN), - DECL(AL_AUTOWAH_RELEASE_TIME), - DECL(AL_AUTOWAH_RESONANCE), -#endif - DECL(AL_COMPRESSOR_ONOFF), DECL(AL_EQUALIZER_LOW_GAIN), diff --git a/Alc/effects/autowah.c b/Alc/effects/autowah.c deleted file mode 100644 index c8b70595..00000000 --- a/Alc/effects/autowah.c +++ /dev/null @@ -1,271 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2013 by Anis A. Hireche, Nasca Octavian Paul - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include - -#include "config.h" -#include "alu.h" -#include "alFilter.h" -#include "alError.h" -#include "alMain.h" -#include "alAuxEffectSlot.h" - - -/* Auto-wah is simply a low-pass filter with a cutoff frequency that shifts up - * or down depending on the input signal, and a resonant peak at the cutoff. - * - * Currently, we assume a cutoff frequency range of 20hz (no amplitude) to - * 20khz (peak gain). Peak gain is assumed to be in normalized scale. - */ - -typedef struct ALautowahState { - DERIVE_FROM_TYPE(ALeffectState); - - /* Effect gains for each channel */ - ALfloat Gain[MAX_OUTPUT_CHANNELS]; - - /* Effect parameters */ - ALfloat AttackRate; - ALfloat ReleaseRate; - ALfloat Resonance; - ALfloat PeakGain; - ALfloat GainCtrl; - ALfloat Frequency; - - /* Samples processing */ - ALfilterState LowPass; -} ALautowahState; - -static ALvoid ALautowahState_Destruct(ALautowahState *state) -{ - ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); -} - -static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *device) -{ - state->Frequency = (ALfloat)device->Frequency; - return AL_TRUE; -} - -static ALvoid ALautowahState_update(ALautowahState *state, const ALCdevice *device, const ALeffectslot *slot, const ALeffectProps *props) -{ - ALfloat attackTime, releaseTime; - - attackTime = props->Autowah.AttackTime * state->Frequency; - releaseTime = props->Autowah.ReleaseTime * state->Frequency; - - state->AttackRate = powf(1.0f/GAIN_SILENCE_THRESHOLD, 1.0f/attackTime); - state->ReleaseRate = powf(GAIN_SILENCE_THRESHOLD/1.0f, 1.0f/releaseTime); - state->PeakGain = props->Autowah.PeakGain; - state->Resonance = props->Autowah.Resonance; - - ComputeAmbientGains(device->Dry, slot->Params.Gain, state->Gain); -} - -static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) -{ - ALuint it, kt; - ALuint base; - - for(base = 0;base < SamplesToDo;) - { - ALfloat temps[256]; - ALuint td = minu(256, SamplesToDo-base); - ALfloat gain = state->GainCtrl; - - for(it = 0;it < td;it++) - { - ALfloat smp = SamplesIn[0][it+base]; - ALfloat a[3], b[3]; - ALfloat alpha, w0; - ALfloat amplitude; - ALfloat cutoff; - - /* Similar to compressor, we get the current amplitude of the - * incoming signal, and attack or release to reach it. */ - amplitude = fabsf(smp); - if(amplitude > gain) - gain = minf(gain*state->AttackRate, amplitude); - else if(amplitude < gain) - gain = maxf(gain*state->ReleaseRate, amplitude); - gain = maxf(gain, GAIN_SILENCE_THRESHOLD); - - /* FIXME: What range does the filter cover? */ - cutoff = lerp(20.0f, 20000.0f, minf(gain/state->PeakGain, 1.0f)); - - /* The code below is like calling ALfilterState_setParams with - * ALfilterType_LowPass. However, instead of passing a bandwidth, - * we use the resonance property for Q. This also inlines the call. - */ - w0 = F_TAU * cutoff / state->Frequency; - - /* FIXME: Resonance controls the resonant peak, or Q. How? Not sure - * that Q = resonance*0.1. */ - alpha = sinf(w0) / (2.0f * state->Resonance*0.1f); - b[0] = (1.0f - cosf(w0)) / 2.0f; - b[1] = 1.0f - cosf(w0); - b[2] = (1.0f - cosf(w0)) / 2.0f; - a[0] = 1.0f + alpha; - a[1] = -2.0f * cosf(w0); - a[2] = 1.0f - alpha; - - state->LowPass.a1 = a[1] / a[0]; - state->LowPass.a2 = a[2] / a[0]; - state->LowPass.b0 = b[0] / a[0]; - state->LowPass.b1 = b[1] / a[0]; - state->LowPass.b2 = b[2] / a[0]; - - temps[it] = ALfilterState_processSingle(&state->LowPass, smp); - } - state->GainCtrl = gain; - - for(kt = 0;kt < NumChannels;kt++) - { - ALfloat gain = state->Gain[kt]; - if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD)) - continue; - - for(it = 0;it < td;it++) - SamplesOut[kt][base+it] += gain * temps[it]; - } - - base += td; - } -} - -DECLARE_DEFAULT_ALLOCATORS(ALautowahState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALautowahState); - - -typedef struct ALautowahStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALautowahStateFactory; - -static ALeffectState *ALautowahStateFactory_create(ALautowahStateFactory *UNUSED(factory)) -{ - ALautowahState *state; - - state = ALautowahState_New(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALautowahState, ALeffectState, state); - - state->AttackRate = 1.0f; - state->ReleaseRate = 1.0f; - state->Resonance = 2.0f; - state->PeakGain = 1.0f; - state->GainCtrl = 1.0f; - - ALfilterState_clear(&state->LowPass); - - return STATIC_CAST(ALeffectState, state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALautowahStateFactory); - -ALeffectStateFactory *ALautowahStateFactory_getFactory(void) -{ - static ALautowahStateFactory AutowahFactory = { { GET_VTABLE2(ALautowahStateFactory, ALeffectStateFactory) } }; - - return STATIC_CAST(ALeffectStateFactory, &AutowahFactory); -} - - -void ALautowah_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALautowah_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALautowah_setParami(effect, context, param, vals[0]); -} -void ALautowah_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_AUTOWAH_ATTACK_TIME: - if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.AttackTime = val; - break; - - case AL_AUTOWAH_RELEASE_TIME: - if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.ReleaseTime = val; - break; - - case AL_AUTOWAH_RESONANCE: - if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.Resonance = val; - break; - - case AL_AUTOWAH_PEAK_GAIN: - if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.PeakGain = val; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALautowah_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALautowah_setParamf(effect, context, param, vals[0]); -} - -void ALautowah_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALautowah_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALautowah_getParami(effect, context, param, vals); -} -void ALautowah_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_AUTOWAH_ATTACK_TIME: - *val = props->Autowah.AttackTime; - break; - - case AL_AUTOWAH_RELEASE_TIME: - *val = props->Autowah.ReleaseTime; - break; - - case AL_AUTOWAH_RESONANCE: - *val = props->Autowah.Resonance; - break; - - case AL_AUTOWAH_PEAK_GAIN: - *val = props->Autowah.PeakGain; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALautowah_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALautowah_getParamf(effect, context, param, vals); -} - -DEFINE_ALEFFECT_VTABLE(ALautowah); diff --git a/CMakeLists.txt b/CMakeLists.txt index 85bc0dda..d8f15153 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -634,7 +634,6 @@ SET(ALC_OBJS Alc/ALc.c Alc/alcConfig.c Alc/alcRing.c Alc/bs2b.c - Alc/effects/autowah.c Alc/effects/chorus.c Alc/effects/compressor.c Alc/effects/dedicated.c diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 034ac217..d0c7c76c 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -155,7 +155,6 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); ALeffectStateFactory *ALnullStateFactory_getFactory(void); ALeffectStateFactory *ALreverbStateFactory_getFactory(void); -ALeffectStateFactory *ALautowahStateFactory_getFactory(void); ALeffectStateFactory *ALchorusStateFactory_getFactory(void); ALeffectStateFactory *ALcompressorStateFactory_getFactory(void); ALeffectStateFactory *ALdistortionStateFactory_getFactory(void); diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index d20ef077..b97b0147 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -12,7 +12,6 @@ struct ALeffect; enum { EAXREVERB = 0, REVERB, - AUTOWAH, CHORUS, COMPRESSOR, DISTORTION, @@ -51,7 +50,6 @@ const struct ALeffectVtable T##_vtable = { \ extern const struct ALeffectVtable ALeaxreverb_vtable; extern const struct ALeffectVtable ALreverb_vtable; -extern const struct ALeffectVtable ALautowah_vtable; extern const struct ALeffectVtable ALchorus_vtable; extern const struct ALeffectVtable ALcompressor_vtable; extern const struct ALeffectVtable ALdistortion_vtable; @@ -93,13 +91,6 @@ typedef union ALeffectProps { ALfloat LFReference; } Reverb; - struct { - ALfloat AttackTime; - ALfloat ReleaseTime; - ALfloat PeakGain; - ALfloat Resonance; - } Autowah; - struct { ALint Waveform; ALint Phase; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 14066cf9..796eec5b 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -452,7 +452,6 @@ void InitEffectFactoryMap(void) InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnullStateFactory_getFactory); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_REVERB, ALreverbStateFactory_getFactory); - InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_AUTOWAH, ALautowahStateFactory_getFactory); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_COMPRESSOR, ALcompressorStateFactory_getFactory); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory); diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 1057f3c1..32053325 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -450,13 +450,6 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; SET_VTABLE1(ALreverb, effect); break; - case AL_EFFECT_AUTOWAH: - effect->Props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME; - effect->Props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN; - effect->Props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME; - effect->Props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE; - SET_VTABLE1(ALautowah, effect); - break; case AL_EFFECT_CHORUS: effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM; effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE; diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c index 609cc969..1a559d9c 100644 --- a/OpenAL32/alExtension.c +++ b/OpenAL32/alExtension.c @@ -38,9 +38,6 @@ const struct EffectList EffectList[] = { { "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB }, { "reverb", REVERB, "AL_EFFECT_REVERB", AL_EFFECT_REVERB }, -#if 0 - { "autowah", AUTOWAH, "AL_EFFECT_AUTOWAH", AL_EFFECT_AUTOWAH }, -#endif { "chorus", CHORUS, "AL_EFFECT_CHORUS", AL_EFFECT_CHORUS }, { "compressor", COMPRESSOR, "AL_EFFECT_COMPRESSOR", AL_EFFECT_COMPRESSOR }, { "distortion", DISTORTION, "AL_EFFECT_DISTORTION", AL_EFFECT_DISTORTION }, -- cgit v1.2.3 From d2eb866abeb699394a35610b4764c8e42acc71b5 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 26 Jul 2016 04:54:27 -0700 Subject: Avoid a NULL deref when creating 0 auxiliary effect slots --- OpenAL32/alAuxEffectSlot.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 796eec5b..db084e5a 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -42,7 +42,6 @@ extern inline void UnlockEffectSlotsWrite(ALCcontext *context); extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); -static void AddEffectSlotList(ALCcontext *Context, ALeffectslot *first, ALeffectslot *last); static void RemoveEffectSlotList(ALCcontext *Context, const ALeffectslot *slot); @@ -97,12 +96,19 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo aluInitEffectPanning(slot); if(!first) first = slot; - if(last) ATOMIC_STORE(&last->next, slot); + if(last) ATOMIC_STORE(&last->next, slot, almemory_order_relaxed); last = slot; effectslots[cur] = slot->id; } - AddEffectSlotList(context, first, last); + if(last != NULL) + { + ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList); + do { + ATOMIC_STORE(&last->next, root, almemory_order_relaxed); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList, + &root, first)); + } done: ALCcontext_DecRef(context); @@ -415,15 +421,6 @@ done: } -static void AddEffectSlotList(ALCcontext *context, ALeffectslot *start, ALeffectslot *last) -{ - ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList); - do { - ATOMIC_STORE(&last->next, root, almemory_order_relaxed); - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList, - &root, start)); -} - static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot) { ALCdevice *device = context->Device; -- cgit v1.2.3 From dc8b7814c771d08abe61656b745e7763a010a3a3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 23 Aug 2016 18:56:01 -0700 Subject: Avoid resupplying unneeded source updates The source's voice holds a copy of the last properties it received, so listener updates can make sources recalculate internal properties from that stored copy. --- Alc/ALc.c | 4 +-- Alc/ALu.c | 79 +++++++++++++++++++++++++++++---------------- OpenAL32/Include/alSource.h | 71 +++++++++++++++++++++------------------- OpenAL32/alAuxEffectSlot.c | 2 +- OpenAL32/alListener.c | 18 ----------- OpenAL32/alState.c | 9 ------ 6 files changed, 91 insertions(+), 92 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index dbda46f1..f5965716 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1602,8 +1602,6 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) { ALsizei pos; - UpdateListenerProps(context); - LockUIntMapRead(&context->SourceMap); V0(device->Backend,lock)(); for(pos = 0;pos < context->SourceMap.size;pos++) @@ -1626,6 +1624,8 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) } V0(device->Backend,unlock)(); UnlockUIntMapRead(&context->SourceMap); + + UpdateListenerProps(context); UpdateAllSourceProps(context); } ReadUnlock(&context->PropLock); diff --git a/Alc/ALu.c b/Alc/ALu.c index a9f89de0..115c9c59 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -228,7 +228,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state) } -static void CalcListenerParams(ALCcontext *Context) +static ALboolean CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALfloat N[3], V[3], U[3], P[3]; @@ -237,7 +237,7 @@ static void CalcListenerParams(ALCcontext *Context) aluVector vel; props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel); - if(!props) return; + if(!props) return AL_FALSE; /* AT then UP */ N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); @@ -288,6 +288,8 @@ static void CalcListenerParams(ALCcontext *Context) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, &Listener->FreeList, &first, props) == 0); + + return AL_TRUE; } static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) @@ -1281,7 +1283,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } } -static void CalcSourceParams(ALvoice *voice, ALCcontext *context) +static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force) { ALsource *source = voice->Source; const ALbufferlistitem *BufferListItem; @@ -1289,33 +1291,54 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context) struct ALsourceProps *props; props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); - if(!props) return; - - BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); - while(BufferListItem != NULL) + if(!props) { - const ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) + if(!force) + return; + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) { - if(buffer->FmtChannels == FmtMono) - CalcAttnSourceParams(voice, props, buffer, context); - else - CalcNonAttnSourceParams(voice, props, buffer, context); - break; + const ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + if(buffer->FmtChannels == FmtMono) + CalcAttnSourceParams(voice, &voice->Props, buffer, context); + else + CalcNonAttnSourceParams(voice, &voice->Props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; } - BufferListItem = BufferListItem->next; } - - /* WARNING: A livelock is theoretically possible if another thread keeps - * changing the freelist head without giving this a chance to actually swap - * in the old container (practically impossible with this little code, - * but...). - */ - first = ATOMIC_LOAD(&source->FreeList); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, - &source->FreeList, &first, props) == 0); + else + { + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) + { + const ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + if(buffer->FmtChannels == FmtMono) + CalcAttnSourceParams(voice, props, buffer, context); + else + CalcNonAttnSourceParams(voice, props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; + } + voice->Props = *props; + + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); + } } @@ -1327,7 +1350,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) IncrementRef(&ctx->UpdateCount); if(!ATOMIC_LOAD(&ctx->HoldUpdates)) { - CalcListenerParams(ctx); + ALboolean force = CalcListenerParams(ctx); while(slot) { CalcEffectSlotParams(slot, ctx->Device); @@ -1342,7 +1365,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) if(source->state != AL_PLAYING && source->state != AL_PAUSED) voice->Source = NULL; else - CalcSourceParams(voice, ctx); + CalcSourceParams(voice, ctx, force); } } IncrementRef(&ctx->UpdateCount); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 74987b34..b288937a 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -22,40 +22,6 @@ typedef struct ALbufferlistitem { } ALbufferlistitem; -typedef struct ALvoice { - struct ALsource *volatile Source; - - /** Current target parameters used for mixing. */ - ALint Step; - - /* If not 'moving', gain/coefficients are set directly without fading. */ - ALboolean Moving; - - ALboolean IsHrtf; - - ALuint Offset; /* Number of output samples mixed since starting. */ - - alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; - - BsincState SincState; - - struct { - ALfloat (*Buffer)[BUFFERSIZE]; - ALuint Channels; - } DirectOut; - - struct { - ALfloat (*Buffer)[BUFFERSIZE]; - ALuint Channels; - } SendOut[MAX_SENDS]; - - struct { - DirectParams Direct; - SendParams Send[MAX_SENDS]; - } Chan[MAX_INPUT_CHANNELS]; -} ALvoice; - - struct ALsourceProps { ATOMIC(ALfloat) Pitch; ATOMIC(ALfloat) Gain; @@ -108,6 +74,43 @@ struct ALsourceProps { ATOMIC(struct ALsourceProps*) next; }; + +typedef struct ALvoice { + struct ALsourceProps Props; + + struct ALsource *volatile Source; + + /** Current target parameters used for mixing. */ + ALint Step; + + /* If not 'moving', gain/coefficients are set directly without fading. */ + ALboolean Moving; + + ALboolean IsHrtf; + + ALuint Offset; /* Number of output samples mixed since starting. */ + + alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; + + BsincState SincState; + + struct { + ALfloat (*Buffer)[BUFFERSIZE]; + ALuint Channels; + } DirectOut; + + struct { + ALfloat (*Buffer)[BUFFERSIZE]; + ALuint Channels; + } SendOut[MAX_SENDS]; + + struct { + DirectParams Direct; + SendParams Send[MAX_SENDS]; + } Chan[MAX_INPUT_CHANNELS]; +} ALvoice; + + typedef struct ALsource { /** Source properties. */ ALfloat Pitch; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index db084e5a..50f1e5c5 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -210,7 +210,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param slot->AuxSendAuto = value; UpdateEffectSlotProps(slot); if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateAllSourceProps(context); + UpdateListenerProps(context); break; default: diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index c7f4955a..3ea23732 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -52,10 +52,7 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -93,10 +90,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -149,10 +143,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -174,10 +165,7 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -207,10 +195,7 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -256,10 +241,7 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 443ab884..59814a4b 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -557,10 +557,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) WriteLock(&context->PropLock); context->DopplerFactor = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } WriteUnlock(&context->PropLock); done: @@ -580,10 +577,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) WriteLock(&context->PropLock); context->DopplerVelocity = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } WriteUnlock(&context->PropLock); done: @@ -603,10 +597,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) WriteLock(&context->PropLock); context->SpeedOfSound = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } WriteUnlock(&context->PropLock); done: -- cgit v1.2.3 From 0fbf34fb4592aa29fcbf4e725719cb253e7d3a78 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 25 Aug 2016 03:42:43 -0700 Subject: Add a ref count to ALeffectState This is mostly just reorganizing the effects to call the Construct method which initializes the ref count. --- Alc/effects/chorus.c | 37 ++++--- Alc/effects/compressor.c | 32 +++--- Alc/effects/dedicated.c | 30 ++++-- Alc/effects/distortion.c | 28 ++++-- Alc/effects/echo.c | 40 +++++--- Alc/effects/equalizer.c | 41 +++++--- Alc/effects/flanger.c | 37 ++++--- Alc/effects/modulator.c | 37 ++++--- Alc/effects/null.c | 37 ++++--- Alc/effects/reverb.c | 193 +++++++++++++++++++------------------ OpenAL32/Include/alAuxEffectSlot.h | 2 + OpenAL32/Include/alMain.h | 6 ++ OpenAL32/alAuxEffectSlot.c | 8 ++ 13 files changed, 325 insertions(+), 203 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index 7877ff6f..63d0ca01 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -55,11 +55,34 @@ typedef struct ALchorusState { ALfloat feedback; } ALchorusState; +static ALvoid ALchorusState_Destruct(ALchorusState *state); +static ALboolean ALchorusState_deviceUpdate(ALchorusState *state, ALCdevice *Device); +static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props); +static ALvoid ALchorusState_process(ALchorusState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALchorusState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); + + +static void ALchorusState_Construct(ALchorusState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALchorusState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer[0] = NULL; + state->SampleBuffer[1] = NULL; + state->offset = 0; + state->lfo_range = 1; + state->waveform = CWF_Triangle; +} + static ALvoid ALchorusState_Destruct(ALchorusState *state) { al_free(state->SampleBuffer[0]); state->SampleBuffer[0] = NULL; state->SampleBuffer[1] = NULL; + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } @@ -246,10 +269,6 @@ static ALvoid ALchorusState_process(ALchorusState *state, ALuint SamplesToDo, co } } -DECLARE_DEFAULT_ALLOCATORS(ALchorusState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALchorusState); - typedef struct ALchorusStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -259,16 +278,8 @@ static ALeffectState *ALchorusStateFactory_create(ALchorusStateFactory *UNUSED(f { ALchorusState *state; - state = ALchorusState_New(sizeof(*state)); + NEW_OBJ0(state, ALchorusState)(); if(!state) return NULL; - SET_VTABLE2(ALchorusState, ALeffectState, state); - - state->BufferLength = 0; - state->SampleBuffer[0] = NULL; - state->SampleBuffer[1] = NULL; - state->offset = 0; - state->lfo_range = 1; - state->waveform = CWF_Triangle; return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index 6329d3f1..1426ea70 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -40,6 +40,26 @@ typedef struct ALcompressorState { ALfloat GainCtrl; } ALcompressorState; +static ALvoid ALcompressorState_Destruct(ALcompressorState *state); +static ALboolean ALcompressorState_deviceUpdate(ALcompressorState *state, ALCdevice *device); +static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice *device, const ALeffectslot *slot, const ALeffectProps *props); +static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALcompressorState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALcompressorState); + + +static void ALcompressorState_Construct(ALcompressorState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALcompressorState, ALeffectState, state); + + state->Enabled = AL_TRUE; + state->AttackRate = 0.0f; + state->ReleaseRate = 0.0f; + state->GainCtrl = 1.0f; +} + static ALvoid ALcompressorState_Destruct(ALcompressorState *state) { ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); @@ -165,10 +185,6 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint Samples } } -DECLARE_DEFAULT_ALLOCATORS(ALcompressorState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALcompressorState); - typedef struct ALcompressorStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -178,14 +194,8 @@ static ALeffectState *ALcompressorStateFactory_create(ALcompressorStateFactory * { ALcompressorState *state; - state = ALcompressorState_New(sizeof(*state)); + NEW_OBJ0(state, ALcompressorState)(); if(!state) return NULL; - SET_VTABLE2(ALcompressorState, ALeffectState, state); - - state->Enabled = AL_TRUE; - state->AttackRate = 0.0f; - state->ReleaseRate = 0.0f; - state->GainCtrl = 1.0f; return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 98dd560b..818cbb6b 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -35,6 +35,25 @@ typedef struct ALdedicatedState { ALfloat gains[MAX_OUTPUT_CHANNELS]; } ALdedicatedState; +static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state); +static ALboolean ALdedicatedState_deviceUpdate(ALdedicatedState *state, ALCdevice *device); +static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice *device, const ALeffectslot *Slot, const ALeffectProps *props); +static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALdedicatedState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); + + +static void ALdedicatedState_Construct(ALdedicatedState *state) +{ + ALsizei s; + + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALdedicatedState, ALeffectState, state); + + for(s = 0;s < MAX_OUTPUT_CHANNELS;s++) + state->gains[s] = 0.0f; +} static ALvoid ALdedicatedState_Destruct(ALdedicatedState *state) { @@ -103,10 +122,6 @@ static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALuint SamplesTo } } -DECLARE_DEFAULT_ALLOCATORS(ALdedicatedState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALdedicatedState); - typedef struct ALdedicatedStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -115,14 +130,9 @@ typedef struct ALdedicatedStateFactory { ALeffectState *ALdedicatedStateFactory_create(ALdedicatedStateFactory *UNUSED(factory)) { ALdedicatedState *state; - ALsizei s; - state = ALdedicatedState_New(sizeof(*state)); + NEW_OBJ0(state, ALdedicatedState)(); if(!state) return NULL; - SET_VTABLE2(ALdedicatedState, ALeffectState, state); - - for(s = 0;s < MAX_OUTPUT_CHANNELS;s++) - state->gains[s] = 0.0f; return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index eabf8a5d..bc1e7d84 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -43,6 +43,24 @@ typedef struct ALdistortionState { ALfloat edge_coeff; } ALdistortionState; +static ALvoid ALdistortionState_Destruct(ALdistortionState *state); +static ALboolean ALdistortionState_deviceUpdate(ALdistortionState *state, ALCdevice *device); +static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props); +static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALdistortionState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); + + +static void ALdistortionState_Construct(ALdistortionState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALdistortionState, ALeffectState, state); + + ALfilterState_clear(&state->lowpass); + ALfilterState_clear(&state->bandpass); +} + static ALvoid ALdistortionState_Destruct(ALdistortionState *state) { ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); @@ -161,10 +179,6 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint Samples } } -DECLARE_DEFAULT_ALLOCATORS(ALdistortionState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALdistortionState); - typedef struct ALdistortionStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -174,12 +188,8 @@ static ALeffectState *ALdistortionStateFactory_create(ALdistortionStateFactory * { ALdistortionState *state; - state = ALdistortionState_New(sizeof(*state)); + NEW_OBJ0(state, ALdistortionState)(); if(!state) return NULL; - SET_VTABLE2(ALdistortionState, ALeffectState, state); - - ALfilterState_clear(&state->lowpass); - ALfilterState_clear(&state->bandpass); return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index 4d2fd6f4..3ad1e975 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -50,6 +50,30 @@ typedef struct ALechoState { ALfilterState Filter; } ALechoState; +static ALvoid ALechoState_Destruct(ALechoState *state); +static ALboolean ALechoState_deviceUpdate(ALechoState *state, ALCdevice *Device); +static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props); +static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALechoState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); + + +static void ALechoState_Construct(ALechoState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALechoState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer = NULL; + + state->Tap[0].delay = 0; + state->Tap[1].delay = 0; + state->Offset = 0; + + ALfilterState_clear(&state->Filter); +} + static ALvoid ALechoState_Destruct(ALechoState *state) { al_free(state->SampleBuffer); @@ -184,10 +208,6 @@ static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const state->Offset = offset; } -DECLARE_DEFAULT_ALLOCATORS(ALechoState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALechoState); - typedef struct ALechoStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -197,18 +217,8 @@ ALeffectState *ALechoStateFactory_create(ALechoStateFactory *UNUSED(factory)) { ALechoState *state; - state = ALechoState_New(sizeof(*state)); + NEW_OBJ0(state, ALechoState)(); 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; - - ALfilterState_clear(&state->Filter); return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index 96676d34..2b59cb37 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -87,6 +87,31 @@ typedef struct ALequalizerState { ALfloat SampleBuffer[4][MAX_EFFECT_CHANNELS][MAX_UPDATE_SAMPLES]; } ALequalizerState; +static ALvoid ALequalizerState_Destruct(ALequalizerState *state); +static ALboolean ALequalizerState_deviceUpdate(ALequalizerState *state, ALCdevice *device); +static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice *device, const ALeffectslot *slot, const ALeffectProps *props); +static ALvoid ALequalizerState_process(ALequalizerState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALequalizerState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); + + +static void ALequalizerState_Construct(ALequalizerState *state) +{ + int it, ft; + + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALequalizerState, ALeffectState, state); + + /* Initialize sample history only on filter creation to avoid */ + /* sound clicks if filter settings were changed in runtime. */ + for(it = 0; it < 4; it++) + { + for(ft = 0;ft < MAX_EFFECT_CHANNELS;ft++) + ALfilterState_clear(&state->filter[it][ft]); + } +} + static ALvoid ALequalizerState_Destruct(ALequalizerState *state) { ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); @@ -223,10 +248,6 @@ static ALvoid ALequalizerState_process(ALequalizerState *state, ALuint SamplesTo } } -DECLARE_DEFAULT_ALLOCATORS(ALequalizerState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALequalizerState); - typedef struct ALequalizerStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -235,19 +256,9 @@ typedef struct ALequalizerStateFactory { ALeffectState *ALequalizerStateFactory_create(ALequalizerStateFactory *UNUSED(factory)) { ALequalizerState *state; - int it, ft; - state = ALequalizerState_New(sizeof(*state)); + NEW_OBJ0(state, ALequalizerState)(); if(!state) return NULL; - SET_VTABLE2(ALequalizerState, ALeffectState, state); - - /* Initialize sample history only on filter creation to avoid */ - /* sound clicks if filter settings were changed in runtime. */ - for(it = 0; it < 4; it++) - { - for(ft = 0;ft < MAX_EFFECT_CHANNELS;ft++) - ALfilterState_clear(&state->filter[it][ft]); - } return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c index f18b2b0f..1575212b 100644 --- a/Alc/effects/flanger.c +++ b/Alc/effects/flanger.c @@ -55,11 +55,34 @@ typedef struct ALflangerState { ALfloat feedback; } ALflangerState; +static ALvoid ALflangerState_Destruct(ALflangerState *state); +static ALboolean ALflangerState_deviceUpdate(ALflangerState *state, ALCdevice *Device); +static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props); +static ALvoid ALflangerState_process(ALflangerState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALflangerState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); + + +static void ALflangerState_Construct(ALflangerState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALflangerState, ALeffectState, state); + + state->BufferLength = 0; + state->SampleBuffer[0] = NULL; + state->SampleBuffer[1] = NULL; + state->offset = 0; + state->lfo_range = 1; + state->waveform = FWF_Triangle; +} + static ALvoid ALflangerState_Destruct(ALflangerState *state) { al_free(state->SampleBuffer[0]); state->SampleBuffer[0] = NULL; state->SampleBuffer[1] = NULL; + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); } @@ -246,10 +269,6 @@ static ALvoid ALflangerState_process(ALflangerState *state, ALuint SamplesToDo, } } -DECLARE_DEFAULT_ALLOCATORS(ALflangerState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALflangerState); - typedef struct ALflangerStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -259,16 +278,8 @@ ALeffectState *ALflangerStateFactory_create(ALflangerStateFactory *UNUSED(factor { ALflangerState *state; - state = ALflangerState_New(sizeof(*state)); + NEW_OBJ0(state, ALflangerState)(); if(!state) return NULL; - SET_VTABLE2(ALflangerState, ALeffectState, state); - - state->BufferLength = 0; - state->SampleBuffer[0] = NULL; - state->SampleBuffer[1] = NULL; - state->offset = 0; - state->lfo_range = 1; - state->waveform = FWF_Triangle; return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index 7e3e89b2..08f3d5eb 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -43,6 +43,15 @@ typedef struct ALmodulatorState { ALfilterState Filter[MAX_EFFECT_CHANNELS]; } ALmodulatorState; +static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state); +static ALboolean ALmodulatorState_deviceUpdate(ALmodulatorState *state, ALCdevice *device); +static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props); +static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALmodulatorState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); + + #define WAVEFORM_FRACBITS 24 #define WAVEFORM_FRACONE (1<index = 0; + state->step = 1; + + for(i = 0;i < MAX_EFFECT_CHANNELS;i++) + ALfilterState_clear(&state->Filter[i]); +} + static ALvoid ALmodulatorState_Destruct(ALmodulatorState *state) { ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); @@ -175,10 +198,6 @@ static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALuint SamplesTo state->index = index; } -DECLARE_DEFAULT_ALLOCATORS(ALmodulatorState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALmodulatorState); - typedef struct ALmodulatorStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -187,17 +206,9 @@ typedef struct ALmodulatorStateFactory { static ALeffectState *ALmodulatorStateFactory_create(ALmodulatorStateFactory *UNUSED(factory)) { ALmodulatorState *state; - ALuint i; - state = ALmodulatorState_New(sizeof(*state)); + NEW_OBJ0(state, ALmodulatorState)(); if(!state) return NULL; - SET_VTABLE2(ALmodulatorState, ALeffectState, state); - - state->index = 0; - state->step = 1; - - for(i = 0;i < MAX_EFFECT_CHANNELS;i++) - ALfilterState_clear(&state->Filter[i]); return STATIC_CAST(ALeffectState, state); } diff --git a/Alc/effects/null.c b/Alc/effects/null.c index a135b194..bff00b56 100644 --- a/Alc/effects/null.c +++ b/Alc/effects/null.c @@ -13,6 +13,27 @@ typedef struct ALnullState { DERIVE_FROM_TYPE(ALeffectState); } ALnullState; +/* Forward-declare "virtual" functions to define the vtable with. */ +static ALvoid ALnullState_Destruct(ALnullState *state); +static ALboolean ALnullState_deviceUpdate(ALnullState *state, ALCdevice *device); +static ALvoid ALnullState_update(ALnullState *state, const ALCdevice *device, const ALeffectslot *slot, const ALeffectProps *props); +static ALvoid ALnullState_process(ALnullState *state, ALuint samplesToDo, const ALfloatBUFFERSIZE*restrict samplesIn, ALfloatBUFFERSIZE*restrict samplesOut, ALuint NumChannels); +static void *ALnullState_New(size_t size); +static void ALnullState_Delete(void *ptr); + +/* Define the ALeffectState vtable for this type. */ +DEFINE_ALEFFECTSTATE_VTABLE(ALnullState); + + +/* This constructs the effect state. It's called when the object is first + * created. Make sure to call the parent Construct function first, and set the + * vtable! + */ +static void ALnullState_Construct(ALnullState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALnullState, ALeffectState, state); +} /* This destructs (not free!) the effect state. It's called only when the * effect slot is no longer used. Make sure to call the parent Destruct @@ -48,24 +69,21 @@ static ALvoid ALnullState_process(ALnullState* UNUSED(state), ALuint UNUSED(samp } /* This allocates memory to store the object, before it gets constructed. - * DECLARE_DEFAULT_ALLOCATORS can be used to declate a default method. + * DECLARE_DEFAULT_ALLOCATORS can be used to declare a default method. */ static void *ALnullState_New(size_t size) { - return malloc(size); + return al_malloc(16, size); } /* This frees the memory used by the object, after it has been destructed. - * DECLARE_DEFAULT_ALLOCATORS can be used to declate a default method. + * DECLARE_DEFAULT_ALLOCATORS can be used to declare a default method. */ static void ALnullState_Delete(void *ptr) { - free(ptr); + al_free(ptr); } -/* Define the forwards and the ALeffectState vtable for this type. */ -DEFINE_ALEFFECTSTATE_VTABLE(ALnullState); - typedef struct ALnullStateFactory { DERIVE_FROM_TYPE(ALeffectStateFactory); @@ -76,10 +94,8 @@ ALeffectState *ALnullStateFactory_create(ALnullStateFactory *UNUSED(factory)) { ALnullState *state; - state = ALnullState_New(sizeof(*state)); + NEW_OBJ0(state, ALnullState)(); if(!state) return NULL; - /* Set vtables for inherited types. */ - SET_VTABLE2(ALnullState, ALeffectState, state); return STATIC_CAST(ALeffectState, state); } @@ -90,7 +106,6 @@ DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALnullStateFactory); ALeffectStateFactory *ALnullStateFactory_getFactory(void) { static ALnullStateFactory NullFactory = { { GET_VTABLE2(ALnullStateFactory, ALeffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &NullFactory); } diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index e6a9e05a..0ffff585 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -168,22 +168,112 @@ typedef struct ALreverbState { ALfloat EarlySamples[MAX_UPDATE_SAMPLES][4]; } ALreverbState; -static ALvoid ALreverbState_Destruct(ALreverbState *State) -{ - al_free(State->SampleBuffer); - State->SampleBuffer = NULL; - ALeffectState_Destruct(STATIC_CAST(ALeffectState,State)); -} - +static ALvoid ALreverbState_Destruct(ALreverbState *State); static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Device); static ALvoid ALreverbState_update(ALreverbState *State, const ALCdevice *Device, const ALeffectslot *Slot, const ALeffectProps *props); -static ALvoid ALreverbState_processStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); -static ALvoid ALreverbState_processEax(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); static ALvoid ALreverbState_process(ALreverbState *State, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels); DECLARE_DEFAULT_ALLOCATORS(ALreverbState) DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState); + +static void ALreverbState_Construct(ALreverbState *state) +{ + ALuint index, l; + + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALreverbState, ALeffectState, state); + + state->IsEax = AL_FALSE; + state->ExtraChannels = 0; + + state->TotalSamples = 0; + state->SampleBuffer = NULL; + + ALfilterState_clear(&state->LpFilter); + ALfilterState_clear(&state->HpFilter); + + 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; + + 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->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; + 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; + } + + for(l = 0;l < 4;l++) + { + for(index = 0;index < MAX_OUTPUT_CHANNELS;index++) + { + state->Early.PanGain[l][index] = 0.0f; + state->Late.PanGain[l][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.0f; + + state->Offset = 0; +} + +static ALvoid ALreverbState_Destruct(ALreverbState *State) +{ + al_free(State->SampleBuffer); + State->SampleBuffer = NULL; + + ALeffectState_Destruct(STATIC_CAST(ALeffectState,State)); +} + /* This is a user config option for modifying the overall output of the reverb * effect. */ @@ -1427,92 +1517,9 @@ typedef struct ALreverbStateFactory { static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(factory)) { ALreverbState *state; - ALuint index, l; - state = ALreverbState_New(sizeof(*state)); + NEW_OBJ0(state, ALreverbState)(); if(!state) return NULL; - SET_VTABLE2(ALreverbState, ALeffectState, state); - - state->IsEax = AL_FALSE; - state->ExtraChannels = 0; - - state->TotalSamples = 0; - state->SampleBuffer = NULL; - - ALfilterState_clear(&state->LpFilter); - ALfilterState_clear(&state->HpFilter); - - 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; - - 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->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; - 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; - } - - for(l = 0;l < 4;l++) - { - for(index = 0;index < MAX_OUTPUT_CHANNELS;index++) - { - state->Early.PanGain[l][index] = 0.0f; - state->Late.PanGain[l][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.0f; - - state->Offset = 0; return STATIC_CAST(ALeffectState, state); } diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index d0c7c76c..363d2467 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -14,12 +14,14 @@ struct ALeffectStateVtable; struct ALeffectslot; typedef struct ALeffectState { + RefCount Ref; const struct ALeffectStateVtable *vtbl; ALfloat (*OutBuffer)[BUFFERSIZE]; ALuint OutChannels; } ALeffectState; +void ALeffectState_Construct(ALeffectState *state); void ALeffectState_Destruct(ALeffectState *state); struct ALeffectStateVtable { diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 56bfa0b0..e0e1b835 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -285,6 +285,12 @@ static void T##_Delete(void *ptr) { al_free(ptr); } { \ memset(_res, 0, sizeof(T)); \ T##_Construct(_res, EXTRACT_NEW_ARGS +#define NEW_OBJ0(_res, T) do { \ + _res = T##_New(sizeof(T)); \ + if(_res) \ + { \ + memset(_res, 0, sizeof(T)); \ + T##_Construct(_res EXTRACT_NEW_ARGS #ifdef __cplusplus diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 50f1e5c5..1a20952b 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -523,6 +523,14 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e } +void ALeffectState_Construct(ALeffectState *state) +{ + InitRef(&state->Ref, 1); + + state->OutBuffer = NULL; + state->OutChannels = 0; +} + void ALeffectState_Destruct(ALeffectState *UNUSED(state)) { } -- cgit v1.2.3 From 4e4e597fa54cc3498ae28bea9c2684e1fee05389 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 25 Aug 2016 04:57:58 -0700 Subject: Track all references for effect states This allows us to not have to play around with trying to avoid duplicate state pointers, since the reference count will ensure they're deleted as appropriate. The only caveat is that the mixer is not allowed to decrement references, since that can cause the object to be freed (which the mixer code is not allowed to do). --- Alc/ALu.c | 15 ++++------ OpenAL32/alAuxEffectSlot.c | 68 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 30 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index 80a031fc..d2aa381c 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -319,18 +319,15 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; } - state = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); - /* If the state object is changed, exchange it with the current one so it - * remains in the freelist and isn't leaked. + /* Swap effect states. No need to play with the ref counts since they keep + * the same number of refs. */ - if(state != slot->Params.EffectState) - { - ATOMIC_STORE(&props->State, slot->Params.EffectState, almemory_order_relaxed); - slot->Params.EffectState = state; - } + state = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Params.EffectState, + almemory_order_relaxed); + slot->Params.EffectState = state; - V(slot->Params.EffectState,update)(device, slot, &props->Props); + V(state,update)(device, slot, &props->Props); /* WARNING: A livelock is theoretically possible if another thread keeps * changing the freelist head without giving this a chance to actually swap diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 1a20952b..85be5c6d 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -44,7 +44,6 @@ extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint static void RemoveEffectSlotList(ALCcontext *Context, const ALeffectslot *slot); - static UIntMap EffectStateFactoryMap; static inline ALeffectStateFactory *getFactoryByType(ALenum type) { @@ -54,6 +53,9 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) return NULL; } +static void ALeffectState_IncRef(ALeffectState *state); +static void ALeffectState_DecRef(ALeffectState *state); + AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { @@ -86,7 +88,9 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(err != AL_NO_ERROR) { FreeThunkEntry(slot->id); - DELETE_OBJ(slot->Params.EffectState); + ALeffectState_DecRef(slot->Effect.State); + if(slot->Params.EffectState) + ALeffectState_DecRef(slot->Params.EffectState); al_free(slot); alDeleteAuxiliaryEffectSlots(cur, effectslots); @@ -469,11 +473,12 @@ void DeinitEffectFactoryMap(void) ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); - ALeffectStateFactory *factory; + struct ALeffectslotProps *props; + ALeffectState *State; if(newtype != EffectSlot->Effect.Type) { - ALeffectState *State; + ALeffectStateFactory *factory; FPUCtl oldMode; factory = getFactoryByType(newtype); @@ -493,7 +498,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e { almtx_unlock(&Device->BackendLock); RestoreFPUMode(&oldMode); - DELETE_OBJ(State); + ALeffectState_DecRef(State); return AL_OUT_OF_MEMORY; } almtx_unlock(&Device->BackendLock); @@ -510,6 +515,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e EffectSlot->Effect.Props = effect->Props; } + ALeffectState_DecRef(EffectSlot->Effect.State); EffectSlot->Effect.State = State; UpdateEffectSlotProps(EffectSlot); } @@ -519,10 +525,35 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e UpdateEffectSlotProps(EffectSlot); } + /* Remove state references from old effect slot property updates. */ + props = ATOMIC_LOAD(&EffectSlot->FreeList); + while(props) + { + State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); + if(State) ALeffectState_DecRef(State); + ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } + return AL_NO_ERROR; } +static void ALeffectState_IncRef(ALeffectState *state) +{ + uint ref; + ref = IncrementRef(&state->Ref); + TRACEREF("%p increasing refcount to %u\n", state, ref); +} + +static void ALeffectState_DecRef(ALeffectState *state) +{ + uint ref; + ref = DecrementRef(&state->Ref); + TRACEREF("%p decreasing refcount to %u\n", state, ref); + if(ref == 0) DELETE_OBJ(state); +} + + void ALeffectState_Construct(ALeffectState *state) { InitRef(&state->Ref, 1); @@ -555,6 +586,7 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.Gain = 1.0f; slot->Params.AuxSendAuto = AL_TRUE; + ALeffectState_IncRef(slot->Effect.State); slot->Params.EffectState = slot->Effect.State; slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; @@ -575,8 +607,7 @@ void DeinitEffectSlot(ALeffectslot *slot) if(props) { state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); - if(state != slot->Params.EffectState) - DELETE_OBJ(state); + if(state) ALeffectState_DecRef(state); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } @@ -586,14 +617,16 @@ void DeinitEffectSlot(ALeffectslot *slot) struct ALeffectslotProps *next; state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - DELETE_OBJ(state); + if(state) ALeffectState_DecRef(state); al_free(props); props = next; ++count; } TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); - DELETE_OBJ(slot->Params.EffectState); + ALeffectState_DecRef(slot->Effect.State); + if(slot->Params.EffectState) + ALeffectState_DecRef(slot->Params.EffectState); } void UpdateEffectSlotProps(ALeffectslot *slot) @@ -602,17 +635,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) ALeffectState *oldstate; props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL); - if(props) - { - /* If there was an unapplied update, check if its state object is the - * same as the current in-use one, or the one that will be set. If - * neither, delete it. - */ - oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); - if(oldstate != slot->Params.EffectState && oldstate != slot->Effect.State) - DELETE_OBJ(oldstate); - } - else + if(!props) { /* Get an unused property container, or allocate a new one as needed. */ props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); @@ -638,6 +661,8 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* Swap out any stale effect state object there may be in the container, to * delete it. */ + if(slot->Effect.State) + ALeffectState_IncRef(slot->Effect.State); oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, almemory_order_relaxed); @@ -656,7 +681,8 @@ void UpdateEffectSlotProps(ALeffectslot *slot) &slot->FreeList, &first, props) == 0); } - DELETE_OBJ(oldstate); + if(oldstate) + ALeffectState_DecRef(oldstate); } ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) -- cgit v1.2.3 From a16739f7651afb7653387b1e79b2985058d76e90 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 25 Aug 2016 06:17:36 -0700 Subject: Properly defer effect slot changes Note that this now also causes all playing sources to update when an effect slot is updated. This is a bit wasteful, as it should only need to re-update sources that are using the effect slot (and only when a relevant property is changed), but it's good enough. Especially with deferring since all playing sources are going to get updated on the process call anyway. --- Alc/ALc.c | 1 + Alc/ALu.c | 8 +++++--- OpenAL32/Include/alAuxEffectSlot.h | 3 +++ OpenAL32/alAuxEffectSlot.c | 39 +++++++++++++++++++++++++++----------- 4 files changed, 37 insertions(+), 14 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 15614dd1..b95c90f8 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1611,6 +1611,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) althrd_yield(); UpdateListenerProps(context); + UpdateAllEffectSlotProps(context); LockUIntMapRead(&context->SourceMap); V0(device->Backend,lock)(); diff --git a/Alc/ALu.c b/Alc/ALu.c index d2aa381c..eafb082c 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -295,14 +295,14 @@ static ALboolean CalcListenerParams(ALCcontext *Context) return AL_TRUE; } -static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) +static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { struct ALeffectslotProps *first; struct ALeffectslotProps *props; ALeffectState *state; props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); - if(!props) return; + if(!props) return AL_FALSE; slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); @@ -339,6 +339,8 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, &slot->FreeList, &first, props) == 0); + + return AL_TRUE; } @@ -1339,7 +1341,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) ALboolean force = CalcListenerParams(ctx); while(slot) { - CalcEffectSlotParams(slot, ctx->Device); + force |= CalcEffectSlotParams(slot, ctx->Device); slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 363d2467..70fcac5c 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -88,6 +88,8 @@ struct ALeffectslotProps { typedef struct ALeffectslot { + ALboolean NeedsUpdate; + ALfloat Gain; ALboolean AuxSendAuto; @@ -152,6 +154,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); void UpdateEffectSlotProps(ALeffectslot *slot); +void UpdateAllEffectSlotProps(ALCcontext *context); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 85be5c6d..fb8c27f4 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -56,6 +56,13 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) static void ALeffectState_IncRef(ALeffectState *state); static void ALeffectState_DecRef(ALeffectState *state); +#define DO_UPDATEPROPS() do { \ + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ + UpdateEffectSlotProps(slot); \ + else \ + slot->NeedsUpdate = AL_TRUE; \ +} while(0) + AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { @@ -212,14 +219,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!(value == AL_TRUE || value == AL_FALSE)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; - UpdateEffectSlotProps(slot); - if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); break; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } + DO_UPDATEPROPS(); done: UnlockEffectSlotsRead(context); @@ -279,7 +284,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateEffectSlotProps(slot); + DO_UPDATEPROPS(); done: UnlockEffectSlotsRead(context); @@ -517,13 +522,9 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALeffectState_DecRef(EffectSlot->Effect.State); EffectSlot->Effect.State = State; - UpdateEffectSlotProps(EffectSlot); } else if(effect) - { EffectSlot->Effect.Props = effect->Props; - UpdateEffectSlotProps(EffectSlot); - } /* Remove state references from old effect slot property updates. */ props = ATOMIC_LOAD(&EffectSlot->FreeList); @@ -531,7 +532,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e { State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); if(State) ALeffectState_DecRef(State); - ATOMIC_LOAD(&props->next, almemory_order_relaxed); + props = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } return AL_NO_ERROR; @@ -577,6 +578,7 @@ ALenum InitEffectSlot(ALeffectslot *slot) if(!(slot->Effect.State=V0(factory,create)())) return AL_OUT_OF_MEMORY; + slot->NeedsUpdate = AL_FALSE; slot->Gain = 1.0; slot->AuxSendAuto = AL_TRUE; InitRef(&slot->ref, 0); @@ -661,8 +663,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* Swap out any stale effect state object there may be in the container, to * delete it. */ - if(slot->Effect.State) - ALeffectState_IncRef(slot->Effect.State); + ALeffectState_IncRef(slot->Effect.State); oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, almemory_order_relaxed); @@ -685,6 +686,22 @@ void UpdateEffectSlotProps(ALeffectslot *slot) ALeffectState_DecRef(oldstate); } +void UpdateAllEffectSlotProps(ALCcontext *context) +{ + ALeffectslot *slot; + + LockEffectSlotsRead(context); + slot = ATOMIC_LOAD(&context->ActiveAuxSlotList); + while(slot) + { + if(slot->NeedsUpdate) + UpdateEffectSlotProps(slot); + slot->NeedsUpdate = AL_FALSE; + slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + } + UnlockEffectSlotsRead(context); +} + ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) { ALsizei pos; -- cgit v1.2.3 From ef03de39814486a1d91949cfff8b6a33bd137f91 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 25 Aug 2016 18:19:13 -0700 Subject: Avoid directly replacing the effect slot Update pointer --- OpenAL32/alAuxEffectSlot.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index fb8c27f4..479646b1 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -636,22 +636,18 @@ void UpdateEffectSlotProps(ALeffectslot *slot) struct ALeffectslotProps *props; ALeffectState *oldstate; - props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL); + /* Get an unused property container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); if(!props) + props = al_calloc(16, sizeof(*props)); + else { - /* Get an unused property container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); - if(!props) - props = al_calloc(16, sizeof(*props)); - else - { - struct ALeffectslotProps *next; - do { - next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, - &slot->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_consume) == 0); - } + struct ALeffectslotProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + &slot->FreeList, &props, next, almemory_order_seq_cst, + almemory_order_consume) == 0); } /* Copy in current property values. */ -- cgit v1.2.3 From 6fb634c3e12fffca56aed9417a1c8233c67839ed Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 31 Aug 2016 09:26:57 -0700 Subject: Remove unnecessary consts They were causing GCC's built-in atomic cmpxchg to complain. --- OpenAL32/alAuxEffectSlot.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 479646b1..b860b2b0 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -42,7 +42,7 @@ extern inline void UnlockEffectSlotsWrite(ALCcontext *context); extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); -static void RemoveEffectSlotList(ALCcontext *Context, const ALeffectslot *slot); +static void RemoveEffectSlotList(ALCcontext *Context, ALeffectslot *slot); static UIntMap EffectStateFactoryMap; static inline ALeffectStateFactory *getFactoryByType(ALenum type) @@ -430,16 +430,16 @@ done: } -static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot) +static void RemoveEffectSlotList(ALCcontext *context, ALeffectslot *slot) { ALCdevice *device = context->Device; - const ALeffectslot *root, *next; + ALeffectslot *root, *next; root = slot; next = ATOMIC_LOAD(&slot->next); if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) { - const ALeffectslot *cur; + ALeffectslot *cur; do { cur = root; root = slot; -- cgit v1.2.3 From a502a41be340826585f9c91b3a8d9a52b5601b54 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 17 Nov 2016 00:46:46 -0800 Subject: Stop using almemory_order_consume --- Alc/ALc.c | 4 ++-- OpenAL32/alAuxEffectSlot.c | 2 +- OpenAL32/alListener.c | 2 +- OpenAL32/alSource.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 7e220205..8c855157 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2377,10 +2377,10 @@ static void FreeContext(ALCcontext *context) al_free(lprops); } count = 0; - lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_consume); + lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire); while(lprops) { - struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_consume); + struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire); al_free(lprops); lprops = next; ++count; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index b860b2b0..4f1601ed 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -647,7 +647,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, &slot->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_consume) == 0); + almemory_order_acquire) == 0); } /* Copy in current property values. */ diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 08ece19d..4e99f24e 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -470,7 +470,7 @@ void UpdateListenerProps(ALCcontext *context) next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, &listener->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_consume) == 0); + almemory_order_acquire) == 0); } /* Copy in current property values. */ diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index f20498f4..7f187dfe 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2829,7 +2829,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, &source->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_consume) == 0); + almemory_order_acquire) == 0); } /* Copy in current property values. */ -- cgit v1.2.3 From 8f581c0e66e52a6f24e85763b39ed3be29a3e792 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 20 Dec 2016 20:49:37 -0800 Subject: Use separate macros for atomics that don't take a memory order --- Alc/ALc.c | 70 +++++++++++++++++----------------- Alc/ALu.c | 14 +++---- Alc/helpers.c | 8 ++-- Alc/mixer.c | 4 +- OpenAL32/alAuxEffectSlot.c | 22 +++++------ OpenAL32/alBuffer.c | 18 ++++----- OpenAL32/alError.c | 4 +- OpenAL32/alListener.c | 4 +- OpenAL32/alSource.c | 61 +++++++++++++++-------------- OpenAL32/alThunk.c | 8 ++-- include/atomic.h | 95 ++++++++++++++++++++++++---------------------- 11 files changed, 159 insertions(+), 149 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 2e7c1e7f..95d5e178 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1173,7 +1173,7 @@ static void alc_cleanup(void) free(alcCaptureDefaultDeviceSpecifier); alcCaptureDefaultDeviceSpecifier = NULL; - if((dev=ATOMIC_EXCHANGE(ALCdevice*, &DeviceList, NULL)) != NULL) + if((dev=ATOMIC_EXCHANGE_SEQ(ALCdevice*, &DeviceList, NULL)) != NULL) { ALCuint num = 0; do { @@ -1587,7 +1587,7 @@ extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS */ void ALCcontext_DeferUpdates(ALCcontext *context, ALenum type) { - ATOMIC_STORE(&context->DeferUpdates, type); + ATOMIC_STORE_SEQ(&context->DeferUpdates, type); } /* ALCcontext_ProcessUpdates @@ -1599,7 +1599,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) ALCdevice *device = context->Device; ReadLock(&context->PropLock); - if(ATOMIC_EXCHANGE(ALenum, &context->DeferUpdates, AL_FALSE)) + if(ATOMIC_EXCHANGE_SEQ(ALenum, &context->DeferUpdates, AL_FALSE)) { ALsizei pos; uint updates; @@ -1607,7 +1607,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) /* Tell the mixer to stop applying updates, then wait for any active * updating to finish, before providing updates. */ - ATOMIC_STORE(&context->HoldUpdates, AL_TRUE); + ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_TRUE); while(((updates=ReadRef(&context->UpdateCount))&1) != 0) althrd_yield(); @@ -1642,7 +1642,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) /* Now with all updates declared, let the mixer continue applying them * so they all happen at once. */ - ATOMIC_STORE(&context->HoldUpdates, AL_FALSE); + ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE); } ReadUnlock(&context->PropLock); } @@ -1666,9 +1666,9 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode) } if(device) - ATOMIC_STORE(&device->LastError, errorCode); + ATOMIC_STORE_SEQ(&device->LastError, errorCode); else - ATOMIC_STORE(&LastNullDeviceError, errorCode); + ATOMIC_STORE_SEQ(&LastNullDeviceError, errorCode); } @@ -2098,7 +2098,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) UpdateEffectSlotProps(slot); } - context = ATOMIC_LOAD(&device->ContextList); + context = ATOMIC_LOAD_SEQ(&device->ContextList); while(context) { ALsizei pos; @@ -2260,7 +2260,7 @@ static ALCboolean VerifyDevice(ALCdevice **device) ALCdevice *tmpDevice; LockLists(); - tmpDevice = ATOMIC_LOAD(&DeviceList); + tmpDevice = ATOMIC_LOAD_SEQ(&DeviceList); while(tmpDevice) { if(tmpDevice == *device) @@ -2413,12 +2413,13 @@ static void ReleaseContext(ALCcontext *context, ALCdevice *device) } origctx = context; - if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &GlobalContext, &origctx, NULL)) + if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &GlobalContext, &origctx, NULL)) ALCcontext_DecRef(context); ALCdevice_Lock(device); origctx = context; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCcontext*, &device->ContextList, &origctx, context->next)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &device->ContextList, + &origctx, context->next)) { ALCcontext *volatile*list = &origctx->next; while(*list) @@ -2466,10 +2467,10 @@ static ALCboolean VerifyContext(ALCcontext **context) ALCdevice *dev; LockLists(); - dev = ATOMIC_LOAD(&DeviceList); + dev = ATOMIC_LOAD_SEQ(&DeviceList); while(dev) { - ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList); + ALCcontext *ctx = ATOMIC_LOAD(&dev->ContextList, almemory_order_acquire); while(ctx) { if(ctx == *context) @@ -2504,7 +2505,7 @@ ALCcontext *GetContextRef(void) else { LockLists(); - context = ATOMIC_LOAD(&GlobalContext); + context = ATOMIC_LOAD_SEQ(&GlobalContext); if(context) ALCcontext_IncRef(context); UnlockLists(); @@ -2528,11 +2529,11 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) if(VerifyDevice(&device)) { - errorCode = ATOMIC_EXCHANGE(ALCenum, &device->LastError, ALC_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &device->LastError, ALC_NO_ERROR); ALCdevice_DecRef(device); } else - errorCode = ATOMIC_EXCHANGE(ALCenum, &LastNullDeviceError, ALC_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &LastNullDeviceError, ALC_NO_ERROR); return errorCode; } @@ -3178,7 +3179,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin almtx_lock(&device->BackendLock); UnlockLists(); - ATOMIC_STORE(&device->LastError, ALC_NO_ERROR); + ATOMIC_STORE_SEQ(&device->LastError, ALC_NO_ERROR); ALContext = al_calloc(16, sizeof(ALCcontext)+sizeof(ALlistener)); if(ALContext) @@ -3251,10 +3252,11 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin UpdateListenerProps(ALContext); { - ALCcontext *head = ATOMIC_LOAD(&device->ContextList); + ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList); do { ALContext->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCcontext*, &device->ContextList, &head, ALContext)); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext*, + &device->ContextList, &head, ALContext) == 0); } almtx_unlock(&device->BackendLock); @@ -3279,7 +3281,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) { almtx_lock(&Device->BackendLock); ReleaseContext(context, Device); - if(!ATOMIC_LOAD(&Device->ContextList)) + if(!ATOMIC_LOAD_SEQ(&Device->ContextList)) { V0(Device->Backend,stop)(); Device->Flags &= ~DEVICE_RUNNING; @@ -3297,7 +3299,7 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context) ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) { ALCcontext *Context = altss_get(LocalContext); - if(!Context) Context = ATOMIC_LOAD(&GlobalContext); + if(!Context) Context = ATOMIC_LOAD_SEQ(&GlobalContext); return Context; } @@ -3325,7 +3327,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) return ALC_FALSE; } /* context's reference count is already incremented */ - context = ATOMIC_EXCHANGE(ALCcontext*, &GlobalContext, context); + context = ATOMIC_EXCHANGE_SEQ(ALCcontext*, &GlobalContext, context); if(context) ALCcontext_DecRef(context); if((context=altss_get(LocalContext)) != NULL) @@ -3606,10 +3608,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) } { - ALCdevice *head = ATOMIC_LOAD(&DeviceList); + ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); } TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName)); @@ -3626,7 +3628,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) ALCcontext *ctx; LockLists(); - iter = ATOMIC_LOAD(&DeviceList); + iter = ATOMIC_LOAD_SEQ(&DeviceList); do { if(iter == device) break; @@ -3640,7 +3642,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) almtx_lock(&device->BackendLock); origdev = device; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, device->next)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next)) { ALCdevice *volatile*list = &origdev->next; while(*list) @@ -3655,7 +3657,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) } UnlockLists(); - ctx = ATOMIC_LOAD(&device->ContextList); + ctx = ATOMIC_LOAD_SEQ(&device->ContextList); while(ctx != NULL) { ALCcontext *next = ctx->next; @@ -3766,10 +3768,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, almtx_init(&device->BackendLock, almtx_plain); { - ALCdevice *head = ATOMIC_LOAD(&DeviceList); + ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); } TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName)); @@ -3781,7 +3783,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) ALCdevice *iter, *origdev; LockLists(); - iter = ATOMIC_LOAD(&DeviceList); + iter = ATOMIC_LOAD_SEQ(&DeviceList); do { if(iter == device) break; @@ -3794,7 +3796,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) } origdev = device; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALCdevice*, &DeviceList, &origdev, device->next)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next)) { ALCdevice *volatile*list = &origdev->next; while(*list) @@ -3973,10 +3975,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN V(device->Backend,open)("Loopback"); { - ALCdevice *head = ATOMIC_LOAD(&DeviceList); + ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); } TRACE("Created device %p\n", device); @@ -4062,7 +4064,7 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) if((device->Flags&DEVICE_PAUSED)) { device->Flags &= ~DEVICE_PAUSED; - if(ATOMIC_LOAD(&device->ContextList) != NULL) + if(ATOMIC_LOAD_SEQ(&device->ContextList) != NULL) { if(V0(device->Backend,start)() != ALC_FALSE) device->Flags |= DEVICE_RUNNING; diff --git a/Alc/ALu.c b/Alc/ALu.c index b90a3983..db032057 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1347,7 +1347,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) ALsource *source; IncrementRef(&ctx->UpdateCount); - if(!ATOMIC_LOAD(&ctx->HoldUpdates)) + if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire)) { ALboolean force = CalcListenerParams(ctx); while(slot) @@ -1461,12 +1461,12 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); } - ctx = ATOMIC_LOAD(&device->ContextList); + ctx = ATOMIC_LOAD(&device->ContextList, almemory_order_acquire); while(ctx) { ALeffectslot *slotroot; - slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList); + slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList, almemory_order_acquire); UpdateContextSources(ctx, slotroot); slot = slotroot; @@ -1631,7 +1631,7 @@ ALvoid aluHandleDisconnect(ALCdevice *device) device->Connected = ALC_FALSE; - Context = ATOMIC_LOAD(&device->ContextList); + Context = ATOMIC_LOAD_SEQ(&device->ContextList); while(Context) { ALvoice *voice, *voice_end; @@ -1646,9 +1646,9 @@ ALvoid aluHandleDisconnect(ALCdevice *device) if(source && source->state == AL_PLAYING) { source->state = AL_STOPPED; - ATOMIC_STORE(&source->current_buffer, NULL); - ATOMIC_STORE(&source->position, 0); - ATOMIC_STORE(&source->position_fraction, 0); + ATOMIC_STORE(&source->current_buffer, NULL, almemory_order_relaxed); + ATOMIC_STORE(&source->position, 0, almemory_order_relaxed); + ATOMIC_STORE(&source->position_fraction, 0, almemory_order_release); } voice++; diff --git a/Alc/helpers.c b/Alc/helpers.c index 0a6982e9..ef0c8e88 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -558,7 +558,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) vector_al_string results = VECTOR_INIT_STATIC(); size_t i; - while(ATOMIC_EXCHANGE(uint, &search_lock, 1) == 1) + while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1) althrd_yield(); /* If the path is absolute, use it directly. */ @@ -629,7 +629,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) al_string_deinit(&path); } - ATOMIC_STORE(&search_lock, 0); + ATOMIC_STORE_SEQ(&search_lock, 0); return results; } @@ -834,7 +834,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) static RefCount search_lock; vector_al_string results = VECTOR_INIT_STATIC(); - while(ATOMIC_EXCHANGE(uint, &search_lock, 1) == 1) + while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1) althrd_yield(); if(subdir[0] == '/') @@ -903,7 +903,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) al_string_deinit(&path); } - ATOMIC_STORE(&search_lock, 0); + ATOMIC_STORE_SEQ(&search_lock, 0); return results; } diff --git a/Alc/mixer.c b/Alc/mixer.c index dba429a0..be6a137c 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -532,7 +532,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } tmpiter = tmpiter->next; if(!tmpiter && Looping) - tmpiter = ATOMIC_LOAD(&Source->queue); + tmpiter = ATOMIC_LOAD(&Source->queue, almemory_order_acquire); else if(!tmpiter) { SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize); @@ -675,7 +675,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam if(!(BufferListItem=BufferListItem->next)) { if(Looping) - BufferListItem = ATOMIC_LOAD(&Source->queue); + BufferListItem = ATOMIC_LOAD(&Source->queue, almemory_order_acquire); else { State = AL_STOPPED; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 4f1601ed..a7bc0f32 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -114,11 +114,11 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo } if(last != NULL) { - ALeffectslot *root = ATOMIC_LOAD(&context->ActiveAuxSlotList); + ALeffectslot *root = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); do { ATOMIC_STORE(&last->next, root, almemory_order_relaxed); - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK(ALeffectslot*, &context->ActiveAuxSlotList, - &root, first)); + } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALeffectslot*, &context->ActiveAuxSlotList, + &root, first)); } done: @@ -436,14 +436,14 @@ static void RemoveEffectSlotList(ALCcontext *context, ALeffectslot *slot) ALeffectslot *root, *next; root = slot; - next = ATOMIC_LOAD(&slot->next); - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) + next = ATOMIC_LOAD_SEQ(&slot->next); + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) { ALeffectslot *cur; do { cur = root; root = slot; - } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next)); + } while(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALeffectslot*, &cur->next, &root, next)); } /* Wait for any mix that may be using these effect slots to finish. */ while((ReadRef(&device->MixCount)&1) != 0) @@ -527,7 +527,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e EffectSlot->Effect.Props = effect->Props; /* Remove state references from old effect slot property updates. */ - props = ATOMIC_LOAD(&EffectSlot->FreeList); + props = ATOMIC_LOAD_SEQ(&EffectSlot->FreeList); while(props) { State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); @@ -605,7 +605,7 @@ void DeinitEffectSlot(ALeffectslot *slot) ALeffectState *state; size_t count = 0; - props = ATOMIC_LOAD(&slot->Update); + props = ATOMIC_LOAD_SEQ(&slot->Update); if(props) { state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); @@ -671,10 +671,10 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* If there was an unused update container, put it back in the * freelist. */ - struct ALeffectslotProps *first = ATOMIC_LOAD(&slot->FreeList); + struct ALeffectslotProps *first = ATOMIC_LOAD_SEQ(&slot->FreeList); do { ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, + } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALeffectslotProps*, &slot->FreeList, &first, props) == 0); } @@ -687,7 +687,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context) ALeffectslot *slot; LockEffectSlotsRead(context); - slot = ATOMIC_LOAD(&context->ActiveAuxSlotList); + slot = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); while(slot) { if(slot->NeedsUpdate) diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 193cfeaa..24470d64 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -161,7 +161,7 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoi if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(srctype, &align) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); switch(srctype) @@ -311,7 +311,7 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); WriteLock(&albuf->lock); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(srctype, &align) == AL_FALSE) { WriteUnlock(&albuf->lock); @@ -390,7 +390,7 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if((samples%align) != 0) @@ -428,7 +428,7 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); WriteLock(&albuf->lock); - align = ATOMIC_LOAD(&albuf->UnpackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) { WriteUnlock(&albuf->lock); @@ -483,7 +483,7 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); ReadLock(&albuf->lock); - align = ATOMIC_LOAD(&albuf->PackAlign); + align = ATOMIC_LOAD_SEQ(&albuf->PackAlign); if(SanitizeAlignment(type, &align) == AL_FALSE) { ReadUnlock(&albuf->lock); @@ -630,13 +630,13 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ATOMIC_STORE(&albuf->UnpackAlign, value); + ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - ATOMIC_STORE(&albuf->PackAlign, value); + ATOMIC_STORE_SEQ(&albuf->PackAlign, value); break; default: @@ -878,11 +878,11 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value break; case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: - *value = ATOMIC_LOAD(&albuf->UnpackAlign); + *value = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: - *value = ATOMIC_LOAD(&albuf->PackAlign); + *value = ATOMIC_LOAD_SEQ(&albuf->PackAlign); break; default: diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c index b38d8dfe..6b7684ce 100644 --- a/OpenAL32/alError.c +++ b/OpenAL32/alError.c @@ -46,7 +46,7 @@ ALvoid alSetError(ALCcontext *Context, ALenum errorCode) raise(SIGTRAP); #endif } - ATOMIC_COMPARE_EXCHANGE_STRONG(ALenum, &Context->LastError, &curerr, errorCode); + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Context->LastError, &curerr, errorCode); } AL_API ALenum AL_APIENTRY alGetError(void) @@ -69,7 +69,7 @@ AL_API ALenum AL_APIENTRY alGetError(void) return AL_INVALID_OPERATION; } - errorCode = ATOMIC_EXCHANGE(ALenum, &Context->LastError, AL_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(ALenum, &Context->LastError, AL_NO_ERROR); ALCcontext_DecRef(Context); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 4e99f24e..f05c20d1 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -506,10 +506,10 @@ void UpdateListenerProps(ALCcontext *context) /* If there was an unused update container, put it back in the * freelist. */ - struct ALlistenerProps *first = ATOMIC_LOAD(&listener->FreeList); + struct ALlistenerProps *first = ATOMIC_LOAD_SEQ(&listener->FreeList); do { ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, + } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALlistenerProps*, &listener->FreeList, &first, props) == 0); } } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 81cd44cd..9f60c545 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -658,7 +658,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); WriteLock(&Source->queue_lock); - ATOMIC_STORE(&Source->looping, *values); + ATOMIC_STORE_SEQ(&Source->looping, *values); WriteUnlock(&Source->queue_lock); return AL_TRUE; @@ -700,8 +700,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->SourceType = AL_UNDETERMINED; newlist = NULL; } - oldlist = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, newlist); - ATOMIC_STORE(&Source->current_buffer, newlist); + oldlist = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &Source->queue, newlist); + ATOMIC_STORE_SEQ(&Source->current_buffer, newlist); WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -1097,7 +1097,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1214,13 +1214,14 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_LOOPING: - *values = ATOMIC_LOAD(&Source->looping); + *values = ATOMIC_LOAD_SEQ(&Source->looping); return AL_TRUE; case AL_BUFFER: ReadLock(&Source->queue_lock); - BufferList = (Source->SourceType == AL_STATIC) ? ATOMIC_LOAD(&Source->queue) : - ATOMIC_LOAD(&Source->current_buffer); + BufferList = (Source->SourceType == AL_STATIC) ? + ATOMIC_LOAD_SEQ(&Source->queue) : + ATOMIC_LOAD_SEQ(&Source->current_buffer); *values = (BufferList && BufferList->buffer) ? BufferList->buffer->id : 0; ReadUnlock(&Source->queue_lock); return AL_TRUE; @@ -1231,7 +1232,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1270,7 +1271,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SAMPLE_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1286,7 +1287,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_QUEUED: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) + if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) *values = 0; else { @@ -1301,7 +1302,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_PROCESSED: ReadLock(&Source->queue_lock); - if(ATOMIC_LOAD(&Source->looping) || Source->SourceType != AL_STREAMING) + if(ATOMIC_LOAD_SEQ(&Source->looping) || Source->SourceType != AL_STREAMING) { /* Buffers on a looping source are in a perpetual state of * PENDING, so don't report any as PROCESSED */ @@ -1309,8 +1310,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } else { - const ALbufferlistitem *BufferList = ATOMIC_LOAD(&Source->queue); - const ALbufferlistitem *Current = ATOMIC_LOAD(&Source->current_buffer); + const ALbufferlistitem *BufferList = ATOMIC_LOAD_SEQ(&Source->queue); + const ALbufferlistitem *Current = ATOMIC_LOAD_SEQ(&Source->current_buffer); ALsizei played = 0; while(BufferList && BufferList != Current) { @@ -2499,7 +2500,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu } /* Check for a valid Buffer, for its frequency and format */ - BufferList = ATOMIC_LOAD(&source->queue); + BufferList = ATOMIC_LOAD_SEQ(&source->queue); while(BufferList) { if(BufferList->buffer) @@ -2588,7 +2589,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu source->SourceType = AL_STREAMING; BufferList = NULL; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->queue, &BufferList, BufferListStart)) + if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->queue, + &BufferList, BufferListStart)) { /* Queue head is not NULL, append to the end of the queue */ while(BufferList->next != NULL) @@ -2599,7 +2601,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu * buffers. */ BufferList = NULL; - ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->current_buffer, &BufferList, BufferListStart); + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->current_buffer, + &BufferList, BufferListStart); WriteUnlock(&source->queue_lock); done: @@ -2630,7 +2633,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); WriteLock(&source->queue_lock); - if(ATOMIC_LOAD(&source->looping) || source->SourceType != AL_STREAMING) + if(ATOMIC_LOAD_SEQ(&source->looping) || source->SourceType != AL_STREAMING) { WriteUnlock(&source->queue_lock); /* Trying to unqueue buffers on a looping or non-streaming source. */ @@ -2638,8 +2641,8 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Find the new buffer queue head */ - OldTail = ATOMIC_LOAD(&source->queue); - Current = ATOMIC_LOAD(&source->current_buffer); + OldTail = ATOMIC_LOAD_SEQ(&source->queue); + Current = ATOMIC_LOAD_SEQ(&source->current_buffer); if(OldTail != Current) { for(i = 1;i < nb;i++) @@ -2657,7 +2660,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Swap it, and cut the new head from the old. */ - OldHead = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, OldTail->next); + OldHead = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, OldTail->next); if(OldTail->next) { ALCdevice *device = context->Device; @@ -2788,7 +2791,7 @@ static void DeinitSource(ALsource *source) size_t count = 0; size_t i; - props = ATOMIC_LOAD(&source->Update); + props = ATOMIC_LOAD_SEQ(&source->Update); if(props) al_free(props); props = ATOMIC_LOAD(&source->FreeList, almemory_order_relaxed); @@ -2806,7 +2809,7 @@ static void DeinitSource(ALsource *source) if(count > 3) WARN("Freed "SZFMT" Source property objects\n", count); - BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NULL); + BufferList = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, NULL); while(BufferList != NULL) { ALbufferlistitem *next = BufferList->next; @@ -2910,7 +2913,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) /* If there was an unused update container, put it back in the * freelist. */ - struct ALsourceProps *first = ATOMIC_LOAD(&source->FreeList); + struct ALsourceProps *first = ATOMIC_LOAD_SEQ(&source->FreeList); do { ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, @@ -2956,7 +2959,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) /* Check that there is a queue containing at least one valid, non zero * length Buffer. */ - BufferList = ATOMIC_LOAD(&Source->queue); + BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList) { ALbuffer *buffer; @@ -3052,7 +3055,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_INITIAL) { Source->state = AL_STOPPED; - ATOMIC_STORE(&Source->current_buffer, NULL); + ATOMIC_STORE_SEQ(&Source->current_buffer, NULL); } Source->OffsetType = AL_NONE; Source->Offset = 0.0; @@ -3062,10 +3065,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_INITIAL) { Source->state = AL_INITIAL; - ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD(&Source->queue), + ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD_SEQ(&Source->queue), almemory_order_relaxed); ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, 0); + ATOMIC_STORE_SEQ(&Source->position_fraction, 0); } Source->OffsetType = AL_NONE; Source->Offset = 0.0; @@ -3304,7 +3307,7 @@ ALboolean ApplyOffset(ALsource *Source) return AL_FALSE; totalBufferLen = 0; - BufferList = ATOMIC_LOAD(&Source->queue); + BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList && totalBufferLen <= offset) { Buffer = BufferList->buffer; @@ -3343,7 +3346,7 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac) ALdouble dbloff, dblfrac; /* Find the first valid Buffer in the Queue */ - BufferList = ATOMIC_LOAD(&Source->queue); + BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList) { if(BufferList->buffer) diff --git a/OpenAL32/alThunk.c b/OpenAL32/alThunk.c index 72fc0dcb..d3892c97 100644 --- a/OpenAL32/alThunk.c +++ b/OpenAL32/alThunk.c @@ -54,7 +54,7 @@ ALenum NewThunkEntry(ALuint *index) ReadLock(&ThunkLock); for(i = 0;i < ThunkArraySize;i++) { - if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE) == AL_FALSE) + if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE) { ReadUnlock(&ThunkLock); *index = i+1; @@ -69,7 +69,7 @@ ALenum NewThunkEntry(ALuint *index) */ for(;i < ThunkArraySize;i++) { - if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE) == AL_FALSE) + if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE) { WriteUnlock(&ThunkLock); *index = i+1; @@ -89,7 +89,7 @@ ALenum NewThunkEntry(ALuint *index) ThunkArray = NewList; ThunkArraySize *= 2; - ATOMIC_STORE(&ThunkArray[i], AL_TRUE); + ATOMIC_STORE_SEQ(&ThunkArray[i], AL_TRUE); WriteUnlock(&ThunkLock); *index = i+1; @@ -100,6 +100,6 @@ void FreeThunkEntry(ALuint index) { ReadLock(&ThunkLock); if(index > 0 && index <= ThunkArraySize) - ATOMIC_STORE(&ThunkArray[index-1], AL_FALSE); + ATOMIC_STORE_SEQ(&ThunkArray[index-1], AL_FALSE); ReadUnlock(&ThunkLock); } diff --git a/include/atomic.h b/include/atomic.h index 4dff05da..4783defe 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -28,26 +28,20 @@ extern "C" { #define ATOMIC_INIT_STATIC(_newval) ATOMIC_VAR_INIT(_newval) /*#define ATOMIC_FLAG_INIT ATOMIC_FLAG_INIT*/ -#define PARAM2(f, a, b, ...) (f((a), (b))) -#define PARAM3(f, a, b, c, ...) (f((a), (b), (c))) -#define PARAM5(f, a, b, c, d, e, ...) (f((a), (b), (c), (d), (e))) +#define ATOMIC_LOAD(_val, _MO) atomic_load_explicit(_val, _MO) +#define ATOMIC_STORE(_val, _newval, _MO) atomic_store_explicit(_val, _newval, _MO) -#define ATOMIC_LOAD(...) PARAM2(atomic_load_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_STORE(...) PARAM3(atomic_store_explicit, __VA_ARGS__, memory_order_seq_cst) +#define ATOMIC_ADD(_val, _incr, _MO) atomic_fetch_add_explicit(_val, _incr, _MO) +#define ATOMIC_SUB(_val, _decr, _MO) atomic_fetch_sub_explicit(_val, _decr, _MO) -#define ATOMIC_ADD(...) PARAM3(atomic_fetch_add_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_SUB(...) PARAM3(atomic_fetch_sub_explicit, __VA_ARGS__, memory_order_seq_cst) +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) atomic_exchange_explicit(_val, _newval, _MO) +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _orig, _newval, _MO1, _MO2) \ + atomic_compare_exchange_strong_explicit(_val, _orig, _newval, _MO1, _MO2) +#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _orig, _newval, _MO1, _MO2) \ + atomic_compare_exchange_weak_explicit(_val, _orig, _newval, _MO1, _MO2) -#define ATOMIC_EXCHANGE(T, ...) PARAM3(atomic_exchange_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, ...) \ - PARAM5(atomic_compare_exchange_strong_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst) -#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) \ - PARAM5(atomic_compare_exchange_weak_explicit, __VA_ARGS__, memory_order_seq_cst, memory_order_seq_cst) - -#define ATOMIC_FLAG_TEST_AND_SET(...) \ - PARAM2(atomic_flag_test_and_set_explicit, __VA_ARGS__, memory_order_seq_cst) -#define ATOMIC_FLAG_CLEAR(...) \ - PARAM2(atomic_flag_clear_explicit, __VA_ARGS__, memory_order_seq_cst) +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) atomic_flag_test_and_set_explicit(_val, _MO) +#define ATOMIC_FLAG_CLEAR(_val, _MO) atomic_flag_clear_explicit(_val, _MO) #define ATOMIC_THREAD_FENCE atomic_thread_fence @@ -70,36 +64,36 @@ enum almemory_order { #define ATOMIC_INIT_STATIC(_newval) {(_newval)} #define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0) -#define ATOMIC_LOAD(_val, ...) __extension__({ \ +#define ATOMIC_LOAD(_val, _MO) __extension__({ \ __typeof((_val)->value) _r = (_val)->value; \ __asm__ __volatile__("" ::: "memory"); \ _r; \ }) -#define ATOMIC_STORE(_val, _newval, ...) do { \ +#define ATOMIC_STORE(_val, _newval, _MO) do { \ __asm__ __volatile__("" ::: "memory"); \ (_val)->value = (_newval); \ } while(0) -#define ATOMIC_ADD(_val, _incr, ...) __sync_fetch_and_add(&(_val)->value, (_incr)) -#define ATOMIC_SUB(_val, _decr, ...) __sync_fetch_and_sub(&(_val)->value, (_decr)) +#define ATOMIC_ADD(_val, _incr, _MO) __sync_fetch_and_add(&(_val)->value, (_incr)) +#define ATOMIC_SUB(_val, _decr, _MO) __sync_fetch_and_sub(&(_val)->value, (_decr)) -#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \ +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) __extension__({ \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ __asm__ __volatile__("" ::: "memory"); \ __sync_lock_test_and_set(&(_val)->value, (_newval)); \ }) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) __extension__({ \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ T _o = *(_oldval); \ *(_oldval) = __sync_val_compare_and_swap(&(_val)->value, _o, (_newval)); \ *(_oldval) == _o; \ }) -#define ATOMIC_FLAG_TEST_AND_SET(_val, ...) __extension__({ \ +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) __extension__({ \ __asm__ __volatile__("" ::: "memory"); \ __sync_lock_test_and_set(&(_val)->value, 1); \ }) -#define ATOMIC_FLAG_CLEAR(_val, ...) __extension__({ \ +#define ATOMIC_FLAG_CLEAR(_val, _MO) __extension__({ \ __sync_lock_release(&(_val)->value); \ __asm__ __volatile__("" ::: "memory"); \ }) @@ -156,24 +150,24 @@ enum almemory_order { #define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) #define ATOMIC_INIT_STATIC(_newval) {(_newval)} -#define ATOMIC_LOAD(_val, ...) __extension__({ \ +#define ATOMIC_LOAD(_val, _MO) __extension__({ \ __typeof((_val)->value) _r = (_val)->value; \ __asm__ __volatile__("" ::: "memory"); \ _r; \ }) -#define ATOMIC_STORE(_val, _newval, ...) do { \ +#define ATOMIC_STORE(_val, _newval, _MO) do { \ __asm__ __volatile__("" ::: "memory"); \ (_val)->value = (_newval); \ } while(0) -#define ATOMIC_ADD(_val, _incr, ...) __extension__({ \ +#define ATOMIC_ADD(_val, _incr, _MO) __extension__({ \ static_assert(sizeof((_val)->value)==4 || sizeof((_val)->value)==8, "Unsupported size!"); \ __typeof((_val)->value) _r; \ if(sizeof((_val)->value) == 4) WRAP_ADD("l", _r, &(_val)->value, _incr); \ else if(sizeof((_val)->value) == 8) WRAP_ADD("q", _r, &(_val)->value, _incr); \ _r; \ }) -#define ATOMIC_SUB(_val, _decr, ...) __extension__({ \ +#define ATOMIC_SUB(_val, _decr, _MO) __extension__({ \ static_assert(sizeof((_val)->value)==4 || sizeof((_val)->value)==8, "Unsupported size!"); \ __typeof((_val)->value) _r; \ if(sizeof((_val)->value) == 4) WRAP_SUB("l", _r, &(_val)->value, _decr); \ @@ -181,7 +175,7 @@ enum almemory_order { _r; \ }) -#define ATOMIC_EXCHANGE(T, _val, _newval, ...) __extension__({ \ +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) __extension__({ \ static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ T _r; \ @@ -189,7 +183,7 @@ enum almemory_order { else if(sizeof(T) == 8) WRAP_XCHG("q", _r, &(_val)->value, (T)(_newval)); \ _r; \ }) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) __extension__({ \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) __extension__({ \ static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ T _old = *(_oldval); \ @@ -279,27 +273,27 @@ enum almemory_order { #define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) #define ATOMIC_INIT_STATIC(_newval) {(_newval)} -#define ATOMIC_LOAD(_val, ...) ((_val)->value) -#define ATOMIC_STORE(_val, _newval, ...) do { \ +#define ATOMIC_LOAD(_val, _MO) ((_val)->value) +#define ATOMIC_STORE(_val, _newval, _MO) do { \ (_val)->value = (_newval); \ } while(0) int _al_invalid_atomic_size(); /* not defined */ -#define ATOMIC_ADD(_val, _incr, ...) \ +#define ATOMIC_ADD(_val, _incr, _MO) \ ((sizeof((_val)->value)==4) ? WRAP_ADDSUB(LONG, AtomicAdd32, &(_val)->value, (_incr)) : \ (sizeof((_val)->value)==8) ? WRAP_ADDSUB(LONGLONG, AtomicAdd64, &(_val)->value, (_incr)) : \ _al_invalid_atomic_size()) -#define ATOMIC_SUB(_val, _decr, ...) \ +#define ATOMIC_SUB(_val, _decr, _MO) \ ((sizeof((_val)->value)==4) ? WRAP_ADDSUB(LONG, AtomicSub32, &(_val)->value, (_decr)) : \ (sizeof((_val)->value)==8) ? WRAP_ADDSUB(LONGLONG, AtomicSub64, &(_val)->value, (_decr)) : \ _al_invalid_atomic_size()) -#define ATOMIC_EXCHANGE(T, _val, _newval, ...) \ +#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) \ ((sizeof(T)==4) ? WRAP_XCHG(T, AtomicSwap32, &(_val)->value, (_newval)) : \ (sizeof(T)==8) ? WRAP_XCHG(T, AtomicSwap64, &(_val)->value, (_newval)) : \ (T)_al_invalid_atomic_size()) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, ...) \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) \ ((sizeof(T)==4) ? WRAP_CMPXCHG(T, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \ (sizeof(T)==8) ? WRAP_CMPXCHG(T, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \ (bool)_al_invalid_atomic_size()) @@ -333,7 +327,7 @@ int _al_invalid_atomic_size(); /* not defined */ #define ATOMIC_FLAG_TEST_AND_SET(...) (0) #define ATOMIC_FLAG_CLEAR(...) ((void)0) -#define ATOMIC_THREAD_FENCE ((void)0) +#define ATOMIC_THREAD_FENCE(...) ((void)0) #endif /* If no weak cmpxchg is provided (not all systems will have one), substitute a @@ -348,24 +342,35 @@ int _al_invalid_atomic_size(); /* not defined */ #ifndef ATOMIC_FLAG #define ATOMIC_FLAG ATOMIC(int) #define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0) -#define ATOMIC_FLAG_TEST_AND_SET_(_val, ...) ATOMIC_EXCHANGE(int, _val, 1, __VA_ARGS__) -#define ATOMIC_FLAG_TEST_AND_SET(...) ATOMIC_FLAG_TEST_AND_SET_(__VA_ARGS__, almemory_order_seq_cst) -#define ATOMIC_FLAG_CLEAR_(_val, ...) ATOMIC_STORE(_val, 0, __VA_ARGS__) -#define ATOMIC_FLAG_CLEAR(...) ATOMIC_FLAG_CLEAR_(__VA_ARGS__, almemory_order_seq_cst) +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) ATOMIC_EXCHANGE(int, _val, 1, _MO) +#define ATOMIC_FLAG_CLEAR(_val, _MO) ATOMIC_STORE(_val, 0, _MO) #endif +#define ATOMIC_LOAD_SEQ(_val) ATOMIC_LOAD(_val, almemory_order_seq_cst) +#define ATOMIC_STORE_SEQ(_val, _newval) ATOMIC_STORE(_val, _newval, almemory_order_seq_cst) + +#define ATOMIC_ADD_SEQ(_val, _incr) ATOMIC_ADD(_val, _incr, almemory_order_seq_cst) +#define ATOMIC_SUB_SEQ(_val, _decr) ATOMIC_SUB(_val, _decr, almemory_order_seq_cst) + +#define ATOMIC_EXCHANGE_SEQ(T, _val, _newval) ATOMIC_EXCHANGE(T, _val, _newval, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(T, _val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(T, _val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) + + typedef unsigned int uint; typedef ATOMIC(uint) RefCount; inline void InitRef(RefCount *ptr, uint value) { ATOMIC_INIT(ptr, value); } inline uint ReadRef(RefCount *ptr) -{ return ATOMIC_LOAD(ptr); } +{ return ATOMIC_LOAD_SEQ(ptr); } inline uint IncrementRef(RefCount *ptr) -{ return ATOMIC_ADD(ptr, 1)+1; } +{ return ATOMIC_ADD_SEQ(ptr, 1)+1; } inline uint DecrementRef(RefCount *ptr) -{ return ATOMIC_SUB(ptr, 1)-1; } +{ return ATOMIC_SUB_SEQ(ptr, 1)-1; } #ifdef __cplusplus -- cgit v1.2.3 From 4c33818dde702128be13040f9fc8bd0a5b835c76 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 21 Dec 2016 19:58:03 -0800 Subject: Avoid duplicating code using a macro --- Alc/ALu.c | 41 +++-------------------------------------- OpenAL32/alAuxEffectSlot.c | 6 +----- OpenAL32/alListener.c | 6 +----- OpenAL32/alSource.c | 7 +------ include/atomic.h | 12 ++++++++++++ 5 files changed, 18 insertions(+), 54 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index db032057..dc979522 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -239,7 +239,6 @@ static ALboolean CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALfloat N[3], V[3], U[3], P[3]; - struct ALlistenerProps *first; struct ALlistenerProps *props; aluVector vel; @@ -288,24 +287,12 @@ static ALboolean CalcListenerParams(ALCcontext *Context) Listener->Params.SourceDistanceModel = ATOMIC_LOAD(&props->SourceDistanceModel, almemory_order_relaxed); Listener->Params.DistanceModel = ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed); - /* WARNING: A livelock is theoretically possible if another thread keeps - * changing the freelist head without giving this a chance to actually swap - * in the old container (practically impossible with this little code, - * but...). - */ - first = ATOMIC_LOAD(&Listener->FreeList, almemory_order_acquire); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, - &Listener->FreeList, &first, props, almemory_order_acq_rel, - almemory_order_acquire) == 0); - + ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props); return AL_TRUE; } static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { - struct ALeffectslotProps *first; struct ALeffectslotProps *props; ALeffectState *state; @@ -337,18 +324,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) V(state,update)(device, slot, &props->Props); - /* WARNING: A livelock is theoretically possible if another thread keeps - * changing the freelist head without giving this a chance to actually swap - * in the old container (practically impossible with this little code, - * but...). - */ - first = ATOMIC_LOAD(&slot->FreeList, almemory_order_acquire); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, - &slot->FreeList, &first, props, almemory_order_acq_rel, - almemory_order_acquire) == 0); - + ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props); return AL_TRUE; } @@ -1301,7 +1277,6 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc { ALsource *source = voice->Source; const ALbufferlistitem *BufferListItem; - struct ALsourceProps *first; struct ALsourceProps *props; props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); @@ -1311,17 +1286,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc { voice->Props = *props; - /* WARNING: A livelock is theoretically possible if another thread - * keeps changing the freelist head without giving this a chance to - * actually swap in the old container (practically impossible with this - * little code, but...). - */ - first = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, - &source->FreeList, &first, props, almemory_order_acq_rel, - almemory_order_acquire) == 0); + ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props); } BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index a7bc0f32..e6b4ff68 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -671,11 +671,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* If there was an unused update container, put it back in the * freelist. */ - struct ALeffectslotProps *first = ATOMIC_LOAD_SEQ(&slot->FreeList); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALeffectslotProps*, - &slot->FreeList, &first, props) == 0); + ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props); } if(oldstate) diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index f05c20d1..9c237e99 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -506,10 +506,6 @@ void UpdateListenerProps(ALCcontext *context) /* If there was an unused update container, put it back in the * freelist. */ - struct ALlistenerProps *first = ATOMIC_LOAD_SEQ(&listener->FreeList); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(struct ALlistenerProps*, - &listener->FreeList, &first, props) == 0); + ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &listener->FreeList, props); } } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 9f60c545..e3d3cf1b 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2913,12 +2913,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) /* If there was an unused update container, put it back in the * freelist. */ - struct ALsourceProps *first = ATOMIC_LOAD_SEQ(&source->FreeList); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, - &source->FreeList, &first, props, almemory_order_acq_rel, - almemory_order_acquire) == 0); + ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props); } } diff --git a/include/atomic.h b/include/atomic.h index 4783defe..57609c33 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -373,6 +373,18 @@ inline uint DecrementRef(RefCount *ptr) { return ATOMIC_SUB_SEQ(ptr, 1)-1; } +/* WARNING: A livelock is theoretically possible if another thread keeps + * changing the head without giving this a chance to actually swap in the new + * one (practically impossible with this little code, but...). + */ +#define ATOMIC_REPLACE_HEAD(T, _head, _entry) do { \ + T _first = ATOMIC_LOAD(_head, almemory_order_acquire); \ + do { \ + ATOMIC_STORE(&(_entry)->next, _first, almemory_order_relaxed); \ + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(T, _head, &_first, _entry, \ + almemory_order_acq_rel, almemory_order_acquire) == 0); \ +} while(0) + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 5ffb0842ac5022b1e5d34973ed6f512b5f0d7434 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 8 Mar 2017 03:38:28 -0800 Subject: Remove unnecessary atomic members --- Alc/ALu.c | 195 ++++++++++++++++--------------------- OpenAL32/Include/alAuxEffectSlot.h | 8 +- OpenAL32/Include/alListener.h | 34 +++---- OpenAL32/Include/alSource.h | 82 ++++++++-------- OpenAL32/alAuxEffectSlot.c | 25 +++-- OpenAL32/alListener.c | 48 ++++----- OpenAL32/alSource.c | 79 ++++++++------- 7 files changed, 221 insertions(+), 250 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index e14c2013..04b9c89d 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -245,13 +245,13 @@ static ALboolean CalcListenerParams(ALCcontext *Context) if(!props) return AL_FALSE; /* AT then UP */ - N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); - N[1] = ATOMIC_LOAD(&props->Forward[1], almemory_order_relaxed); - N[2] = ATOMIC_LOAD(&props->Forward[2], almemory_order_relaxed); + N[0] = props->Forward[0]; + N[1] = props->Forward[1]; + N[2] = props->Forward[2]; aluNormalize(N); - V[0] = ATOMIC_LOAD(&props->Up[0], almemory_order_relaxed); - V[1] = ATOMIC_LOAD(&props->Up[1], almemory_order_relaxed); - V[2] = ATOMIC_LOAD(&props->Up[2], almemory_order_relaxed); + V[0] = props->Up[0]; + V[1] = props->Up[1]; + V[2] = props->Up[2]; aluNormalize(V); /* Build and normalize right-vector */ aluCrossproduct(N, V, U); @@ -264,27 +264,23 @@ static ALboolean CalcListenerParams(ALCcontext *Context) 0.0, 0.0, 0.0, 1.0 ); - P[0] = ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed); - P[1] = ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed); - P[2] = ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed); + P[0] = props->Position[0]; + P[1] = props->Position[1]; + P[2] = props->Position[2]; aluMatrixfFloat3(P, 1.0, &Listener->Params.Matrix); aluMatrixfSetRow(&Listener->Params.Matrix, 3, -P[0], -P[1], -P[2], 1.0f); - aluVectorSet(&vel, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), - 0.0f); + aluVectorSet(&vel, props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f); Listener->Params.Velocity = aluMatrixfVector(&Listener->Params.Matrix, &vel); - Listener->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed) * Context->GainBoost; - Listener->Params.MetersPerUnit = ATOMIC_LOAD(&props->MetersPerUnit, almemory_order_relaxed); + Listener->Params.Gain = props->Gain * Context->GainBoost; + Listener->Params.MetersPerUnit = props->MetersPerUnit; - Listener->Params.DopplerFactor = ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); - Listener->Params.SpeedOfSound = ATOMIC_LOAD(&props->SpeedOfSound, almemory_order_relaxed) * - ATOMIC_LOAD(&props->DopplerVelocity, almemory_order_relaxed); + Listener->Params.DopplerFactor = props->DopplerFactor; + Listener->Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; - Listener->Params.SourceDistanceModel = ATOMIC_LOAD(&props->SourceDistanceModel, almemory_order_relaxed); - Listener->Params.DistanceModel = ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed); + Listener->Params.SourceDistanceModel = props->SourceDistanceModel; + Listener->Params.DistanceModel = props->DistanceModel; ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props); return AL_TRUE; @@ -298,9 +294,9 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); if(!props) return AL_FALSE; - slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); - slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); - slot->Params.EffectType = ATOMIC_LOAD(&props->Type, almemory_order_relaxed); + slot->Params.Gain = props->Gain; + slot->Params.AuxSendAuto = props->AuxSendAuto; + slot->Params.EffectType = props->Type; if(IsReverbEffect(slot->Params.EffectType)) { slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; @@ -317,8 +313,8 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) /* Swap effect states. No need to play with the ref counts since they keep * the same number of refs. */ - state = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Params.EffectState, - almemory_order_relaxed); + state = props->State; + props->State = slot->Params.EffectState; slot->Params.EffectState = state; V(state,update)(device, slot, &props->Props); @@ -396,22 +392,22 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * ListenerGain = Listener->Params.Gain; /* Get source properties */ - SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); - MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); - MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); - Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); - Relative = ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed); - DirectChannels = ATOMIC_LOAD(&props->DirectChannels, almemory_order_relaxed); + SourceVolume = props->Gain; + MinVolume = props->MinGain; + MaxVolume = props->MaxGain; + Pitch = props->Pitch; + Relative = props->HeadRelative; + DirectChannels = props->DirectChannels; /* Convert counter-clockwise to clockwise. */ - StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed); - StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed); + StereoMap[0].angle = -props->StereoPan[0]; + StereoMap[1].angle = -props->StereoPan[1]; voice->Direct.Buffer = Device->Dry.Buffer; voice->Direct.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); + SendSlots[i] = props->Send[i].Slot; if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) @@ -437,17 +433,17 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); - DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGain *= props->Direct.Gain * ListenerGain; DryGain = minf(DryGain, GAIN_MIX_MAX); - DryGainHF = ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); - DryGainLF = ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); + DryGainHF = props->Direct.GainHF; + DryGainLF = props->Direct.GainLF; for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume); - WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGain[i] *= props->Send[i].Gain * ListenerGain; WetGain[i] = minf(WetGain[i], GAIN_MIX_MAX); - WetGainHF[i] = ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); - WetGainLF[i] = ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); + WetGainHF[i] = props->Send[i].GainHF; + WetGainLF[i] = props->Send[i].GainLF; } switch(ALBuffer->FmtChannels) @@ -507,13 +503,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * ALfloat scale; /* AT then UP */ - N[0] = ATOMIC_LOAD(&props->Orientation[0][0], almemory_order_relaxed); - N[1] = ATOMIC_LOAD(&props->Orientation[0][1], almemory_order_relaxed); - N[2] = ATOMIC_LOAD(&props->Orientation[0][2], almemory_order_relaxed); + N[0] = props->Orientation[0][0]; + N[1] = props->Orientation[0][1]; + N[2] = props->Orientation[0][2]; aluNormalize(N); - V[0] = ATOMIC_LOAD(&props->Orientation[1][0], almemory_order_relaxed); - V[1] = ATOMIC_LOAD(&props->Orientation[1][1], almemory_order_relaxed); - V[2] = ATOMIC_LOAD(&props->Orientation[1][2], almemory_order_relaxed); + V[0] = props->Orientation[1][0]; + V[1] = props->Orientation[1][1]; + V[2] = props->Orientation[1][2]; aluNormalize(V); if(!Relative) { @@ -704,8 +700,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * } { - HFScale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Direct.HFReference / Frequency; + LFScale = props->Direct.LFReference / Frequency; DryGainHF = maxf(DryGainHF, 0.0625f); /* Limit -24dB */ DryGainLF = maxf(DryGainLF, 0.0625f); for(c = 0;c < num_channels;c++) @@ -725,8 +721,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * } for(i = 0;i < NumSends;i++) { - HFScale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Send[i].HFReference / Frequency; + LFScale = props->Send[i].LFReference / Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0625f); WetGainLF[i] = maxf(WetGainLF[i], 0.0625f); for(c = 0;c < num_channels;c++) @@ -790,40 +786,30 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro MetersPerUnit = Listener->Params.MetersPerUnit; /* Get source properties */ - SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); - MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); - MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); - Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); - aluVectorSet(&Position, ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed), - 1.0f); - aluVectorSet(&Direction, ATOMIC_LOAD(&props->Direction[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Direction[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Direction[2], almemory_order_relaxed), - 0.0f); - aluVectorSet(&Velocity, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), - 0.0f); - MinDist = ATOMIC_LOAD(&props->RefDistance, almemory_order_relaxed); - MaxDist = ATOMIC_LOAD(&props->MaxDistance, almemory_order_relaxed); - Rolloff = ATOMIC_LOAD(&props->RollOffFactor, almemory_order_relaxed); - DopplerFactor *= ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); - InnerAngle = ATOMIC_LOAD(&props->InnerAngle, almemory_order_relaxed); - OuterAngle = ATOMIC_LOAD(&props->OuterAngle, almemory_order_relaxed); - AirAbsorptionFactor = ATOMIC_LOAD(&props->AirAbsorptionFactor, almemory_order_relaxed); - DryGainHFAuto = ATOMIC_LOAD(&props->DryGainHFAuto, almemory_order_relaxed); - WetGainAuto = ATOMIC_LOAD(&props->WetGainAuto, almemory_order_relaxed); - WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed); - RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed); + SourceVolume = props->Gain; + MinVolume = props->MinGain; + MaxVolume = props->MaxGain; + Pitch = props->Pitch; + aluVectorSet(&Position, props->Position[0], props->Position[1], props->Position[2], 1.0f); + aluVectorSet(&Direction, props->Direction[0], props->Direction[1], props->Direction[2], 0.0f); + aluVectorSet(&Velocity, props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f); + MinDist = props->RefDistance; + MaxDist = props->MaxDistance; + Rolloff = props->RollOffFactor; + DopplerFactor *= props->DopplerFactor; + InnerAngle = props->InnerAngle; + OuterAngle = props->OuterAngle; + AirAbsorptionFactor = props->AirAbsorptionFactor; + DryGainHFAuto = props->DryGainHFAuto; + WetGainAuto = props->WetGainAuto; + WetGainHFAuto = props->WetGainHFAuto; + RoomRolloffBase = props->RoomRolloffFactor; voice->Direct.Buffer = Device->Dry.Buffer; voice->Direct.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); - + SendSlots[i] = props->Send[i].Slot; if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) @@ -862,7 +848,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } /* Transform source to listener space (convert to head relative) */ - if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE) + if(props->HeadRelative == AL_FALSE) { const aluMatrixf *Matrix = &Listener->Params.Matrix; /* Transform source vectors */ @@ -893,8 +879,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro for(i = 0;i < NumSends;i++) RoomAttenuation[i] = 1.0f; switch(Listener->Params.SourceDistanceModel ? - ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed) : - Listener->Params.DistanceModel) + props->DistanceModel : Listener->Params.DistanceModel) { case InverseDistanceClamped: ClampedDist = clampf(ClampedDist, MinDist, MaxDist); @@ -1003,17 +988,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro if(Angle < OuterAngle) { scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), scale - ); - ConeHF = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), scale - ); + ConeVolume = lerp(1.0f, props->OuterGain, scale); + ConeHF = lerp(1.0f, props->OuterGainHF, scale); } else { - ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed); - ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed); + ConeVolume = props->OuterGain; + ConeHF = props->OuterGainHF; } DryGain *= ConeVolume; if(DryGainHFAuto) @@ -1027,17 +1008,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro (InnerAngle/360.0f); if(WetGainAuto) { - ConeVolume = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), scale - ); + ConeVolume = lerp(1.0f, props->OuterGain, scale); for(i = 0;i < NumSends;i++) WetGain[i] *= ConeVolume; } if(WetGainHFAuto) { - ConeHF = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), scale - ); + ConeHF = lerp(1.0f, props->OuterGainHF, scale); for(i = 0;i < NumSends;i++) WetGainHF[i] *= ConeHF; } @@ -1045,17 +1022,17 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Apply gain and frequency filters */ DryGain = clampf(DryGain, MinVolume, MaxVolume); - DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGain *= props->Direct.Gain * ListenerGain; DryGain = minf(DryGain, GAIN_MIX_MAX); - DryGainHF *= ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); - DryGainLF *= ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); + DryGainHF *= props->Direct.GainHF; + DryGainLF *= props->Direct.GainLF; for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume); - WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGain[i] *= props->Send[i].Gain * ListenerGain; WetGain[i] = minf(WetGain[i], GAIN_MIX_MAX); - WetGainHF[i] *= ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); - WetGainLF[i] *= ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); + WetGainHF[i] *= props->Send[i].GainHF; + WetGainLF[i] *= props->Send[i].GainLF; } /* Calculate velocity-based doppler effect */ @@ -1093,9 +1070,9 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro * real outputs. */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; - ALfloat ev = 0.0f, az = 0.0f; - ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat radius = props->Radius; + ALfloat ev = 0.0f, az = 0.0f; ALfloat spread = 0.0f; voice->Direct.Buffer = Device->RealOut.Buffer; @@ -1144,8 +1121,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { /* Non-HRTF rendering. */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; - ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat radius = props->Radius; ALfloat spread = 0.0f; /* Get the localized direction, and compute panned gains. */ @@ -1188,8 +1165,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } { - HFScale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Direct.HFReference / Frequency; + LFScale = props->Direct.LFReference / Frequency; DryGainHF = maxf(DryGainHF, 0.0625f); /* Limit -24dB */ DryGainLF = maxf(DryGainLF, 0.0625f); voice->Direct.Params[0].FilterType = AF_None; @@ -1206,8 +1183,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } for(i = 0;i < NumSends;i++) { - HFScale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Send[i].HFReference / Frequency; + LFScale = props->Send[i].LFReference / Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0625f); WetGainLF[i] = maxf(WetGainLF[i], 0.0625f); voice->Send[i].Params[0].FilterType = AF_None; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 40ff1393..3c24f80c 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -75,13 +75,13 @@ static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = struct ALeffectslotProps { - ATOMIC(ALfloat) Gain; - ATOMIC(ALboolean) AuxSendAuto; + ALfloat Gain; + ALboolean AuxSendAuto; - ATOMIC(ALenum) Type; + ALenum Type; ALeffectProps Props; - ATOMIC(ALeffectState*) State; + ALeffectState *State; ATOMIC(struct ALeffectslotProps*) next; }; diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index b89a00e7..9a7f9d49 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -9,29 +9,29 @@ extern "C" { #endif struct ALlistenerProps { - ATOMIC(ALfloat) Position[3]; - ATOMIC(ALfloat) Velocity[3]; - ATOMIC(ALfloat) Forward[3]; - ATOMIC(ALfloat) Up[3]; - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) MetersPerUnit; + ALfloat Position[3]; + ALfloat Velocity[3]; + ALfloat Forward[3]; + ALfloat Up[3]; + ALfloat Gain; + ALfloat MetersPerUnit; - ATOMIC(ALfloat) DopplerFactor; - ATOMIC(ALfloat) DopplerVelocity; - ATOMIC(ALfloat) SpeedOfSound; - ATOMIC(ALboolean) SourceDistanceModel; - ATOMIC(enum DistanceModel) DistanceModel; + ALfloat DopplerFactor; + ALfloat DopplerVelocity; + ALfloat SpeedOfSound; + ALboolean SourceDistanceModel; + enum DistanceModel DistanceModel; ATOMIC(struct ALlistenerProps*) next; }; typedef struct ALlistener { - volatile ALfloat Position[3]; - volatile ALfloat Velocity[3]; - volatile ALfloat Forward[3]; - volatile ALfloat Up[3]; - volatile ALfloat Gain; - volatile ALfloat MetersPerUnit; + ALfloat Position[3]; + ALfloat Velocity[3]; + ALfloat Forward[3]; + ALfloat Up[3]; + ALfloat Gain; + ALfloat MetersPerUnit; /* Pointer to the most recent property values that are awaiting an update. */ diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 2525f107..12b4587b 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -27,52 +27,52 @@ typedef struct ALbufferlistitem { struct ALsourceProps { ATOMIC(struct ALsourceProps*) next; - ATOMIC(ALfloat) Pitch; - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) OuterGain; - ATOMIC(ALfloat) MinGain; - ATOMIC(ALfloat) MaxGain; - ATOMIC(ALfloat) InnerAngle; - ATOMIC(ALfloat) OuterAngle; - ATOMIC(ALfloat) RefDistance; - ATOMIC(ALfloat) MaxDistance; - ATOMIC(ALfloat) RollOffFactor; - ATOMIC(ALfloat) Position[3]; - ATOMIC(ALfloat) Velocity[3]; - ATOMIC(ALfloat) Direction[3]; - ATOMIC(ALfloat) Orientation[2][3]; - ATOMIC(ALboolean) HeadRelative; - ATOMIC(enum DistanceModel) DistanceModel; - ATOMIC(ALboolean) DirectChannels; - - ATOMIC(ALboolean) DryGainHFAuto; - ATOMIC(ALboolean) WetGainAuto; - ATOMIC(ALboolean) WetGainHFAuto; - ATOMIC(ALfloat) OuterGainHF; - - ATOMIC(ALfloat) AirAbsorptionFactor; - ATOMIC(ALfloat) RoomRolloffFactor; - ATOMIC(ALfloat) DopplerFactor; - - ATOMIC(ALfloat) StereoPan[2]; - - ATOMIC(ALfloat) Radius; + ALfloat Pitch; + ALfloat Gain; + ALfloat OuterGain; + ALfloat MinGain; + ALfloat MaxGain; + ALfloat InnerAngle; + ALfloat OuterAngle; + ALfloat RefDistance; + ALfloat MaxDistance; + ALfloat RollOffFactor; + ALfloat Position[3]; + ALfloat Velocity[3]; + ALfloat Direction[3]; + ALfloat Orientation[2][3]; + ALboolean HeadRelative; + enum DistanceModel DistanceModel; + ALboolean DirectChannels; + + ALboolean DryGainHFAuto; + ALboolean WetGainAuto; + ALboolean WetGainHFAuto; + ALfloat OuterGainHF; + + ALfloat AirAbsorptionFactor; + ALfloat RoomRolloffFactor; + ALfloat DopplerFactor; + + ALfloat StereoPan[2]; + + ALfloat Radius; /** Direct filter and auxiliary send info. */ struct { - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) GainHF; - ATOMIC(ALfloat) HFReference; - ATOMIC(ALfloat) GainLF; - ATOMIC(ALfloat) LFReference; + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; } Direct; struct { - ATOMIC(struct ALeffectslot*) Slot; - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) GainHF; - ATOMIC(ALfloat) HFReference; - ATOMIC(ALfloat) GainLF; - ATOMIC(ALfloat) LFReference; + struct ALeffectslot *Slot; + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; } Send[]; }; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index e6b4ff68..37316549 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -530,8 +530,9 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e props = ATOMIC_LOAD_SEQ(&EffectSlot->FreeList); while(props) { - State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); - if(State) ALeffectState_DecRef(State); + if(props->State) + ALeffectState_DecRef(props->State); + props->State = NULL; props = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } @@ -602,24 +603,20 @@ ALenum InitEffectSlot(ALeffectslot *slot) void DeinitEffectSlot(ALeffectslot *slot) { struct ALeffectslotProps *props; - ALeffectState *state; size_t count = 0; props = ATOMIC_LOAD_SEQ(&slot->Update); if(props) { - state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); - if(state) ALeffectState_DecRef(state); + if(props->State) ALeffectState_DecRef(props->State); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); while(props) { - struct ALeffectslotProps *next; - state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); - next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - if(state) ALeffectState_DecRef(state); + struct ALeffectslotProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + if(props->State) ALeffectState_DecRef(props->State); al_free(props); props = next; ++count; @@ -651,17 +648,17 @@ void UpdateEffectSlotProps(ALeffectslot *slot) } /* Copy in current property values. */ - ATOMIC_STORE(&props->Gain, slot->Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->AuxSendAuto, slot->AuxSendAuto, almemory_order_relaxed); + props->Gain = slot->Gain; + props->AuxSendAuto = slot->AuxSendAuto; - ATOMIC_STORE(&props->Type, slot->Effect.Type, almemory_order_relaxed); + props->Type = slot->Effect.Type; props->Props = slot->Effect.Props; /* Swap out any stale effect state object there may be in the container, to * delete it. */ ALeffectState_IncRef(slot->Effect.State); - oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, - almemory_order_relaxed); + oldstate = props->State; + props->State = slot->Effect.State; /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 9c237e99..e3d71435 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -474,30 +474,30 @@ void UpdateListenerProps(ALCcontext *context) } /* Copy in current property values. */ - ATOMIC_STORE(&props->Position[0], listener->Position[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Position[1], listener->Position[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Position[2], listener->Position[2], almemory_order_relaxed); - - ATOMIC_STORE(&props->Velocity[0], listener->Velocity[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Velocity[1], listener->Velocity[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Velocity[2], listener->Velocity[2], almemory_order_relaxed); - - ATOMIC_STORE(&props->Forward[0], listener->Forward[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Forward[1], listener->Forward[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Forward[2], listener->Forward[2], almemory_order_relaxed); - ATOMIC_STORE(&props->Up[0], listener->Up[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Up[1], listener->Up[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Up[2], listener->Up[2], almemory_order_relaxed); - - ATOMIC_STORE(&props->Gain, listener->Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->MetersPerUnit, listener->MetersPerUnit, almemory_order_relaxed); - - ATOMIC_STORE(&props->DopplerFactor, context->DopplerFactor, almemory_order_relaxed); - ATOMIC_STORE(&props->DopplerVelocity, context->DopplerVelocity, almemory_order_relaxed); - ATOMIC_STORE(&props->SpeedOfSound, context->SpeedOfSound, almemory_order_relaxed); - - ATOMIC_STORE(&props->SourceDistanceModel, context->SourceDistanceModel, almemory_order_relaxed); - ATOMIC_STORE(&props->DistanceModel, context->DistanceModel, almemory_order_relaxed); + props->Position[0] = listener->Position[0]; + props->Position[1] = listener->Position[1]; + props->Position[2] = listener->Position[2]; + + props->Velocity[0] = listener->Velocity[0]; + props->Velocity[1] = listener->Velocity[1]; + props->Velocity[2] = listener->Velocity[2]; + + props->Forward[0] = listener->Forward[0]; + props->Forward[1] = listener->Forward[1]; + props->Forward[2] = listener->Forward[2]; + props->Up[0] = listener->Up[0]; + props->Up[1] = listener->Up[1]; + props->Up[2] = listener->Up[2]; + + props->Gain = listener->Gain; + props->MetersPerUnit = listener->MetersPerUnit; + + props->DopplerFactor = context->DopplerFactor; + props->DopplerVelocity = context->DopplerVelocity; + props->SpeedOfSound = context->SpeedOfSound; + + props->SourceDistanceModel = context->SourceDistanceModel; + props->DistanceModel = context->DistanceModel;; /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &listener->Update, props, almemory_order_acq_rel); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index e81fd853..c4c0bfb1 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2892,63 +2892,60 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends) } /* Copy in current property values. */ - ATOMIC_STORE(&props->Pitch, source->Pitch, almemory_order_relaxed); - ATOMIC_STORE(&props->Gain, source->Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->OuterGain, source->OuterGain, almemory_order_relaxed); - ATOMIC_STORE(&props->MinGain, source->MinGain, almemory_order_relaxed); - ATOMIC_STORE(&props->MaxGain, source->MaxGain, almemory_order_relaxed); - ATOMIC_STORE(&props->InnerAngle, source->InnerAngle, almemory_order_relaxed); - ATOMIC_STORE(&props->OuterAngle, source->OuterAngle, almemory_order_relaxed); - ATOMIC_STORE(&props->RefDistance, source->RefDistance, almemory_order_relaxed); - ATOMIC_STORE(&props->MaxDistance, source->MaxDistance, almemory_order_relaxed); - ATOMIC_STORE(&props->RollOffFactor, source->RollOffFactor, almemory_order_relaxed); + props->Pitch = source->Pitch; + props->Gain = source->Gain; + props->OuterGain = source->OuterGain; + props->MinGain = source->MinGain; + props->MaxGain = source->MaxGain; + props->InnerAngle = source->InnerAngle; + props->OuterAngle = source->OuterAngle; + props->RefDistance = source->RefDistance; + props->MaxDistance = source->MaxDistance; + props->RollOffFactor = source->RollOffFactor; for(i = 0;i < 3;i++) - ATOMIC_STORE(&props->Position[i], source->Position[i], almemory_order_relaxed); + props->Position[i] = source->Position[i]; for(i = 0;i < 3;i++) - ATOMIC_STORE(&props->Velocity[i], source->Velocity[i], almemory_order_relaxed); + props->Velocity[i] = source->Velocity[i]; for(i = 0;i < 3;i++) - ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed); + props->Direction[i] = source->Direction[i]; for(i = 0;i < 2;i++) { ALsizei j; for(j = 0;j < 3;j++) - ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j], - almemory_order_relaxed); + props->Orientation[i][j] = source->Orientation[i][j]; } - ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); - ATOMIC_STORE(&props->DistanceModel, source->DistanceModel, almemory_order_relaxed); - ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed); + props->HeadRelative = source->HeadRelative; + props->DistanceModel = source->DistanceModel; + props->DirectChannels = source->DirectChannels; - ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed); - ATOMIC_STORE(&props->WetGainAuto, source->WetGainAuto, almemory_order_relaxed); - ATOMIC_STORE(&props->WetGainHFAuto, source->WetGainHFAuto, almemory_order_relaxed); - ATOMIC_STORE(&props->OuterGainHF, source->OuterGainHF, almemory_order_relaxed); + props->DryGainHFAuto = source->DryGainHFAuto; + props->WetGainAuto = source->WetGainAuto; + props->WetGainHFAuto = source->WetGainHFAuto; + props->OuterGainHF = source->OuterGainHF; - ATOMIC_STORE(&props->AirAbsorptionFactor, source->AirAbsorptionFactor, almemory_order_relaxed); - ATOMIC_STORE(&props->RoomRolloffFactor, source->RoomRolloffFactor, almemory_order_relaxed); - ATOMIC_STORE(&props->DopplerFactor, source->DopplerFactor, almemory_order_relaxed); + props->AirAbsorptionFactor = source->AirAbsorptionFactor; + props->RoomRolloffFactor = source->RoomRolloffFactor; + props->DopplerFactor = source->DopplerFactor; - ATOMIC_STORE(&props->StereoPan[0], source->StereoPan[0], almemory_order_relaxed); - ATOMIC_STORE(&props->StereoPan[1], source->StereoPan[1], almemory_order_relaxed); + props->StereoPan[0] = source->StereoPan[0]; + props->StereoPan[1] = source->StereoPan[1]; - ATOMIC_STORE(&props->Radius, source->Radius, almemory_order_relaxed); + props->Radius = source->Radius; - ATOMIC_STORE(&props->Direct.Gain, source->Direct.Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.GainHF, source->Direct.GainHF, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.HFReference, source->Direct.HFReference, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.GainLF, source->Direct.GainLF, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.LFReference, source->Direct.LFReference, almemory_order_relaxed); + props->Direct.Gain = source->Direct.Gain; + props->Direct.GainHF = source->Direct.GainHF; + props->Direct.HFReference = source->Direct.HFReference; + props->Direct.GainLF = source->Direct.GainLF; + props->Direct.LFReference = source->Direct.LFReference; for(i = 0;i < num_sends;i++) { - ATOMIC_STORE(&props->Send[i].Slot, source->Send[i].Slot, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].Gain, source->Send[i].Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].GainHF, source->Send[i].GainHF, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].HFReference, source->Send[i].HFReference, - almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].GainLF, source->Send[i].GainLF, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].LFReference, source->Send[i].LFReference, - almemory_order_relaxed); + props->Send[i].Slot = source->Send[i].Slot; + props->Send[i].Gain = source->Send[i].Gain; + props->Send[i].GainHF = source->Send[i].GainHF; + props->Send[i].HFReference = source->Send[i].HFReference; + props->Send[i].GainLF = source->Send[i].GainLF; + props->Send[i].LFReference = source->Send[i].LFReference; } /* Set the new container for updating internal parameters. */ -- cgit v1.2.3 From 1c49d0542d53133c1e023fc22ff5537ea3ca41aa Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 23 Mar 2017 19:16:32 -0700 Subject: Use an atomic flag to mark auxiliary effect slot updates --- OpenAL32/Include/alAuxEffectSlot.h | 5 +++-- OpenAL32/alAuxEffectSlot.c | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 3c24f80c..c6e40a55 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -4,6 +4,7 @@ #include "alMain.h" #include "alEffect.h" +#include "atomic.h" #include "align.h" #ifdef __cplusplus @@ -88,8 +89,6 @@ struct ALeffectslotProps { typedef struct ALeffectslot { - ALboolean NeedsUpdate; - ALfloat Gain; ALboolean AuxSendAuto; @@ -100,6 +99,8 @@ typedef struct ALeffectslot { ALeffectState *State; } Effect; + ATOMIC_FLAG PropsClean; + RefCount ref; ATOMIC(struct ALeffectslotProps*) Update; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 37316549..8fc62bde 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -60,7 +60,7 @@ static void ALeffectState_DecRef(ALeffectState *state); if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ UpdateEffectSlotProps(slot); \ else \ - slot->NeedsUpdate = AL_TRUE; \ + ATOMIC_FLAG_CLEAR(&slot->PropsClean, almemory_order_release); \ } while(0) @@ -579,9 +579,9 @@ ALenum InitEffectSlot(ALeffectslot *slot) if(!(slot->Effect.State=V0(factory,create)())) return AL_OUT_OF_MEMORY; - slot->NeedsUpdate = AL_FALSE; slot->Gain = 1.0; slot->AuxSendAuto = AL_TRUE; + ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_relaxed); InitRef(&slot->ref, 0); ATOMIC_INIT(&slot->Update, NULL); @@ -683,9 +683,8 @@ void UpdateAllEffectSlotProps(ALCcontext *context) slot = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); while(slot) { - if(slot->NeedsUpdate) + if(ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) UpdateEffectSlotProps(slot); - slot->NeedsUpdate = AL_FALSE; slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } UnlockEffectSlotsRead(context); -- cgit v1.2.3 From 1aca34468877feb07a2c05a23d4fdb8f41cecfd2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 23 Mar 2017 19:32:53 -0700 Subject: Fix handling of the PropsClean flags --- OpenAL32/alAuxEffectSlot.c | 2 +- OpenAL32/alSource.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 8fc62bde..65107287 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -683,7 +683,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context) slot = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); while(slot) { - if(ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) + if(!ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) UpdateEffectSlotProps(slot); slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a882cb83..e18a00e2 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -3113,7 +3113,7 @@ void UpdateAllSourceProps(ALCcontext *context) { ALvoice *voice = context->Voices[pos]; ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); - if(source != NULL && ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel)) + if(source != NULL && !ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel)) UpdateSourceProps(source, num_sends); } } -- cgit v1.2.3 From 70aefa75e2253ef7a93cdd6412e8523663d3c6e9 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 27 Mar 2017 23:16:23 -0700 Subject: Use an array of pointers for effects instead of a linked list --- Alc/ALc.c | 12 +++- Alc/ALu.c | 34 +++++------ OpenAL32/Include/alAuxEffectSlot.h | 8 ++- OpenAL32/Include/alMain.h | 2 +- OpenAL32/alAuxEffectSlot.c | 113 +++++++++++++++++++++++-------------- common/uintmap.c | 75 ++++++++++++++++++++++++ include/uintmap.h | 1 + 7 files changed, 179 insertions(+), 66 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 8d241802..84007020 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2449,6 +2449,7 @@ static ALCboolean VerifyDevice(ALCdevice **device) static ALvoid InitContext(ALCcontext *Context) { ALlistener *listener = Context->Listener; + struct ALeffectslotArray *auxslots; //Initialise listener listener->Gain = 1.0f; @@ -2490,6 +2491,10 @@ static ALvoid InitContext(ALCcontext *Context) InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax); InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax); + auxslots = al_calloc(DEF_ALIGN, offsetof(struct ALeffectslotArray, slot[0])); + auxslots->count = 0; + ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots); + //Set globals Context->DistanceModel = DefaultDistanceModel; Context->SourceDistanceModel = AL_FALSE; @@ -2510,11 +2515,16 @@ static ALvoid InitContext(ALCcontext *Context) static void FreeContext(ALCcontext *context) { ALlistener *listener = context->Listener; + struct ALeffectslotArray *auxslots; struct ALlistenerProps *lprops; size_t count; TRACE("%p\n", context); + auxslots = ATOMIC_EXCHANGE(struct ALeffectslotArray*, &context->ActiveAuxSlots, + NULL, almemory_order_relaxed); + al_free(auxslots); + if(context->SourceMap.size > 0) { WARN("(%p) Deleting %d Source%s\n", context, context->SourceMap.size, @@ -3511,7 +3521,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin ALContext->Listener = (ALlistener*)ALContext->_listener_mem; ALContext->Device = device; - ATOMIC_INIT(&ALContext->ActiveAuxSlotList, NULL); + ATOMIC_INIT(&ALContext->ActiveAuxSlots, NULL); ALContext->Voices = NULL; ALContext->MaxVoices = 0; diff --git a/Alc/ALu.c b/Alc/ALu.c index 7936c706..f0e4d735 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1281,20 +1281,18 @@ static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *conte } -static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) +static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray *slots) { ALvoice **voice, **voice_end; ALsource *source; + ALsizei i; IncrementRef(&ctx->UpdateCount); if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire)) { ALboolean force = CalcListenerParams(ctx); - while(slot) - { - force |= CalcEffectSlotParams(slot, ctx->Device); - slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); - } + for(i = 0;i < slots->count;i++) + force |= CalcEffectSlotParams(slots->slot[i], ctx->Device); voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; @@ -1417,24 +1415,23 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) if((slot=device->DefaultSlot) != NULL) { CalcEffectSlotParams(device->DefaultSlot, device); - for(i = 0;i < slot->NumChannels;i++) - memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); + for(c = 0;c < slot->NumChannels;c++) + memset(slot->WetBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); } ctx = ATOMIC_LOAD(&device->ContextList, almemory_order_acquire); while(ctx) { - ALeffectslot *slotroot; + const struct ALeffectslotArray *auxslots; - slotroot = ATOMIC_LOAD(&ctx->ActiveAuxSlotList, almemory_order_acquire); - UpdateContextSources(ctx, slotroot); + auxslots = ATOMIC_LOAD(&ctx->ActiveAuxSlots, almemory_order_acquire); + UpdateContextSources(ctx, auxslots); - slot = slotroot; - while(slot) + for(i = 0;i < auxslots->count;i++) { - for(i = 0;i < slot->NumChannels;i++) - memset(slot->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); - slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); + ALeffectslot *slot = auxslots->slot[i]; + for(c = 0;c < slot->NumChannels;c++) + memset(slot->WetBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); } /* source processing */ @@ -1455,13 +1452,12 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) } /* effect slot processing */ - slot = slotroot; - while(slot) + for(i = 0;i < auxslots->count;i++) { + ALeffectslot *slot = auxslots->slot[i]; ALeffectState *state = slot->Params.EffectState; V(state,process)(SamplesToDo, SAFE_CONST(ALfloatBUFFERSIZE*,slot->WetBuffer), state->OutBuffer, state->OutChannels); - slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } ctx = ctx->next; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index c6e40a55..7f95dc91 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -75,6 +75,12 @@ static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = #define MAX_EFFECT_CHANNELS (4) +struct ALeffectslotArray { + ALsizei count; + struct ALeffectslot *slot[]; +}; + + struct ALeffectslotProps { ALfloat Gain; ALboolean AuxSendAuto; @@ -134,8 +140,6 @@ typedef struct ALeffectslot { * first-order device output (FOAOut). */ alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]; - - ATOMIC(struct ALeffectslot*) next; } ALeffectslot; inline void LockEffectSlotsRead(ALCcontext *context) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 2182d3f0..9c1ef099 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -855,7 +855,7 @@ struct ALCcontext_struct { ALsizei VoiceCount; ALsizei MaxVoices; - ATOMIC(struct ALeffectslot*) ActiveAuxSlotList; + ATOMIC(struct ALeffectslotArray*) ActiveAuxSlots; ALCdevice *Device; const ALCchar *ExtensionList; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 65107287..743fac14 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -42,8 +42,6 @@ extern inline void UnlockEffectSlotsWrite(ALCcontext *context); extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); -static void RemoveEffectSlotList(ALCcontext *Context, ALeffectslot *slot); - static UIntMap EffectStateFactoryMap; static inline ALeffectStateFactory *getFactoryByType(ALenum type) { @@ -67,7 +65,7 @@ static void ALeffectState_DecRef(ALeffectState *state); AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *context; - ALeffectslot *first, *last; + ALeffectslot **tmpslots = NULL; ALsizei cur; ALenum err; @@ -76,8 +74,9 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + tmpslots = al_malloc(DEF_ALIGN, sizeof(ALeffectslot*)*n); - first = last = NULL; + LockEffectSlotsWrite(context); for(cur = 0;cur < n;cur++) { ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); @@ -85,13 +84,15 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) { al_free(slot); + UnlockEffectSlotsWrite(context); + alDeleteAuxiliaryEffectSlots(cur, effectslots); SET_ERROR_AND_GOTO(context, err, done); } err = NewThunkEntry(&slot->id); if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&context->EffectSlotMap, slot->id, slot); + err = InsertUIntMapEntryNoLock(&context->EffectSlotMap, slot->id, slot); if(err != AL_NO_ERROR) { FreeThunkEntry(slot->id); @@ -99,6 +100,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(slot->Params.EffectState) ALeffectState_DecRef(slot->Params.EffectState); al_free(slot); + UnlockEffectSlotsWrite(context); alDeleteAuxiliaryEffectSlots(cur, effectslots); SET_ERROR_AND_GOTO(context, err, done); @@ -106,22 +108,36 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo aluInitEffectPanning(slot); - if(!first) first = slot; - if(last) ATOMIC_STORE(&last->next, slot, almemory_order_relaxed); - last = slot; - + tmpslots[cur] = slot; effectslots[cur] = slot->id; } - if(last != NULL) + if(n > 0) { - ALeffectslot *root = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); - do { - ATOMIC_STORE(&last->next, root, almemory_order_relaxed); - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALeffectslot*, &context->ActiveAuxSlotList, - &root, first)); + struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); + struct ALeffectslotArray *newarray = NULL; + ALsizei newcount = curarray->count + n; + ALCdevice *device; + + newarray = al_calloc(DEF_ALIGN, + offsetof(struct ALeffectslotArray, slot[newcount]) + ); + newarray->count = newcount; + memcpy(newarray->slot, tmpslots, sizeof(ALeffectslot*)*n); + if(curarray) + memcpy(newarray->slot+n, curarray->slot, sizeof(ALeffectslot*)*curarray->count); + + newarray = ATOMIC_EXCHANGE(struct ALeffectslotArray*, + &context->ActiveAuxSlots, newarray, almemory_order_acq_rel + ); + device = context->Device; + while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) + althrd_yield(); + al_free(newarray); } + UnlockEffectSlotsWrite(context); done: + al_free(tmpslots); ALCcontext_DecRef(context); } @@ -146,13 +162,46 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * } // All effectslots are valid + if(n > 0) + { + struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); + struct ALeffectslotArray *newarray = NULL; + ALsizei newcount = curarray->count - n; + ALCdevice *device; + ALsizei j, k; + + assert(newcount >= 0); + newarray = al_calloc(DEF_ALIGN, + offsetof(struct ALeffectslotArray, slot[newcount]) + ); + newarray->count = newcount; + for(i = j = 0;i < newarray->count;) + { + slot = curarray->slot[j++]; + for(k = 0;k < n;k++) + { + if(slot->id == effectslots[k]) + break; + } + if(k == n) + newarray->slot[i++] = slot; + } + + newarray = ATOMIC_EXCHANGE(struct ALeffectslotArray*, + &context->ActiveAuxSlots, newarray, almemory_order_acq_rel + ); + device = context->Device; + while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) + althrd_yield(); + al_free(newarray); + } + for(i = 0;i < n;i++) { if((slot=RemoveEffectSlot(context, effectslots[i])) == NULL) continue; FreeThunkEntry(slot->id); - RemoveEffectSlotList(context, slot); DeinitEffectSlot(slot); memset(slot, 0, sizeof(*slot)); @@ -430,27 +479,6 @@ done: } -static void RemoveEffectSlotList(ALCcontext *context, ALeffectslot *slot) -{ - ALCdevice *device = context->Device; - ALeffectslot *root, *next; - - root = slot; - next = ATOMIC_LOAD_SEQ(&slot->next); - if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALeffectslot*, &context->ActiveAuxSlotList, &root, next)) - { - ALeffectslot *cur; - do { - cur = root; - root = slot; - } while(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALeffectslot*, &cur->next, &root, next)); - } - /* Wait for any mix that may be using these effect slots to finish. */ - while((ReadRef(&device->MixCount)&1) != 0) - althrd_yield(); -} - - void InitEffectFactoryMap(void) { InitUIntMap(&EffectStateFactoryMap, ~0); @@ -595,8 +623,6 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.DecayTime = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; - ATOMIC_INIT(&slot->next, NULL); - return AL_NO_ERROR; } @@ -677,15 +703,16 @@ void UpdateEffectSlotProps(ALeffectslot *slot) void UpdateAllEffectSlotProps(ALCcontext *context) { - ALeffectslot *slot; + struct ALeffectslotArray *auxslots; + ALsizei i; LockEffectSlotsRead(context); - slot = ATOMIC_LOAD_SEQ(&context->ActiveAuxSlotList); - while(slot) + auxslots = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); + for(i = 0;i < auxslots->count;i++) { + ALeffectslot *slot = auxslots->slot[i]; if(!ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) UpdateEffectSlotProps(slot); - slot = ATOMIC_LOAD(&slot->next, almemory_order_relaxed); } UnlockEffectSlotsRead(context); } diff --git a/common/uintmap.c b/common/uintmap.c index 7b27b36e..21a921b2 100644 --- a/common/uintmap.c +++ b/common/uintmap.c @@ -119,6 +119,81 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) return AL_NO_ERROR; } +ALenum InsertUIntMapEntryNoLock(UIntMap *map, ALuint key, ALvoid *value) +{ + ALsizei pos = 0; + + if(map->size > 0) + { + ALsizei count = map->size; + do { + ALsizei step = count>>1; + ALsizei i = pos+step; + if(!(map->keys[i] < key)) + count = step; + else + { + pos = i+1; + count -= step+1; + } + } while(count > 0); + } + + if(pos == map->size || map->keys[pos] != key) + { + if(map->size == map->limit) + return AL_OUT_OF_MEMORY; + + if(map->size == map->capacity) + { + ALuint *keys = NULL; + ALvoid **values; + ALsizei newcap, keylen; + + newcap = (map->capacity ? (map->capacity<<1) : 4); + if(map->limit > 0 && newcap > map->limit) + newcap = map->limit; + if(newcap > map->capacity) + { + /* Round the memory size for keys up to a multiple of the + * pointer size. + */ + keylen = newcap * sizeof(map->keys[0]); + keylen += sizeof(map->values[0]) - 1; + keylen -= keylen%sizeof(map->values[0]); + + keys = al_malloc(16, keylen + newcap*sizeof(map->values[0])); + } + if(!keys) + return AL_OUT_OF_MEMORY; + values = (ALvoid**)((ALbyte*)keys + keylen); + + if(map->keys) + { + memcpy(keys, map->keys, map->size*sizeof(map->keys[0])); + memcpy(values, map->values, map->size*sizeof(map->values[0])); + } + al_free(map->keys); + map->keys = keys; + map->values = values; + map->capacity = newcap; + } + + if(pos < map->size) + { + memmove(&map->keys[pos+1], &map->keys[pos], + (map->size-pos)*sizeof(map->keys[0])); + memmove(&map->values[pos+1], &map->values[pos], + (map->size-pos)*sizeof(map->values[0])); + } + map->size++; + } + map->keys[pos] = key; + map->values[pos] = value; + + return AL_NO_ERROR; +} + ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key) { ALvoid *ptr = NULL; diff --git a/include/uintmap.h b/include/uintmap.h index acb2749a..f70d99fd 100644 --- a/include/uintmap.h +++ b/include/uintmap.h @@ -24,6 +24,7 @@ typedef struct UIntMap { void InitUIntMap(UIntMap *map, ALsizei limit); void ResetUIntMap(UIntMap *map); ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value); +ALenum InsertUIntMapEntryNoLock(UIntMap *map, ALuint key, ALvoid *value); ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key); ALvoid *RemoveUIntMapKeyNoLock(UIntMap *map, ALuint key); ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key); -- cgit v1.2.3 From f94fa5d5cfb78ab5438a53b2ad17f033660103c9 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 14 Apr 2017 17:47:55 -0700 Subject: Use separate atomic macros for pointers --- Alc/ALc.c | 36 ++++++------ Alc/ALu.c | 12 ++-- Alc/backends/opensl.c | 4 +- Alc/backends/oss.c | 4 +- Alc/backends/solaris.c | 2 +- Alc/helpers.c | 4 +- OpenAL32/alAuxEffectSlot.c | 18 +++--- OpenAL32/alError.c | 4 +- OpenAL32/alListener.c | 7 +-- OpenAL32/alSource.c | 19 +++---- include/atomic.h | 133 ++++++++++++++++++++++++++++----------------- 11 files changed, 135 insertions(+), 108 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 2a636c59..cc9aa5c3 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1247,7 +1247,7 @@ static void alc_cleanup(void) free(alcCaptureDefaultDeviceSpecifier); alcCaptureDefaultDeviceSpecifier = NULL; - if((dev=ATOMIC_EXCHANGE_SEQ(ALCdevice*, &DeviceList, NULL)) != NULL) + if((dev=ATOMIC_EXCHANGE_PTR_SEQ(&DeviceList, NULL)) != NULL) { ALCuint num = 0; do { @@ -1678,7 +1678,7 @@ void ALCcontext_DeferUpdates(ALCcontext *context) void ALCcontext_ProcessUpdates(ALCcontext *context) { ReadLock(&context->PropLock); - if(ATOMIC_EXCHANGE_SEQ(ALenum, &context->DeferUpdates, AL_FALSE)) + if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE)) { /* Tell the mixer to stop applying updates, then wait for any active * updating to finish, before providing updates. @@ -2225,11 +2225,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) * number of auxiliary sends changed. Playing (or paused) sources * will have updates respecified in UpdateAllSourceProps. */ - props = ATOMIC_EXCHANGE_SEQ(struct ALsourceProps*, &source->Update, NULL); + props = ATOMIC_EXCHANGE_PTR_SEQ(&source->Update, NULL); al_free(props); - props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->FreeList, NULL, - almemory_order_relaxed); + props = ATOMIC_EXCHANGE_PTR(&source->FreeList, NULL, almemory_order_relaxed); while(props) { struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); @@ -2489,8 +2488,7 @@ static void FreeContext(ALCcontext *context) TRACE("%p\n", context); - auxslots = ATOMIC_EXCHANGE(struct ALeffectslotArray*, &context->ActiveAuxSlots, - NULL, almemory_order_relaxed); + auxslots = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, NULL, almemory_order_relaxed); al_free(auxslots); if(context->SourceMap.size > 0) @@ -2557,13 +2555,13 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device) } origctx = context; - if(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &GlobalContext, &origctx, NULL)) + if(ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&GlobalContext, &origctx, NULL)) ALCcontext_DecRef(context); ALCdevice_Lock(device); origctx = context; newhead = context->next; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCcontext*, &device->ContextList, &origctx, newhead)) + if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&device->ContextList, &origctx, newhead)) { ALCcontext *volatile*list = &origctx->next; while(*list) @@ -2750,11 +2748,11 @@ ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) if(VerifyDevice(&device)) { - errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &device->LastError, ALC_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(&device->LastError, ALC_NO_ERROR); ALCdevice_DecRef(device); } else - errorCode = ATOMIC_EXCHANGE_SEQ(ALCenum, &LastNullDeviceError, ALC_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(&LastNullDeviceError, ALC_NO_ERROR); return errorCode; } @@ -3549,8 +3547,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin ALCcontext *head = ATOMIC_LOAD_SEQ(&device->ContextList); do { ALContext->next = head; - } while(ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCcontext*, - &device->ContextList, &head, ALContext) == 0); + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&device->ContextList, &head, + ALContext) == 0); } almtx_unlock(&device->BackendLock); @@ -3628,7 +3626,7 @@ ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) return ALC_FALSE; } /* context's reference count is already incremented */ - context = ATOMIC_EXCHANGE_SEQ(ALCcontext*, &GlobalContext, context); + context = ATOMIC_EXCHANGE_PTR_SEQ(&GlobalContext, context); if(context) ALCcontext_DecRef(context); if((context=altss_get(LocalContext)) != NULL) @@ -3937,7 +3935,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device)); } TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName)); @@ -3968,7 +3966,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) almtx_lock(&device->BackendLock); origdev = device; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next)) + if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next)) { ALCdevice *volatile*list = &origdev->next; while(*list) @@ -4113,7 +4111,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device)); } TRACE("Created device %p, \"%s\"\n", device, alstr_get_cstr(device->DeviceName)); @@ -4138,7 +4136,7 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) } origdev = device; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALCdevice*, &DeviceList, &origdev, device->next)) + if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&DeviceList, &origdev, device->next)) { ALCdevice *volatile*list = &origdev->next; while(*list) @@ -4334,7 +4332,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); do { device->next = head; - } while(!ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(ALCdevice*, &DeviceList, &head, device)); + } while(!ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(&DeviceList, &head, device)); } TRACE("Created device %p\n", device); diff --git a/Alc/ALu.c b/Alc/ALu.c index 4f41d012..89689fba 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -241,7 +241,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context) struct ALlistenerProps *props; aluVector vel; - props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&Listener->Update, NULL, almemory_order_acq_rel); if(!props) return AL_FALSE; /* AT then UP */ @@ -291,7 +291,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) struct ALeffectslotProps *props; ALeffectState *state; - props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&slot->Update, NULL, almemory_order_acq_rel); if(!props) return AL_FALSE; slot->Params.Gain = props->Gain; @@ -1252,7 +1252,7 @@ static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *conte const ALbufferlistitem *BufferListItem; struct ALsourceProps *props; - props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&source->Update, NULL, almemory_order_acq_rel); if(!props && !force) return; if(props) @@ -1607,14 +1607,14 @@ void aluHandleDisconnect(ALCdevice *device) voice_end = voice + Context->VoiceCount; while(voice != voice_end) { - ALsource *source = ATOMIC_EXCHANGE(ALsource*, &(*voice)->Source, NULL, - almemory_order_acq_rel); + ALsource *source = ATOMIC_EXCHANGE_PTR(&(*voice)->Source, NULL, + almemory_order_acq_rel); ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release); if(source) { ALenum playing = AL_PLAYING; - ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED); + (void)(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(&source->state, &playing, AL_STOPPED)); } voice++; diff --git a/Alc/backends/opensl.c b/Alc/backends/opensl.c index 622437b8..4e295f23 100644 --- a/Alc/backends/opensl.c +++ b/Alc/backends/opensl.c @@ -149,7 +149,7 @@ typedef struct ALCopenslPlayback { ALsizei mFrameSize; - ATOMIC(ALboolean) mKillNow; + ATOMIC(ALenum) mKillNow; althrd_t mThread; } ALCopenslPlayback; @@ -637,7 +637,7 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self) SLresult result; int res; - if(ATOMIC_EXCHANGE_SEQ(ALboolean, &self->mKillNow, AL_TRUE)) + if(ATOMIC_EXCHANGE_SEQ(&self->mKillNow, AL_TRUE)) return; /* Lock the backend to ensure we don't flag the mixer to die and signal the diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c index 6774a789..33ea55eb 100644 --- a/Alc/backends/oss.c +++ b/Alc/backends/oss.c @@ -491,7 +491,7 @@ static void ALCplaybackOSS_stop(ALCplaybackOSS *self) { int res; - if(ATOMIC_EXCHANGE_SEQ(ALenum, &self->killNow, AL_TRUE)) + if(ATOMIC_EXCHANGE_SEQ(&self->killNow, AL_TRUE)) return; althrd_join(self->thread, &res); @@ -745,7 +745,7 @@ static void ALCcaptureOSS_stop(ALCcaptureOSS *self) { int res; - if(ATOMIC_EXCHANGE_SEQ(ALenum, &self->killNow, AL_TRUE)) + if(ATOMIC_EXCHANGE_SEQ(&self->killNow, AL_TRUE)) return; althrd_join(self->thread, &res); diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c index 5b3f6136..5dfb5084 100644 --- a/Alc/backends/solaris.c +++ b/Alc/backends/solaris.c @@ -285,7 +285,7 @@ static void ALCsolarisBackend_stop(ALCsolarisBackend *self) { int res; - if(ATOMIC_EXCHANGE_SEQ(int, &self->killNow, AL_TRUE)) + if(ATOMIC_EXCHANGE_SEQ(&self->killNow, AL_TRUE)) return; althrd_join(self->thread, &res); diff --git a/Alc/helpers.c b/Alc/helpers.c index 5d23c3a7..8e685c75 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -564,7 +564,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) vector_al_string results = VECTOR_INIT_STATIC(); size_t i; - while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1) + while(ATOMIC_EXCHANGE_SEQ(&search_lock, 1) == 1) althrd_yield(); /* If the path is absolute, use it directly. */ @@ -840,7 +840,7 @@ vector_al_string SearchDataFiles(const char *ext, const char *subdir) static RefCount search_lock; vector_al_string results = VECTOR_INIT_STATIC(); - while(ATOMIC_EXCHANGE_SEQ(uint, &search_lock, 1) == 1) + while(ATOMIC_EXCHANGE_SEQ(&search_lock, 1) == 1) althrd_yield(); if(subdir[0] == '/') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 743fac14..de7de943 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -126,9 +126,8 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(curarray) memcpy(newarray->slot+n, curarray->slot, sizeof(ALeffectslot*)*curarray->count); - newarray = ATOMIC_EXCHANGE(struct ALeffectslotArray*, - &context->ActiveAuxSlots, newarray, almemory_order_acq_rel - ); + newarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, + almemory_order_acq_rel); device = context->Device; while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) althrd_yield(); @@ -187,9 +186,8 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * newarray->slot[i++] = slot; } - newarray = ATOMIC_EXCHANGE(struct ALeffectslotArray*, - &context->ActiveAuxSlots, newarray, almemory_order_acq_rel - ); + newarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, + almemory_order_acq_rel); device = context->Device; while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) althrd_yield(); @@ -668,9 +666,8 @@ void UpdateEffectSlotProps(ALeffectslot *slot) struct ALeffectslotProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, - &slot->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_acquire) == 0); + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&slot->FreeList, &props, next, + almemory_order_seq_cst, almemory_order_acquire) == 0); } /* Copy in current property values. */ @@ -687,8 +684,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) props->State = slot->Effect.State; /* Set the new container for updating internal parameters. */ - props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, - almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&slot->Update, props, almemory_order_acq_rel); if(props) { /* If there was an unused update container, put it back in the diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c index 19fcaa6d..6c953977 100644 --- a/OpenAL32/alError.c +++ b/OpenAL32/alError.c @@ -49,7 +49,7 @@ ALvoid alSetError(ALCcontext *Context, ALenum errorCode) #endif } - ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Context->LastError, &curerr, errorCode); + (void)(ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(&Context->LastError, &curerr, errorCode)); } AL_API ALenum AL_APIENTRY alGetError(void) @@ -74,7 +74,7 @@ AL_API ALenum AL_APIENTRY alGetError(void) return AL_INVALID_OPERATION; } - errorCode = ATOMIC_EXCHANGE_SEQ(ALenum, &Context->LastError, AL_NO_ERROR); + errorCode = ATOMIC_EXCHANGE_SEQ(&Context->LastError, AL_NO_ERROR); ALCcontext_DecRef(Context); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index e3d71435..d117c0ca 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -468,9 +468,8 @@ void UpdateListenerProps(ALCcontext *context) struct ALlistenerProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, - &listener->FreeList, &props, next, almemory_order_seq_cst, - almemory_order_acquire) == 0); + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&listener->FreeList, &props, next, + almemory_order_seq_cst, almemory_order_acquire) == 0); } /* Copy in current property values. */ @@ -500,7 +499,7 @@ void UpdateListenerProps(ALCcontext *context) props->DistanceModel = context->DistanceModel;; /* Set the new container for updating internal parameters. */ - props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &listener->Update, props, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&listener->Update, props, almemory_order_acq_rel); if(props) { /* If there was an unused update container, put it back in the diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a8c4ce2f..040078df 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -158,7 +158,7 @@ static inline ALenum GetSourceState(ALsource *source, ALvoice *voice) if(!voice) { ALenum state = AL_PLAYING; - if(ATOMIC_COMPARE_EXCHANGE_STRONG(ALenum, &source->state, &state, AL_STOPPED, + if(ATOMIC_COMPARE_EXCHANGE_STRONG(&source->state, &state, AL_STOPPED, almemory_order_acq_rel, almemory_order_acquire)) return AL_STOPPED; return state; @@ -747,7 +747,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->SourceType = AL_UNDETERMINED; newlist = NULL; } - oldlist = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &Source->queue, newlist); + oldlist = ATOMIC_EXCHANGE_PTR_SEQ(&Source->queue, newlist); WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -2784,8 +2784,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu source->SourceType = AL_STREAMING; BufferList = NULL; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->queue, - &BufferList, BufferListStart)) + if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&source->queue, &BufferList, + BufferListStart)) { /* Queue head is not NULL, append to the end of the queue */ while(BufferList->next != NULL) @@ -2854,7 +2854,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Swap it, and cut the new head from the old. */ - OldHead = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, OldTail->next); + OldHead = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, OldTail->next); if(OldTail->next) { ALCdevice *device = context->Device; @@ -3003,7 +3003,7 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) if(count > 3) WARN("Freed "SZFMT" Source property objects\n", count); - BufferList = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &source->queue, NULL); + BufferList = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, NULL); while(BufferList != NULL) { ALbufferlistitem *next = BufferList->next; @@ -3040,9 +3040,8 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends) struct ALsourceProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, - &source->FreeList, &props, next, almemory_order_acq_rel, - almemory_order_acquire) == 0); + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&source->FreeList, &props, next, + almemory_order_acq_rel, almemory_order_acquire) == 0); } /* Copy in current property values. */ @@ -3103,7 +3102,7 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends) } /* Set the new container for updating internal parameters. */ - props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, props, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&source->Update, props, almemory_order_acq_rel); if(props) { /* If there was an unused update container, put it back in the diff --git a/include/atomic.h b/include/atomic.h index 57609c33..a42cfa4a 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -34,10 +34,10 @@ extern "C" { #define ATOMIC_ADD(_val, _incr, _MO) atomic_fetch_add_explicit(_val, _incr, _MO) #define ATOMIC_SUB(_val, _decr, _MO) atomic_fetch_sub_explicit(_val, _decr, _MO) -#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) atomic_exchange_explicit(_val, _newval, _MO) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _orig, _newval, _MO1, _MO2) \ +#define ATOMIC_EXCHANGE(_val, _newval, _MO) atomic_exchange_explicit(_val, _newval, _MO) +#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _orig, _newval, _MO1, _MO2) \ atomic_compare_exchange_strong_explicit(_val, _orig, _newval, _MO1, _MO2) -#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _orig, _newval, _MO1, _MO2) \ +#define ATOMIC_COMPARE_EXCHANGE_WEAK(_val, _orig, _newval, _MO1, _MO2) \ atomic_compare_exchange_weak_explicit(_val, _orig, _newval, _MO1, _MO2) #define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) atomic_flag_test_and_set_explicit(_val, _MO) @@ -77,14 +77,12 @@ enum almemory_order { #define ATOMIC_ADD(_val, _incr, _MO) __sync_fetch_and_add(&(_val)->value, (_incr)) #define ATOMIC_SUB(_val, _decr, _MO) __sync_fetch_and_sub(&(_val)->value, (_decr)) -#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) __extension__({ \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ +#define ATOMIC_EXCHANGE(_val, _newval, _MO) __extension__({ \ __asm__ __volatile__("" ::: "memory"); \ __sync_lock_test_and_set(&(_val)->value, (_newval)); \ }) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) __extension__({ \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _o = *(_oldval); \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, _MO1, _MO2) __extension__({ \ + __typeof(*(_oldval)) _o = *(_oldval); \ *(_oldval) = __sync_val_compare_and_swap(&(_val)->value, _o, (_newval)); \ *(_oldval) == _o; \ }) @@ -175,20 +173,29 @@ enum almemory_order { _r; \ }) -#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) __extension__({ \ - static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _r; \ - if(sizeof(T) == 4) WRAP_XCHG("l", _r, &(_val)->value, (T)(_newval)); \ - else if(sizeof(T) == 8) WRAP_XCHG("q", _r, &(_val)->value, (T)(_newval)); \ +#define ATOMIC_EXCHANGE(_val, _newval, _MO) __extension__({ \ + __typeof((_val)->value) _r; \ + if(sizeof((_val)->value) == 4) WRAP_XCHG("l", _r, &(_val)->value, (_newval)); \ + else if(sizeof((_val)->value) == 8) WRAP_XCHG("q", _r, &(_val)->value, (_newval)); \ _r; \ }) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) __extension__({ \ - static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _old = *(_oldval); \ - if(sizeof(T) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (T)(_newval)); \ - else if(sizeof(T) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (T)(_newval)); \ +#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, _MO1, _MO2) __extension__({ \ + __typeof(*(_oldval)) _old = *(_oldval); \ + if(sizeof((_val)->value) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (_newval)); \ + else if(sizeof((_val)->value) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (_newval)); \ + *(_oldval) == _old; \ +}) + +#define ATOMIC_EXCHANGE_PTR(_val, _newval, _MO) __extension__({ \ + void *_r; \ + if(sizeof(void*) == 4) WRAP_XCHG("l", _r, &(_val)->value, (_newval)); \ + else if(sizeof(void*) == 8) WRAP_XCHG("q", _r, &(_val)->value, (_newval));\ + _r; \ +}) +#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG(_val, _oldval, _newval, _MO1, _MO2) __extension__({ \ + void *_old = *(_oldval); \ + if(sizeof(void*) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (_newval)); \ + else if(sizeof(void*) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (_newval)); \ *(_oldval) == _old; \ }) @@ -205,14 +212,13 @@ enum almemory_order { #define WIN32_LEAN_AND_MEAN #include -/* NOTE: This mess is *extremely* noisy, at least on GCC. It works by wrapping - * Windows' 32-bit and 64-bit atomic methods, which are then casted to use the - * given type based on its size (e.g. int and float use 32-bit atomics). This - * is fine for the swap and compare-and-swap methods, although the add and - * subtract methods only work properly for integer types. +/* NOTE: This mess is *extremely* touchy. It lacks quite a bit of safety + * checking due to the lack of multi-statement expressions, typeof(), and C99 + * compound literals. It is incapable of properly exchanging floats, which get + * casted to LONG/int, and could cast away potential warnings. * - * Despite how noisy it is, it's unfortunately the only way that doesn't rely - * on C99 (damn MSVC). + * Unfortunately, it's the only semi-safe way that doesn't rely on C99 (because + * MSVC). */ inline LONG AtomicAdd32(volatile LONG *dest, LONG incr) @@ -240,6 +246,10 @@ inline LONGLONG AtomicSwap64(volatile LONGLONG *dest, LONGLONG newval) { return InterlockedExchange64(dest, newval); } +inline void *AtomicSwapPtr(void *volatile *dest, void *newval) +{ + return InterlockedExchangePointer(dest, newval); +} inline bool CompareAndSwap32(volatile LONG *dest, LONG newval, LONG *oldval) { @@ -253,10 +263,16 @@ inline bool CompareAndSwap64(volatile LONGLONG *dest, LONGLONG newval, LONGLONG *oldval = InterlockedCompareExchange64(dest, newval, *oldval); return old == *oldval; } +inline bool CompareAndSwapPtr(void *volatile *dest, void *newval, void **oldval) +{ + void *old = *oldval; + *oldval = InterlockedCompareExchangePointer(dest, newval, *oldval); + return old == *oldval; +} #define WRAP_ADDSUB(T, _func, _ptr, _amnt) _func((T volatile*)(_ptr), (_amnt)) -#define WRAP_XCHG(T, _func, _ptr, _newval) ((T(*)(T volatile*,T))_func)((_ptr), (_newval)) -#define WRAP_CMPXCHG(T, _func, _ptr, _newval, _oldval) ((bool(*)(T volatile*,T,T*))_func)((_ptr), (_newval), (_oldval)) +#define WRAP_XCHG(T, _func, _ptr, _newval) _func((T volatile*)(_ptr), (_newval)) +#define WRAP_CMPXCHG(T, _func, _ptr, _newval, _oldval) _func((T volatile*)(_ptr), (_newval), (T*)(_oldval)) enum almemory_order { @@ -289,13 +305,20 @@ int _al_invalid_atomic_size(); /* not defined */ (sizeof((_val)->value)==8) ? WRAP_ADDSUB(LONGLONG, AtomicSub64, &(_val)->value, (_decr)) : \ _al_invalid_atomic_size()) -#define ATOMIC_EXCHANGE(T, _val, _newval, _MO) \ - ((sizeof(T)==4) ? WRAP_XCHG(T, AtomicSwap32, &(_val)->value, (_newval)) : \ - (sizeof(T)==8) ? WRAP_XCHG(T, AtomicSwap64, &(_val)->value, (_newval)) : \ - (T)_al_invalid_atomic_size()) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, _MO1, _MO2) \ - ((sizeof(T)==4) ? WRAP_CMPXCHG(T, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \ - (sizeof(T)==8) ? WRAP_CMPXCHG(T, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \ +#define ATOMIC_EXCHANGE(_val, _newval, _MO) \ + ((sizeof((_val)->value)==4) ? WRAP_XCHG(LONG, AtomicSwap32, &(_val)->value, (_newval)) : \ + (sizeof((_val)->value)==8) ? WRAP_XCHG(LONGLONG, AtomicSwap64, &(_val)->value, (_newval)) : \ + (LONG)_al_invalid_atomic_size()) +#define ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, _MO1, _MO2) \ + ((sizeof((_val)->value)==4) ? WRAP_CMPXCHG(LONG, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \ + (sizeof((_val)->value)==8) ? WRAP_CMPXCHG(LONGLONG, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \ + (bool)_al_invalid_atomic_size()) + +#define ATOMIC_EXCHANGE_PTR(_val, _newval, _MO) \ + ((sizeof((_val)->value)==sizeof(void*)) ? AtomicSwapPtr((void*volatile*)&(_val)->value, (_newval)) : \ + (void*)_al_invalid_atomic_size()) +#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG(_val, _oldval, _newval, _MO1, _MO2)\ + ((sizeof((_val)->value)==sizeof(void*)) ? CompareAndSwapPtr((void*volatile*)&(_val)->value, (_newval), (void**)(_oldval)) : \ (bool)_al_invalid_atomic_size()) #define ATOMIC_THREAD_FENCE(order) do { \ @@ -320,21 +343,27 @@ int _al_invalid_atomic_size(); /* not defined */ #define ATOMIC_ADD(...) (0) #define ATOMIC_SUB(...) (0) -#define ATOMIC_EXCHANGE(T, ...) (0) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, ...) (0) -#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, ...) (0) - -#define ATOMIC_FLAG_TEST_AND_SET(...) (0) -#define ATOMIC_FLAG_CLEAR(...) ((void)0) +#define ATOMIC_EXCHANGE(...) (0) +#define ATOMIC_COMPARE_EXCHANGE_STRONG(...) (0) #define ATOMIC_THREAD_FENCE(...) ((void)0) #endif +/* If no PTR xchg variants are provided, the normal ones can handle it. */ +#ifndef ATOMIC_EXCHANGE_PTR +#define ATOMIC_EXCHANGE_PTR ATOMIC_EXCHANGE +#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG ATOMIC_COMPARE_EXCHANGE_STRONG +#define ATOMIC_COMPARE_EXCHANGE_PTR_WEAK ATOMIC_COMPARE_EXCHANGE_WEAK +#endif + /* If no weak cmpxchg is provided (not all systems will have one), substitute a * strong cmpxchg. */ #ifndef ATOMIC_COMPARE_EXCHANGE_WEAK #define ATOMIC_COMPARE_EXCHANGE_WEAK ATOMIC_COMPARE_EXCHANGE_STRONG #endif +#ifndef ATOMIC_COMPARE_EXCHANGE_PTR_WEAK +#define ATOMIC_COMPARE_EXCHANGE_PTR_WEAK ATOMIC_COMPARE_EXCHANGE_PTR_STRONG +#endif /* If no ATOMIC_FLAG is defined, simulate one with an atomic int using exchange * and store ops. @@ -342,7 +371,7 @@ int _al_invalid_atomic_size(); /* not defined */ #ifndef ATOMIC_FLAG #define ATOMIC_FLAG ATOMIC(int) #define ATOMIC_FLAG_INIT ATOMIC_INIT_STATIC(0) -#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) ATOMIC_EXCHANGE(int, _val, 1, _MO) +#define ATOMIC_FLAG_TEST_AND_SET(_val, _MO) ATOMIC_EXCHANGE(_val, 1, _MO) #define ATOMIC_FLAG_CLEAR(_val, _MO) ATOMIC_STORE(_val, 0, _MO) #endif @@ -353,11 +382,17 @@ int _al_invalid_atomic_size(); /* not defined */ #define ATOMIC_ADD_SEQ(_val, _incr) ATOMIC_ADD(_val, _incr, almemory_order_seq_cst) #define ATOMIC_SUB_SEQ(_val, _decr) ATOMIC_SUB(_val, _decr, almemory_order_seq_cst) -#define ATOMIC_EXCHANGE_SEQ(T, _val, _newval) ATOMIC_EXCHANGE(T, _val, _newval, almemory_order_seq_cst) -#define ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(T, _val, _oldval, _newval) \ - ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) -#define ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(T, _val, _oldval, _newval) \ - ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) +#define ATOMIC_EXCHANGE_SEQ(_val, _newval) ATOMIC_EXCHANGE(_val, _newval, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(_val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_STRONG(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_WEAK_SEQ(_val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_WEAK(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) + +#define ATOMIC_EXCHANGE_PTR_SEQ(_val, _newval) ATOMIC_EXCHANGE_PTR(_val, _newval, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(_val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_PTR_STRONG(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) +#define ATOMIC_COMPARE_EXCHANGE_PTR_WEAK_SEQ(_val, _oldval, _newval) \ + ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(_val, _oldval, _newval, almemory_order_seq_cst, almemory_order_seq_cst) typedef unsigned int uint; @@ -381,7 +416,7 @@ inline uint DecrementRef(RefCount *ptr) T _first = ATOMIC_LOAD(_head, almemory_order_acquire); \ do { \ ATOMIC_STORE(&(_entry)->next, _first, almemory_order_relaxed); \ - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(T, _head, &_first, _entry, \ + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(_head, &_first, _entry, \ almemory_order_acq_rel, almemory_order_acquire) == 0); \ } while(0) -- cgit v1.2.3 From d9bf4f7620c1e13846a53ee9df5c8c9eb2fcfe7d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 14 Apr 2017 22:56:54 -0700 Subject: Allow increasing the maximum source limit If the requested number of mono and stereo sources exceeds 256, the source limit will be expanded. Any config file setting overrides this. If the device is reset to have fewer sources than are currently allocated, excess sources will remain and be usable as normal, but no more can be generated until enough are delated to go back below the limit. --- Alc/ALc.c | 74 ++++++++++++++++++++++++++++++++++++---------- OpenAL32/alAuxEffectSlot.c | 2 +- common/uintmap.c | 9 ++++-- common/uintmap.h | 3 +- 4 files changed, 69 insertions(+), 19 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index cc9aa5c3..2d0d64f5 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1834,13 +1834,18 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) return ALC_INVALID_VALUE; } + if(attrList[attrIdx] == ALC_MONO_SOURCES) + { + numMono = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_MONO_SOURCES, numMono); + numMono = maxi(numMono, 0); + } + if(attrList[attrIdx] == ALC_STEREO_SOURCES) { numStereo = attrList[attrIdx + 1]; TRACE_ATTR(ALC_STEREO_SOURCES, numStereo); - - numStereo = clampi(numStereo, 0, device->SourcesMax); - numMono = device->SourcesMax - numStereo; + numStereo = maxi(numStereo, 0); } if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS) @@ -1898,6 +1903,21 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->AmbiLayout = alayout; device->AmbiScale = ascale; } + + if(numMono > INT_MAX-numStereo) + numMono = INT_MAX-numStereo; + numMono += numStereo; + if(ConfigValueInt(NULL, NULL, "sources", &numMono)) + { + if(numMono <= 0) + numMono = 256; + } + else + numMono = maxi(numMono, 256); + numStereo = mini(numStereo, numMono); + numMono -= numStereo; + device->SourcesMax = numMono + numStereo; + device->NumMonoSources = numMono; device->NumStereoSources = numStereo; @@ -1935,13 +1955,18 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->Flags |= DEVICE_FREQUENCY_REQUEST; } + if(attrList[attrIdx] == ALC_MONO_SOURCES) + { + numMono = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_MONO_SOURCES, numMono); + numMono = maxi(numMono, 0); + } + if(attrList[attrIdx] == ALC_STEREO_SOURCES) { numStereo = attrList[attrIdx + 1]; TRACE_ATTR(ALC_STEREO_SOURCES, numStereo); - - numStereo = clampi(numStereo, 0, device->SourcesMax); - numMono = device->SourcesMax - numStereo; + numStereo = maxi(numStereo, 0); } if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS) @@ -1982,6 +2007,21 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->UpdateSize = (device->UpdateSize+3)&~3; device->Frequency = freq; + + if(numMono > INT_MAX-numStereo) + numMono = INT_MAX-numStereo; + numMono += numStereo; + if(ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "sources", &numMono)) + { + if(numMono <= 0) + numMono = 256; + } + else + numMono = maxi(numMono, 256); + numStereo = mini(numStereo, numMono); + numMono -= numStereo; + device->SourcesMax = numMono + numStereo; + device->NumMonoSources = numMono; device->NumStereoSources = numStereo; @@ -2150,6 +2190,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) * allocated with the appropriate size. */ device->NumAuxSends = new_sends; + TRACE("Max sources: %d (%d + %d), effect slots: %d, sends: %d\n", + device->SourcesMax, device->NumMonoSources, device->NumStereoSources, + device->AuxiliaryEffectSlotMax, device->NumAuxSends); update_failed = AL_FALSE; SetMixerFPUMode(&oldMode); if(device->DefaultSlot) @@ -2187,6 +2230,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) UnlockUIntMapRead(&context->EffectSlotMap); LockUIntMapRead(&context->SourceMap); + RelimitUIntMapNoLock(&context->SourceMap, device->SourcesMax); for(pos = 0;pos < context->SourceMap.size;pos++) { ALsource *source = context->SourceMap.values[pos]; @@ -3751,9 +3795,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->AuxiliaryEffectSlotMax = 64; device->NumAuxSends = DEFAULT_SENDS; - InitUIntMap(&device->BufferMap, ~0); - InitUIntMap(&device->EffectMap, ~0); - InitUIntMap(&device->FilterMap, ~0); + InitUIntMap(&device->BufferMap, INT_MAX); + InitUIntMap(&device->EffectMap, INT_MAX); + InitUIntMap(&device->FilterMap, INT_MAX); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) { @@ -4051,9 +4095,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, device->RealOut.Buffer = NULL; device->RealOut.NumChannels = 0; - InitUIntMap(&device->BufferMap, ~0); - InitUIntMap(&device->EffectMap, ~0); - InitUIntMap(&device->FilterMap, ~0); + InitUIntMap(&device->BufferMap, INT_MAX); + InitUIntMap(&device->EffectMap, INT_MAX); + InitUIntMap(&device->FilterMap, INT_MAX); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) { @@ -4279,9 +4323,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN device->AuxiliaryEffectSlotMax = 64; device->NumAuxSends = DEFAULT_SENDS; - InitUIntMap(&device->BufferMap, ~0); - InitUIntMap(&device->EffectMap, ~0); - InitUIntMap(&device->FilterMap, ~0); + InitUIntMap(&device->BufferMap, INT_MAX); + InitUIntMap(&device->EffectMap, INT_MAX); + InitUIntMap(&device->FilterMap, INT_MAX); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) { diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index de7de943..3ec857ca 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -479,7 +479,7 @@ done: void InitEffectFactoryMap(void) { - InitUIntMap(&EffectStateFactoryMap, ~0); + InitUIntMap(&EffectStateFactoryMap, INT_MAX); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnullStateFactory_getFactory); InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory); diff --git a/common/uintmap.c b/common/uintmap.c index 21a921b2..98ed3191 100644 --- a/common/uintmap.c +++ b/common/uintmap.c @@ -36,6 +36,11 @@ void ResetUIntMap(UIntMap *map) WriteUnlock(&map->lock); } +void RelimitUIntMapNoLock(UIntMap *map, ALsizei limit) +{ + map->limit = limit; +} + ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) { ALsizei pos = 0; @@ -59,7 +64,7 @@ ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) if(pos == map->size || map->keys[pos] != key) { - if(map->size == map->limit) + if(map->size >= map->limit) { WriteUnlock(&map->lock); return AL_OUT_OF_MEMORY; @@ -141,7 +146,7 @@ ALenum InsertUIntMapEntryNoLock(UIntMap *map, ALuint key, ALvoid *value) if(pos == map->size || map->keys[pos] != key) { - if(map->size == map->limit) + if(map->size >= map->limit) return AL_OUT_OF_MEMORY; if(map->size == map->capacity) diff --git a/common/uintmap.h b/common/uintmap.h index f70d99fd..47bd0d42 100644 --- a/common/uintmap.h +++ b/common/uintmap.h @@ -19,10 +19,11 @@ typedef struct UIntMap { RWLock lock; } UIntMap; #define UINTMAP_STATIC_INITIALIZE_N(_n) { NULL, NULL, 0, 0, (_n), RWLOCK_STATIC_INITIALIZE } -#define UINTMAP_STATIC_INITIALIZE UINTMAP_STATIC_INITIALIZE_N(~0) +#define UINTMAP_STATIC_INITIALIZE UINTMAP_STATIC_INITIALIZE_N(INT_MAX) void InitUIntMap(UIntMap *map, ALsizei limit); void ResetUIntMap(UIntMap *map); +void RelimitUIntMapNoLock(UIntMap *map, ALsizei limit); ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value); ALenum InsertUIntMapEntryNoLock(UIntMap *map, ALuint key, ALvoid *value); ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key); -- cgit v1.2.3 From 55011d4bfd46c920580d1aa6663bcfdb1e996d3e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 18 Apr 2017 14:11:15 -0700 Subject: Use a different way to get the size of structs with flexible array members --- Alc/ALc.c | 6 +++--- Alc/ALu.c | 2 +- Alc/converter.c | 2 +- Alc/hrtf.c | 4 ++-- Alc/panning.c | 4 +--- OpenAL32/Include/alMain.h | 6 ++++++ OpenAL32/alAuxEffectSlot.c | 8 ++------ OpenAL32/alSource.c | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index a352cacd..ecd8fd0d 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2501,7 +2501,7 @@ static ALvoid InitContext(ALCcontext *Context) InitUIntMap(&Context->SourceMap, Context->Device->SourcesMax); InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax); - auxslots = al_calloc(DEF_ALIGN, offsetof(struct ALeffectslotArray, slot[0])); + auxslots = al_calloc(DEF_ALIGN, sizeof(struct ALeffectslotArray)); auxslots->count = 0; ATOMIC_INIT(&Context->ActiveAuxSlots, auxslots); @@ -2725,8 +2725,8 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) * property set (including the dynamically-sized Send[] array) in one * chunk. */ - sizeof_props = RoundUp(offsetof(struct ALvoiceProps, Send[num_sends]), 16); - sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16); + sizeof_props = RoundUp(FAM_SIZE(struct ALvoiceProps, Send, num_sends), 16); + sizeof_voice = RoundUp(FAM_SIZE(ALvoice, Send, num_sends), 16); size = sizeof(ALvoice*) + sizeof_voice + sizeof_props; voices = al_calloc(16, RoundUp(size*num_voices, 16)); diff --git a/Alc/ALu.c b/Alc/ALu.c index 4a4709b0..da3ae9d5 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1283,7 +1283,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc if(props) { memcpy(voice->Props, props, - offsetof(struct ALvoiceProps, Send[context->Device->NumAuxSends]) + FAM_SIZE(struct ALvoiceProps, Send, context->Device->NumAuxSends) ); ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props); diff --git a/Alc/converter.c b/Alc/converter.c index 99069d15..f1a3a96b 100644 --- a/Alc/converter.c +++ b/Alc/converter.c @@ -13,7 +13,7 @@ SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType if(numchans <= 0 || srcRate <= 0 || dstRate <= 0) return NULL; - converter = al_calloc(16, offsetof(SampleConverter, Chan[numchans])); + converter = al_calloc(16, FAM_SIZE(SampleConverter, Chan, numchans)); converter->mSrcType = srcType; converter->mDstType = dstType; converter->mNumChannels = numchans; diff --git a/Alc/hrtf.c b/Alc/hrtf.c index 23817d66..3047915b 100644 --- a/Alc/hrtf.c +++ b/Alc/hrtf.c @@ -688,7 +688,7 @@ static void AddFileEntry(vector_EnumeratedHrtf *list, const_al_string filename) TRACE("Got new file \"%s\"\n", alstr_get_cstr(filename)); loaded_entry = al_calloc(DEF_ALIGN, - offsetof(struct HrtfEntry, filename[alstr_length(filename)+1]) + FAM_SIZE(struct HrtfEntry, filename, alstr_length(filename)+1) ); loaded_entry->next = LoadedHrtfs; loaded_entry->handle = NULL; @@ -769,7 +769,7 @@ static void AddBuiltInEntry(vector_EnumeratedHrtf *list, const_al_string filenam TRACE("Got new file \"%s\"\n", alstr_get_cstr(filename)); loaded_entry = al_calloc(DEF_ALIGN, - offsetof(struct HrtfEntry, filename[namelen]) + FAM_SIZE(struct HrtfEntry, filename, namelen) ); loaded_entry->next = LoadedHrtfs; loaded_entry->handle = hrtf; diff --git a/Alc/panning.c b/Alc/panning.c index e4941720..5ce93b9b 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -922,13 +922,11 @@ static void InitHrtfPanning(ALCdevice *device, bool hoa_mode) }; const ALfloat (*AmbiMatrix)[2][MAX_AMBI_COEFFS] = hoa_mode ? AmbiMatrixHOA : AmbiMatrixFOA; ALsizei count = hoa_mode ? 9 : 4; - size_t sizeof_hrtfstate; ALsizei i; static_assert(COUNTOF(AmbiPoints) <= HRTF_AMBI_MAX_CHANNELS, "HRTF_AMBI_MAX_CHANNELS is too small"); - sizeof_hrtfstate = offsetof(DirectHrtfState, Chan[count]); - device->Hrtf = al_calloc(16, sizeof_hrtfstate); + device->Hrtf = al_calloc(16, FAM_SIZE(DirectHrtfState, Chan, count)); for(i = 0;i < count;i++) { diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 191bb658..3a8aabde 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -225,6 +225,12 @@ typedef ALuint64SOFT ALuint64; #define DECL_FORMAT(x, y, z) #endif +/* Calculates the size of a struct with N elements of a flexible array member. + * GCC and Clang allow offsetof(Type, fam[N]) for this, but MSVC seems to have + * trouble, so a bit more verbose workaround is needed. + */ +#define FAM_SIZE(T, M, N) (offsetof(T, M) + sizeof(((T*)NULL)->M[0])*(N)) + #if defined(__GNUC__) && defined(__i386__) /* force_align_arg_pointer is required for proper function arguments aligning * when SSE code is used. Some systems (Windows, QNX) do not guarantee our diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 3ec857ca..5d110500 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -118,9 +118,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo ALsizei newcount = curarray->count + n; ALCdevice *device; - newarray = al_calloc(DEF_ALIGN, - offsetof(struct ALeffectslotArray, slot[newcount]) - ); + newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); newarray->count = newcount; memcpy(newarray->slot, tmpslots, sizeof(ALeffectslot*)*n); if(curarray) @@ -170,9 +168,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * ALsizei j, k; assert(newcount >= 0); - newarray = al_calloc(DEF_ALIGN, - offsetof(struct ALeffectslotArray, slot[newcount]) - ); + newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); newarray->count = newcount; for(i = j = 0;i < newarray->count;) { diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 236188cf..9fc22205 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -3013,7 +3013,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send /* Get an unused property container, or allocate a new one as needed. */ props = ATOMIC_LOAD(&voice->FreeList, almemory_order_acquire); if(!props) - props = al_calloc(16, offsetof(struct ALvoiceProps, Send[num_sends])); + props = al_calloc(16, FAM_SIZE(struct ALvoiceProps, Send, num_sends)); else { struct ALvoiceProps *next; -- cgit v1.2.3 From a306407b6713f0e17d1258e512a465a254f9fba3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 19 May 2017 18:59:04 -0700 Subject: Apply more proper air absorption to the wet path This properly accounts for the room rolloff factor for normal air absorption (which makes it none by default, like distance attenuation), and uses the reverb's decay time, decay hf ratio, decay hf limit, and room air absorption properties to calculate an initial hf decay with the WetGainAuto flag. This mirrors the behavior of the initial distance decay. --- Alc/ALu.c | 74 +++++++++++++++++++++++++++----------- OpenAL32/Include/alAuxEffectSlot.h | 2 ++ OpenAL32/alAuxEffectSlot.c | 2 ++ 3 files changed, 57 insertions(+), 21 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index 0fca7a73..32043cdd 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -337,13 +337,17 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; slot->Params.DecayTime = props->Props.Reverb.DecayTime; + slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; + slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; } else { slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; + slot->Params.DecayHFRatio = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; + slot->Params.DecayHFLimit = AL_FALSE; } /* Swap effect states. No need to play with the ref counts since they keep @@ -1059,13 +1063,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop ALeffectslot *SendSlots[MAX_SENDS]; ALfloat RoomRolloff[MAX_SENDS]; ALfloat DecayDistance[MAX_SENDS]; + ALfloat DecayHFDistance[MAX_SENDS]; ALfloat DryGain, DryGainHF, DryGainLF; ALfloat WetGain[MAX_SENDS]; ALfloat WetGainHF[MAX_SENDS]; ALfloat WetGainLF[MAX_SENDS]; ALfloat dir[3]; ALfloat spread; - ALfloat meters; ALfloat Pitch; ALint i; @@ -1082,14 +1086,22 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop SendSlots[i] = NULL; RoomRolloff[i] = 0.0f; DecayDistance[i] = 0.0f; + DecayHFDistance[i] = 0.0f; RoomAirAbsorption[i] = 1.0f; } else if(SendSlots[i]->Params.AuxSendAuto) { RoomRolloff[i] = SendSlots[i]->Params.RoomRolloff + props->RoomRolloffFactor; - DecayDistance[i] = SendSlots[i]->Params.DecayTime * - SPEEDOFSOUNDMETRESPERSEC; + DecayDistance[i] = SendSlots[i]->Params.DecayTime * SPEEDOFSOUNDMETRESPERSEC; + DecayHFDistance[i] = DecayDistance[i] * SendSlots[i]->Params.DecayHFRatio; RoomAirAbsorption[i] = SendSlots[i]->Params.AirAbsorptionGainHF; + if(SendSlots[i]->Params.DecayHFLimit && RoomAirAbsorption[i] < 1.0f) + { + ALfloat limitRatio = log10f(0.001f)/*-60 dB*/ / (log10f(RoomAirAbsorption[i]) * + DecayDistance[i]); + limitRatio = minf(limitRatio, SendSlots[i]->Params.DecayHFRatio); + DecayHFDistance[i] = minf(DecayHFDistance[i], limitRatio*DecayDistance[i]); + } } else { @@ -1097,6 +1109,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop * effect slot is the same as the dry path, sans filter effects */ RoomRolloff[i] = props->RolloffFactor; DecayDistance[i] = 0.0f; + DecayHFDistance[i] = 0.0f; RoomAirAbsorption[i] = AIRABSORBGAINHF; } @@ -1215,28 +1228,47 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop } /* Distance-based air absorption */ - meters = (ClampedDist-props->RefDistance) * props->RolloffFactor * - Listener->Params.MetersPerUnit; - if(meters > 0.0f && props->AirAbsorptionFactor > 0.0f) - DryGainHF *= powf(AIRABSORBGAINHF, props->AirAbsorptionFactor*meters); - - if(props->WetGainAuto && meters > 0.0f) + if(ClampedDist > props->RefDistance) { - /* Apply a decay-time transformation to the wet path, based on the - * source distance in meters. The initial decay of the reverb effect is - * calculated and applied to the wet path. - */ - for(i = 0;i < NumSends;i++) + ALfloat meters_base = (ClampedDist-props->RefDistance) * Listener->Params.MetersPerUnit; + if(props->AirAbsorptionFactor > 0.0f) { - if(DecayDistance[i] > 0.0f) - WetGain[i] *= powf(0.001f/*-60dB*/, meters/DecayDistance[i]); + ALfloat absorb = props->AirAbsorptionFactor * meters_base; + DryGainHF *= powf(AIRABSORBGAINHF, absorb*props->RolloffFactor); + for(i = 0;i < NumSends;i++) + { + if(RoomRolloff[i] > 0.0f) + WetGainHF[i] *= powf(RoomAirAbsorption[i], absorb*RoomRolloff[i]); + } } - /* Yes, the wet path's air absorption is applied with WetGainAuto on, - * rather than WetGainHFAuto. - */ - for(i = 0;i < NumSends;i++) - WetGainHF[i] *= powf(RoomAirAbsorption[i], meters); + if(props->WetGainAuto) + { + meters_base *= props->RolloffFactor; + + /* Apply a decay-time transformation to the wet path, based on the + * source distance in meters. The initial decay of the reverb + * effect is calculated and applied to the wet path. + */ + for(i = 0;i < NumSends;i++) + { + ALfloat gain; + + if(!(DecayDistance[i] > 0.0f)) + continue; + + gain = powf(0.001f/*-60dB*/, meters_base/DecayDistance[i]); + WetGain[i] *= gain; + /* Yes, the wet path's air absorption is applied with + * WetGainAuto on, rather than WetGainHFAuto. + */ + if(gain > 0.0f) + { + ALfloat gainhf = powf(0.001f/*-60dB*/, meters_base/DecayHFDistance[i]) / gain; + WetGainHF[i] *= minf(gainhf, 1.0f); + } + } + } } /* Calculate directional soundcones */ diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 4eb340a4..7126f8f5 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -121,7 +121,9 @@ typedef struct ALeffectslot { ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */ ALfloat DecayTime; + ALfloat DecayHFRatio; ALfloat AirAbsorptionGainHF; + ALboolean DecayHFLimit; } Params; /* Self ID */ diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 5d110500..8a990584 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -615,7 +615,9 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.EffectState = slot->Effect.State; slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; + slot->Params.DecayHFRatio = 0.0f; slot->Params.AirAbsorptionGainHF = 1.0f; + slot->Params.DecayHFLimit = AL_FALSE; return AL_NO_ERROR; } -- cgit v1.2.3 From e9505b164e6587b1bb0d04b478ddc45033dfbac8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 May 2017 22:33:40 -0700 Subject: Fix source sends' initial HF absorption and decay calculation The HF absorption is applied given the source distance, as relative to the source's immediate environment, with additional absorption being applied given the room/reverb environment. This does double up the amount of absorption compared to the dry path, but it can be assumed the initial reflections travel a longer distance. --- Alc/ALu.c | 36 +++++++++++++++--------------------- OpenAL32/Include/alAuxEffectSlot.h | 2 +- OpenAL32/alAuxEffectSlot.c | 2 +- 3 files changed, 17 insertions(+), 23 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index 7bf6f2ff..d7a8a89b 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -348,16 +348,16 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; slot->Params.DecayTime = props->Props.Reverb.DecayTime; slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; - slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; + slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; } else { slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; slot->Params.DecayHFRatio = 0.0f; - slot->Params.AirAbsorptionGainHF = 1.0f; slot->Params.DecayHFLimit = AL_FALSE; + slot->Params.AirAbsorptionGainHF = 1.0f; } /* Swap effect states. No need to play with the ref counts since they keep @@ -1079,7 +1079,6 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop const ALsizei NumSends = Device->NumAuxSends; aluVector Position, Velocity, Direction, SourceToListener; ALfloat Distance, ClampedDist, DopplerFactor; - ALfloat RoomAirAbsorption[MAX_SENDS]; ALeffectslot *SendSlots[MAX_SENDS]; ALfloat RoomRolloff[MAX_SENDS]; ALfloat DecayDistance[MAX_SENDS]; @@ -1108,20 +1107,20 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop RoomRolloff[i] = 0.0f; DecayDistance[i] = 0.0f; DecayHFDistance[i] = 0.0f; - RoomAirAbsorption[i] = 1.0f; } else if(SendSlots[i]->Params.AuxSendAuto) { RoomRolloff[i] = SendSlots[i]->Params.RoomRolloff + props->RoomRolloffFactor; DecayDistance[i] = SendSlots[i]->Params.DecayTime * SPEEDOFSOUNDMETRESPERSEC; DecayHFDistance[i] = DecayDistance[i] * SendSlots[i]->Params.DecayHFRatio; - RoomAirAbsorption[i] = SendSlots[i]->Params.AirAbsorptionGainHF; - if(SendSlots[i]->Params.DecayHFLimit && RoomAirAbsorption[i] < 1.0f) + if(SendSlots[i]->Params.DecayHFLimit) { - ALfloat limitRatio = log10f(REVERB_DECAY_GAIN) / - (log10f(RoomAirAbsorption[i]) * DecayDistance[i]); - limitRatio = minf(limitRatio, SendSlots[i]->Params.DecayHFRatio); - DecayHFDistance[i] = minf(DecayHFDistance[i], limitRatio*DecayDistance[i]); + ALfloat airAbsorption = SendSlots[i]->Params.AirAbsorptionGainHF; + if(airAbsorption < 1.0f) + { + ALfloat limitRatio = log10f(REVERB_DECAY_GAIN) / log10f(airAbsorption); + DecayHFDistance[i] = minf(limitRatio, DecayHFDistance[i]); + } } } else @@ -1131,7 +1130,6 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop RoomRolloff[i] = props->RolloffFactor; DecayDistance[i] = 0.0f; DecayHFDistance[i] = 0.0f; - RoomAirAbsorption[i] = AIRABSORBGAINHF; } if(!SendSlots[i]) @@ -1249,24 +1247,20 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop } /* Distance-based air absorption */ - if(ClampedDist > props->RefDistance) + if(ClampedDist > props->RefDistance && props->RolloffFactor > 0.0f) { - ALfloat meters_base = (ClampedDist-props->RefDistance) * Listener->Params.MetersPerUnit; + ALfloat meters_base = (ClampedDist-props->RefDistance) * props->RolloffFactor * + Listener->Params.MetersPerUnit; if(props->AirAbsorptionFactor > 0.0f) { - ALfloat absorb = props->AirAbsorptionFactor * meters_base; - DryGainHF *= powf(AIRABSORBGAINHF, absorb*props->RolloffFactor); + ALfloat hfattn = powf(AIRABSORBGAINHF, meters_base * props->AirAbsorptionFactor); + DryGainHF *= hfattn; for(i = 0;i < NumSends;i++) - { - if(RoomRolloff[i] > 0.0f) - WetGainHF[i] *= powf(AIRABSORBGAINHF, absorb*RoomRolloff[i]); - } + WetGainHF[i] *= hfattn; } if(props->WetGainAuto) { - meters_base *= props->RolloffFactor; - /* Apply a decay-time transformation to the wet path, based on the * source distance in meters. The initial decay of the reverb * effect is calculated and applied to the wet path. diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 7126f8f5..5be9ae7a 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -122,8 +122,8 @@ typedef struct ALeffectslot { ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */ ALfloat DecayTime; ALfloat DecayHFRatio; - ALfloat AirAbsorptionGainHF; ALboolean DecayHFLimit; + ALfloat AirAbsorptionGainHF; } Params; /* Self ID */ diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 8a990584..cd2c1e09 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -616,8 +616,8 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; slot->Params.DecayHFRatio = 0.0f; - slot->Params.AirAbsorptionGainHF = 1.0f; slot->Params.DecayHFLimit = AL_FALSE; + slot->Params.AirAbsorptionGainHF = 1.0f; return AL_NO_ERROR; } -- cgit v1.2.3 From a535169bbdd6766cbc6b53188065fbee6d4da1bc Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 13 Jul 2017 22:30:39 -0700 Subject: Use macros to set and restore the mixer FPU mode --- Alc/ALc.c | 10 ++++------ Alc/ALu.c | 7 ++----- Alc/converter.c | 10 ++++------ OpenAL32/Include/alMain.h | 11 +++++++++++ OpenAL32/alAuxEffectSlot.c | 7 +++---- 5 files changed, 24 insertions(+), 21 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 107d4ef2..e4b57c45 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1741,7 +1741,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ALCsizei hrtf_id = -1; ALCcontext *context; ALCuint oldFreq; - FPUCtl oldMode; size_t size; ALCsizei i; int val; @@ -2244,7 +2243,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) * allocated with the appropriate size. */ update_failed = AL_FALSE; - SetMixerFPUMode(&oldMode); + START_MIXER_MODE(); context = ATOMIC_LOAD_SEQ(&device->ContextList); while(context) { @@ -2359,7 +2358,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) context = context->next; } - RestoreFPUMode(&oldMode); + END_MIXER_MODE(); if(update_failed) return ALC_INVALID_DEVICE; @@ -3662,11 +3661,10 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin if(ALContext->DefaultSlot) { - FPUCtl oldMode; ALeffectslot *slot = ALContext->DefaultSlot; ALeffectState *state = slot->Effect.State; - SetMixerFPUMode(&oldMode); + START_MIXER_MODE(); state->OutBuffer = device->Dry.Buffer; state->OutChannels = device->Dry.NumChannels; if(V(state,deviceUpdate)(device) != AL_FALSE) @@ -3676,7 +3674,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin DeinitEffectSlot(ALContext->DefaultSlot); ALContext->DefaultSlot = NULL; } - RestoreFPUMode(&oldMode); + END_MIXER_MODE(); } ALCdevice_IncRef(ALContext->Device); diff --git a/Alc/ALu.c b/Alc/ALu.c index e44c6c2c..25626320 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1611,11 +1611,9 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { ALsizei SamplesToDo; ALCcontext *ctx; - FPUCtl oldMode; ALsizei i, c; - SetMixerFPUMode(&oldMode); - + START_MIXER_MODE(); while(size > 0) { SamplesToDo = mini(size, BUFFERSIZE); @@ -1819,8 +1817,7 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) size -= SamplesToDo; } - - RestoreFPUMode(&oldMode); + END_MIXER_MODE(); } diff --git a/Alc/converter.c b/Alc/converter.c index d9d8ecbf..5cfe7031 100644 --- a/Alc/converter.c +++ b/Alc/converter.c @@ -9,7 +9,6 @@ SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType dstType, ALsizei numchans, ALsizei srcRate, ALsizei dstRate) { SampleConverter *converter; - FPUCtl oldMode; ALsizei step; if(numchans <= 0 || srcRate <= 0 || dstRate <= 0) @@ -26,7 +25,7 @@ SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType converter->mFracOffset = 0; /* Have to set the mixer FPU mode since that's what the resampler code expects. */ - SetMixerFPUMode(&oldMode); + START_MIXER_MODE(); step = fastf2i(minf((ALdouble)srcRate / dstRate, MAX_PITCH)*FRACTIONONE + 0.5f); converter->mIncrement = maxi(step, 1); if(converter->mIncrement == FRACTIONONE) @@ -37,7 +36,7 @@ SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType BsincPrepare(converter->mIncrement, &converter->mState.bsinc); converter->mResample = SelectResampler(BSincResampler); } - RestoreFPUMode(&oldMode); + END_MIXER_MODE(); return converter; } @@ -230,9 +229,8 @@ ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALs const ALsizei DstFrameSize = converter->mNumChannels * converter->mDstTypeSize; const ALsizei increment = converter->mIncrement; ALsizei pos = 0; - FPUCtl oldMode; - SetMixerFPUMode(&oldMode); + START_MIXER_MODE(); while(pos < dstframes && *srcframes > 0) { ALfloat *restrict SrcData = ASSUME_ALIGNED(converter->mSrcSamples, 16); @@ -344,7 +342,7 @@ ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALs dst = (ALbyte*)dst + DstFrameSize*DstSize; pos += DstSize; } - RestoreFPUMode(&oldMode); + END_MIXER_MODE(); return pos; } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 4081508e..ca97bff0 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -907,6 +907,17 @@ typedef struct { } FPUCtl; void SetMixerFPUMode(FPUCtl *ctl); void RestoreFPUMode(const FPUCtl *ctl); +#ifdef __GNUC__ +/* Use an alternate macro set with GCC to avoid accidental continue or break + * statements within the mixer mode. + */ +#define START_MIXER_MODE() __extension__({ FPUCtl _oldMode; SetMixerFPUMode(&_oldMode); +#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); }) +#else +#define START_MIXER_MODE() do { FPUCtl _oldMode; SetMixerFPUMode(&_oldMode); +#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); } while(0) +#endif +#define LEAVE_MIXER_MODE() RestoreFPUMode(&_oldMode) typedef struct ll_ringbuffer ll_ringbuffer_t; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index cd2c1e09..02288a31 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -506,7 +506,6 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e if(newtype != EffectSlot->Effect.Type) { ALeffectStateFactory *factory; - FPUCtl oldMode; factory = getFactoryByType(newtype); if(!factory) @@ -517,19 +516,19 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e State = V0(factory,create)(); if(!State) return AL_OUT_OF_MEMORY; - SetMixerFPUMode(&oldMode); + START_MIXER_MODE(); almtx_lock(&Device->BackendLock); State->OutBuffer = Device->Dry.Buffer; State->OutChannels = Device->Dry.NumChannels; if(V(State,deviceUpdate)(Device) == AL_FALSE) { almtx_unlock(&Device->BackendLock); - RestoreFPUMode(&oldMode); + LEAVE_MIXER_MODE(); ALeffectState_DecRef(State); return AL_OUT_OF_MEMORY; } almtx_unlock(&Device->BackendLock); - RestoreFPUMode(&oldMode); + END_MIXER_MODE(); if(!effect) { -- cgit v1.2.3 From 1ab890262168444c2f6e1a9d84c3d65e5afe37f5 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 27 Sep 2017 11:13:18 -0700 Subject: Re-update effect slots when context properties change Also keep all free property update structs together in the context instead of per-object. --- Alc/ALc.c | 74 +++++++++++++++++++---------- Alc/ALu.c | 95 ++++++++++++++++---------------------- OpenAL32/Include/alAuxEffectSlot.h | 8 ++-- OpenAL32/Include/alListener.h | 5 -- OpenAL32/Include/alMain.h | 12 ++++- OpenAL32/Include/alu.h | 1 - OpenAL32/alAuxEffectSlot.c | 34 +++++--------- OpenAL32/alListener.c | 6 +-- OpenAL32/alSource.c | 18 ++++---- OpenAL32/alState.c | 6 +-- 10 files changed, 133 insertions(+), 126 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 44170434..7b4c1cfc 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2255,6 +2255,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) context = ATOMIC_LOAD_SEQ(&device->ContextList); while(context) { + struct ALvoiceProps *vprops; ALsizei pos; if(context->DefaultSlot) @@ -2267,7 +2268,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(V(state,deviceUpdate)(device) == AL_FALSE) update_failed = AL_TRUE; else - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, context); } WriteLock(&context->PropLock); @@ -2282,7 +2283,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(V(state,deviceUpdate)(device) == AL_FALSE) update_failed = AL_TRUE; else - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, context); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -2321,26 +2322,25 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release); } + + /* Clear any pre-existing voice property structs, in case the number of + * auxiliary sends is changing. Active sources will have updates + * respecified in UpdateAllSourceProps. + */ + vprops = ATOMIC_EXCHANGE_PTR(&context->FreeVoiceProps, NULL, almemory_order_acq_rel); + while(vprops) + { + struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed); + al_free(vprops); + vprops = next; + } + AllocateVoices(context, context->MaxVoices, old_sends); for(pos = 0;pos < context->VoiceCount;pos++) { ALvoice *voice = context->Voices[pos]; - struct ALvoiceProps *props; - /* Clear any pre-existing voice property structs, in case the - * number of auxiliary sends changed. Active sources will have - * updates respecified in UpdateAllSourceProps. - */ - props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed); - al_free(props); - - props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed); - while(props) - { - struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - al_free(props); - props = next; - } + al_free(ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_acq_rel)); if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL) continue; @@ -2540,7 +2540,6 @@ static ALvoid InitContext(ALCcontext *Context) ATOMIC_FLAG_TEST_AND_SET(&listener->PropsClean, almemory_order_relaxed); ATOMIC_INIT(&listener->Update, NULL); - ATOMIC_INIT(&listener->FreeList, NULL); //Validate Context InitRef(&Context->UpdateCount, 0); @@ -2575,7 +2574,10 @@ static ALvoid InitContext(ALCcontext *Context) ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE); ATOMIC_INIT(&Context->Update, NULL); - ATOMIC_INIT(&Context->FreeList, NULL); + ATOMIC_INIT(&Context->FreeContextProps, NULL); + ATOMIC_INIT(&Context->FreeListenerProps, NULL); + ATOMIC_INIT(&Context->FreeVoiceProps, NULL); + ATOMIC_INIT(&Context->FreeEffectslotProps, NULL); Context->ExtensionList = alExtList; @@ -2605,8 +2607,10 @@ static void FreeContext(ALCcontext *context) { ALlistener *listener = context->Listener; struct ALeffectslotArray *auxslots; + struct ALeffectslotProps *eprops; struct ALlistenerProps *lprops; struct ALcontextProps *cprops; + struct ALvoiceProps *vprops; size_t count; ALsizei i; @@ -2617,8 +2621,9 @@ static void FreeContext(ALCcontext *context) TRACE("Freed unapplied context update %p\n", cprops); al_free(cprops); } + count = 0; - cprops = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire); + cprops = ATOMIC_LOAD(&context->FreeContextProps, almemory_order_acquire); while(cprops) { struct ALcontextProps *next = ATOMIC_LOAD(&cprops->next, almemory_order_acquire); @@ -2645,6 +2650,17 @@ static void FreeContext(ALCcontext *context) } ResetUIntMap(&context->SourceMap); + count = 0; + eprops = ATOMIC_LOAD(&context->FreeEffectslotProps, almemory_order_relaxed); + while(eprops) + { + struct ALeffectslotProps *next = ATOMIC_LOAD(&eprops->next, almemory_order_relaxed); + if(eprops->State) ALeffectState_DecRef(eprops->State); + al_free(eprops); + eprops = next; + ++count; + } + TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); if(context->EffectSlotMap.size > 0) { WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size, @@ -2653,6 +2669,17 @@ static void FreeContext(ALCcontext *context) } ResetUIntMap(&context->EffectSlotMap); + count = 0; + vprops = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_relaxed); + while(vprops) + { + struct ALvoiceProps *next = ATOMIC_LOAD(&vprops->next, almemory_order_relaxed); + al_free(vprops); + vprops = next; + ++count; + } + TRACE("Freed "SZFMT" voice property object%s\n", count, (count==1)?"":"s"); + for(i = 0;i < context->VoiceCount;i++) DeinitVoice(context->Voices[i]); al_free(context->Voices); @@ -2666,7 +2693,7 @@ static void FreeContext(ALCcontext *context) al_free(lprops); } count = 0; - lprops = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire); + lprops = ATOMIC_LOAD(&context->FreeListenerProps, almemory_order_acquire); while(lprops) { struct ALlistenerProps *next = ATOMIC_LOAD(&lprops->next, almemory_order_acquire); @@ -2878,7 +2905,6 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) for(;v < num_voices;v++) { ATOMIC_INIT(&voice->Update, NULL); - ATOMIC_INIT(&voice->FreeList, NULL); voice->Props = props; voices[v] = voice; @@ -3725,8 +3751,8 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin if(ALContext->DefaultSlot) { - if(InitializeEffect(device, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR) - UpdateEffectSlotProps(ALContext->DefaultSlot); + if(InitializeEffect(ALContext, ALContext->DefaultSlot, &DefaultEffect) == AL_NO_ERROR) + UpdateEffectSlotProps(ALContext->DefaultSlot, ALContext); else ERR("Failed to initialize the default effect\n"); } diff --git a/Alc/ALu.c b/Alc/ALu.c index 20b2d817..0da610d1 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -111,26 +111,7 @@ static HrtfDirectMixerFunc MixDirectHrtf = MixDirectHrtf_C; void DeinitVoice(ALvoice *voice) { - struct ALvoiceProps *props; - size_t count = 0; - - props = ATOMIC_EXCHANGE_PTR_SEQ(&voice->Update, NULL); - if(props) al_free(props); - - props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed); - while(props) - { - struct ALvoiceProps *next; - next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - al_free(props); - props = next; - ++count; - } - /* This is excessively spammy if it traces every voice destruction, so just - * warn if it was unexpectedly large. - */ - if(count > 3) - WARN("Freed "SZFMT" voice property objects\n", count); + al_free(ATOMIC_EXCHANGE_PTR_SEQ(&voice->Update, NULL)); } @@ -290,7 +271,7 @@ static bool CalcContextParams(ALCcontext *Context) Listener->Params.SourceDistanceModel = props->SourceDistanceModel; Listener->Params.DistanceModel = props->DistanceModel; - ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &Context->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &Context->FreeContextProps, props); return true; } @@ -335,48 +316,54 @@ static bool CalcListenerParams(ALCcontext *Context) Listener->Params.Gain = props->Gain * Context->GainBoost; - ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Context->FreeListenerProps, props); return true; } -static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context) +static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force) { struct ALeffectslotProps *props; ALeffectState *state; props = ATOMIC_EXCHANGE_PTR(&slot->Update, NULL, almemory_order_acq_rel); - if(!props) return false; + if(!props && !force) return false; - slot->Params.Gain = props->Gain; - slot->Params.AuxSendAuto = props->AuxSendAuto; - slot->Params.EffectType = props->Type; - if(IsReverbEffect(slot->Params.EffectType)) - { - slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; - slot->Params.DecayTime = props->Props.Reverb.DecayTime; - slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; - slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; - slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; - } - else + if(props) { - slot->Params.RoomRolloff = 0.0f; - slot->Params.DecayTime = 0.0f; - slot->Params.DecayHFRatio = 0.0f; - slot->Params.DecayHFLimit = AL_FALSE; - slot->Params.AirAbsorptionGainHF = 1.0f; - } + slot->Params.Gain = props->Gain; + slot->Params.AuxSendAuto = props->AuxSendAuto; + slot->Params.EffectType = props->Type; + slot->Params.EffectProps = props->Props; + if(IsReverbEffect(props->Type)) + { + slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; + slot->Params.DecayTime = props->Props.Reverb.DecayTime; + slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; + slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; + slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; + } + else + { + slot->Params.RoomRolloff = 0.0f; + slot->Params.DecayTime = 0.0f; + slot->Params.DecayHFRatio = 0.0f; + slot->Params.DecayHFLimit = AL_FALSE; + slot->Params.AirAbsorptionGainHF = 1.0f; + } - /* Swap effect states. No need to play with the ref counts since they keep - * the same number of refs. - */ - state = props->State; - props->State = slot->Params.EffectState; - slot->Params.EffectState = state; + /* Swap effect states. No need to play with the ref counts since they + * keep the same number of refs. + */ + state = props->State; + props->State = slot->Params.EffectState; + slot->Params.EffectState = state; - V(state,update)(context, slot, &props->Props); + ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &context->FreeEffectslotProps, props); + } + else + state = slot->Params.EffectState; - ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props); + V(state,update)(context, slot, &slot->Params.EffectProps); return true; } @@ -1455,7 +1442,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force) FAM_SIZE(struct ALvoiceProps, Send, context->Device->NumAuxSends) ); - ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &context->FreeVoiceProps, props); } props = voice->Props; @@ -1486,10 +1473,10 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray IncrementRef(&ctx->UpdateCount); if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire)) { - ALboolean cforce = CalcContextParams(ctx); - ALboolean force = CalcListenerParams(ctx) | cforce; + bool cforce = CalcContextParams(ctx); + bool force = CalcListenerParams(ctx) | cforce; for(i = 0;i < slots->count;i++) - force |= CalcEffectSlotParams(slots->slot[i], ctx); + force |= CalcEffectSlotParams(slots->slot[i], ctx, cforce); voice = ctx->Voices; voice_end = voice + ctx->VoiceCount; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index fe05e008..908c72c5 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -110,13 +110,13 @@ typedef struct ALeffectslot { RefCount ref; ATOMIC(struct ALeffectslotProps*) Update; - ATOMIC(struct ALeffectslotProps*) FreeList; struct { ALfloat Gain; ALboolean AuxSendAuto; ALenum EffectType; + ALeffectProps EffectProps; ALeffectState *EffectState; ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */ @@ -160,7 +160,7 @@ inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); -void UpdateEffectSlotProps(ALeffectslot *slot); +void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context); void UpdateAllEffectSlotProps(ALCcontext *context); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); @@ -178,11 +178,13 @@ ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void); ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void); -ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect); +ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect); void InitEffectFactoryMap(void); void DeinitEffectFactoryMap(void); +void ALeffectState_DecRef(ALeffectState *state); + #ifdef __cplusplus } #endif diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index 8b212d47..0d80a8d7 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -42,11 +42,6 @@ typedef struct ALlistener { */ ATOMIC(struct ALlistenerProps*) Update; - /* A linked list of unused property containers, free to use for future - * updates. - */ - ATOMIC(struct ALlistenerProps*) FreeList; - struct { aluMatrixf Matrix; aluVector Velocity; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 7ac7eb13..776fb37b 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -383,6 +383,9 @@ struct HrtfEntry; struct FrontStablizer; struct Compressor; struct ALcontextProps; +struct ALlistenerProps; +struct ALvoiceProps; +struct ALeffectslotProps; #define DEFAULT_OUTPUT_RATE (44100) @@ -868,7 +871,14 @@ struct ALCcontext_struct { ALfloat GainBoost; ATOMIC(struct ALcontextProps*) Update; - ATOMIC(struct ALcontextProps*) FreeList; + + /* Linked lists of unused property containers, free to use for future + * updates. + */ + ATOMIC(struct ALcontextProps*) FreeContextProps; + ATOMIC(struct ALlistenerProps*) FreeListenerProps; + ATOMIC(struct ALvoiceProps*) FreeVoiceProps; + ATOMIC(struct ALeffectslotProps*) FreeEffectslotProps; struct ALvoice **Voices; ALsizei VoiceCount; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 2344cc6d..049a9dcd 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -251,7 +251,6 @@ typedef struct ALvoice { struct ALvoiceProps *Props; ATOMIC(struct ALvoiceProps*) Update; - ATOMIC(struct ALvoiceProps*) FreeList; ATOMIC(struct ALsource*) Source; ATOMIC(bool) Playing; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 02288a31..12092100 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -52,11 +52,10 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) } static void ALeffectState_IncRef(ALeffectState *state); -static void ALeffectState_DecRef(ALeffectState *state); #define DO_UPDATEPROPS() do { \ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ - UpdateEffectSlotProps(slot); \ + UpdateEffectSlotProps(slot, context); \ else \ ATOMIC_FLAG_CLEAR(&slot->PropsClean, almemory_order_release); \ } while(0) @@ -251,7 +250,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param UnlockEffectsRead(device); SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } - err = InitializeEffect(device, slot, effect); + err = InitializeEffect(context, slot, effect); UnlockEffectsRead(device); if(err != AL_NO_ERROR) @@ -497,8 +496,9 @@ void DeinitEffectFactoryMap(void) } -ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) +ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect) { + ALCdevice *Device = Context->Device; ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); struct ALeffectslotProps *props; ALeffectState *State; @@ -548,7 +548,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e EffectSlot->Effect.Props = effect->Props; /* Remove state references from old effect slot property updates. */ - props = ATOMIC_LOAD_SEQ(&EffectSlot->FreeList); + props = ATOMIC_LOAD_SEQ(&Context->FreeEffectslotProps); while(props) { if(props->State) @@ -568,7 +568,7 @@ static void ALeffectState_IncRef(ALeffectState *state) TRACEREF("%p increasing refcount to %u\n", state, ref); } -static void ALeffectState_DecRef(ALeffectState *state) +void ALeffectState_DecRef(ALeffectState *state) { uint ref; ref = DecrementRef(&state->Ref); @@ -606,7 +606,6 @@ ALenum InitEffectSlot(ALeffectslot *slot) InitRef(&slot->ref, 0); ATOMIC_INIT(&slot->Update, NULL); - ATOMIC_INIT(&slot->FreeList, NULL); slot->Params.Gain = 1.0f; slot->Params.AuxSendAuto = AL_TRUE; @@ -624,7 +623,6 @@ ALenum InitEffectSlot(ALeffectslot *slot) void DeinitEffectSlot(ALeffectslot *slot) { struct ALeffectslotProps *props; - size_t count = 0; props = ATOMIC_LOAD_SEQ(&slot->Update); if(props) @@ -633,29 +631,19 @@ void DeinitEffectSlot(ALeffectslot *slot) TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } - props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); - while(props) - { - struct ALeffectslotProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - if(props->State) ALeffectState_DecRef(props->State); - al_free(props); - props = next; - ++count; - } - TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); ALeffectState_DecRef(slot->Effect.State); if(slot->Params.EffectState) ALeffectState_DecRef(slot->Params.EffectState); } -void UpdateEffectSlotProps(ALeffectslot *slot) +void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context) { struct ALeffectslotProps *props; ALeffectState *oldstate; /* Get an unused property container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); + props = ATOMIC_LOAD(&context->FreeEffectslotProps, almemory_order_relaxed); if(!props) props = al_calloc(16, sizeof(*props)); else @@ -663,7 +651,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) struct ALeffectslotProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&slot->FreeList, &props, next, + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeEffectslotProps, &props, next, almemory_order_seq_cst, almemory_order_acquire) == 0); } @@ -687,7 +675,7 @@ void UpdateEffectSlotProps(ALeffectslot *slot) /* If there was an unused update container, put it back in the * freelist. */ - ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &context->FreeEffectslotProps, props); } if(oldstate) @@ -705,7 +693,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context) { ALeffectslot *slot = auxslots->slot[i]; if(!ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) - UpdateEffectSlotProps(slot); + UpdateEffectSlotProps(slot, context); } UnlockEffectSlotsRead(context); } diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 7062f8c4..9a90c16e 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -470,7 +470,7 @@ void UpdateListenerProps(ALCcontext *context) struct ALlistenerProps *props; /* Get an unused proprty container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&listener->FreeList, almemory_order_acquire); + props = ATOMIC_LOAD(&context->FreeListenerProps, almemory_order_acquire); if(!props) props = al_calloc(16, sizeof(*props)); else @@ -478,7 +478,7 @@ void UpdateListenerProps(ALCcontext *context) struct ALlistenerProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&listener->FreeList, &props, next, + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeListenerProps, &props, next, almemory_order_seq_cst, almemory_order_acquire) == 0); } @@ -507,6 +507,6 @@ void UpdateListenerProps(ALCcontext *context) /* If there was an unused update container, put it back in the * freelist. */ - ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &listener->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &context->FreeListenerProps, props); } } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index be191fdb..db698692 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -49,7 +49,7 @@ extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); static void InitSourceParams(ALsource *Source, ALsizei num_sends); static void DeinitSource(ALsource *source, ALsizei num_sends); -static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends); +static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends, ALCcontext *context); static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime); static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime); static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context); @@ -447,7 +447,7 @@ static ALint Int64ValsByProp(ALenum prop) ALvoice *voice; \ if(SourceShouldUpdate(Source, Context) && \ (voice=GetSourceVoice(Source, Context)) != NULL) \ - UpdateSourceProps(Source, voice, device->NumAuxSends); \ + UpdateSourceProps(Source, voice, device->NumAuxSends, Context); \ else \ ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release); \ } while(0) @@ -948,7 +948,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p * active source, in case the slot is about to be deleted. */ if((voice=GetSourceVoice(Source, Context)) != NULL) - UpdateSourceProps(Source, voice, device->NumAuxSends); + UpdateSourceProps(Source, voice, device->NumAuxSends, Context); else ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release); } @@ -2528,7 +2528,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->Playing, false, almemory_order_release); ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acquire); - UpdateSourceProps(source, voice, device->NumAuxSends); + UpdateSourceProps(source, voice, device->NumAuxSends, context); /* A source that's not playing or paused has any offset applied when it * starts playing. @@ -3061,13 +3061,13 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) } } -static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends) +static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends, ALCcontext *context) { struct ALvoiceProps *props; ALsizei i; /* Get an unused property container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&voice->FreeList, almemory_order_acquire); + props = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_acquire); if(!props) props = al_calloc(16, FAM_SIZE(struct ALvoiceProps, Send, num_sends)); else @@ -3075,7 +3075,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send struct ALvoiceProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&voice->FreeList, &props, next, + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeVoiceProps, &props, next, almemory_order_acq_rel, almemory_order_acquire) == 0); } @@ -3145,7 +3145,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send /* If there was an unused update container, put it back in the * freelist. */ - ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &context->FreeVoiceProps, props); } } @@ -3159,7 +3159,7 @@ void UpdateAllSourceProps(ALCcontext *context) ALvoice *voice = context->Voices[pos]; ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); if(source && !ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel)) - UpdateSourceProps(source, voice, num_sends); + UpdateSourceProps(source, voice, num_sends, context); } } diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 14646043..a5565f87 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -786,7 +786,7 @@ void UpdateContextProps(ALCcontext *context) struct ALcontextProps *props; /* Get an unused proprty container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire); + props = ATOMIC_LOAD(&context->FreeContextProps, almemory_order_acquire); if(!props) props = al_calloc(16, sizeof(*props)); else @@ -794,7 +794,7 @@ void UpdateContextProps(ALCcontext *context) struct ALcontextProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeList, &props, next, + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeContextProps, &props, next, almemory_order_seq_cst, almemory_order_acquire) == 0); } @@ -815,6 +815,6 @@ void UpdateContextProps(ALCcontext *context) /* If there was an unused update container, put it back in the * freelist. */ - ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeContextProps, props); } } -- cgit v1.2.3 From 15ad5245bfa498dff729d2bb1cd91fad161cc806 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 11 Jan 2018 08:44:52 -0800 Subject: Move the FPU mode declarations to a separate header Also don't use inheritance with FPUCtl. --- Alc/ALc.c | 1 + Alc/ALu.c | 1 + Alc/converter.c | 1 + Alc/fpu_modes.h | 37 +++++++++++++++++++++++++++++++++++++ Alc/helpers.c | 5 +++-- OpenAL32/Include/alMain.h | 32 -------------------------------- OpenAL32/alAuxEffectSlot.c | 1 + 7 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 Alc/fpu_modes.h (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 5297af30..3b175b66 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -42,6 +42,7 @@ #include "alu.h" #include "alconfig.h" +#include "fpu_modes.h" #include "cpu_caps.h" #include "compat.h" #include "threads.h" diff --git a/Alc/ALu.c b/Alc/ALu.c index e0496513..2fe579b9 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -39,6 +39,7 @@ #include "bformatdec.h" #include "static_assert.h" +#include "fpu_modes.h" #include "cpu_caps.h" #include "mixer_defs.h" #include "bsinc_inc.h" diff --git a/Alc/converter.c b/Alc/converter.c index 8cba04a1..157073f2 100644 --- a/Alc/converter.c +++ b/Alc/converter.c @@ -3,6 +3,7 @@ #include "converter.h" +#include "fpu_modes.h" #include "mixer_defs.h" diff --git a/Alc/fpu_modes.h b/Alc/fpu_modes.h new file mode 100644 index 00000000..750252fc --- /dev/null +++ b/Alc/fpu_modes.h @@ -0,0 +1,37 @@ +#ifndef FPU_MODES_H +#define FPU_MODES_H + +#ifdef HAVE_FENV_H +#include +#endif + + +typedef struct FPUCtl { +#ifdef HAVE_FENV_H + fenv_t flt_env; +#ifdef _WIN32 + int round_mode; +#endif +#else + int state; +#endif +#ifdef HAVE_SSE + int sse_state; +#endif +} FPUCtl; +void SetMixerFPUMode(FPUCtl *ctl); +void RestoreFPUMode(const FPUCtl *ctl); + +#ifdef __GNUC__ +/* Use an alternate macro set with GCC to avoid accidental continue or break + * statements within the mixer mode. + */ +#define START_MIXER_MODE() __extension__({ FPUCtl _oldMode; SetMixerFPUMode(&_oldMode) +#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); }) +#else +#define START_MIXER_MODE() do { FPUCtl _oldMode; SetMixerFPUMode(&_oldMode) +#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); } while(0) +#endif +#define LEAVE_MIXER_MODE() RestoreFPUMode(&_oldMode) + +#endif /* FPU_MODES_H */ diff --git a/Alc/helpers.c b/Alc/helpers.c index 0f69b29e..238569d6 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -109,6 +109,7 @@ DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_GUID, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x #include "alMain.h" #include "alu.h" #include "cpu_caps.h" +#include "fpu_modes.h" #include "atomic.h" #include "uintmap.h" #include "vector.h" @@ -295,7 +296,7 @@ void FillCPUCaps(int capfilter) void SetMixerFPUMode(FPUCtl *ctl) { #ifdef HAVE_FENV_H - fegetenv(STATIC_CAST(fenv_t, ctl)); + fegetenv(&ctl->flt_env); #ifdef _WIN32 /* HACK: A nasty bug in MinGW-W64 causes fegetenv and fesetenv to not save * and restore the FPU rounding mode, so we have to do it manually. Don't @@ -348,7 +349,7 @@ void SetMixerFPUMode(FPUCtl *ctl) void RestoreFPUMode(const FPUCtl *ctl) { #ifdef HAVE_FENV_H - fesetenv(STATIC_CAST(fenv_t, ctl)); + fesetenv(&ctl->flt_env); #ifdef _WIN32 fesetround(ctl->round_mode); #endif diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index ea797053..5b4519eb 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -13,10 +13,6 @@ #include #endif -#ifdef HAVE_FENV_H -#include -#endif - #include "AL/al.h" #include "AL/alc.h" #include "AL/alext.h" @@ -803,34 +799,6 @@ void ALCcontext_DeferUpdates(ALCcontext *context); void ALCcontext_ProcessUpdates(ALCcontext *context); -typedef struct { -#ifdef HAVE_FENV_H - DERIVE_FROM_TYPE(fenv_t); -#ifdef _WIN32 - int round_mode; -#endif -#else - int state; -#endif -#ifdef HAVE_SSE - int sse_state; -#endif -} FPUCtl; -void SetMixerFPUMode(FPUCtl *ctl); -void RestoreFPUMode(const FPUCtl *ctl); -#ifdef __GNUC__ -/* Use an alternate macro set with GCC to avoid accidental continue or break - * statements within the mixer mode. - */ -#define START_MIXER_MODE() __extension__({ FPUCtl _oldMode; SetMixerFPUMode(&_oldMode); -#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); }) -#else -#define START_MIXER_MODE() do { FPUCtl _oldMode; SetMixerFPUMode(&_oldMode); -#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); } while(0) -#endif -#define LEAVE_MIXER_MODE() RestoreFPUMode(&_oldMode) - - typedef struct ll_ringbuffer ll_ringbuffer_t; typedef struct ll_ringbuffer_data { char *buf; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 12092100..2dcf7125 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -32,6 +32,7 @@ #include "alListener.h" #include "alSource.h" +#include "fpu_modes.h" #include "almalloc.h" -- cgit v1.2.3 From 2ded5547ba431a0859bc08276ab720aea9ca92a8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 24 Jan 2018 17:07:01 -0800 Subject: Provide messages for the remaining AL errors --- Alc/effects/chorus.c | 68 +++++++--------- Alc/effects/compressor.c | 37 ++++----- Alc/effects/dedicated.c | 34 +++----- Alc/effects/distortion.c | 42 ++++------ Alc/effects/echo.c | 42 ++++------ Alc/effects/equalizer.c | 52 +++++------- Alc/effects/modulator.c | 30 +++---- Alc/effects/null.c | 32 ++++---- Alc/effects/reverb.c | 112 ++++++++++++-------------- OpenAL32/Include/alError.h | 18 +---- OpenAL32/alAuxEffectSlot.c | 62 ++++++++------ OpenAL32/alBuffer.c | 196 ++++++++++++++++++++++++--------------------- OpenAL32/alEffect.c | 10 +-- OpenAL32/alExtension.c | 4 +- OpenAL32/alFilter.c | 118 +++++++++++++-------------- OpenAL32/alListener.c | 107 ++++++++++++------------- OpenAL32/alSource.c | 115 +++++++++++++++----------- OpenAL32/alState.c | 94 +++++++++------------- OpenAL32/event.c | 11 +-- 19 files changed, 559 insertions(+), 625 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index 2592c673..75de6be7 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -317,24 +317,22 @@ void ALchorus_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALi { case AL_CHORUS_WAVEFORM: if(!(val >= AL_CHORUS_MIN_WAVEFORM && val <= AL_CHORUS_MAX_WAVEFORM)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Invalid chorus waveform",); props->Chorus.Waveform = val; break; case AL_CHORUS_PHASE: if(!(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus phase out of range",); props->Chorus.Phase = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus integer property"); } } void ALchorus_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALchorus_setParami(effect, context, param, vals[0]); -} +{ ALchorus_setParami(effect, context, param, vals[0]); } void ALchorus_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -342,36 +340,34 @@ void ALchorus_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALf { case AL_CHORUS_RATE: if(!(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus rate out of range",); props->Chorus.Rate = val; break; case AL_CHORUS_DEPTH: if(!(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus depth out of range",); props->Chorus.Depth = val; break; case AL_CHORUS_FEEDBACK: if(!(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus feedback out of range",); props->Chorus.Feedback = val; break; case AL_CHORUS_DELAY: if(!(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus delay out of range",); props->Chorus.Delay = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus float property"); } } void ALchorus_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALchorus_setParamf(effect, context, param, vals[0]); -} +{ ALchorus_setParamf(effect, context, param, vals[0]); } void ALchorus_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) { @@ -387,13 +383,11 @@ void ALchorus_getParami(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus integer property"); } } void ALchorus_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALchorus_getParami(effect, context, param, vals); -} +{ ALchorus_getParami(effect, context, param, vals); } void ALchorus_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -416,13 +410,11 @@ void ALchorus_getParamf(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus float property"); } } void ALchorus_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALchorus_getParamf(effect, context, param, vals); -} +{ ALchorus_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALchorus); @@ -461,24 +453,22 @@ void ALflanger_setParami(ALeffect *effect, ALCcontext *context, ALenum param, AL { case AL_FLANGER_WAVEFORM: if(!(val >= AL_FLANGER_MIN_WAVEFORM && val <= AL_FLANGER_MAX_WAVEFORM)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Invalid flanger waveform",); props->Chorus.Waveform = val; break; case AL_FLANGER_PHASE: if(!(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger phase out of range",); props->Chorus.Phase = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger integer property"); } } void ALflanger_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALflanger_setParami(effect, context, param, vals[0]); -} +{ ALflanger_setParami(effect, context, param, vals[0]); } void ALflanger_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -486,36 +476,34 @@ void ALflanger_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, AL { case AL_FLANGER_RATE: if(!(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger rate out of range",); props->Chorus.Rate = val; break; case AL_FLANGER_DEPTH: if(!(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger depth out of range",); props->Chorus.Depth = val; break; case AL_FLANGER_FEEDBACK: if(!(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger feedback out of range",); props->Chorus.Feedback = val; break; case AL_FLANGER_DELAY: if(!(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger delay out of range",); props->Chorus.Delay = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger float property"); } } void ALflanger_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALflanger_setParamf(effect, context, param, vals[0]); -} +{ ALflanger_setParamf(effect, context, param, vals[0]); } void ALflanger_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) { @@ -531,7 +519,7 @@ void ALflanger_getParami(const ALeffect *effect, ALCcontext *context, ALenum par break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger integer property"); } } void ALflanger_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) @@ -560,12 +548,10 @@ void ALflanger_getParamf(const ALeffect *effect, ALCcontext *context, ALenum par break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger float property"); } } void ALflanger_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALflanger_getParamf(effect, context, param, vals); -} +{ ALflanger_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALflanger); diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index 4ae2acdb..330733b3 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -210,24 +210,20 @@ void ALcompressor_setParami(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_COMPRESSOR_ONOFF: if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Compressor state out of range",); props->Compressor.OnOff = val; break; - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + default: + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor integer property"); } } void ALcompressor_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALcompressor_setParami(effect, context, param, vals[0]); -} -void ALcompressor_setParamf(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALcompressor_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALcompressor_setParamf(effect, context, param, vals[0]); -} +{ ALcompressor_setParami(effect, context, param, vals[0]); } +void ALcompressor_setParamf(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float property"); } +void ALcompressor_setParamfv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float-vector property"); } void ALcompressor_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) { @@ -237,19 +233,16 @@ void ALcompressor_getParami(const ALeffect *effect, ALCcontext *context, ALenum case AL_COMPRESSOR_ONOFF: *val = props->Compressor.OnOff; break; + default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor integer property"); } } void ALcompressor_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALcompressor_getParami(effect, context, param, vals); -} -void ALcompressor_getParamf(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALcompressor_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALcompressor_getParamf(effect, context, param, vals); -} +{ ALcompressor_getParami(effect, context, param, vals); } +void ALcompressor_getParamf(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float property"); } +void ALcompressor_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float-vector property"); } DEFINE_ALEFFECT_VTABLE(ALcompressor); diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 7dc2545b..684e8171 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -139,12 +139,10 @@ ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) } -void ALdedicated_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALdedicated_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALdedicated_setParami(effect, context, param, vals[0]); -} +void ALdedicated_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer property"); } +void ALdedicated_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer-vector property"); } void ALdedicated_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -152,25 +150,21 @@ void ALdedicated_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_DEDICATED_GAIN: if(!(val >= 0.0f && isfinite(val))) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Dedicated gain out of range",); props->Dedicated.Gain = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated float property"); } } void ALdedicated_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALdedicated_setParamf(effect, context, param, vals[0]); -} +{ ALdedicated_setParamf(effect, context, param, vals[0]); } -void ALdedicated_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALdedicated_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALdedicated_getParami(effect, context, param, vals); -} +void ALdedicated_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer property"); } +void ALdedicated_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer-vector property"); } void ALdedicated_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -181,12 +175,10 @@ void ALdedicated_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated float property"); } } void ALdedicated_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALdedicated_getParamf(effect, context, param, vals); -} +{ ALdedicated_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALdedicated); diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index 8fba07df..2a7c21ec 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -198,12 +198,10 @@ ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) } -void ALdistortion_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALdistortion_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALdistortion_setParami(effect, context, param, vals[0]); -} +void ALdistortion_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer property"); } +void ALdistortion_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer-vector property"); } void ALdistortion_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -211,49 +209,45 @@ void ALdistortion_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_DISTORTION_EDGE: if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion edge out of range",); props->Distortion.Edge = val; break; case AL_DISTORTION_GAIN: if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion gain out of range",); props->Distortion.Gain = val; break; case AL_DISTORTION_LOWPASS_CUTOFF: if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion low-pass cutoff out of range",); props->Distortion.LowpassCutoff = val; break; case AL_DISTORTION_EQCENTER: if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion EQ center out of range",); props->Distortion.EQCenter = val; break; case AL_DISTORTION_EQBANDWIDTH: if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion EQ bandwidth out of range",); props->Distortion.EQBandwidth = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion float property"); } } void ALdistortion_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALdistortion_setParamf(effect, context, param, vals[0]); -} +{ ALdistortion_setParamf(effect, context, param, vals[0]); } -void ALdistortion_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALdistortion_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALdistortion_getParami(effect, context, param, vals); -} +void ALdistortion_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer property"); } +void ALdistortion_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer-vector property"); } void ALdistortion_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -280,12 +274,10 @@ void ALdistortion_getParamf(const ALeffect *effect, ALCcontext *context, ALenum break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion float property"); } } void ALdistortion_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALdistortion_getParamf(effect, context, param, vals); -} +{ ALdistortion_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALdistortion); diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index cd556f1a..b59b06b0 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -230,12 +230,10 @@ ALeffectStateFactory *ALechoStateFactory_getFactory(void) } -void ALecho_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALecho_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALecho_setParami(effect, context, param, vals[0]); -} +void ALecho_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer property"); } +void ALecho_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer-vector property"); } void ALecho_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -243,49 +241,45 @@ void ALecho_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALflo { case AL_ECHO_DELAY: if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo delay out of range",); props->Echo.Delay = val; break; case AL_ECHO_LRDELAY: if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo LR delay out of range",); props->Echo.LRDelay = val; break; case AL_ECHO_DAMPING: if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo damping out of range",); props->Echo.Damping = val; break; case AL_ECHO_FEEDBACK: if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo feedback out of range",); props->Echo.Feedback = val; break; case AL_ECHO_SPREAD: if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo spread out of range",); props->Echo.Spread = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo float property"); } } void ALecho_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALecho_setParamf(effect, context, param, vals[0]); -} +{ ALecho_setParamf(effect, context, param, vals[0]); } -void ALecho_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALecho_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALecho_getParami(effect, context, param, vals); -} +void ALecho_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer property"); } +void ALecho_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer-vector property"); } void ALecho_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -312,12 +306,10 @@ void ALecho_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo float property"); } } void ALecho_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALecho_getParamf(effect, context, param, vals); -} +{ ALecho_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALecho); diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index bc84f87f..b800d27a 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -220,12 +220,10 @@ ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) } -void ALequalizer_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALequalizer_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALequalizer_setParami(effect, context, param, vals[0]); -} +void ALequalizer_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer property"); } +void ALequalizer_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer-vector property"); } void ALequalizer_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -233,79 +231,75 @@ void ALequalizer_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EQUALIZER_LOW_GAIN: if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer low-band gain out of range",); props->Equalizer.LowGain = val; break; case AL_EQUALIZER_LOW_CUTOFF: if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer low-band cutoff out of range",); props->Equalizer.LowCutoff = val; break; case AL_EQUALIZER_MID1_GAIN: if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid1-band gain out of range",); props->Equalizer.Mid1Gain = val; break; case AL_EQUALIZER_MID1_CENTER: if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid1-band center out of range",); props->Equalizer.Mid1Center = val; break; case AL_EQUALIZER_MID1_WIDTH: if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid1-band width out of range",); props->Equalizer.Mid1Width = val; break; case AL_EQUALIZER_MID2_GAIN: if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid2-band gain out of range",); props->Equalizer.Mid2Gain = val; break; case AL_EQUALIZER_MID2_CENTER: if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid2-band center out of range",); props->Equalizer.Mid2Center = val; break; case AL_EQUALIZER_MID2_WIDTH: if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid2-band width out of range",); props->Equalizer.Mid2Width = val; break; case AL_EQUALIZER_HIGH_GAIN: if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer high-band gain out of range",); props->Equalizer.HighGain = val; break; case AL_EQUALIZER_HIGH_CUTOFF: if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer high-band cutoff out of range",); props->Equalizer.HighCutoff = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer float property"); } } void ALequalizer_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALequalizer_setParamf(effect, context, param, vals[0]); -} +{ ALequalizer_setParamf(effect, context, param, vals[0]); } -void ALequalizer_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALequalizer_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALequalizer_getParami(effect, context, param, vals); -} +void ALequalizer_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer property"); } +void ALequalizer_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer-vector property"); } void ALequalizer_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -352,12 +346,10 @@ void ALequalizer_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer float property"); } } void ALequalizer_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALequalizer_getParamf(effect, context, param, vals); -} +{ ALequalizer_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALequalizer); diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index 431941ce..0fb03042 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -217,24 +217,22 @@ void ALmodulator_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_RING_MODULATOR_FREQUENCY: if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Modulator frequency out of range",); props->Modulator.Frequency = val; break; case AL_RING_MODULATOR_HIGHPASS_CUTOFF: if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Modulator high-pass cutoff out of range",); props->Modulator.HighPassCutoff = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator float property"); } } void ALmodulator_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALmodulator_setParamf(effect, context, param, vals[0]); -} +{ ALmodulator_setParamf(effect, context, param, vals[0]); } void ALmodulator_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) { ALeffectProps *props = &effect->Props; @@ -247,18 +245,16 @@ void ALmodulator_setParami(ALeffect *effect, ALCcontext *context, ALenum param, case AL_RING_MODULATOR_WAVEFORM: if(!(val >= AL_RING_MODULATOR_MIN_WAVEFORM && val <= AL_RING_MODULATOR_MAX_WAVEFORM)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Invalid modulator waveform",); props->Modulator.Waveform = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator integer property"); } } void ALmodulator_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALmodulator_setParami(effect, context, param, vals[0]); -} +{ ALmodulator_setParami(effect, context, param, vals[0]); } void ALmodulator_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) { @@ -276,13 +272,11 @@ void ALmodulator_getParami(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator integer property"); } } void ALmodulator_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALmodulator_getParami(effect, context, param, vals); -} +{ ALmodulator_getParami(effect, context, param, vals); } void ALmodulator_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -296,12 +290,10 @@ void ALmodulator_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator float property"); } } void ALmodulator_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALmodulator_getParamf(effect, context, param, vals); -} +{ ALmodulator_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALmodulator); diff --git a/Alc/effects/null.c b/Alc/effects/null.c index f3e8a6df..2dc43870 100644 --- a/Alc/effects/null.c +++ b/Alc/effects/null.c @@ -110,69 +110,69 @@ ALeffectStateFactory *ALnullStateFactory_getFactory(void) } -void ALnull_setParami(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +void ALnull_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint UNUSED(val)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer property"); } } -void ALnull_setParamiv(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, const ALint* UNUSED(vals)) +void ALnull_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint* UNUSED(vals)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer-vector property"); } } -void ALnull_setParamf(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALfloat UNUSED(val)) +void ALnull_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat UNUSED(val)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float property"); } } -void ALnull_setParamfv(ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, const ALfloat* UNUSED(vals)) +void ALnull_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat* UNUSED(vals)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float-vector property"); } } -void ALnull_getParami(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALint* UNUSED(val)) +void ALnull_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint* UNUSED(val)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer property"); } } -void ALnull_getParamiv(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALint* UNUSED(vals)) +void ALnull_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint* UNUSED(vals)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer-vector property"); } } -void ALnull_getParamf(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALfloat* UNUSED(val)) +void ALnull_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat* UNUSED(val)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float property"); } } -void ALnull_getParamfv(const ALeffect* UNUSED(effect), ALCcontext *context, ALenum param, ALfloat* UNUSED(vals)) +void ALnull_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat* UNUSED(vals)) { switch(param) { default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float-vector property"); } } diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index 7729caec..0cebab9b 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -1775,18 +1775,16 @@ void ALeaxreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EAXREVERB_DECAY_HFLIMIT: if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay hflimit out of range",); props->Reverb.DecayHFLimit = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb integer property"); } } void ALeaxreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALeaxreverb_setParami(effect, context, param, vals[0]); -} +{ ALeaxreverb_setParami(effect, context, param, vals[0]); } void ALeaxreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -1794,126 +1792,126 @@ void ALeaxreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EAXREVERB_DENSITY: if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb density out of range",); props->Reverb.Density = val; break; case AL_EAXREVERB_DIFFUSION: if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb diffusion out of range",); props->Reverb.Diffusion = val; break; case AL_EAXREVERB_GAIN: if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb gain out of range",); props->Reverb.Gain = val; break; case AL_EAXREVERB_GAINHF: if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb gainhf out of range",); props->Reverb.GainHF = val; break; case AL_EAXREVERB_GAINLF: if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb gainlf out of range",); props->Reverb.GainLF = val; break; case AL_EAXREVERB_DECAY_TIME: if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay time out of range",); props->Reverb.DecayTime = val; break; case AL_EAXREVERB_DECAY_HFRATIO: if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay hfratio out of range",); props->Reverb.DecayHFRatio = val; break; case AL_EAXREVERB_DECAY_LFRATIO: if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay lfratio out of range",); props->Reverb.DecayLFRatio = val; break; case AL_EAXREVERB_REFLECTIONS_GAIN: if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb reflections gain out of range",); props->Reverb.ReflectionsGain = val; break; case AL_EAXREVERB_REFLECTIONS_DELAY: if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb reflections delay out of range",); props->Reverb.ReflectionsDelay = val; break; case AL_EAXREVERB_LATE_REVERB_GAIN: if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb late reverb gain out of range",); props->Reverb.LateReverbGain = val; break; case AL_EAXREVERB_LATE_REVERB_DELAY: if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb late reverb delay out of range",); props->Reverb.LateReverbDelay = val; break; case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb air absorption gainhf out of range",); props->Reverb.AirAbsorptionGainHF = val; break; case AL_EAXREVERB_ECHO_TIME: if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb echo time out of range",); props->Reverb.EchoTime = val; break; case AL_EAXREVERB_ECHO_DEPTH: if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb echo depth out of range",); props->Reverb.EchoDepth = val; break; case AL_EAXREVERB_MODULATION_TIME: if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb modulation time out of range",); props->Reverb.ModulationTime = val; break; case AL_EAXREVERB_MODULATION_DEPTH: if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb modulation depth out of range",); props->Reverb.ModulationDepth = val; break; case AL_EAXREVERB_HFREFERENCE: if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb hfreference out of range",); props->Reverb.HFReference = val; break; case AL_EAXREVERB_LFREFERENCE: if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb lfreference out of range",); props->Reverb.LFReference = val; break; case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb room rolloff factor out of range",); props->Reverb.RoomRolloffFactor = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb float property"); } } void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -1923,14 +1921,14 @@ void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EAXREVERB_REFLECTIONS_PAN: if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb reflections pan out of range",); props->Reverb.ReflectionsPan[0] = vals[0]; props->Reverb.ReflectionsPan[1] = vals[1]; props->Reverb.ReflectionsPan[2] = vals[2]; break; case AL_EAXREVERB_LATE_REVERB_PAN: if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb late reverb pan out of range",); props->Reverb.LateReverbPan[0] = vals[0]; props->Reverb.LateReverbPan[1] = vals[1]; props->Reverb.LateReverbPan[2] = vals[2]; @@ -1952,13 +1950,11 @@ void ALeaxreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb integer property"); } } void ALeaxreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALeaxreverb_getParami(effect, context, param, vals); -} +{ ALeaxreverb_getParami(effect, context, param, vals); } void ALeaxreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -2045,7 +2041,7 @@ void ALeaxreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb float property"); } } void ALeaxreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) @@ -2079,18 +2075,16 @@ void ALreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALi { case AL_REVERB_DECAY_HFLIMIT: if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb decay hflimit out of range",); props->Reverb.DecayHFLimit = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb integer property"); } } void ALreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALreverb_setParami(effect, context, param, vals[0]); -} +{ ALreverb_setParami(effect, context, param, vals[0]); } void ALreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -2098,84 +2092,82 @@ void ALreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALf { case AL_REVERB_DENSITY: if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb density out of range",); props->Reverb.Density = val; break; case AL_REVERB_DIFFUSION: if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb diffusion out of range",); props->Reverb.Diffusion = val; break; case AL_REVERB_GAIN: if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb gain out of range",); props->Reverb.Gain = val; break; case AL_REVERB_GAINHF: if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb gainhf out of range",); props->Reverb.GainHF = val; break; case AL_REVERB_DECAY_TIME: if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb decay time out of range",); props->Reverb.DecayTime = val; break; case AL_REVERB_DECAY_HFRATIO: if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb decay hfratio out of range",); props->Reverb.DecayHFRatio = val; break; case AL_REVERB_REFLECTIONS_GAIN: if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb reflections gain out of range",); props->Reverb.ReflectionsGain = val; break; case AL_REVERB_REFLECTIONS_DELAY: if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb reflections delay out of range",); props->Reverb.ReflectionsDelay = val; break; case AL_REVERB_LATE_REVERB_GAIN: if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb late reverb gain out of range",); props->Reverb.LateReverbGain = val; break; case AL_REVERB_LATE_REVERB_DELAY: if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb late reverb delay out of range",); props->Reverb.LateReverbDelay = val; break; case AL_REVERB_AIR_ABSORPTION_GAINHF: if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb air absorption gainhf out of range",); props->Reverb.AirAbsorptionGainHF = val; break; case AL_REVERB_ROOM_ROLLOFF_FACTOR: if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb room rolloff factor out of range",); props->Reverb.RoomRolloffFactor = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb float property"); } } void ALreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALreverb_setParamf(effect, context, param, vals[0]); -} +{ ALreverb_setParamf(effect, context, param, vals[0]); } void ALreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) { @@ -2187,13 +2179,11 @@ void ALreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb integer property"); } } void ALreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALreverb_getParami(effect, context, param, vals); -} +{ ALreverb_getParami(effect, context, param, vals); } void ALreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -2248,12 +2238,10 @@ void ALreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb float property"); } } void ALreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALreverb_getParamf(effect, context, param, vals); -} +{ ALreverb_getParamf(effect, context, param, vals); } DEFINE_ALEFFECT_VTABLE(ALreverb); diff --git a/OpenAL32/Include/alError.h b/OpenAL32/Include/alError.h index 9fb7a7e3..3dc16103 100644 --- a/OpenAL32/Include/alError.h +++ b/OpenAL32/Include/alError.h @@ -11,24 +11,14 @@ extern ALboolean TrapALError; ALvoid alSetError(ALCcontext *context, ALenum errorCode, ALuint objid, const char *msg); -#define SET_ERROR_AND_RETURN(ctx, err) do { \ - alSetError((ctx), (err), 0, "Unimplemented message"); \ - return; \ -} while(0) - -#define SET_ERROR_AND_RETURN_VALUE(ctx, err, val) do { \ - alSetError((ctx), (err), 0, "Unimplemented message"); \ - return (val); \ -} while(0) - -#define SET_ERROR_AND_GOTO(ctx, err, lbl) do { \ - alSetError((ctx), (err), 0, "Unimplemented message"); \ +#define SETERR_GOTO(ctx, err, objid, msg, lbl) do { \ + alSetError((ctx), (err), (objid), (msg)); \ goto lbl; \ } while(0) -#define SET_ERR_AND_RETURN(ctx, err, objid, msg) do { \ +#define SETERR_RETURN(ctx, err, objid, msg, retval) do { \ alSetError((ctx), (err), (objid), (msg)); \ - return; \ + return retval; \ } while(0) #ifdef __cplusplus diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 2dcf7125..a8186f07 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -73,7 +73,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(!context) return; if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative effect slots", done); tmpslots = al_malloc(DEF_ALIGN, sizeof(ALeffectslot*)*n); LockEffectSlotsWrite(context); @@ -87,7 +87,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo UnlockEffectSlotsWrite(context); alDeleteAuxiliaryEffectSlots(cur, effectslots); - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, 0, "Effect slot object allocation failed", done); } err = NewThunkEntry(&slot->id); @@ -103,7 +103,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo UnlockEffectSlotsWrite(context); alDeleteAuxiliaryEffectSlots(cur, effectslots); - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, 0, "Failed to set effect slot ID", done); } aluInitEffectPanning(slot); @@ -149,13 +149,15 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * LockEffectSlotsWrite(context); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative effect slots", + done); for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslots[i], "Invalid effect slot ID", done); if(ReadRef(&slot->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + SETERR_GOTO(context, AL_INVALID_OPERATION, effectslots[i], + "Deleting in-use effect slot", done); } // All effectslots are valid @@ -238,7 +240,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param WriteLock(&context->PropLock); LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { case AL_EFFECTSLOT_EFFECT: @@ -249,23 +251,25 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!(value == 0 || effect != NULL)) { UnlockEffectsRead(device); - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, effectslot, "Invalid effect ID", done); } err = InitializeEffect(context, slot, effect); UnlockEffectsRead(device); if(err != AL_NO_ERROR) - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, effectslot, "Effect initialization failed", done); break; case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: if(!(value == AL_TRUE || value == AL_FALSE)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, effectslot, + "Effect slot auxiliary send auto out of range", done); slot->AuxSendAuto = value; break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + SETERR_GOTO(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot integer property", + done); } DO_UPDATEPROPS(); @@ -292,11 +296,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, effectslot, + "Invalid effect slot integer-vector property"); } done: @@ -315,17 +320,19 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param WriteLock(&context->PropLock); LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { case AL_EFFECTSLOT_GAIN: if(!(value >= 0.0f && value <= 1.0f)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, effectslot, "Effect slot gain out of range", + done); slot->Gain = value; break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + SETERR_GOTO(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot float property", + done); } DO_UPDATEPROPS(); @@ -351,11 +358,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum para LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, effectslot, + "Invalid effect slot float-vector property"); } done: @@ -373,7 +381,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: @@ -381,7 +389,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot integer property"); } done: @@ -406,11 +414,12 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, effectslot, + "Invalid effect slot integer-vector property"); } done: @@ -428,7 +437,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { case AL_EFFECTSLOT_GAIN: @@ -436,7 +445,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot float property"); } done: @@ -460,11 +469,12 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, effectslot, + "Invalid effect slot float-vector property"); } done: diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 754368b7..922c379c 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -66,7 +66,7 @@ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers) if(!context) return; if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative buffers", done); for(cur = 0;cur < n;cur++) { @@ -98,7 +98,7 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) LockBuffersWrite(device); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative buffers", done); for(i = 0;i < n;i++) { @@ -107,9 +107,9 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) /* Check for valid Buffer ID */ if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffers[i], "Invalid buffer ID", done); if(ReadRef(&ALBuf->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + SETERR_GOTO(context, AL_INVALID_OPERATION, buffers[i], "Deleting in-use buffer", done); } for(i = 0;i < n;i++) @@ -161,16 +161,19 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(!(size >= 0 && freq > 0) || (flags&INVALID_STORAGE_MASK) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + if(!(size >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Negative storage size", done); + if(!(freq > 0)) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid sample rate", done); + if((flags&INVALID_STORAGE_MASK) != 0) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid storage flags", done); if((flags&AL_MAP_PERSISTENT_BIT_SOFT) && !(flags&MAP_READ_WRITE_FLAGS)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, + "Declaring persistently mapped storage without read or write access", done); if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + SETERR_GOTO(context, AL_INVALID_ENUM, buffer, "Invalid format", done); align = SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign)); - if(align < 1) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid unpack alignment", done); switch(srctype) { @@ -215,21 +218,32 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(!(access&MAP_READ_WRITE_FLAGS) || (access&~MAP_ACCESS_FLAGS) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + if((access&~MAP_ACCESS_FLAGS) != 0) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid map flags", done); + if(!(access&MAP_READ_WRITE_FLAGS)) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, + "Mapping buffer without read or write access", done); WriteLock(&albuf->lock); - if((ReadRef(&albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT)) || - albuf->MappedAccess != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, unlock_done); - if(((access&AL_MAP_READ_BIT_SOFT) && !(albuf->Access&AL_MAP_READ_BIT_SOFT)) || - ((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)) || - ((access&AL_MAP_PERSISTENT_BIT_SOFT) && !(albuf->Access&AL_MAP_PERSISTENT_BIT_SOFT))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done); + if(ReadRef(&albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT)) + SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, + "Mapping in-use buffer without persistent mapping", unlock_done); + if(albuf->MappedAccess != 0) + SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, "Mapping already-mapped buffer", + unlock_done); + if((access&AL_MAP_READ_BIT_SOFT) && !(albuf->Access&AL_MAP_READ_BIT_SOFT)) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, + "Mapping buffer for reading without read access", unlock_done); + if((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, + "Mapping buffer for writing without write access", unlock_done); + if((access&AL_MAP_PERSISTENT_BIT_SOFT) && !(albuf->Access&AL_MAP_PERSISTENT_BIT_SOFT)) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, + "Mapping buffer persistently without persistent access", unlock_done); if(offset < 0 || offset >= albuf->OriginalSize || length <= 0 || length > albuf->OriginalSize - offset) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Mapping out of range", unlock_done); retval = (ALbyte*)albuf->data + offset; albuf->MappedAccess = access; @@ -258,7 +272,7 @@ AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer) device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); WriteLock(&albuf->lock); if(albuf->MappedAccess == 0) @@ -288,7 +302,7 @@ AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, A device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); WriteLock(&albuf->lock); if(albuf->MappedAccess == 0 || !(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT)) @@ -332,21 +346,22 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(!(length >= 0 && offset >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + SETERR_GOTO(context, AL_INVALID_ENUM, buffer, "Invalid format", done); WriteLock(&albuf->lock); align = SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign)); - if(align < 1) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done); + if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid unpack alignment", done); if((long)srcchannels != (long)albuf->FmtChannels || srctype != albuf->OriginalType) - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, unlock_done); + SETERR_GOTO(context, AL_INVALID_ENUM, buffer, "Unpacking data with mismatched format", + unlock_done); if(align != albuf->OriginalAlign) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Unpacking data with mismatched alignment", + unlock_done); if(albuf->MappedAccess != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, unlock_done); + SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, "Unpacking data into mapped buffer", + unlock_done); num_chans = ChannelsFromFmt(albuf->FmtChannels); frame_size = num_chans * BytesFromFmt(albuf->FmtType); @@ -357,9 +372,11 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons else byte_align = align * frame_size; - if(offset > albuf->OriginalSize || length > albuf->OriginalSize-offset || - (offset%byte_align) != 0 || (length%byte_align) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done); + if(offset < 0 || length < 0 || offset > albuf->OriginalSize || + length > albuf->OriginalSize-offset) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Data sub-range out of range", unlock_done); + if((offset%byte_align) != 0 || (length%byte_align) != 0) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid sub-range alignment", unlock_done); /* offset -> byte offset, length -> sample count */ offset = offset/byte_align * frame_size; @@ -452,12 +469,12 @@ AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(va device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float property"); } done: @@ -477,12 +494,12 @@ AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(v device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-float property"); } done: @@ -502,14 +519,13 @@ AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *v device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float-vector property"); } done: @@ -530,24 +546,26 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); switch(param) { case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, + "Negative buffer unpack block alignment", done); ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Negative buffer pack block alignment", + done); ATOMIC_STORE_SEQ(&albuf->PackAlign, value); break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer property"); } done: @@ -566,12 +584,12 @@ AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(val device = context->Device; if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-integer property"); } done: @@ -602,10 +620,9 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { case AL_LOOP_POINTS_SOFT: @@ -613,13 +630,14 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val if(ReadRef(&albuf->ref) != 0) { WriteUnlock(&albuf->lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, + "Modifying in-use buffer loop points", done); } if(values[0] >= values[1] || values[0] < 0 || values[1] > albuf->SampleLen) { WriteUnlock(&albuf->lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid loop point range", done); } albuf->LoopStart = values[0]; @@ -628,7 +646,7 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer-vector property"); } done: @@ -649,14 +667,13 @@ AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *val device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(value)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float property"); } done: @@ -676,14 +693,14 @@ AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *valu device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(value1 && value2 && value3)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!value1 || !value2 || !value3) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-float property"); } done: @@ -710,14 +727,13 @@ AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *valu device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float-vector property"); } done: @@ -738,10 +754,9 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(value)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { case AL_FREQUENCY: @@ -772,7 +787,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer property"); } done: @@ -792,14 +807,14 @@ AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1 device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(value1 && value2 && value3)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!value1 || !value2 || !value3) + SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-integer property"); } done: @@ -835,10 +850,9 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); switch(param) { case AL_LOOP_POINTS_SOFT: @@ -849,7 +863,7 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer-vector property"); } done: @@ -884,7 +898,7 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei case UserFmtBFormat3D: DstChannels = FmtBFormat3D; break; } if(UNLIKELY((long)SrcChannels != (long)DstChannels)) - SET_ERR_AND_RETURN(context, AL_INVALID_ENUM, ALBuf->id, "Invalid format"); + SETERR_RETURN(context, AL_INVALID_ENUM, ALBuf->id, "Invalid format",); /* IMA4 and MSADPCM convert to 16-bit short. */ switch(SrcType) @@ -902,23 +916,23 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei if(access != 0) { if(UNLIKELY((long)SrcType != (long)DstType)) - SET_ERR_AND_RETURN(context, AL_INVALID_VALUE, ALBuf->id, - "Format cannot be mapped or preserved"); + SETERR_RETURN(context, AL_INVALID_VALUE, ALBuf->id, + "Format cannot be mapped or preserved",); } NumChannels = ChannelsFromFmt(DstChannels); FrameSize = NumChannels * BytesFromFmt(DstType); if(UNLIKELY(frames > INT_MAX/FrameSize)) - SET_ERR_AND_RETURN(context, AL_OUT_OF_MEMORY, ALBuf->id, "Buffer size too large"); + SETERR_RETURN(context, AL_OUT_OF_MEMORY, ALBuf->id, "Buffer size too large",); newsize = frames*FrameSize; WriteLock(&ALBuf->lock); if(UNLIKELY(ReadRef(&ALBuf->ref) != 0 || ALBuf->MappedAccess != 0)) { WriteUnlock(&ALBuf->lock); - SET_ERR_AND_RETURN(context, AL_INVALID_OPERATION, ALBuf->id, - "Modifying storage for in-use buffer"); + SETERR_RETURN(context, AL_INVALID_OPERATION, ALBuf->id, + "Modifying storage for in-use buffer",); } if((access&AL_PRESERVE_DATA_BIT_SOFT)) @@ -927,14 +941,14 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei if(UNLIKELY(ALBuf->FmtChannels != DstChannels || ALBuf->OriginalType != SrcType)) { WriteUnlock(&ALBuf->lock); - SET_ERR_AND_RETURN(context, AL_INVALID_VALUE, ALBuf->id, - "Preserving data of mismatched format"); + SETERR_RETURN(context, AL_INVALID_VALUE, ALBuf->id, + "Preserving data of mismatched format",); } if(UNLIKELY(ALBuf->OriginalAlign != align)) { WriteUnlock(&ALBuf->lock); - SET_ERR_AND_RETURN(context, AL_INVALID_VALUE, ALBuf->id, - "Preserving data of mismatched alignment"); + SETERR_RETURN(context, AL_INVALID_VALUE, ALBuf->id, + "Preserving data of mismatched alignment",); } } @@ -952,7 +966,7 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei if(UNLIKELY(!temp && newsize)) { WriteUnlock(&ALBuf->lock); - SET_ERR_AND_RETURN(context, AL_OUT_OF_MEMORY, ALBuf->id, "Failed to allocate storage"); + SETERR_RETURN(context, AL_OUT_OF_MEMORY, ALBuf->id, "Failed to allocate storage",); } if((access&AL_PRESERVE_DATA_BIT_SOFT)) { @@ -1190,7 +1204,7 @@ ALbuffer *NewBuffer(ALCcontext *context) buffer = al_calloc(16, sizeof(ALbuffer)); if(!buffer) - SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); + SETERR_RETURN(context, AL_OUT_OF_MEMORY, 0, "Failed to allocate buffer object", NULL); RWLockInit(&buffer->lock); buffer->Access = 0; buffer->MappedAccess = 0; @@ -1204,7 +1218,7 @@ ALbuffer *NewBuffer(ALCcontext *context) memset(buffer, 0, sizeof(ALbuffer)); al_free(buffer); - SET_ERROR_AND_RETURN_VALUE(context, err, NULL); + SETERR_RETURN(context, err, 0, "Failed to set buffer ID", NULL); } return buffer; diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 755d792e..5f6e661a 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -69,7 +69,7 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) if(!context) return; if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative effects", done); device = context->Device; for(cur = 0;cur < n;cur++) @@ -80,7 +80,7 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) { al_free(effect); alDeleteEffects(cur, effects); - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, 0, "Failed to allocate effect object", done); } err = NewThunkEntry(&effect->id); @@ -93,7 +93,7 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) al_free(effect); alDeleteEffects(cur, effects); - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, 0, "Failed to set effect ID", done); } effects[cur] = effect->id; @@ -116,11 +116,11 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) device = context->Device; LockEffectsWrite(device); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative effects", done); for(i = 0;i < n;i++) { if(effects[i] && LookupEffect(device, effects[i]) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, effects[i], "Invalid effect ID", done); } for(i = 0;i < n;i++) { diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c index 7db326a2..9b6e5a97 100644 --- a/OpenAL32/alExtension.c +++ b/OpenAL32/alExtension.c @@ -45,8 +45,8 @@ AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName) context = GetContextRef(); if(!context) return AL_FALSE; - if(!(extName)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!extName) + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "NULL pointer", done); len = strlen(extName); ptr = context->ExtensionList; diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 16796760..24b0e607 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -55,7 +55,7 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) if(!context) return; if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative filters", done); device = context->Device; for(cur = 0;cur < n;cur++) @@ -64,7 +64,7 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) if(!filter) { alDeleteFilters(cur, filters); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, 0, "Failed to allocate filter object", done); } InitFilterParams(filter, AL_FILTER_NULL); @@ -78,7 +78,7 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) al_free(filter); alDeleteFilters(cur, filters); - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, 0, "Failed ot set filter ID", done); } filters[cur] = filter->id; @@ -101,11 +101,11 @@ AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) device = context->Device; LockFiltersWrite(device); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative filters", done); for(i = 0;i < n;i++) { if(filters[i] && LookupFilter(device, filters[i]) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, filters[i], "Invalid filter ID", done); } for(i = 0;i < n;i++) { @@ -435,37 +435,37 @@ void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat g } -static void ALlowpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALlowpass_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALlowpass_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer property"); } +static void ALlowpass_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer-vector property"); } static void ALlowpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_LOWPASS_GAIN: if(!(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Low-pass gain out of range",); filter->Gain = val; break; case AL_LOWPASS_GAINHF: if(!(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Low-pass gainhf out of range",); filter->GainHF = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass float property"); } } static void ALlowpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) { ALlowpass_setParamf(filter, context, param, vals[0]); } -static void ALlowpass_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALlowpass_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALlowpass_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer property"); } +static void ALlowpass_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer-vector property"); } static void ALlowpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -479,7 +479,7 @@ static void ALlowpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum pa break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass float property"); } } static void ALlowpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -488,37 +488,37 @@ static void ALlowpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum p DEFINE_ALFILTER_VTABLE(ALlowpass); -static void ALhighpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALhighpass_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALhighpass_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer property"); } +static void ALhighpass_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer-vector property"); } static void ALhighpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_HIGHPASS_GAIN: if(!(val >= AL_HIGHPASS_MIN_GAIN && val <= AL_HIGHPASS_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "High-pass gain out of range",); filter->Gain = val; break; case AL_HIGHPASS_GAINLF: if(!(val >= AL_HIGHPASS_MIN_GAINLF && val <= AL_HIGHPASS_MAX_GAINLF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "High-pass gainlf out of range",); filter->GainLF = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass float property"); } } static void ALhighpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) { ALhighpass_setParamf(filter, context, param, vals[0]); } -static void ALhighpass_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALhighpass_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALhighpass_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer property"); } +static void ALhighpass_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer-vector property"); } static void ALhighpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -532,7 +532,7 @@ static void ALhighpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass float property"); } } static void ALhighpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -541,43 +541,43 @@ static void ALhighpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum DEFINE_ALFILTER_VTABLE(ALhighpass); -static void ALbandpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALbandpass_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALbandpass_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer property"); } +static void ALbandpass_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer-vector property"); } static void ALbandpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_BANDPASS_GAIN: if(!(val >= AL_BANDPASS_MIN_GAIN && val <= AL_BANDPASS_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Band-pass gain out of range",); filter->Gain = val; break; case AL_BANDPASS_GAINHF: if(!(val >= AL_BANDPASS_MIN_GAINHF && val <= AL_BANDPASS_MAX_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Band-pass gainhf out of range",); filter->GainHF = val; break; case AL_BANDPASS_GAINLF: if(!(val >= AL_BANDPASS_MIN_GAINLF && val <= AL_BANDPASS_MAX_GAINLF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Band-pass gainlf out of range",); filter->GainLF = val; break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass float property"); } } static void ALbandpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) { ALbandpass_setParamf(filter, context, param, vals[0]); } -static void ALbandpass_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALbandpass_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALbandpass_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer property"); } +static void ALbandpass_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer-vector property"); } static void ALbandpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -595,7 +595,7 @@ static void ALbandpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum p break; default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass float property"); } } static void ALbandpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -604,23 +604,23 @@ static void ALbandpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum DEFINE_ALFILTER_VTABLE(ALbandpass); -static void ALnullfilter_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALnullfilter_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALnullfilter_setParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALnullfilter_setParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } - -static void ALnullfilter_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALnullfilter_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALnullfilter_getParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -static void ALnullfilter_getParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void ALnullfilter_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_setParamf(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_setParamfv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } + +static void ALnullfilter_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_getParamf(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_getParamfv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } DEFINE_ALFILTER_VTABLE(ALnullfilter); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 9a90c16e..51ab6fc9 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -48,14 +48,15 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) { case AL_GAIN: if(!(value >= 0.0f && isfinite(value))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener gain out of range", done); listener->Gain = value; DO_UPDATEPROPS(); break; case AL_METERS_PER_UNIT: if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener meters per unit out of range", + done); context->MetersPerUnit = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) UpdateContextProps(context); @@ -64,7 +65,7 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener float property"); } done: @@ -87,7 +88,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val { case AL_POSITION: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener position out of range", done); listener->Position[0] = value1; listener->Position[1] = value2; listener->Position[2] = value3; @@ -96,7 +97,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val case AL_VELOCITY: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener velocity out of range", done); listener->Velocity[0] = value1; listener->Velocity[1] = value2; listener->Velocity[2] = value3; @@ -104,7 +105,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener 3-float property"); } done: @@ -139,14 +140,13 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) listener = context->Listener; WriteLock(&context->PropLock); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, 0, "NULL pointer", done); switch(param) { case AL_ORIENTATION: if(!(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener orientation out of range", done); /* AT then UP */ listener->Forward[0] = values[0]; listener->Forward[1] = values[1]; @@ -158,7 +158,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener float-vector property"); } done: @@ -178,11 +178,10 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener integer property"); } - -done: WriteUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -206,11 +205,10 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener 3-integer property"); } - -done: WriteUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -245,16 +243,15 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) if(!context) return; WriteLock(&context->PropLock); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch(param) + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener integer-vector property"); } - -done: WriteUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -267,9 +264,9 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) if(!context) return; ReadLock(&context->PropLock); - if(!(value)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch(param) + if(!value) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { case AL_GAIN: *value = context->Listener->Gain; @@ -280,11 +277,10 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener float property"); } - -done: ReadUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -297,9 +293,9 @@ AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat if(!context) return; ReadLock(&context->PropLock); - if(!(value1 && value2 && value3)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch(param) + if(!value1 || !value2 || !value3) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { case AL_POSITION: *value1 = context->Listener->Position[0]; @@ -314,11 +310,10 @@ AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener 3-float property"); } - -done: ReadUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -344,9 +339,9 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) if(!context) return; ReadLock(&context->PropLock); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch(param) + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { case AL_ORIENTATION: // AT then UP @@ -359,11 +354,10 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener float-vector property"); } - -done: ReadUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -376,16 +370,15 @@ AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) if(!context) return; ReadLock(&context->PropLock); - if(!(value)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch(param) + if(!value) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener integer property"); } - -done: ReadUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -398,9 +391,9 @@ AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *valu if(!context) return; ReadLock(&context->PropLock); - if(!(value1 && value2 && value3)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch (param) + if(!value1 || !value2 || !value3) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { case AL_POSITION: *value1 = (ALint)context->Listener->Position[0]; @@ -415,11 +408,10 @@ AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *valu break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener 3-integer property"); } - -done: ReadUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -440,9 +432,9 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) if(!context) return; ReadLock(&context->PropLock); - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - switch(param) + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); + else switch(param) { case AL_ORIENTATION: // AT then UP @@ -455,11 +447,10 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_ENUM, 0, "Invalid listener integer-vector property"); } - -done: ReadUnlock(&context->PropLock); + ALCcontext_DecRef(context); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 2b561597..c60b6a01 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -452,7 +452,11 @@ static ALint Int64ValsByProp(ALenum prop) #define CHECKVAL(x) do { \ if(!(x)) \ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \ + { \ + alSetError(Context, AL_INVALID_VALUE, Source->id, \ + "Value out of range"); \ + return AL_FALSE; \ + } \ } while(0) #define DO_UPDATEPROPS() do { \ @@ -477,7 +481,8 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_OFFSET_LATENCY_SOFT: case AL_SEC_OFFSET_CLOCK_SOFT: /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, + "Setting read-only source property", AL_FALSE); case AL_PITCH: CHECKVAL(*values >= 0.0f); @@ -601,7 +606,8 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid offset", + AL_FALSE); } WriteUnlock(&Source->queue_lock); } @@ -694,7 +700,7 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source float property", AL_FALSE); } static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALint *values) @@ -716,7 +722,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SAMPLE_LENGTH_SOFT: case AL_SEC_LENGTH_SOFT: /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, + "Setting read-only source property", AL_FALSE); case AL_SOURCE_RELATIVE: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); @@ -756,7 +763,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if(!(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL)) { UnlockBuffersRead(device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid buffer ID", + AL_FALSE); } WriteLock(&Source->queue_lock); @@ -765,7 +773,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, + "Setting non-persistently mapped buffer", AL_FALSE); } else { @@ -774,7 +783,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, + "Setting buffer on playing or paused source", AL_FALSE); } } @@ -839,7 +849,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, + "Invalid source offset", AL_FALSE); } WriteUnlock(&Source->queue_lock); } @@ -852,7 +863,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if(!(*values == 0 || (filter=LookupFilter(device, *values)) != NULL)) { UnlockFiltersRead(device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid filter ID", + AL_FALSE); } if(!filter) @@ -941,7 +953,9 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { UnlockFiltersRead(device); UnlockEffectSlotsRead(Context); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + /* TODO: Fix message */ + SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid send parameter", + AL_FALSE); } if(!filter) @@ -1040,7 +1054,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer property", + AL_FALSE); } static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALint64SOFT *values) @@ -1060,8 +1075,8 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp case AL_SAMPLE_LENGTH_SOFT: case AL_SEC_LENGTH_SOFT: /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - + SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, + "Setting read-only source property", AL_FALSE); /* 1x int */ case AL_SOURCE_RELATIVE: @@ -1145,7 +1160,8 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp } ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer64 property", + AL_FALSE); } #undef CHECKVAL @@ -1342,7 +1358,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source double property", + AL_FALSE); } static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values) @@ -1586,7 +1603,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer property", + AL_FALSE); } static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values) @@ -1718,7 +1736,8 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp } ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer64 property", + AL_FALSE); } @@ -1733,7 +1752,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) if(!context) return; if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative sources", done); device = context->Device; for(cur = 0;cur < n;cur++) { @@ -1741,7 +1760,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) if(!source) { alDeleteSources(cur, sources); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + SETERR_GOTO(context, AL_OUT_OF_MEMORY,0, "Failed to allocate source object", done); } InitSourceParams(source, device->NumAuxSends); @@ -1755,7 +1774,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) al_free(source); alDeleteSources(cur, sources); - SET_ERROR_AND_GOTO(context, err, done); + SETERR_GOTO(context, err, 0, "Failed to set source ID", done); } sources[cur] = source->id; @@ -1778,13 +1797,13 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) LockSourcesWrite(context); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative sources", done); /* Check that all Sources are valid */ for(i = 0;i < n;i++) { if(LookupSource(context, sources[i]) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); } device = context->Device; for(i = 0;i < n;i++) @@ -2490,11 +2509,11 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Playing negative sources", done); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); } device = context->Device; @@ -2517,7 +2536,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) if(context->MaxVoices >= newcount) { ALCdevice_Unlock(device); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, 0, "Max voice count overflow", done); } AllocateVoices(context, newcount, device->NumAuxSends); } @@ -2677,11 +2696,11 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Pausing negative sources", done); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); } device = context->Device; @@ -2724,11 +2743,11 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Stopping negative sources", done); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); } device = context->Device; @@ -2774,11 +2793,11 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Rewinding negative sources", done); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); } device = context->Device; @@ -2828,16 +2847,16 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu LockSourcesRead(context); if(!(nb >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, src, "Queueing negative buffers", done); if((source=LookupSource(context, src)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, src, "Invalid source ID", done); WriteLock(&source->queue_lock); if(source->SourceType == AL_STATIC) { WriteUnlock(&source->queue_lock); /* Can't queue on a Static Source */ - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + SETERR_GOTO(context, AL_INVALID_OPERATION, src, "Queueing onto a static source", done); } /* Check for a valid Buffer, for its frequency and format */ @@ -2862,7 +2881,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) { WriteUnlock(&source->queue_lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, buffer_error); + SETERR_GOTO(context, AL_INVALID_NAME, src, "Invalid buffer ID", buffer_error); } if(!BufferListStart) @@ -2892,7 +2911,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT)) { WriteUnlock(&source->queue_lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, buffer_error); + SETERR_GOTO(context, AL_INVALID_OPERATION, src, + "Queueing non-persistently mapped buffer", buffer_error); } if(BufferFmt == NULL) @@ -2902,7 +2922,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferFmt->OriginalType != buffer->OriginalType) { WriteUnlock(&source->queue_lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, buffer_error); + alSetError(context, AL_INVALID_OPERATION, src, + "Queueing buffer with mismatched format"); buffer_error: /* A buffer failed (invalid ID or format), so unlock and release @@ -2973,20 +2994,25 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint LockSourcesRead(context); if(!(nb >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing negative buffers", done); if((source=LookupSource(context, src)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + SETERR_GOTO(context, AL_INVALID_NAME, src, "Invalid source ID", done); /* Nothing to unqueue. */ if(nb == 0) goto done; WriteLock(&source->queue_lock); - if(source->Looping || source->SourceType != AL_STREAMING) + if(source->Looping) + { + WriteUnlock(&source->queue_lock); + SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing from a looping source", done); + } + if(source->SourceType != AL_STREAMING) { WriteUnlock(&source->queue_lock); - /* Trying to unqueue buffers on a looping or non-streaming source. */ - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing from a non-streaming source", + done); } /* Find the new buffer queue head */ @@ -3008,8 +3034,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint if(i != nb) { WriteUnlock(&source->queue_lock); - /* Trying to unqueue pending buffers. */ - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing pending buffers", done); } /* Swap it, and cut the new head from the old. */ diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 36afd46e..f34f385f 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -88,11 +88,10 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid enable property"); } - -done: WriteUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -112,11 +111,10 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid disable property"); } - -done: WriteUnlock(&context->PropLock); + ALCcontext_DecRef(context); } @@ -135,12 +133,10 @@ AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid is enabled property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -194,12 +190,10 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid boolean property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -247,12 +241,10 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid double property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -300,12 +292,10 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid float property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -353,12 +343,10 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid integer property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -406,12 +394,10 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid integer64 property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -433,13 +419,11 @@ AL_API void* AL_APIENTRY alGetPointerSOFT(ALenum pname) value = context->EventParam; break; - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + default: + alSetError(context, AL_INVALID_VALUE, 0, "Invalid pointer property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -461,15 +445,14 @@ AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void **values) context = GetContextRef(); if(!context) return; - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); switch(pname) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid pointer-vector property"); } -done: ALCcontext_DecRef(context); } @@ -497,15 +480,14 @@ AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values) context = GetContextRef(); if(!context) return; - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); switch(pname) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid boolean-vector property"); } -done: ALCcontext_DecRef(context); } @@ -533,15 +515,14 @@ AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values) context = GetContextRef(); if(!context) return; - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); switch(pname) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid double-vector property"); } -done: ALCcontext_DecRef(context); } @@ -569,15 +550,14 @@ AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values) context = GetContextRef(); if(!context) return; - if(!(values)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); switch(pname) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid float-vector property"); } -done: ALCcontext_DecRef(context); } @@ -605,13 +585,14 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) context = GetContextRef(); if(!context) return; + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); switch(pname) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid integer-vector property"); } -done: ALCcontext_DecRef(context); } @@ -639,13 +620,14 @@ AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) context = GetContextRef(); if(!context) return; + if(!values) + alSetError(context, AL_INVALID_VALUE, 0, "NULL pointer"); switch(pname) { default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid integer64-vector property"); } -done: ALCcontext_DecRef(context); } @@ -700,12 +682,10 @@ AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname) break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid string property"); } -done: ALCcontext_DecRef(context); - return value; } @@ -717,7 +697,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) if(!context) return; if(!(value >= 0.0f && isfinite(value))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Doppler factor out of range", done); WriteLock(&context->PropLock); context->DopplerFactor = value; @@ -736,7 +716,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) if(!context) return; if(!(value >= 0.0f && isfinite(value))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Doppler velocity out of range", done); WriteLock(&context->PropLock); context->DopplerVelocity = value; @@ -755,7 +735,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) if(!context) return; if(!(value > 0.0f && isfinite(value))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Speed of sound out of range", done); WriteLock(&context->PropLock); context->SpeedOfSound = value; @@ -777,7 +757,7 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED || value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED || value == AL_NONE)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Distance model out of range", done); WriteLock(&context->PropLock); context->DistanceModel = value; @@ -834,12 +814,12 @@ AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index) { case AL_RESAMPLER_NAME_SOFT: if(index < 0 || (size_t)index >= COUNTOF(ResamplerNames)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Resampler name index out of range", done); value = ResamplerNames[index]; break; default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + alSetError(context, AL_INVALID_VALUE, 0, "Invalid string indexed property"); } done: diff --git a/OpenAL32/event.c b/OpenAL32/event.c index 4e844ce9..88885f52 100644 --- a/OpenAL32/event.c +++ b/OpenAL32/event.c @@ -17,11 +17,9 @@ AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, A context = GetContextRef(); if(!context) return; - if(count < 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(count < 0) SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Controlling negative events", done); if(count == 0) goto done; - if(!types) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!types) SETERR_GOTO(context, AL_INVALID_VALUE, 0, "NULL pointer", done); for(i = 0;i < count;i++) { @@ -34,17 +32,16 @@ AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, A else if(types[i] == AL_EVENT_TYPE_PERFORMANCE_SOFT) flags |= EventType_Performance; else - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + SETERR_GOTO(context, AL_INVALID_ENUM, 0, "Invalid event type", done); } almtx_lock(&context->EventLock); - if(enable) context->EnabledEvts |= flags; else context->EnabledEvts &= ~flags; - almtx_unlock(&context->EventLock); + done: ALCcontext_DecRef(context); } -- cgit v1.2.3 From 99f0377ae3f24ebf3391a09940d888dec1d4b4c4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 25 Jan 2018 15:59:59 -0800 Subject: Construct error messages using parameterized values --- Alc/effects/chorus.c | 44 ++++---- Alc/effects/compressor.c | 24 ++-- Alc/effects/dedicated.c | 22 ++-- Alc/effects/distortion.c | 32 +++--- Alc/effects/echo.c | 30 ++--- Alc/effects/equalizer.c | 40 +++---- Alc/effects/modulator.c | 14 +-- Alc/effects/null.c | 48 ++++---- Alc/effects/reverb.c | 92 ++++++++-------- OpenAL32/Include/alError.h | 10 +- OpenAL32/alAuxEffectSlot.c | 71 ++++++------ OpenAL32/alBuffer.c | 208 ++++++++++++++++++----------------- OpenAL32/alEffect.c | 28 ++--- OpenAL32/alError.c | 30 ++++- OpenAL32/alExtension.c | 2 +- OpenAL32/alFilter.c | 136 +++++++++++------------ OpenAL32/alListener.c | 13 +-- OpenAL32/alSource.c | 266 +++++++++++++++++++++++---------------------- OpenAL32/alState.c | 65 +++++------ OpenAL32/event.c | 6 +- 20 files changed, 610 insertions(+), 571 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index 75de6be7..666933a8 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -317,18 +317,18 @@ void ALchorus_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALi { case AL_CHORUS_WAVEFORM: if(!(val >= AL_CHORUS_MIN_WAVEFORM && val <= AL_CHORUS_MAX_WAVEFORM)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Invalid chorus waveform",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid chorus waveform"); props->Chorus.Waveform = val; break; case AL_CHORUS_PHASE: if(!(val >= AL_CHORUS_MIN_PHASE && val <= AL_CHORUS_MAX_PHASE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus phase out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Chorus phase out of range"); props->Chorus.Phase = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param); } } void ALchorus_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) @@ -340,30 +340,30 @@ void ALchorus_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALf { case AL_CHORUS_RATE: if(!(val >= AL_CHORUS_MIN_RATE && val <= AL_CHORUS_MAX_RATE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus rate out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Chorus rate out of range"); props->Chorus.Rate = val; break; case AL_CHORUS_DEPTH: if(!(val >= AL_CHORUS_MIN_DEPTH && val <= AL_CHORUS_MAX_DEPTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus depth out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Chorus depth out of range"); props->Chorus.Depth = val; break; case AL_CHORUS_FEEDBACK: if(!(val >= AL_CHORUS_MIN_FEEDBACK && val <= AL_CHORUS_MAX_FEEDBACK)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus feedback out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Chorus feedback out of range"); props->Chorus.Feedback = val; break; case AL_CHORUS_DELAY: if(!(val >= AL_CHORUS_MIN_DELAY && val <= AL_CHORUS_MAX_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Chorus delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Chorus delay out of range"); props->Chorus.Delay = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param); } } void ALchorus_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -383,7 +383,7 @@ void ALchorus_getParami(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid chorus integer property 0x%04x", param); } } void ALchorus_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) @@ -410,7 +410,7 @@ void ALchorus_getParamf(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid chorus float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid chorus float property 0x%04x", param); } } void ALchorus_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) @@ -453,18 +453,18 @@ void ALflanger_setParami(ALeffect *effect, ALCcontext *context, ALenum param, AL { case AL_FLANGER_WAVEFORM: if(!(val >= AL_FLANGER_MIN_WAVEFORM && val <= AL_FLANGER_MAX_WAVEFORM)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Invalid flanger waveform",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid flanger waveform"); props->Chorus.Waveform = val; break; case AL_FLANGER_PHASE: if(!(val >= AL_FLANGER_MIN_PHASE && val <= AL_FLANGER_MAX_PHASE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger phase out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Flanger phase out of range"); props->Chorus.Phase = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param); } } void ALflanger_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) @@ -476,30 +476,30 @@ void ALflanger_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, AL { case AL_FLANGER_RATE: if(!(val >= AL_FLANGER_MIN_RATE && val <= AL_FLANGER_MAX_RATE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger rate out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Flanger rate out of range"); props->Chorus.Rate = val; break; case AL_FLANGER_DEPTH: if(!(val >= AL_FLANGER_MIN_DEPTH && val <= AL_FLANGER_MAX_DEPTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger depth out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Flanger depth out of range"); props->Chorus.Depth = val; break; case AL_FLANGER_FEEDBACK: if(!(val >= AL_FLANGER_MIN_FEEDBACK && val <= AL_FLANGER_MAX_FEEDBACK)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger feedback out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Flanger feedback out of range"); props->Chorus.Feedback = val; break; case AL_FLANGER_DELAY: if(!(val >= AL_FLANGER_MIN_DELAY && val <= AL_FLANGER_MAX_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Flanger delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Flanger delay out of range"); props->Chorus.Delay = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param); } } void ALflanger_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -519,13 +519,11 @@ void ALflanger_getParami(const ALeffect *effect, ALCcontext *context, ALenum par break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid flanger integer property 0x%04x", param); } } void ALflanger_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALflanger_getParami(effect, context, param, vals); -} +{ ALflanger_getParami(effect, context, param, vals); } void ALflanger_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -548,7 +546,7 @@ void ALflanger_getParamf(const ALeffect *effect, ALCcontext *context, ALenum par break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid flanger float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid flanger float property 0x%04x", param); } } void ALflanger_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index 330733b3..bb9be8b9 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -210,20 +210,21 @@ void ALcompressor_setParami(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_COMPRESSOR_ONOFF: if(!(val >= AL_COMPRESSOR_MIN_ONOFF && val <= AL_COMPRESSOR_MAX_ONOFF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Compressor state out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Compressor state out of range"); props->Compressor.OnOff = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid compressor integer property 0x%04x", + param); } } void ALcompressor_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) { ALcompressor_setParami(effect, context, param, vals[0]); } -void ALcompressor_setParamf(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float property"); } -void ALcompressor_setParamfv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float-vector property"); } +void ALcompressor_setParamf(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param); } +void ALcompressor_setParamfv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x", param); } void ALcompressor_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) { @@ -235,14 +236,15 @@ void ALcompressor_getParami(const ALeffect *effect, ALCcontext *context, ALenum break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid compressor integer property 0x%04x", + param); } } void ALcompressor_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) { ALcompressor_getParami(effect, context, param, vals); } -void ALcompressor_getParamf(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float property"); } -void ALcompressor_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid compressor float-vector property"); } +void ALcompressor_getParamf(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid compressor float property 0x%04x", param); } +void ALcompressor_getParamfv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid compressor float-vector property 0x%04x", param); } DEFINE_ALEFFECT_VTABLE(ALcompressor); diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 684e8171..70a97ea9 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -139,10 +139,10 @@ ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) } -void ALdedicated_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer property"); } -void ALdedicated_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer-vector property"); } +void ALdedicated_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param); } +void ALdedicated_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param); } void ALdedicated_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -150,21 +150,21 @@ void ALdedicated_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_DEDICATED_GAIN: if(!(val >= 0.0f && isfinite(val))) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Dedicated gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Dedicated gain out of range"); props->Dedicated.Gain = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param); } } void ALdedicated_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) { ALdedicated_setParamf(effect, context, param, vals[0]); } -void ALdedicated_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer property"); } -void ALdedicated_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated integer-vector property"); } +void ALdedicated_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer property 0x%04x", param); } +void ALdedicated_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid dedicated integer-vector property 0x%04x", param); } void ALdedicated_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -175,7 +175,7 @@ void ALdedicated_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid dedicated float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid dedicated float property 0x%04x", param); } } void ALdedicated_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index 2a7c21ec..dcb2bfe4 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -198,10 +198,10 @@ ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) } -void ALdistortion_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer property"); } -void ALdistortion_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer-vector property"); } +void ALdistortion_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param); } +void ALdistortion_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x", param); } void ALdistortion_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -209,45 +209,46 @@ void ALdistortion_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_DISTORTION_EDGE: if(!(val >= AL_DISTORTION_MIN_EDGE && val <= AL_DISTORTION_MAX_EDGE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion edge out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Distortion edge out of range"); props->Distortion.Edge = val; break; case AL_DISTORTION_GAIN: if(!(val >= AL_DISTORTION_MIN_GAIN && val <= AL_DISTORTION_MAX_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Distortion gain out of range"); props->Distortion.Gain = val; break; case AL_DISTORTION_LOWPASS_CUTOFF: if(!(val >= AL_DISTORTION_MIN_LOWPASS_CUTOFF && val <= AL_DISTORTION_MAX_LOWPASS_CUTOFF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion low-pass cutoff out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Distortion low-pass cutoff out of range"); props->Distortion.LowpassCutoff = val; break; case AL_DISTORTION_EQCENTER: if(!(val >= AL_DISTORTION_MIN_EQCENTER && val <= AL_DISTORTION_MAX_EQCENTER)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion EQ center out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Distortion EQ center out of range"); props->Distortion.EQCenter = val; break; case AL_DISTORTION_EQBANDWIDTH: if(!(val >= AL_DISTORTION_MIN_EQBANDWIDTH && val <= AL_DISTORTION_MAX_EQBANDWIDTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Distortion EQ bandwidth out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Distortion EQ bandwidth out of range"); props->Distortion.EQBandwidth = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", + param); } } void ALdistortion_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) { ALdistortion_setParamf(effect, context, param, vals[0]); } -void ALdistortion_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer property"); } -void ALdistortion_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion integer-vector property"); } +void ALdistortion_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid distortion integer property 0x%04x", param); } +void ALdistortion_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid distortion integer-vector property 0x%04x", param); } void ALdistortion_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -274,7 +275,8 @@ void ALdistortion_getParamf(const ALeffect *effect, ALCcontext *context, ALenum break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid distortion float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid distortion float property 0x%04x", + param); } } void ALdistortion_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index b59b06b0..d8cbd214 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -230,10 +230,10 @@ ALeffectStateFactory *ALechoStateFactory_getFactory(void) } -void ALecho_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer property"); } -void ALecho_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer-vector property"); } +void ALecho_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param); } +void ALecho_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param); } void ALecho_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -241,45 +241,45 @@ void ALecho_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALflo { case AL_ECHO_DELAY: if(!(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Echo delay out of range"); props->Echo.Delay = val; break; case AL_ECHO_LRDELAY: if(!(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo LR delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Echo LR delay out of range"); props->Echo.LRDelay = val; break; case AL_ECHO_DAMPING: if(!(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo damping out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Echo damping out of range"); props->Echo.Damping = val; break; case AL_ECHO_FEEDBACK: if(!(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo feedback out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Echo feedback out of range"); props->Echo.Feedback = val; break; case AL_ECHO_SPREAD: if(!(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Echo spread out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Echo spread out of range"); props->Echo.Spread = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param); } } void ALecho_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) { ALecho_setParamf(effect, context, param, vals[0]); } -void ALecho_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer property"); } -void ALecho_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo integer-vector property"); } +void ALecho_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid echo integer property 0x%04x", param); } +void ALecho_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid echo integer-vector property 0x%04x", param); } void ALecho_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -306,7 +306,7 @@ void ALecho_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid echo float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid echo float property 0x%04x", param); } } void ALecho_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index b800d27a..8c2b31e2 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -220,10 +220,10 @@ ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) } -void ALequalizer_setParami(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer property"); } -void ALequalizer_setParamiv(ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer-vector property"); } +void ALequalizer_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param); } +void ALequalizer_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x", param); } void ALequalizer_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) { ALeffectProps *props = &effect->Props; @@ -231,75 +231,75 @@ void ALequalizer_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EQUALIZER_LOW_GAIN: if(!(val >= AL_EQUALIZER_MIN_LOW_GAIN && val <= AL_EQUALIZER_MAX_LOW_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer low-band gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer low-band gain out of range"); props->Equalizer.LowGain = val; break; case AL_EQUALIZER_LOW_CUTOFF: if(!(val >= AL_EQUALIZER_MIN_LOW_CUTOFF && val <= AL_EQUALIZER_MAX_LOW_CUTOFF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer low-band cutoff out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer low-band cutoff out of range"); props->Equalizer.LowCutoff = val; break; case AL_EQUALIZER_MID1_GAIN: if(!(val >= AL_EQUALIZER_MIN_MID1_GAIN && val <= AL_EQUALIZER_MAX_MID1_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid1-band gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer mid1-band gain out of range"); props->Equalizer.Mid1Gain = val; break; case AL_EQUALIZER_MID1_CENTER: if(!(val >= AL_EQUALIZER_MIN_MID1_CENTER && val <= AL_EQUALIZER_MAX_MID1_CENTER)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid1-band center out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer mid1-band center out of range"); props->Equalizer.Mid1Center = val; break; case AL_EQUALIZER_MID1_WIDTH: if(!(val >= AL_EQUALIZER_MIN_MID1_WIDTH && val <= AL_EQUALIZER_MAX_MID1_WIDTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid1-band width out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer mid1-band width out of range"); props->Equalizer.Mid1Width = val; break; case AL_EQUALIZER_MID2_GAIN: if(!(val >= AL_EQUALIZER_MIN_MID2_GAIN && val <= AL_EQUALIZER_MAX_MID2_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid2-band gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer mid2-band gain out of range"); props->Equalizer.Mid2Gain = val; break; case AL_EQUALIZER_MID2_CENTER: if(!(val >= AL_EQUALIZER_MIN_MID2_CENTER && val <= AL_EQUALIZER_MAX_MID2_CENTER)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid2-band center out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer mid2-band center out of range"); props->Equalizer.Mid2Center = val; break; case AL_EQUALIZER_MID2_WIDTH: if(!(val >= AL_EQUALIZER_MIN_MID2_WIDTH && val <= AL_EQUALIZER_MAX_MID2_WIDTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer mid2-band width out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer mid2-band width out of range"); props->Equalizer.Mid2Width = val; break; case AL_EQUALIZER_HIGH_GAIN: if(!(val >= AL_EQUALIZER_MIN_HIGH_GAIN && val <= AL_EQUALIZER_MAX_HIGH_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer high-band gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer high-band gain out of range"); props->Equalizer.HighGain = val; break; case AL_EQUALIZER_HIGH_CUTOFF: if(!(val >= AL_EQUALIZER_MIN_HIGH_CUTOFF && val <= AL_EQUALIZER_MAX_HIGH_CUTOFF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Equalizer high-band cutoff out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Equalizer high-band cutoff out of range"); props->Equalizer.HighCutoff = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param); } } void ALequalizer_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) { ALequalizer_setParamf(effect, context, param, vals[0]); } -void ALequalizer_getParami(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer property"); } -void ALequalizer_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer integer-vector property"); } +void ALequalizer_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid equalizer integer property 0x%04x", param); } +void ALequalizer_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid equalizer integer-vector property 0x%04x", param); } void ALequalizer_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) { const ALeffectProps *props = &effect->Props; @@ -346,7 +346,7 @@ void ALequalizer_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid equalizer float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid equalizer float property 0x%04x", param); } } void ALequalizer_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index 0fb03042..ed0851d6 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -217,18 +217,18 @@ void ALmodulator_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_RING_MODULATOR_FREQUENCY: if(!(val >= AL_RING_MODULATOR_MIN_FREQUENCY && val <= AL_RING_MODULATOR_MAX_FREQUENCY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Modulator frequency out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Modulator frequency out of range"); props->Modulator.Frequency = val; break; case AL_RING_MODULATOR_HIGHPASS_CUTOFF: if(!(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Modulator high-pass cutoff out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Modulator high-pass cutoff out of range"); props->Modulator.HighPassCutoff = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param); } } void ALmodulator_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -245,12 +245,12 @@ void ALmodulator_setParami(ALeffect *effect, ALCcontext *context, ALenum param, case AL_RING_MODULATOR_WAVEFORM: if(!(val >= AL_RING_MODULATOR_MIN_WAVEFORM && val <= AL_RING_MODULATOR_MAX_WAVEFORM)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Invalid modulator waveform",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid modulator waveform"); props->Modulator.Waveform = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x", param); } } void ALmodulator_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) @@ -272,7 +272,7 @@ void ALmodulator_getParami(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid modulator integer property 0x%04x", param); } } void ALmodulator_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) @@ -290,7 +290,7 @@ void ALmodulator_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid modulator float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid modulator float property 0x%04x", param); } } void ALmodulator_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/Alc/effects/null.c b/Alc/effects/null.c index 2dc43870..f9583011 100644 --- a/Alc/effects/null.c +++ b/Alc/effects/null.c @@ -110,69 +110,69 @@ ALeffectStateFactory *ALnullStateFactory_getFactory(void) } -void ALnull_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint UNUSED(val)) +void ALnull_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x", param); } } -void ALnull_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint* UNUSED(vals)) +void ALnull_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint* UNUSED(vals)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer-vector property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect integer-vector property 0x%04x", param); } } -void ALnull_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat UNUSED(val)) +void ALnull_setParamf(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat UNUSED(val)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect float property 0x%04x", param); } } -void ALnull_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat* UNUSED(vals)) +void ALnull_setParamfv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALfloat* UNUSED(vals)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float-vector property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect float-vector property 0x%04x", param); } } -void ALnull_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint* UNUSED(val)) +void ALnull_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint* UNUSED(val)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect integer property 0x%04x", param); } } -void ALnull_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint* UNUSED(vals)) +void ALnull_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint* UNUSED(vals)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect integer-vector property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect integer-vector property 0x%04x", param); } } -void ALnull_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat* UNUSED(val)) +void ALnull_getParamf(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat* UNUSED(val)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect float property 0x%04x", param); } } -void ALnull_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat* UNUSED(vals)) +void ALnull_getParamfv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat* UNUSED(vals)) { switch(param) { - default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid null effect float-vector property"); + default: + alSetError(context, AL_INVALID_ENUM, "Invalid null effect float-vector property 0x%04x", param); } } diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index 0cebab9b..64aa8916 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -1775,12 +1775,13 @@ void ALeaxreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EAXREVERB_DECAY_HFLIMIT: if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay hflimit out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb decay hflimit out of range"); props->Reverb.DecayHFLimit = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x", + param); } } void ALeaxreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) @@ -1792,126 +1793,127 @@ void ALeaxreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EAXREVERB_DENSITY: if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb density out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb density out of range"); props->Reverb.Density = val; break; case AL_EAXREVERB_DIFFUSION: if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb diffusion out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb diffusion out of range"); props->Reverb.Diffusion = val; break; case AL_EAXREVERB_GAIN: if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb gain out of range"); props->Reverb.Gain = val; break; case AL_EAXREVERB_GAINHF: if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb gainhf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb gainhf out of range"); props->Reverb.GainHF = val; break; case AL_EAXREVERB_GAINLF: if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb gainlf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb gainlf out of range"); props->Reverb.GainLF = val; break; case AL_EAXREVERB_DECAY_TIME: if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay time out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb decay time out of range"); props->Reverb.DecayTime = val; break; case AL_EAXREVERB_DECAY_HFRATIO: if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay hfratio out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb decay hfratio out of range"); props->Reverb.DecayHFRatio = val; break; case AL_EAXREVERB_DECAY_LFRATIO: if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb decay lfratio out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb decay lfratio out of range"); props->Reverb.DecayLFRatio = val; break; case AL_EAXREVERB_REFLECTIONS_GAIN: if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb reflections gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb reflections gain out of range"); props->Reverb.ReflectionsGain = val; break; case AL_EAXREVERB_REFLECTIONS_DELAY: if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb reflections delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb reflections delay out of range"); props->Reverb.ReflectionsDelay = val; break; case AL_EAXREVERB_LATE_REVERB_GAIN: if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb late reverb gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb late reverb gain out of range"); props->Reverb.LateReverbGain = val; break; case AL_EAXREVERB_LATE_REVERB_DELAY: if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb late reverb delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb late reverb delay out of range"); props->Reverb.LateReverbDelay = val; break; case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb air absorption gainhf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb air absorption gainhf out of range"); props->Reverb.AirAbsorptionGainHF = val; break; case AL_EAXREVERB_ECHO_TIME: if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb echo time out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb echo time out of range"); props->Reverb.EchoTime = val; break; case AL_EAXREVERB_ECHO_DEPTH: if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb echo depth out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb echo depth out of range"); props->Reverb.EchoDepth = val; break; case AL_EAXREVERB_MODULATION_TIME: if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb modulation time out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb modulation time out of range"); props->Reverb.ModulationTime = val; break; case AL_EAXREVERB_MODULATION_DEPTH: if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb modulation depth out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb modulation depth out of range"); props->Reverb.ModulationDepth = val; break; case AL_EAXREVERB_HFREFERENCE: if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb hfreference out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb hfreference out of range"); props->Reverb.HFReference = val; break; case AL_EAXREVERB_LFREFERENCE: if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb lfreference out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb lfreference out of range"); props->Reverb.LFReference = val; break; case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb room rolloff factor out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb room rolloff factor out of range"); props->Reverb.RoomRolloffFactor = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", + param); } } void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -1921,14 +1923,14 @@ void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, { case AL_EAXREVERB_REFLECTIONS_PAN: if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb reflections pan out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb reflections pan out of range"); props->Reverb.ReflectionsPan[0] = vals[0]; props->Reverb.ReflectionsPan[1] = vals[1]; props->Reverb.ReflectionsPan[2] = vals[2]; break; case AL_EAXREVERB_LATE_REVERB_PAN: if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "EAX Reverb late reverb pan out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "EAX Reverb late reverb pan out of range"); props->Reverb.LateReverbPan[0] = vals[0]; props->Reverb.LateReverbPan[1] = vals[1]; props->Reverb.LateReverbPan[2] = vals[2]; @@ -1950,7 +1952,8 @@ void ALeaxreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid EAX reverb integer property 0x%04x", + param); } } void ALeaxreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) @@ -2041,7 +2044,8 @@ void ALeaxreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid EAX reverb float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid EAX reverb float property 0x%04x", + param); } } void ALeaxreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) @@ -2075,12 +2079,12 @@ void ALreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALi { case AL_REVERB_DECAY_HFLIMIT: if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb decay hflimit out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb decay hflimit out of range"); props->Reverb.DecayHFLimit = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param); } } void ALreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) @@ -2092,78 +2096,78 @@ void ALreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALf { case AL_REVERB_DENSITY: if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb density out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb density out of range"); props->Reverb.Density = val; break; case AL_REVERB_DIFFUSION: if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb diffusion out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb diffusion out of range"); props->Reverb.Diffusion = val; break; case AL_REVERB_GAIN: if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb gain out of range"); props->Reverb.Gain = val; break; case AL_REVERB_GAINHF: if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb gainhf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb gainhf out of range"); props->Reverb.GainHF = val; break; case AL_REVERB_DECAY_TIME: if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb decay time out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb decay time out of range"); props->Reverb.DecayTime = val; break; case AL_REVERB_DECAY_HFRATIO: if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb decay hfratio out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb decay hfratio out of range"); props->Reverb.DecayHFRatio = val; break; case AL_REVERB_REFLECTIONS_GAIN: if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb reflections gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb reflections gain out of range"); props->Reverb.ReflectionsGain = val; break; case AL_REVERB_REFLECTIONS_DELAY: if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb reflections delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb reflections delay out of range"); props->Reverb.ReflectionsDelay = val; break; case AL_REVERB_LATE_REVERB_GAIN: if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb late reverb gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb late reverb gain out of range"); props->Reverb.LateReverbGain = val; break; case AL_REVERB_LATE_REVERB_DELAY: if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb late reverb delay out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb late reverb delay out of range"); props->Reverb.LateReverbDelay = val; break; case AL_REVERB_AIR_ABSORPTION_GAINHF: if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb air absorption gainhf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb air absorption gainhf out of range"); props->Reverb.AirAbsorptionGainHF = val; break; case AL_REVERB_ROOM_ROLLOFF_FACTOR: if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)) - SETERR_RETURN(context, AL_INVALID_VALUE, effect->id, "Reverb room rolloff factor out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Reverb room rolloff factor out of range"); props->Reverb.RoomRolloffFactor = val; break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param); } } void ALreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -2179,7 +2183,7 @@ void ALreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid reverb integer property 0x%04x", param); } } void ALreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) @@ -2238,7 +2242,7 @@ void ALreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum para break; default: - alSetError(context, AL_INVALID_ENUM, effect->id, "Invalid reverb float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid reverb float property 0x%04x", param); } } void ALreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) diff --git a/OpenAL32/Include/alError.h b/OpenAL32/Include/alError.h index 3dc16103..479697f2 100644 --- a/OpenAL32/Include/alError.h +++ b/OpenAL32/Include/alError.h @@ -9,15 +9,15 @@ extern "C" { extern ALboolean TrapALError; -ALvoid alSetError(ALCcontext *context, ALenum errorCode, ALuint objid, const char *msg); +void alSetError(ALCcontext *context, ALenum errorCode, const char *msg, ...); -#define SETERR_GOTO(ctx, err, objid, msg, lbl) do { \ - alSetError((ctx), (err), (objid), (msg)); \ +#define SETERR_GOTO(ctx, err, lbl, ...) do { \ + alSetError((ctx), (err), __VA_ARGS__); \ goto lbl; \ } while(0) -#define SETERR_RETURN(ctx, err, objid, msg, retval) do { \ - alSetError((ctx), (err), (objid), (msg)); \ +#define SETERR_RETURN(ctx, err, retval, ...) do { \ + alSetError((ctx), (err), __VA_ARGS__); \ return retval; \ } while(0) diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index a8186f07..d2039097 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -73,7 +73,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(!context) return; if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative effect slots", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effect slots", n); tmpslots = al_malloc(DEF_ALIGN, sizeof(ALeffectslot*)*n); LockEffectSlotsWrite(context); @@ -87,7 +87,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo UnlockEffectSlotsWrite(context); alDeleteAuxiliaryEffectSlots(cur, effectslots); - SETERR_GOTO(context, err, 0, "Effect slot object allocation failed", done); + SETERR_GOTO(context, err, done, "Effect slot object allocation failed"); } err = NewThunkEntry(&slot->id); @@ -103,7 +103,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo UnlockEffectSlotsWrite(context); alDeleteAuxiliaryEffectSlots(cur, effectslots); - SETERR_GOTO(context, err, 0, "Failed to set effect slot ID", done); + SETERR_GOTO(context, err, done, "Failed to set effect slot ID"); } aluInitEffectPanning(slot); @@ -149,15 +149,15 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * LockEffectSlotsWrite(context); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative effect slots", - done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effect slots", n); for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslots[i], "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", + effectslots[i]); if(ReadRef(&slot->ref) != 0) - SETERR_GOTO(context, AL_INVALID_OPERATION, effectslots[i], - "Deleting in-use effect slot", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Deleting in-use effect slot %u", + effectslots[i]); } // All effectslots are valid @@ -240,7 +240,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param WriteLock(&context->PropLock); LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { case AL_EFFECTSLOT_EFFECT: @@ -251,25 +251,25 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!(value == 0 || effect != NULL)) { UnlockEffectsRead(device); - SETERR_GOTO(context, AL_INVALID_VALUE, effectslot, "Invalid effect ID", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid effect ID %u", value); } err = InitializeEffect(context, slot, effect); UnlockEffectsRead(device); if(err != AL_NO_ERROR) - SETERR_GOTO(context, err, effectslot, "Effect initialization failed", done); + SETERR_GOTO(context, err, done, "Effect initialization failed"); break; case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: if(!(value == AL_TRUE || value == AL_FALSE)) - SETERR_GOTO(context, AL_INVALID_VALUE, effectslot, - "Effect slot auxiliary send auto out of range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, + "Effect slot auxiliary send auto out of range"); slot->AuxSendAuto = value; break; default: - SETERR_GOTO(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot integer property", - done); + SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid effect slot integer property 0x%04x", + param); } DO_UPDATEPROPS(); @@ -296,12 +296,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, effectslot, - "Invalid effect slot integer-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid effect slot integer-vector property 0x%04x", + param); } done: @@ -320,19 +320,18 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param WriteLock(&context->PropLock); LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { case AL_EFFECTSLOT_GAIN: if(!(value >= 0.0f && value <= 1.0f)) - SETERR_GOTO(context, AL_INVALID_VALUE, effectslot, "Effect slot gain out of range", - done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Effect slot gain out of range"); slot->Gain = value; break; default: - SETERR_GOTO(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot float property", - done); + SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid effect slot float property 0x%04x", + param); } DO_UPDATEPROPS(); @@ -358,12 +357,12 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum para LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, effectslot, - "Invalid effect slot float-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid effect slot float-vector property 0x%04x", + param); } done: @@ -381,7 +380,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: @@ -389,7 +388,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa break; default: - alSetError(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid effect slot integer property 0x%04x", param); } done: @@ -414,12 +413,12 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, effectslot, - "Invalid effect slot integer-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid effect slot integer-vector property 0x%04x", + param); } done: @@ -437,7 +436,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa LockEffectSlotsRead(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { case AL_EFFECTSLOT_GAIN: @@ -445,7 +444,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa break; default: - alSetError(context, AL_INVALID_ENUM, effectslot, "Invalid effect slot float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid effect slot float property 0x%04x", param); } done: @@ -469,12 +468,12 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p LockEffectSlotsRead(context); if(LookupEffectSlot(context, effectslot) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effectslot, "Invalid effect slot ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, effectslot, - "Invalid effect slot float-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid effect slot float-vector property 0x%04x", + param); } done: diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 922c379c..0ef4bf69 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -66,7 +66,7 @@ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers) if(!context) return; if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative buffers", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d buffers", n); for(cur = 0;cur < n;cur++) { @@ -98,7 +98,7 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) LockBuffersWrite(device); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative buffers", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d buffers", n); for(i = 0;i < n;i++) { @@ -107,9 +107,10 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) /* Check for valid Buffer ID */ if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffers[i], "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffers[i]); if(ReadRef(&ALBuf->ref) != 0) - SETERR_GOTO(context, AL_INVALID_OPERATION, buffers[i], "Deleting in-use buffer", done); + SETERR_GOTO(context, AL_INVALID_OPERATION, done, "Deleting in-use buffer %u", + buffers[i]); } for(i = 0;i < n;i++) @@ -161,19 +162,20 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); - if(!(size >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Negative storage size", done); - if(!(freq > 0)) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid sample rate", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); + if(!(size >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Negative storage size %d", size); + if(!(freq > 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid sample rate %d", freq); if((flags&INVALID_STORAGE_MASK) != 0) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid storage flags", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid storage flags 0x%x", + flags&INVALID_STORAGE_MASK); if((flags&AL_MAP_PERSISTENT_BIT_SOFT) && !(flags&MAP_READ_WRITE_FLAGS)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, - "Declaring persistently mapped storage without read or write access", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, + "Declaring persistently mapped storage without read or write access"); if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) - SETERR_GOTO(context, AL_INVALID_ENUM, buffer, "Invalid format", done); + SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid format 0x%04x", format); align = SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign)); - if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid unpack alignment", done); + if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid unpack alignment"); switch(srctype) { @@ -195,7 +197,8 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const break; } if((size%framesize) != 0) - alSetError(context, AL_INVALID_VALUE, buffer, "Data size is not a frame multiple"); + alSetError(context, AL_INVALID_VALUE, "Data size %d is not a multiple of frame size %d", + size, framesize); else LoadData(context, albuf, freq, size/framesize*align, srcchannels, srctype, data, align, flags); @@ -218,32 +221,33 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); if((access&~MAP_ACCESS_FLAGS) != 0) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid map flags", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid map flags 0x%x", + access&~MAP_ACCESS_FLAGS); if(!(access&MAP_READ_WRITE_FLAGS)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, - "Mapping buffer without read or write access", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, + "Mapping buffer without read or write access"); WriteLock(&albuf->lock); if(ReadRef(&albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT)) - SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, - "Mapping in-use buffer without persistent mapping", unlock_done); + SETERR_GOTO(context, AL_INVALID_OPERATION, unlock_done, + "Mapping in-use buffer without persistent mapping"); if(albuf->MappedAccess != 0) - SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, "Mapping already-mapped buffer", - unlock_done); + SETERR_GOTO(context, AL_INVALID_OPERATION, unlock_done, "Mapping already-mapped buffer"); if((access&AL_MAP_READ_BIT_SOFT) && !(albuf->Access&AL_MAP_READ_BIT_SOFT)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, - "Mapping buffer for reading without read access", unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, + "Mapping buffer for reading without read access"); if((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, - "Mapping buffer for writing without write access", unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, + "Mapping buffer for writing without write access"); if((access&AL_MAP_PERSISTENT_BIT_SOFT) && !(albuf->Access&AL_MAP_PERSISTENT_BIT_SOFT)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, - "Mapping buffer persistently without persistent access", unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, + "Mapping buffer persistently without persistent access"); if(offset < 0 || offset >= albuf->OriginalSize || length <= 0 || length > albuf->OriginalSize - offset) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Mapping out of range", unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Mapping invalid range %d+%d", + offset, length); retval = (ALbyte*)albuf->data + offset; albuf->MappedAccess = access; @@ -272,11 +276,11 @@ AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer) device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); WriteLock(&albuf->lock); if(albuf->MappedAccess == 0) - alSetError(context, AL_INVALID_OPERATION, albuf->id, "Unmapping an unmapped buffer"); + alSetError(context, AL_INVALID_OPERATION, "Unmapping an unmapped buffer %u", buffer); else { albuf->MappedAccess = 0; @@ -302,15 +306,15 @@ AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, A device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); WriteLock(&albuf->lock); if(albuf->MappedAccess == 0 || !(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT)) - alSetError(context, AL_INVALID_OPERATION, albuf->id, - "Flushing a buffer not mapped for writing"); + alSetError(context, AL_INVALID_OPERATION, "Flushing buffer %u not mapped for writing", + buffer); else if(offset < albuf->MappedOffset || offset >= albuf->MappedOffset+albuf->MappedSize || length <= 0 || length > albuf->MappedOffset+albuf->MappedSize-offset) - alSetError(context, AL_INVALID_VALUE, albuf->id, "Flushing an invalid range"); + alSetError(context, AL_INVALID_VALUE, "Flushing an invalid range %d+%d", offset, length); else { /* FIXME: Need to use some method of double-buffering for the mixer and @@ -346,22 +350,22 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) - SETERR_GOTO(context, AL_INVALID_ENUM, buffer, "Invalid format", done); + SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid format 0x%04x", format); WriteLock(&albuf->lock); align = SanitizeAlignment(srctype, ATOMIC_LOAD_SEQ(&albuf->UnpackAlign)); - if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid unpack alignment", done); + if(align < 1) SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Invalid unpack alignment"); if((long)srcchannels != (long)albuf->FmtChannels || srctype != albuf->OriginalType) - SETERR_GOTO(context, AL_INVALID_ENUM, buffer, "Unpacking data with mismatched format", - unlock_done); + SETERR_GOTO(context, AL_INVALID_ENUM, unlock_done, + "Unpacking data with mismatched format"); if(align != albuf->OriginalAlign) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Unpacking data with mismatched alignment", - unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, + "Unpacking data with mismatched alignment"); if(albuf->MappedAccess != 0) - SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, "Unpacking data into mapped buffer", - unlock_done); + SETERR_GOTO(context, AL_INVALID_OPERATION, unlock_done, + "Unpacking data into mapped buffer"); num_chans = ChannelsFromFmt(albuf->FmtChannels); frame_size = num_chans * BytesFromFmt(albuf->FmtType); @@ -374,9 +378,10 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons if(offset < 0 || length < 0 || offset > albuf->OriginalSize || length > albuf->OriginalSize-offset) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Data sub-range out of range", unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Invalid data sub-range %d+%d", + offset, length); if((offset%byte_align) != 0 || (length%byte_align) != 0) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid sub-range alignment", unlock_done); + SETERR_GOTO(context, AL_INVALID_VALUE, unlock_done, "Invalid sub-range alignment"); /* offset -> byte offset, length -> sample count */ offset = offset/byte_align * frame_size; @@ -411,7 +416,7 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint UNUSED(buffer), context = GetContextRef(); if(!context) return; - alSetError(context, AL_INVALID_OPERATION, 0, "alBufferSamplesSOFT not supported"); + alSetError(context, AL_INVALID_OPERATION, "alBufferSamplesSOFT not supported"); ALCcontext_DecRef(context); } @@ -425,7 +430,7 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint UNUSED(buffer), context = GetContextRef(); if(!context) return; - alSetError(context, AL_INVALID_OPERATION, 0, "alBufferSubSamplesSOFT not supported"); + alSetError(context, AL_INVALID_OPERATION, "alBufferSubSamplesSOFT not supported"); ALCcontext_DecRef(context); } @@ -439,7 +444,7 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint UNUSED(buffer), context = GetContextRef(); if(!context) return; - alSetError(context, AL_INVALID_OPERATION, 0, "alGetBufferSamplesSOFT not supported"); + alSetError(context, AL_INVALID_OPERATION, "alGetBufferSamplesSOFT not supported"); ALCcontext_DecRef(context); } @@ -451,7 +456,7 @@ AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum UNUSED(format) context = GetContextRef(); if(!context) return AL_FALSE; - alSetError(context, AL_INVALID_OPERATION, 0, "alIsBufferFormatSupportedSOFT not supported"); + alSetError(context, AL_INVALID_OPERATION, "alIsBufferFormatSupportedSOFT not supported"); ALCcontext_DecRef(context); return AL_FALSE; @@ -469,12 +474,12 @@ AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(va device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer float property 0x%04x", param); } done: @@ -494,12 +499,12 @@ AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(v device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-float property 0x%04x", param); } done: @@ -519,13 +524,13 @@ AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *v device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); - if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer float-vector property 0x%04x", param); } done: @@ -546,26 +551,26 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); switch(param) { case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, - "Negative buffer unpack block alignment", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, + "Buffer unpack block alignment %d is invalid", value); ATOMIC_STORE_SEQ(&albuf->UnpackAlign, value); break; case AL_PACK_BLOCK_ALIGNMENT_SOFT: if(!(value >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Negative buffer pack block alignment", - done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, + "Buffer pack block alignment %d is invalid", value); ATOMIC_STORE_SEQ(&albuf->PackAlign, value); break; default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer property 0x%04x", param); } done: @@ -584,12 +589,12 @@ AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(val device = context->Device; if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-integer property 0x%04x", param); } done: @@ -620,9 +625,9 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); - if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { case AL_LOOP_POINTS_SOFT: @@ -630,14 +635,15 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val if(ReadRef(&albuf->ref) != 0) { WriteUnlock(&albuf->lock); - SETERR_GOTO(context, AL_INVALID_OPERATION, buffer, - "Modifying in-use buffer loop points", done); + SETERR_GOTO(context, AL_INVALID_OPERATION, done, + "Modifying in-use buffer loop points"); } if(values[0] >= values[1] || values[0] < 0 || values[1] > albuf->SampleLen) { WriteUnlock(&albuf->lock); - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "Invalid loop point range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid loop point range %d -> %d", + values[0], values[1]); } albuf->LoopStart = values[0]; @@ -646,7 +652,8 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val break; default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer-vector property 0x%04x", + param); } done: @@ -667,13 +674,13 @@ AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *val device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); - if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer float property 0x%04x", param); } done: @@ -693,14 +700,14 @@ AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *valu device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); if(!value1 || !value2 || !value3) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-float property 0x%04x", param); } done: @@ -727,13 +734,13 @@ AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *valu device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); - if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer float-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer float-vector property 0x%04x", param); } done: @@ -754,9 +761,9 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); - if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + if(!value) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { case AL_FREQUENCY: @@ -787,7 +794,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value break; default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer property 0x%04x", param); } done: @@ -807,14 +814,14 @@ AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1 device = context->Device; LockBuffersRead(device); if(LookupBuffer(device, buffer) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); if(!value1 || !value2 || !value3) - SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer 3-integer property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer 3-integer property 0x%04x", param); } done: @@ -850,9 +857,9 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values device = context->Device; LockBuffersRead(device); if((albuf=LookupBuffer(device, buffer)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, buffer, "Invalid buffer ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid buffer ID %u", buffer); - if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, buffer, "NULL pointer", done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { case AL_LOOP_POINTS_SOFT: @@ -863,7 +870,8 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values break; default: - alSetError(context, AL_INVALID_ENUM, buffer, "Invalid buffer integer-vector property"); + alSetError(context, AL_INVALID_ENUM, "Invalid buffer integer-vector property 0x%04x", + param); } done: @@ -898,7 +906,7 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei case UserFmtBFormat3D: DstChannels = FmtBFormat3D; break; } if(UNLIKELY((long)SrcChannels != (long)DstChannels)) - SETERR_RETURN(context, AL_INVALID_ENUM, ALBuf->id, "Invalid format",); + SETERR_RETURN(context, AL_INVALID_ENUM,, "Invalid format"); /* IMA4 and MSADPCM convert to 16-bit short. */ switch(SrcType) @@ -916,23 +924,22 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei if(access != 0) { if(UNLIKELY((long)SrcType != (long)DstType)) - SETERR_RETURN(context, AL_INVALID_VALUE, ALBuf->id, - "Format cannot be mapped or preserved",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Format cannot be mapped or preserved"); } NumChannels = ChannelsFromFmt(DstChannels); FrameSize = NumChannels * BytesFromFmt(DstType); if(UNLIKELY(frames > INT_MAX/FrameSize)) - SETERR_RETURN(context, AL_OUT_OF_MEMORY, ALBuf->id, "Buffer size too large",); + SETERR_RETURN(context, AL_OUT_OF_MEMORY,, + "Buffer size overflow, %d frames x %d bytes per frame", frames, FrameSize); newsize = frames*FrameSize; WriteLock(&ALBuf->lock); if(UNLIKELY(ReadRef(&ALBuf->ref) != 0 || ALBuf->MappedAccess != 0)) { WriteUnlock(&ALBuf->lock); - SETERR_RETURN(context, AL_INVALID_OPERATION, ALBuf->id, - "Modifying storage for in-use buffer",); + SETERR_RETURN(context, AL_INVALID_OPERATION,, "Modifying storage for in-use buffer"); } if((access&AL_PRESERVE_DATA_BIT_SOFT)) @@ -941,14 +948,12 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei if(UNLIKELY(ALBuf->FmtChannels != DstChannels || ALBuf->OriginalType != SrcType)) { WriteUnlock(&ALBuf->lock); - SETERR_RETURN(context, AL_INVALID_VALUE, ALBuf->id, - "Preserving data of mismatched format",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched format"); } if(UNLIKELY(ALBuf->OriginalAlign != align)) { WriteUnlock(&ALBuf->lock); - SETERR_RETURN(context, AL_INVALID_VALUE, ALBuf->id, - "Preserving data of mismatched alignment",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched alignment"); } } @@ -966,7 +971,8 @@ static void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei if(UNLIKELY(!temp && newsize)) { WriteUnlock(&ALBuf->lock); - SETERR_RETURN(context, AL_OUT_OF_MEMORY, ALBuf->id, "Failed to allocate storage",); + SETERR_RETURN(context, AL_OUT_OF_MEMORY,, "Failed to allocate %d bytes of storage", + newsize); } if((access&AL_PRESERVE_DATA_BIT_SOFT)) { @@ -1204,7 +1210,7 @@ ALbuffer *NewBuffer(ALCcontext *context) buffer = al_calloc(16, sizeof(ALbuffer)); if(!buffer) - SETERR_RETURN(context, AL_OUT_OF_MEMORY, 0, "Failed to allocate buffer object", NULL); + SETERR_RETURN(context, AL_OUT_OF_MEMORY, NULL, "Failed to allocate buffer object"); RWLockInit(&buffer->lock); buffer->Access = 0; buffer->MappedAccess = 0; @@ -1218,7 +1224,7 @@ ALbuffer *NewBuffer(ALCcontext *context) memset(buffer, 0, sizeof(ALbuffer)); al_free(buffer); - SETERR_RETURN(context, err, 0, "Failed to set buffer ID", NULL); + SETERR_RETURN(context, err, NULL, "Failed to set buffer ID"); } return buffer; diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 5f6e661a..ab42112c 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -69,7 +69,7 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) if(!context) return; if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative effects", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effects", n); device = context->Device; for(cur = 0;cur < n;cur++) @@ -80,7 +80,7 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) { al_free(effect); alDeleteEffects(cur, effects); - SETERR_GOTO(context, err, 0, "Failed to allocate effect object", done); + SETERR_GOTO(context, err, done, "Failed to allocate effect object"); } err = NewThunkEntry(&effect->id); @@ -93,7 +93,7 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) al_free(effect); alDeleteEffects(cur, effects); - SETERR_GOTO(context, err, 0, "Failed to set effect ID", done); + SETERR_GOTO(context, err, done, "Failed to set effect ID"); } effects[cur] = effect->id; @@ -116,11 +116,11 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) device = context->Device; LockEffectsWrite(device); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative effects", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effects", n); for(i = 0;i < n;i++) { if(effects[i] && LookupEffect(device, effects[i]) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, effects[i], "Invalid effect ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect ID %u", effects[i]); } for(i = 0;i < n;i++) { @@ -167,7 +167,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) Device = Context->Device; LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { if(param == AL_EFFECT_TYPE) @@ -184,7 +184,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) if(isOk) InitEffectParams(ALEffect, value); else - alSetError(Context, AL_INVALID_VALUE, effect, "Effect type not supported"); + alSetError(Context, AL_INVALID_VALUE, "Effect type 0x%04x not supported", value); } else { @@ -216,7 +216,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v Device = Context->Device; LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { /* Call the appropriate handler */ @@ -239,7 +239,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) Device = Context->Device; LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { /* Call the appropriate handler */ @@ -262,7 +262,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat Device = Context->Device; LockEffectsWrite(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { /* Call the appropriate handler */ @@ -285,7 +285,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value Device = Context->Device; LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { if(param == AL_EFFECT_TYPE) @@ -320,7 +320,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu Device = Context->Device; LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { /* Call the appropriate handler */ @@ -343,7 +343,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val Device = Context->Device; LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { /* Call the appropriate handler */ @@ -366,7 +366,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va Device = Context->Device; LockEffectsRead(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) - alSetError(Context, AL_INVALID_NAME, effect, "Invalid effect ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else { /* Call the appropriate handler */ diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c index 8d138aa2..fe0e02be 100644 --- a/OpenAL32/alError.c +++ b/OpenAL32/alError.c @@ -21,6 +21,7 @@ #include "config.h" #include +#include #ifdef HAVE_WINDOWS_H #define WIN32_LEAN_AND_MEAN @@ -33,12 +34,32 @@ ALboolean TrapALError = AL_FALSE; -ALvoid alSetError(ALCcontext *context, ALenum errorCode, ALuint objid, const char *msg) +void alSetError(ALCcontext *context, ALenum errorCode, const char *msg, ...) { ALenum curerr = AL_NO_ERROR; + char message[1024] = { 0 }; + va_list args; + int msglen; - WARN("Error generated on context %p, code 0x%04x, object %u, \"%s\"\n", - context, errorCode, objid, msg); + va_start(args, msg); + msglen = vsnprintf(message, sizeof(message), msg, args); + va_end(args); + + if(msglen < 0 || (size_t)msglen >= sizeof(message)) + { + message[sizeof(message)-1] = 0; + msglen = strlen(message); + } + if(msglen > 0) + msg = message; + else + { + msg = ""; + msglen = strlen(msg); + } + + WARN("Error generated on context %p, code 0x%04x, \"%s\"\n", + context, errorCode, message); if(TrapALError) { #ifdef _WIN32 @@ -55,7 +76,7 @@ ALvoid alSetError(ALCcontext *context, ALenum errorCode, ALuint objid, const cha { almtx_lock(&context->EventLock); if((context->EnabledEvts&EventType_Error) && context->EventCb) - (*context->EventCb)(AL_EVENT_TYPE_ERROR_SOFT, objid, errorCode, strlen(msg), msg, + (*context->EventCb)(AL_EVENT_TYPE_ERROR_SOFT, 0, errorCode, msglen, msg, context->EventParam); almtx_unlock(&context->EventLock); } @@ -86,6 +107,5 @@ AL_API ALenum AL_APIENTRY alGetError(void) errorCode = ATOMIC_EXCHANGE_SEQ(&context->LastError, AL_NO_ERROR); ALCcontext_DecRef(context); - return errorCode; } diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c index 9b6e5a97..f6378c70 100644 --- a/OpenAL32/alExtension.c +++ b/OpenAL32/alExtension.c @@ -46,7 +46,7 @@ AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName) if(!context) return AL_FALSE; if(!extName) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "NULL pointer", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); len = strlen(extName); ptr = context->ExtensionList; diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 24b0e607..34f2f271 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -55,7 +55,7 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) if(!context) return; if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative filters", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d filters", n); device = context->Device; for(cur = 0;cur < n;cur++) @@ -64,7 +64,7 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) if(!filter) { alDeleteFilters(cur, filters); - SETERR_GOTO(context, AL_OUT_OF_MEMORY, 0, "Failed to allocate filter object", done); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, "Failed to allocate filter object"); } InitFilterParams(filter, AL_FILTER_NULL); @@ -78,7 +78,7 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) al_free(filter); alDeleteFilters(cur, filters); - SETERR_GOTO(context, err, 0, "Failed ot set filter ID", done); + SETERR_GOTO(context, err, done, "Failed ot set filter ID"); } filters[cur] = filter->id; @@ -101,11 +101,11 @@ AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) device = context->Device; LockFiltersWrite(device); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative filters", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d filters", n); for(i = 0;i < n;i++) { if(filters[i] && LookupFilter(device, filters[i]) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, filters[i], "Invalid filter ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid filter ID %u", filters[i]); } for(i = 0;i < n;i++) { @@ -152,7 +152,7 @@ AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value) Device = Context->Device; LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { if(param == AL_FILTER_TYPE) @@ -161,7 +161,7 @@ AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value) value == AL_FILTER_HIGHPASS || value == AL_FILTER_BANDPASS) InitFilterParams(ALFilter, value); else - alSetError(Context, AL_INVALID_VALUE, filter, "Filter type not supported"); + alSetError(Context, AL_INVALID_VALUE, "Invalid filter type 0x%04x", value); } else { @@ -193,7 +193,7 @@ AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *v Device = Context->Device; LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { /* Call the appropriate handler */ @@ -216,7 +216,7 @@ AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value) Device = Context->Device; LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { /* Call the appropriate handler */ @@ -239,7 +239,7 @@ AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat Device = Context->Device; LockFiltersWrite(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { /* Call the appropriate handler */ @@ -262,7 +262,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value Device = Context->Device; LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { if(param == AL_FILTER_TYPE) @@ -297,7 +297,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *valu Device = Context->Device; LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { /* Call the appropriate handler */ @@ -320,7 +320,7 @@ AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *val Device = Context->Device; LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { /* Call the appropriate handler */ @@ -343,7 +343,7 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *va Device = Context->Device; LockFiltersRead(Device); if((ALFilter=LookupFilter(Device, filter)) == NULL) - alSetError(Context, AL_INVALID_NAME, filter, "Invalid filter ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter); else { /* Call the appropriate handler */ @@ -435,37 +435,37 @@ void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat g } -static void ALlowpass_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer property"); } -static void ALlowpass_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer-vector property"); } +static void ALlowpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param); } +static void ALlowpass_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid low-pass integer-vector property 0x%04x", param); } static void ALlowpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_LOWPASS_GAIN: if(!(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Low-pass gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Low-pass gain %f out of range", val); filter->Gain = val; break; case AL_LOWPASS_GAINHF: if(!(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Low-pass gainhf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Low-pass gainhf %f out of range", val); filter->GainHF = val; break; default: - alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param); } } static void ALlowpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) { ALlowpass_setParamf(filter, context, param, vals[0]); } -static void ALlowpass_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer property"); } -static void ALlowpass_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass integer-vector property"); } +static void ALlowpass_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param); } +static void ALlowpass_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid low-pass integer-vector property 0x%04x", param); } static void ALlowpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -479,7 +479,7 @@ static void ALlowpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum pa break; default: - alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid low-pass float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param); } } static void ALlowpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -488,37 +488,37 @@ static void ALlowpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum p DEFINE_ALFILTER_VTABLE(ALlowpass); -static void ALhighpass_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer property"); } -static void ALhighpass_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer-vector property"); } +static void ALhighpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param); } +static void ALhighpass_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid high-pass integer-vector property 0x%04x", param); } static void ALhighpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_HIGHPASS_GAIN: if(!(val >= AL_HIGHPASS_MIN_GAIN && val <= AL_HIGHPASS_MAX_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "High-pass gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "High-pass gain out of range"); filter->Gain = val; break; case AL_HIGHPASS_GAINLF: if(!(val >= AL_HIGHPASS_MIN_GAINLF && val <= AL_HIGHPASS_MAX_GAINLF)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "High-pass gainlf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "High-pass gainlf out of range"); filter->GainLF = val; break; default: - alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param); } } static void ALhighpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) { ALhighpass_setParamf(filter, context, param, vals[0]); } -static void ALhighpass_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer property"); } -static void ALhighpass_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass integer-vector property"); } +static void ALhighpass_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param); } +static void ALhighpass_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid high-pass integer-vector property 0x%04x", param); } static void ALhighpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -532,7 +532,7 @@ static void ALhighpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid high-pass float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param); } } static void ALhighpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -541,43 +541,43 @@ static void ALhighpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum DEFINE_ALFILTER_VTABLE(ALhighpass); -static void ALbandpass_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer property"); } -static void ALbandpass_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer-vector property"); } +static void ALbandpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param); } +static void ALbandpass_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid band-pass integer-vector property 0x%04x", param); } static void ALbandpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_BANDPASS_GAIN: if(!(val >= AL_BANDPASS_MIN_GAIN && val <= AL_BANDPASS_MAX_GAIN)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Band-pass gain out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Band-pass gain out of range"); filter->Gain = val; break; case AL_BANDPASS_GAINHF: if(!(val >= AL_BANDPASS_MIN_GAINHF && val <= AL_BANDPASS_MAX_GAINHF)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Band-pass gainhf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Band-pass gainhf out of range"); filter->GainHF = val; break; case AL_BANDPASS_GAINLF: if(!(val >= AL_BANDPASS_MIN_GAINLF && val <= AL_BANDPASS_MAX_GAINLF)) - SETERR_RETURN(context, AL_INVALID_VALUE, filter->id, "Band-pass gainlf out of range",); + SETERR_RETURN(context, AL_INVALID_VALUE,, "Band-pass gainlf out of range"); filter->GainLF = val; break; default: - alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param); } } static void ALbandpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) { ALbandpass_setParamf(filter, context, param, vals[0]); } -static void ALbandpass_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer property"); } -static void ALbandpass_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass integer-vector property"); } +static void ALbandpass_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param); } +static void ALbandpass_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid band-pass integer-vector property 0x%04x", param); } static void ALbandpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -595,7 +595,7 @@ static void ALbandpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum p break; default: - alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid band-pass float property"); + alSetError(context, AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param); } } static void ALbandpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -604,23 +604,23 @@ static void ALbandpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum DEFINE_ALFILTER_VTABLE(ALbandpass); -static void ALnullfilter_setParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } -static void ALnullfilter_setParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } -static void ALnullfilter_setParamf(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } -static void ALnullfilter_setParamfv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } - -static void ALnullfilter_getParami(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } -static void ALnullfilter_getParamiv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } -static void ALnullfilter_getParamf(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } -static void ALnullfilter_getParamfv(ALfilter *filter, ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) -{ alSetError(context, AL_INVALID_ENUM, filter->id, "Invalid null filter property"); } +static void ALnullfilter_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } +static void ALnullfilter_setParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } +static void ALnullfilter_setParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALfloat UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } +static void ALnullfilter_setParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, const ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } + +static void ALnullfilter_getParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } +static void ALnullfilter_getParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } +static void ALnullfilter_getParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALfloat *UNUSED(val)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } +static void ALnullfilter_getParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALfloat *UNUSED(vals)) +{ alSetError(context, AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); } DEFINE_ALFILTER_VTABLE(ALnullfilter); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 51ab6fc9..6d1db2fb 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -48,15 +48,14 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) { case AL_GAIN: if(!(value >= 0.0f && isfinite(value))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener gain out of range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Listener gain out of range"); listener->Gain = value; DO_UPDATEPROPS(); break; case AL_METERS_PER_UNIT: if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener meters per unit out of range", - done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Listener meters per unit out of range"); context->MetersPerUnit = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) UpdateContextProps(context); @@ -88,7 +87,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val { case AL_POSITION: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener position out of range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Listener position out of range"); listener->Position[0] = value1; listener->Position[1] = value2; listener->Position[2] = value3; @@ -97,7 +96,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val case AL_VELOCITY: if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener velocity out of range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Listener velocity out of range"); listener->Velocity[0] = value1; listener->Velocity[1] = value2; listener->Velocity[2] = value3; @@ -140,13 +139,13 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) listener = context->Listener; WriteLock(&context->PropLock); - if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, 0, "NULL pointer", done); + if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { case AL_ORIENTATION: if(!(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Listener orientation out of range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Listener orientation out of range"); /* AT then UP */ listener->Forward[0] = values[0]; listener->Forward[1] = values[1]; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index c60b6a01..898e54d6 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -453,8 +453,7 @@ static ALint Int64ValsByProp(ALenum prop) #define CHECKVAL(x) do { \ if(!(x)) \ { \ - alSetError(Context, AL_INVALID_VALUE, Source->id, \ - "Value out of range"); \ + alSetError(Context, AL_INVALID_VALUE, "Value out of range"); \ return AL_FALSE; \ } \ } while(0) @@ -481,8 +480,8 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_OFFSET_LATENCY_SOFT: case AL_SEC_OFFSET_CLOCK_SOFT: /* Query only */ - SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, - "Setting read-only source property", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, + "Setting read-only source property 0x%04x", prop); case AL_PITCH: CHECKVAL(*values >= 0.0f); @@ -606,8 +605,7 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); - SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid offset", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid offset"); } WriteUnlock(&Source->queue_lock); } @@ -700,7 +698,7 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source float property", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, AL_FALSE, "Invalid source float property 0x%04x", prop); } static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALint *values) @@ -722,8 +720,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SAMPLE_LENGTH_SOFT: case AL_SEC_LENGTH_SOFT: /* Query only */ - SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, - "Setting read-only source property", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, + "Setting read-only source property 0x%04x", prop); case AL_SOURCE_RELATIVE: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); @@ -763,8 +761,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if(!(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL)) { UnlockBuffersRead(device); - SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid buffer ID", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid buffer ID %u", + *values); } WriteLock(&Source->queue_lock); @@ -773,8 +771,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); - SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, - "Setting non-persistently mapped buffer", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, + "Setting non-persistently mapped buffer %u", buffer->id); } else { @@ -783,8 +781,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); - SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, - "Setting buffer on playing or paused source", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, + "Setting buffer on playing or paused source %u", Source->id); } } @@ -849,8 +847,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); - SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, - "Invalid source offset", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, + "Invalid source offset"); } WriteUnlock(&Source->queue_lock); } @@ -863,8 +861,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if(!(*values == 0 || (filter=LookupFilter(device, *values)) != NULL)) { UnlockFiltersRead(device); - SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid filter ID", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid filter ID %u", + *values); } if(!filter) @@ -946,16 +944,24 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_AUXILIARY_SEND_FILTER: LockEffectSlotsRead(Context); + if(!(values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL)) + { + UnlockEffectSlotsRead(Context); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid effect ID %u", + values[0]); + } + if(!((ALuint)values[1] < (ALuint)device->NumAuxSends)) + { + UnlockEffectSlotsRead(Context); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid send %u", values[1]); + } LockFiltersRead(device); - if(!((ALuint)values[1] < (ALuint)device->NumAuxSends && - (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && - (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) + if(!(values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL)) { UnlockFiltersRead(device); UnlockEffectSlotsRead(Context); - /* TODO: Fix message */ - SETERR_RETURN(Context, AL_INVALID_VALUE, Source->id, "Invalid send parameter", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid filter ID %u", + values[2]); } if(!filter) @@ -1054,8 +1060,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer property", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, AL_FALSE, "Invalid source integer property 0x%04x", + prop); } static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALint64SOFT *values) @@ -1075,8 +1081,8 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp case AL_SAMPLE_LENGTH_SOFT: case AL_SEC_LENGTH_SOFT: /* Query only */ - SETERR_RETURN(Context, AL_INVALID_OPERATION, Source->id, - "Setting read-only source property", AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, + "Setting read-only source property 0x%04x", prop); /* 1x int */ case AL_SOURCE_RELATIVE: @@ -1160,8 +1166,8 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp } ERR("Unexpected property: 0x%04x\n", prop); - SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer64 property", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, AL_FALSE, "Invalid source integer64 property 0x%04x", + prop); } #undef CHECKVAL @@ -1358,8 +1364,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source double property", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, AL_FALSE, "Invalid source double property 0x%04x", + prop); } static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values) @@ -1603,8 +1609,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } ERR("Unexpected property: 0x%04x\n", prop); - SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer property", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, AL_FALSE, "Invalid source integer property 0x%04x", + prop); } static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values) @@ -1736,8 +1742,8 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp } ERR("Unexpected property: 0x%04x\n", prop); - SETERR_RETURN(Context, AL_INVALID_ENUM, Source->id, "Invalid source integer64 property", - AL_FALSE); + SETERR_RETURN(Context, AL_INVALID_ENUM, AL_FALSE, "Invalid source integer64 property 0x%04x", + prop); } @@ -1752,7 +1758,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) if(!context) return; if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Generating negative sources", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d sources", n); device = context->Device; for(cur = 0;cur < n;cur++) { @@ -1760,7 +1766,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) if(!source) { alDeleteSources(cur, sources); - SETERR_GOTO(context, AL_OUT_OF_MEMORY,0, "Failed to allocate source object", done); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, "Failed to allocate source object"); } InitSourceParams(source, device->NumAuxSends); @@ -1774,7 +1780,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) al_free(source); alDeleteSources(cur, sources); - SETERR_GOTO(context, err, 0, "Failed to set source ID", done); + SETERR_GOTO(context, err, done, "Failed to set source ID"); } sources[cur] = source->id; @@ -1797,13 +1803,13 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) LockSourcesWrite(context); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Deleting negative sources", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d sources", n); /* Check that all Sources are valid */ for(i = 0;i < n;i++) { if(LookupSource(context, sources[i]) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", sources[i]); } device = context->Device; for(i = 0;i < n;i++) @@ -1863,9 +1869,9 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(FloatValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid float property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid float property 0x%04x", param); else SetSourcefv(Source, Context, param, &value); UnlockSourcesRead(Context); @@ -1885,9 +1891,9 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(FloatValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-float property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-float property 0x%04x", param); else { ALfloat fvals[3] = { value1, value2, value3 }; @@ -1910,11 +1916,11 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(FloatValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid float-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid float-vector property 0x%04x", param); else SetSourcefv(Source, Context, param, values); UnlockSourcesRead(Context); @@ -1935,9 +1941,9 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(DoubleValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid double property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid double property 0x%04x", param); else { ALfloat fval = (ALfloat)value; @@ -1960,9 +1966,9 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(DoubleValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-double property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-double property 0x%04x", param); else { ALfloat fvals[3] = { (ALfloat)value1, (ALfloat)value2, (ALfloat)value3 }; @@ -1986,11 +1992,11 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!((count=DoubleValsByProp(param)) > 0 && count <= 6)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid double-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid double-vector property 0x%04x", param); else { ALfloat fvals[6]; @@ -2018,9 +2024,9 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(IntValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer property 0x%04x", param); else SetSourceiv(Source, Context, param, &value); UnlockSourcesRead(Context); @@ -2040,9 +2046,9 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(IntValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-integer property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-integer property 0x%04x", param); else { ALint ivals[3] = { value1, value2, value3 }; @@ -2065,11 +2071,11 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(IntValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer-vector property 0x%04x", param); else SetSourceiv(Source, Context, param, values); UnlockSourcesRead(Context); @@ -2090,9 +2096,9 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(Int64ValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer64 property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer64 property 0x%04x", param); else SetSourcei64v(Source, Context, param, &value); UnlockSourcesRead(Context); @@ -2112,9 +2118,9 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(Int64ValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-integer64 property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-integer64 property 0x%04x", param); else { ALint64SOFT i64vals[3] = { value1, value2, value3 }; @@ -2137,11 +2143,11 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(Int64ValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer64-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer64-vector property 0x%04x", param); else SetSourcei64v(Source, Context, param, values); UnlockSourcesRead(Context); @@ -2162,11 +2168,11 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!value) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(FloatValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid float property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid float property 0x%04x", param); else { ALdouble dval; @@ -2191,11 +2197,11 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(FloatValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-float property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-float property 0x%04x", param); else { ALdouble dvals[3]; @@ -2225,11 +2231,11 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!((count=FloatValsByProp(param)) > 0 && count <= 6)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid float-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid float-vector property 0x%04x", param); else { ALdouble dvals[6]; @@ -2258,11 +2264,11 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!value) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(DoubleValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid double property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid double property 0x%04x", param); else GetSourcedv(Source, Context, param, value); UnlockSourcesRead(Context); @@ -2282,11 +2288,11 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(DoubleValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-double property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-double property 0x%04x", param); else { ALdouble dvals[3]; @@ -2314,11 +2320,11 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(DoubleValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid double-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid double-vector property 0x%04x", param); else GetSourcedv(Source, Context, param, values); UnlockSourcesRead(Context); @@ -2339,11 +2345,11 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!value) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(IntValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer property 0x%04x", param); else GetSourceiv(Source, Context, param, value); UnlockSourcesRead(Context); @@ -2364,11 +2370,11 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(IntValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-integer property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-integer property 0x%04x", param); else { ALint ivals[3]; @@ -2397,11 +2403,11 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(IntValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer-vector property 0x%04x", param); else GetSourceiv(Source, Context, param, values); UnlockSourcesRead(Context); @@ -2422,11 +2428,11 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!value) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(Int64ValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer64 property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer64 property 0x%04x", param); else GetSourcei64v(Source, Context, param, value); UnlockSourcesRead(Context); @@ -2446,11 +2452,11 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(Int64ValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid 3-integer64 property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid 3-integer64 property 0x%04x", param); else { ALint64 i64vals[3]; @@ -2478,11 +2484,11 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME, source, "Invalid source ID"); + alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); else if(!values) - alSetError(Context, AL_INVALID_VALUE, source, "NULL pointer"); + alSetError(Context, AL_INVALID_VALUE, "NULL pointer"); else if(!(Int64ValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM, source, "Invalid integer64-vector property"); + alSetError(Context, AL_INVALID_ENUM, "Invalid integer64-vector property 0x%04x", param); else GetSourcei64v(Source, Context, param, values); UnlockSourcesRead(Context); @@ -2509,11 +2515,11 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Playing negative sources", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Playing %d sources", n); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", sources[i]); } device = context->Device; @@ -2536,7 +2542,8 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) if(context->MaxVoices >= newcount) { ALCdevice_Unlock(device); - SETERR_GOTO(context, AL_OUT_OF_MEMORY, 0, "Max voice count overflow", done); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, + "Overflow increasing voice count %d -> %d", context->MaxVoices, newcount); } AllocateVoices(context, newcount, device->NumAuxSends); } @@ -2696,11 +2703,11 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Pausing negative sources", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Pausing %d sources", n); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", sources[i]); } device = context->Device; @@ -2743,11 +2750,11 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Stopping negative sources", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Stopping %d sources", n); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", sources[i]); } device = context->Device; @@ -2793,11 +2800,11 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) LockSourcesRead(context); if(!(n >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Rewinding negative sources", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Rewinding %d sources", n); for(i = 0;i < n;i++) { if(!LookupSource(context, sources[i])) - SETERR_GOTO(context, AL_INVALID_NAME, sources[i], "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", sources[i]); } device = context->Device; @@ -2847,16 +2854,16 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu LockSourcesRead(context); if(!(nb >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, src, "Queueing negative buffers", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Queueing %d buffers", nb); if((source=LookupSource(context, src)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, src, "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", src); WriteLock(&source->queue_lock); if(source->SourceType == AL_STATIC) { WriteUnlock(&source->queue_lock); /* Can't queue on a Static Source */ - SETERR_GOTO(context, AL_INVALID_OPERATION, src, "Queueing onto a static source", done); + SETERR_GOTO(context, AL_INVALID_OPERATION, done, "Queueing onto static source %u", src); } /* Check for a valid Buffer, for its frequency and format */ @@ -2881,7 +2888,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) { WriteUnlock(&source->queue_lock); - SETERR_GOTO(context, AL_INVALID_NAME, src, "Invalid buffer ID", buffer_error); + SETERR_GOTO(context, AL_INVALID_NAME, buffer_error, "Queueing invalid buffer ID %u", + buffers[i]); } if(!BufferListStart) @@ -2911,8 +2919,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT)) { WriteUnlock(&source->queue_lock); - SETERR_GOTO(context, AL_INVALID_OPERATION, src, - "Queueing non-persistently mapped buffer", buffer_error); + SETERR_GOTO(context, AL_INVALID_OPERATION, buffer_error, + "Queueing non-persistently mapped buffer %u", buffer->id); } if(BufferFmt == NULL) @@ -2922,8 +2930,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferFmt->OriginalType != buffer->OriginalType) { WriteUnlock(&source->queue_lock); - alSetError(context, AL_INVALID_OPERATION, src, - "Queueing buffer with mismatched format"); + alSetError(context, AL_INVALID_OPERATION, "Queueing buffer with mismatched format"); buffer_error: /* A buffer failed (invalid ID or format), so unlock and release @@ -2994,10 +3001,9 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint LockSourcesRead(context); if(!(nb >= 0)) - SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing negative buffers", done); - + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing %d buffers", nb); if((source=LookupSource(context, src)) == NULL) - SETERR_GOTO(context, AL_INVALID_NAME, src, "Invalid source ID", done); + SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", src); /* Nothing to unqueue. */ if(nb == 0) goto done; @@ -3006,13 +3012,13 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint if(source->Looping) { WriteUnlock(&source->queue_lock); - SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing from a looping source", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing from looping source %u", src); } if(source->SourceType != AL_STREAMING) { WriteUnlock(&source->queue_lock); - SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing from a non-streaming source", - done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing from a non-streaming source %u", + src); } /* Find the new buffer queue head */ @@ -3034,7 +3040,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint if(i != nb) { WriteUnlock(&source->queue_lock); - SETERR_GOTO(context, AL_INVALID_VALUE, src, "Unqueueing pending buffers", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing pending buffers"); } /* Swap it, and cut the new head from the old. */ diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 9c49b2e8..1d442a1c 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -697,14 +697,15 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) if(!context) return; if(!(value >= 0.0f && isfinite(value))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Doppler factor out of range", done); - - WriteLock(&context->PropLock); - context->DopplerFactor = value; - DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + alSetError(context, AL_INVALID_VALUE, "Doppler factor out of range"); + else + { + WriteLock(&context->PropLock); + context->DopplerFactor = value; + DO_UPDATEPROPS(); + WriteUnlock(&context->PropLock); + } -done: ALCcontext_DecRef(context); } @@ -727,14 +728,15 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) } if(!(value >= 0.0f && isfinite(value))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Doppler velocity out of range", done); - - WriteLock(&context->PropLock); - context->DopplerVelocity = value; - DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + alSetError(context, AL_INVALID_VALUE, "Doppler velocity out of range"); + else + { + WriteLock(&context->PropLock); + context->DopplerVelocity = value; + DO_UPDATEPROPS(); + WriteUnlock(&context->PropLock); + } -done: ALCcontext_DecRef(context); } @@ -746,14 +748,15 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) if(!context) return; if(!(value > 0.0f && isfinite(value))) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Speed of sound out of range", done); - - WriteLock(&context->PropLock); - context->SpeedOfSound = value; - DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + alSetError(context, AL_INVALID_VALUE, "Speed of sound out of range"); + else + { + WriteLock(&context->PropLock); + context->SpeedOfSound = value; + DO_UPDATEPROPS(); + WriteUnlock(&context->PropLock); + } -done: ALCcontext_DecRef(context); } @@ -768,15 +771,16 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED || value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED || value == AL_NONE)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Distance model out of range", done); - - WriteLock(&context->PropLock); - context->DistanceModel = value; - if(!context->SourceDistanceModel) - DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + alSetError(context, AL_INVALID_VALUE, "Distance model out of range"); + else + { + WriteLock(&context->PropLock); + context->DistanceModel = value; + if(!context->SourceDistanceModel) + DO_UPDATEPROPS(); + WriteUnlock(&context->PropLock); + } -done: ALCcontext_DecRef(context); } @@ -825,7 +829,7 @@ AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index) { case AL_RESAMPLER_NAME_SOFT: if(index < 0 || (size_t)index >= COUNTOF(ResamplerNames)) - SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Resampler name index out of range", done); + SETERR_GOTO(context, AL_INVALID_VALUE, done, "Resampler name index out of range"); value = ResamplerNames[index]; break; @@ -835,7 +839,6 @@ AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index) done: ALCcontext_DecRef(context); - return value; } diff --git a/OpenAL32/event.c b/OpenAL32/event.c index 06db8713..3b70c9f3 100644 --- a/OpenAL32/event.c +++ b/OpenAL32/event.c @@ -17,9 +17,9 @@ AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, A context = GetContextRef(); if(!context) return; - if(count < 0) SETERR_GOTO(context, AL_INVALID_VALUE, 0, "Controlling negative events", done); + if(count < 0) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Controlling %d events", count); if(count == 0) goto done; - if(!types) SETERR_GOTO(context, AL_INVALID_VALUE, 0, "NULL pointer", done); + if(!types) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); for(i = 0;i < count;i++) { @@ -34,7 +34,7 @@ AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, A else if(types[i] == AL_EVENT_TYPE_DEPRECATED_SOFT) flags |= EventType_Deprecated; else - SETERR_GOTO(context, AL_INVALID_ENUM, 0, "Invalid event type", done); + SETERR_GOTO(context, AL_INVALID_ENUM, done, "Invalid event type 0x%04x", types[i]); } almtx_lock(&context->EventLock); -- cgit v1.2.3 From 6a839600b96b73104f8b93a4fa4a1a8da67cae5c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 Jan 2018 17:24:18 -0800 Subject: Use a vector to store the effect slot pointers And make the ID a simple index into it (1-base, to avoid ID 0). --- Alc/ALc.c | 25 +++---- OpenAL32/Include/alAuxEffectSlot.h | 14 ---- OpenAL32/Include/alMain.h | 9 ++- OpenAL32/alAuxEffectSlot.c | 143 +++++++++++++++++++++---------------- OpenAL32/alSource.c | 18 +++-- 5 files changed, 116 insertions(+), 93 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index f59c6e90..0dc93b56 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2249,10 +2249,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } WriteLock(&context->PropLock); - LockUIntMapRead(&context->EffectSlotMap); - for(pos = 0;pos < context->EffectSlotMap.size;pos++) + almtx_lock(&context->EffectSlotLock); + for(pos = 0;pos < (ALsizei)VECTOR_SIZE(context->EffectSlotList);pos++) { - ALeffectslot *slot = context->EffectSlotMap.values[pos]; + ALeffectslot *slot = VECTOR_ELEM(context->EffectSlotList, pos); ALeffectState *state = slot->Effect.State; state->OutBuffer = device->Dry.Buffer; @@ -2262,7 +2262,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) else UpdateEffectSlotProps(slot, context); } - UnlockUIntMapRead(&context->EffectSlotMap); + almtx_unlock(&context->EffectSlotLock); almtx_lock(&context->SourceLock); sublist = VECTOR_BEGIN(context->SourceList); @@ -2534,7 +2534,8 @@ static ALvoid InitContext(ALCcontext *Context) VECTOR_INIT(Context->SourceList); Context->NumSources = 0; almtx_init(&Context->SourceLock, almtx_plain); - InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax); + VECTOR_INIT(Context->EffectSlotList); + almtx_init(&Context->EffectSlotLock, almtx_plain); if(Context->DefaultSlot) { @@ -2648,13 +2649,13 @@ static void FreeContext(ALCcontext *context) ++count; } TRACE("Freed "SZFMT" AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s"); - if(context->EffectSlotMap.size > 0) - { - WARN("(%p) Deleting %d AuxiliaryEffectSlot%s\n", context, context->EffectSlotMap.size, - (context->EffectSlotMap.size==1)?"":"s"); - ReleaseALAuxiliaryEffectSlots(context); - } - ResetUIntMap(&context->EffectSlotMap); + + ReleaseALAuxiliaryEffectSlots(context); +#define FREE_EFFECTSLOTPTR(x) al_free(*(x)) + VECTOR_FOR_EACH(ALeffectslotPtr, context->EffectSlotList, FREE_EFFECTSLOTPTR); +#undef FREE_EFFECTSLOTPTR + VECTOR_DEINIT(context->EffectSlotList); + almtx_destroy(&context->EffectSlotLock); count = 0; vprops = ATOMIC_LOAD(&context->FreeVoiceProps, almemory_order_relaxed); diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 74bb841c..e4e954a0 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -149,20 +149,6 @@ typedef struct ALeffectslot { alignas(16) ALfloat WetBuffer[MAX_EFFECT_CHANNELS][BUFFERSIZE]; } ALeffectslot; -inline void LockEffectSlotsRead(ALCcontext *context) -{ LockUIntMapRead(&context->EffectSlotMap); } -inline void UnlockEffectSlotsRead(ALCcontext *context) -{ UnlockUIntMapRead(&context->EffectSlotMap); } -inline void LockEffectSlotsWrite(ALCcontext *context) -{ LockUIntMapWrite(&context->EffectSlotMap); } -inline void UnlockEffectSlotsWrite(ALCcontext *context) -{ UnlockUIntMapWrite(&context->EffectSlotMap); } - -inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) -{ return (struct ALeffectslot*)LookupUIntMapKeyNoLock(&context->EffectSlotMap, id); } -inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id) -{ return (struct ALeffectslot*)RemoveUIntMapKeyNoLock(&context->EffectSlotMap, id); } - ALenum InitEffectSlot(ALeffectslot *slot); void DeinitEffectSlot(ALeffectslot *slot); void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index f7ae2ecd..d1ae0a94 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -387,6 +387,12 @@ typedef struct SourceSubList { } SourceSubList; TYPEDEF_VECTOR(SourceSubList, vector_SourceSubList) +/* Effect slots are rather large, and apps aren't likely to have more than one + * or two (let alone 64), so hold them individually. + */ +typedef struct ALeffectslot *ALeffectslotPtr; +TYPEDEF_VECTOR(ALeffectslotPtr, vector_ALeffectslotPtr) + typedef struct EnumeratedHrtf { al_string name; @@ -600,7 +606,8 @@ struct ALCcontext_struct { ALuint NumSources; almtx_t SourceLock; - UIntMap EffectSlotMap; + vector_ALeffectslotPtr EffectSlotList; + almtx_t EffectSlotLock; ATOMIC(ALenum) LastError; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index d2039097..3fbf4b6e 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -36,13 +36,6 @@ #include "almalloc.h" -extern inline void LockEffectSlotsRead(ALCcontext *context); -extern inline void UnlockEffectSlotsRead(ALCcontext *context); -extern inline void LockEffectSlotsWrite(ALCcontext *context); -extern inline void UnlockEffectSlotsWrite(ALCcontext *context); -extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); -extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); - static UIntMap EffectStateFactoryMap; static inline ALeffectStateFactory *getFactoryByType(ALenum type) { @@ -54,6 +47,21 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) static void ALeffectState_IncRef(ALeffectState *state); + +static inline void LockEffectSlotList(ALCcontext *context) +{ almtx_lock(&context->EffectSlotLock); } +static inline void UnlockEffectSlotList(ALCcontext *context) +{ almtx_unlock(&context->EffectSlotLock); } + +static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) +{ + id--; + if(UNLIKELY(id >= VECTOR_SIZE(context->EffectSlotList))) + return NULL; + return VECTOR_ELEM(context->EffectSlotList, id); +} + + #define DO_UPDATEPROPS() do { \ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ UpdateEffectSlotProps(slot, context); \ @@ -76,38 +84,45 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effect slots", n); tmpslots = al_malloc(DEF_ALIGN, sizeof(ALeffectslot*)*n); - LockEffectSlotsWrite(context); + LockEffectSlotList(context); for(cur = 0;cur < n;cur++) { - ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); - err = AL_OUT_OF_MEMORY; - if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) - { - al_free(slot); - UnlockEffectSlotsWrite(context); + ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList); + ALeffectslotPtr *end = VECTOR_END(context->EffectSlotList); + ALeffectslot *slot = NULL; - alDeleteAuxiliaryEffectSlots(cur, effectslots); - SETERR_GOTO(context, err, done, "Effect slot object allocation failed"); + for(;iter != end;iter++) + { + if(!*iter) + break; } + if(iter == end) + { + if(VECTOR_SIZE(context->EffectSlotList) >= INT_MAX) + { + UnlockEffectSlotList(context); - err = NewThunkEntry(&slot->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntryNoLock(&context->EffectSlotMap, slot->id, slot); - if(err != AL_NO_ERROR) + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SETERR_GOTO(context, err, done, "Too many effect slot objects"); + } + VECTOR_PUSH_BACK(context->EffectSlotList, NULL); + iter = &VECTOR_BACK(context->EffectSlotList); + } + slot = al_calloc(16, sizeof(ALeffectslot)); + err = AL_OUT_OF_MEMORY; + if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) { - FreeThunkEntry(slot->id); - ALeffectState_DecRef(slot->Effect.State); - if(slot->Params.EffectState) - ALeffectState_DecRef(slot->Params.EffectState); al_free(slot); - UnlockEffectSlotsWrite(context); + UnlockEffectSlotList(context); alDeleteAuxiliaryEffectSlots(cur, effectslots); - SETERR_GOTO(context, err, done, "Failed to set effect slot ID"); + SETERR_GOTO(context, err, done, "Effect slot object allocation failed"); } - aluInitEffectPanning(slot); + slot->id = (iter - VECTOR_BEGIN(context->EffectSlotList)) + 1; + *iter = slot; + tmpslots[cur] = slot; effectslots[cur] = slot->id; } @@ -131,7 +146,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo althrd_yield(); al_free(newarray); } - UnlockEffectSlotsWrite(context); + UnlockEffectSlotList(context); done: al_free(tmpslots); @@ -147,7 +162,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * context = GetContextRef(); if(!context) return; - LockEffectSlotsWrite(context); + LockEffectSlotList(context); if(!(n >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effect slots", n); for(i = 0;i < n;i++) @@ -194,9 +209,9 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * for(i = 0;i < n;i++) { - if((slot=RemoveEffectSlot(context, effectslots[i])) == NULL) + if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) continue; - FreeThunkEntry(slot->id); + VECTOR_ELEM(context->EffectSlotList, effectslots[i]-1) = NULL; DeinitEffectSlot(slot); @@ -205,7 +220,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * } done: - UnlockEffectSlotsWrite(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -217,9 +232,9 @@ AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot) context = GetContextRef(); if(!context) return AL_FALSE; - LockEffectSlotsRead(context); + LockEffectSlotList(context); ret = (LookupEffectSlot(context, effectslot) ? AL_TRUE : AL_FALSE); - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); @@ -238,7 +253,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param if(!context) return; WriteLock(&context->PropLock); - LockEffectSlotsRead(context); + LockEffectSlotList(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -274,7 +289,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param DO_UPDATEPROPS(); done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -294,7 +309,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para context = GetContextRef(); if(!context) return; - LockEffectSlotsRead(context); + LockEffectSlotList(context); if(LookupEffectSlot(context, effectslot) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -305,7 +320,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para } done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -318,7 +333,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param if(!context) return; WriteLock(&context->PropLock); - LockEffectSlotsRead(context); + LockEffectSlotList(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -336,7 +351,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param DO_UPDATEPROPS(); done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); WriteUnlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -355,7 +370,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum para context = GetContextRef(); if(!context) return; - LockEffectSlotsRead(context); + LockEffectSlotList(context); if(LookupEffectSlot(context, effectslot) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -366,7 +381,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum para } done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -378,7 +393,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa context = GetContextRef(); if(!context) return; - LockEffectSlotsRead(context); + LockEffectSlotList(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -392,7 +407,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum pa } done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -411,7 +426,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p context = GetContextRef(); if(!context) return; - LockEffectSlotsRead(context); + LockEffectSlotList(context); if(LookupEffectSlot(context, effectslot) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -422,7 +437,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p } done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -434,7 +449,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa context = GetContextRef(); if(!context) return; - LockEffectSlotsRead(context); + LockEffectSlotList(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -448,7 +463,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum pa } done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -466,7 +481,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p context = GetContextRef(); if(!context) return; - LockEffectSlotsRead(context); + LockEffectSlotList(context); if(LookupEffectSlot(context, effectslot) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); switch(param) @@ -477,7 +492,7 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p } done: - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); ALCcontext_DecRef(context); } @@ -697,7 +712,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context) struct ALeffectslotArray *auxslots; ALsizei i; - LockEffectSlotsRead(context); + LockEffectSlotList(context); auxslots = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); for(i = 0;i < auxslots->count;i++) { @@ -705,21 +720,27 @@ void UpdateAllEffectSlotProps(ALCcontext *context) if(!ATOMIC_FLAG_TEST_AND_SET(&slot->PropsClean, almemory_order_acq_rel)) UpdateEffectSlotProps(slot, context); } - UnlockEffectSlotsRead(context); + UnlockEffectSlotList(context); } -ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) +ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *context) { - ALsizei pos; - for(pos = 0;pos < Context->EffectSlotMap.size;pos++) + ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList); + ALeffectslotPtr *end = VECTOR_END(context->EffectSlotList); + size_t leftover = 0; + + for(;iter != end;iter++) { - ALeffectslot *temp = Context->EffectSlotMap.values[pos]; - Context->EffectSlotMap.values[pos] = NULL; + ALeffectslot *slot = *iter; + if(!slot) continue; + *iter = NULL; - DeinitEffectSlot(temp); + DeinitEffectSlot(slot); - FreeThunkEntry(temp->id); - memset(temp, 0, sizeof(ALeffectslot)); - al_free(temp); + memset(slot, 0, sizeof(*slot)); + al_free(slot); + ++leftover; } + if(leftover > 0) + WARN("(%p) Deleted "SZFMT" AuxiliaryEffectSlot%s\n", context, leftover, (leftover==1)?"":"s"); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 05d9a456..58026aeb 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -84,6 +84,14 @@ static inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) return sublist->Buffers + slidx; } +static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) +{ + id--; + if(UNLIKELY(id >= VECTOR_SIZE(context->EffectSlotList))) + return NULL; + return VECTOR_ELEM(context->EffectSlotList, id); +} + typedef enum SourceProp { srcPitch = AL_PITCH, @@ -972,23 +980,23 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_AUXILIARY_SEND_FILTER: - LockEffectSlotsRead(Context); + almtx_lock(&Context->EffectSlotLock); if(!(values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL)) { - UnlockEffectSlotsRead(Context); + almtx_unlock(&Context->EffectSlotLock); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid effect ID %u", values[0]); } if(!((ALuint)values[1] < (ALuint)device->NumAuxSends)) { - UnlockEffectSlotsRead(Context); + almtx_unlock(&Context->EffectSlotLock); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid send %u", values[1]); } LockFiltersRead(device); if(!(values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL)) { UnlockFiltersRead(device); - UnlockEffectSlotsRead(Context); + almtx_unlock(&Context->EffectSlotLock); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid filter ID %u", values[2]); } @@ -1037,7 +1045,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].Slot = slot; DO_UPDATEPROPS(); } - UnlockEffectSlotsRead(Context); + almtx_unlock(&Context->EffectSlotLock); return AL_TRUE; -- cgit v1.2.3 From e8c268ef09d53461386fa7e81bd853cd1007d6c2 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 Jan 2018 19:01:25 -0800 Subject: Store effects in an array of lists --- Alc/ALc.c | 22 ++--- OpenAL32/Include/alEffect.h | 14 ---- OpenAL32/Include/alMain.h | 10 ++- OpenAL32/alAuxEffectSlot.c | 20 ++++- OpenAL32/alEffect.c | 195 ++++++++++++++++++++++++++++++-------------- 5 files changed, 172 insertions(+), 89 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 0dc93b56..9a0fa63b 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2392,13 +2392,12 @@ static ALCvoid FreeDevice(ALCdevice *device) VECTOR_DEINIT(device->BufferList); almtx_destroy(&device->BufferLock); - if(device->EffectMap.size > 0) - { - WARN("(%p) Deleting %d Effect%s\n", device, device->EffectMap.size, - (device->EffectMap.size==1)?"":"s"); - ReleaseALEffects(device); - } - ResetUIntMap(&device->EffectMap); + ReleaseALEffects(device); +#define FREE_EFFECTSUBLIST(x) al_free((x)->Effects) + VECTOR_FOR_EACH(EffectSubList, device->EffectList, FREE_EFFECTSUBLIST); +#undef FREE_EFFECTSUBLIST + VECTOR_DEINIT(device->EffectList); + almtx_destroy(&device->EffectLock); if(device->FilterMap.size > 0) { @@ -4000,7 +3999,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->NumAuxSends = DEFAULT_SENDS; VECTOR_INIT(device->BufferList); - InitUIntMap(&device->EffectMap, INT_MAX); + VECTOR_INIT(device->EffectList); InitUIntMap(&device->FilterMap, INT_MAX); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) @@ -4132,6 +4131,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) } almtx_init(&device->BackendLock, almtx_plain); almtx_init(&device->BufferLock, almtx_plain); + almtx_init(&device->EffectLock, almtx_plain); if(ConfigValueStr(alstr_get_cstr(device->DeviceName), NULL, "ambi-format", &fmt)) { @@ -4278,7 +4278,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, device->RealOut.NumChannels = 0; VECTOR_INIT(device->BufferList); - InitUIntMap(&device->EffectMap, INT_MAX); + VECTOR_INIT(device->EffectList); InitUIntMap(&device->FilterMap, INT_MAX); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) @@ -4327,6 +4327,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, } almtx_init(&device->BackendLock, almtx_plain); almtx_init(&device->BufferLock, almtx_plain); + almtx_init(&device->EffectLock, almtx_plain); { ALCdevice *head = ATOMIC_LOAD_SEQ(&DeviceList); @@ -4502,7 +4503,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN device->NumAuxSends = DEFAULT_SENDS; VECTOR_INIT(device->BufferList); - InitUIntMap(&device->EffectMap, INT_MAX); + VECTOR_INIT(device->EffectList); InitUIntMap(&device->FilterMap, INT_MAX); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) @@ -4522,6 +4523,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN } almtx_init(&device->BackendLock, almtx_plain); almtx_init(&device->BufferLock, almtx_plain); + almtx_init(&device->EffectLock, almtx_plain); //Set output format device->NumUpdates = 0; diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index dbbd8966..30055f1f 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -166,20 +166,6 @@ typedef struct ALeffect { ALuint id; } ALeffect; -inline void LockEffectsRead(ALCdevice *device) -{ LockUIntMapRead(&device->EffectMap); } -inline void UnlockEffectsRead(ALCdevice *device) -{ UnlockUIntMapRead(&device->EffectMap); } -inline void LockEffectsWrite(ALCdevice *device) -{ LockUIntMapWrite(&device->EffectMap); } -inline void UnlockEffectsWrite(ALCdevice *device) -{ UnlockUIntMapWrite(&device->EffectMap); } - -inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id) -{ return (struct ALeffect*)LookupUIntMapKeyNoLock(&device->EffectMap, id); } -inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id) -{ return (struct ALeffect*)RemoveUIntMapKeyNoLock(&device->EffectMap, id); } - inline ALboolean IsReverbEffect(ALenum type) { return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index d1ae0a94..8908d93f 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -165,6 +165,7 @@ struct FrontStablizer; struct Compressor; struct ALCbackend; struct ALbuffer; +struct ALeffect; struct ALsource; struct ALcontextProps; struct ALlistenerProps; @@ -381,6 +382,12 @@ typedef struct BufferSubList { } BufferSubList; TYPEDEF_VECTOR(BufferSubList, vector_BufferSubList) +typedef struct EffectSubList { + ALuint64 FreeMask; + struct ALeffect *Effects; /* 64 */ +} EffectSubList; +TYPEDEF_VECTOR(EffectSubList, vector_EffectSubList) + typedef struct SourceSubList { ALuint64 FreeMask; struct ALsource *Sources; /* 64 */ @@ -485,7 +492,8 @@ struct ALCdevice_struct almtx_t BufferLock; // Map of Effects for this device - UIntMap EffectMap; + vector_EffectSubList EffectList; + almtx_t EffectLock; // Map of Filters for this device UIntMap FilterMap; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 3fbf4b6e..30ca097f 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -61,6 +61,20 @@ static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) return VECTOR_ELEM(context->EffectSlotList, id); } +static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) +{ + EffectSubList *sublist; + ALuint lidx = (id-1) >> 6; + ALsizei slidx = (id-1) & 0x3f; + + if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList))) + return NULL; + sublist = &VECTOR_ELEM(device->EffectList, lidx); + if(UNLIKELY(sublist->FreeMask & (U64(1)<Effects + slidx; +} + #define DO_UPDATEPROPS() do { \ if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) \ @@ -261,15 +275,15 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param case AL_EFFECTSLOT_EFFECT: device = context->Device; - LockEffectsRead(device); + almtx_lock(&device->EffectLock); effect = (value ? LookupEffect(device, value) : NULL); if(!(value == 0 || effect != NULL)) { - UnlockEffectsRead(device); + almtx_unlock(&device->EffectLock); SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid effect ID %u", value); } err = InitializeEffect(context, slot, effect); - UnlockEffectsRead(device); + almtx_unlock(&device->EffectLock); if(err != AL_NO_ERROR) SETERR_GOTO(context, err, done, "Effect initialization failed"); diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index ab42112c..797687fa 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -48,20 +48,34 @@ const struct EffectList EffectList[EFFECTLIST_SIZE] = { ALboolean DisabledEffects[MAX_EFFECTS]; -extern inline void LockEffectsRead(ALCdevice *device); -extern inline void UnlockEffectsRead(ALCdevice *device); -extern inline void LockEffectsWrite(ALCdevice *device); -extern inline void UnlockEffectsWrite(ALCdevice *device); -extern inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id); -extern inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id); extern inline ALboolean IsReverbEffect(ALenum type); +static ALeffect *AllocEffect(ALCcontext *context); +static void FreeEffect(ALCdevice *device, ALeffect *effect); static void InitEffectParams(ALeffect *effect, ALenum type); +static inline void LockEffectList(ALCdevice *device) +{ almtx_lock(&device->EffectLock); } +static inline void UnlockEffectList(ALCdevice *device) +{ almtx_unlock(&device->EffectLock); } + +static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) +{ + EffectSubList *sublist; + ALuint lidx = (id-1) >> 6; + ALsizei slidx = (id-1) & 0x3f; + + if(UNLIKELY(lidx >= VECTOR_SIZE(device->EffectList))) + return NULL; + sublist = &VECTOR_ELEM(device->EffectList, lidx); + if(UNLIKELY(sublist->FreeMask & (U64(1)<Effects + slidx; +} + AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) { - ALCdevice *device; ALCcontext *context; ALsizei cur; @@ -71,31 +85,14 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) if(!(n >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effects", n); - device = context->Device; for(cur = 0;cur < n;cur++) { - ALeffect *effect = al_calloc(16, sizeof(ALeffect)); - ALenum err = AL_OUT_OF_MEMORY; - if(!effect || (err=InitEffect(effect)) != AL_NO_ERROR) + ALeffect *effect = AllocEffect(context); + if(!effect) { - al_free(effect); - alDeleteEffects(cur, effects); - SETERR_GOTO(context, err, done, "Failed to allocate effect object"); - } - - err = NewThunkEntry(&effect->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->EffectMap, effect->id, effect); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(effect->id); - memset(effect, 0, sizeof(ALeffect)); - al_free(effect); - alDeleteEffects(cur, effects); - SETERR_GOTO(context, err, done, "Failed to set effect ID"); + break; } - effects[cur] = effect->id; } @@ -114,7 +111,7 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) if(!context) return; device = context->Device; - LockEffectsWrite(device); + LockEffectList(device); if(!(n >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effects", n); for(i = 0;i < n;i++) @@ -124,16 +121,12 @@ AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) } for(i = 0;i < n;i++) { - if((effect=RemoveEffect(device, effects[i])) == NULL) - continue; - FreeThunkEntry(effect->id); - - memset(effect, 0, sizeof(*effect)); - al_free(effect); + if((effect=LookupEffect(device, effects[i])) != NULL) + FreeEffect(device, effect); } done: - UnlockEffectsWrite(device); + UnlockEffectList(device); ALCcontext_DecRef(context); } @@ -145,10 +138,10 @@ AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) Context = GetContextRef(); if(!Context) return AL_FALSE; - LockEffectsRead(Context->Device); + LockEffectList(Context->Device); result = ((!effect || LookupEffect(Context->Device, effect)) ? AL_TRUE : AL_FALSE); - UnlockEffectsRead(Context->Device); + UnlockEffectList(Context->Device); ALCcontext_DecRef(Context); @@ -165,7 +158,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) if(!Context) return; Device = Context->Device; - LockEffectsWrite(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -192,7 +185,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) V(ALEffect,setParami)(Context, param, value); } } - UnlockEffectsWrite(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -214,7 +207,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v if(!Context) return; Device = Context->Device; - LockEffectsWrite(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -222,7 +215,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v /* Call the appropriate handler */ V(ALEffect,setParamiv)(Context, param, values); } - UnlockEffectsWrite(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -237,7 +230,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) if(!Context) return; Device = Context->Device; - LockEffectsWrite(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -245,7 +238,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) /* Call the appropriate handler */ V(ALEffect,setParamf)(Context, param, value); } - UnlockEffectsWrite(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -260,7 +253,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat if(!Context) return; Device = Context->Device; - LockEffectsWrite(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -268,7 +261,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat /* Call the appropriate handler */ V(ALEffect,setParamfv)(Context, param, values); } - UnlockEffectsWrite(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -283,7 +276,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value if(!Context) return; Device = Context->Device; - LockEffectsRead(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -296,7 +289,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value V(ALEffect,getParami)(Context, param, value); } } - UnlockEffectsRead(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -318,7 +311,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu if(!Context) return; Device = Context->Device; - LockEffectsRead(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -326,7 +319,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu /* Call the appropriate handler */ V(ALEffect,getParamiv)(Context, param, values); } - UnlockEffectsRead(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -341,7 +334,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val if(!Context) return; Device = Context->Device; - LockEffectsRead(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -349,7 +342,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val /* Call the appropriate handler */ V(ALEffect,getParamf)(Context, param, value); } - UnlockEffectsRead(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -364,7 +357,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va if(!Context) return; Device = Context->Device; - LockEffectsRead(Device); + LockEffectList(Device); if((ALEffect=LookupEffect(Device, effect)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid effect ID %u", effect); else @@ -372,7 +365,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va /* Call the appropriate handler */ V(ALEffect,getParamfv)(Context, param, values); } - UnlockEffectsRead(Device); + UnlockEffectList(Device); ALCcontext_DecRef(Context); } @@ -384,19 +377,99 @@ ALenum InitEffect(ALeffect *effect) return AL_NO_ERROR; } +static ALeffect *AllocEffect(ALCcontext *context) +{ + ALCdevice *device = context->Device; + EffectSubList *sublist, *subend; + ALeffect *effect = NULL; + ALsizei lidx = 0; + ALsizei slidx; + + almtx_lock(&device->EffectLock); + sublist = VECTOR_BEGIN(device->EffectList); + subend = VECTOR_END(device->EffectList); + for(;sublist != subend;++sublist) + { + if(sublist->FreeMask) + { + slidx = CTZ64(sublist->FreeMask); + effect = sublist->Effects + slidx; + break; + } + ++lidx; + } + if(UNLIKELY(!effect)) + { + const EffectSubList empty_sublist = { 0, NULL }; + /* Don't allocate so many list entries that the 32-bit ID could + * overflow... + */ + if(UNLIKELY(VECTOR_SIZE(device->EffectList) >= 1<<25)) + { + almtx_unlock(&device->EffectLock); + return NULL; + } + lidx = (ALsizei)VECTOR_SIZE(device->EffectList); + VECTOR_PUSH_BACK(device->EffectList, empty_sublist); + sublist = &VECTOR_BACK(device->EffectList); + sublist->FreeMask = ~U64(0); + sublist->Effects = al_calloc(16, sizeof(ALeffect)*64); + if(UNLIKELY(!sublist->Effects)) + { + VECTOR_POP_BACK(device->EffectList); + almtx_unlock(&device->EffectLock); + return NULL; + } + + slidx = 0; + effect = sublist->Effects + slidx; + } + + memset(effect, 0, sizeof(*effect)); + InitEffectParams(effect, AL_EFFECT_NULL); + + /* Add 1 to avoid effect ID 0. */ + effect->id = ((lidx<<6) | slidx) + 1; + + sublist->FreeMask &= ~(U64(1)<EffectLock); + + return effect; +} + +static void FreeEffect(ALCdevice *device, ALeffect *effect) +{ + ALuint id = effect->id - 1; + ALsizei lidx = id >> 6; + ALsizei slidx = id & 0x3f; + + memset(effect, 0, sizeof(*effect)); + + VECTOR_ELEM(device->EffectList, lidx).FreeMask |= U64(1) << slidx; +} + ALvoid ReleaseALEffects(ALCdevice *device) { - ALsizei i; - for(i = 0;i < device->EffectMap.size;i++) + EffectSubList *sublist = VECTOR_BEGIN(device->EffectList); + EffectSubList *subend = VECTOR_END(device->EffectList); + size_t leftover = 0; + for(;sublist != subend;++sublist) { - ALeffect *temp = device->EffectMap.values[i]; - device->EffectMap.values[i] = NULL; + ALuint64 usemask = ~sublist->FreeMask; + while(usemask) + { + ALsizei idx = CTZ64(usemask); + ALeffect *effect = sublist->Effects + idx; - // Release effect structure - FreeThunkEntry(temp->id); - memset(temp, 0, sizeof(ALeffect)); - al_free(temp); + memset(effect, 0, sizeof(*effect)); + ++leftover; + + usemask &= ~(U64(1) << idx); + } + sublist->FreeMask = ~usemask; } + if(leftover > 0) + WARN("(%p) Deleted "SZFMT" Effect%s\n", device, leftover, (leftover==1)?"":"s"); } -- cgit v1.2.3 From f16ece6048ebe3e81b892476fa0dc66f4091a4a9 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 Jan 2018 21:16:24 -0800 Subject: Move some inline functions into a header instead of copying them Unfortunately does not include the Lookup* functions, which need the full type declaration to offset the pointer. --- OpenAL32/Include/alMain.h | 17 +++++++++++++---- OpenAL32/alAuxEffectSlot.c | 14 ++++++-------- OpenAL32/alEffect.c | 11 ++++------- OpenAL32/alFilter.c | 7 ++----- OpenAL32/alSource.c | 22 +++++++++++----------- 5 files changed, 36 insertions(+), 35 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index d21ec3b0..5b31696e 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -723,10 +723,19 @@ inline ALint GetChannelIdxByName(const RealMixParams *real, enum Channel chan) { return GetChannelIndex(real->ChannelName, chan); } -inline void LockBufferList(ALCdevice *device) -{ almtx_lock(&device->BufferLock); } -inline void UnlockBufferList(ALCdevice *device) -{ almtx_unlock(&device->BufferLock); } +inline void LockBufferList(ALCdevice *device) { almtx_lock(&device->BufferLock); } +inline void UnlockBufferList(ALCdevice *device) { almtx_unlock(&device->BufferLock); } + +inline void LockEffectList(ALCdevice *device) { almtx_lock(&device->EffectLock); } +inline void UnlockEffectList(ALCdevice *device) { almtx_unlock(&device->EffectLock); } + +inline void LockFilterList(ALCdevice *device) { almtx_lock(&device->FilterLock); } +inline void UnlockFilterList(ALCdevice *device) { almtx_unlock(&device->FilterLock); } + +inline void LockEffectSlotList(ALCcontext *context) +{ almtx_lock(&context->EffectSlotLock); } +inline void UnlockEffectSlotList(ALCcontext *context) +{ almtx_unlock(&context->EffectSlotLock); } vector_al_string SearchDataFiles(const char *match, const char *subdir); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 30ca097f..70025409 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -36,6 +36,9 @@ #include "almalloc.h" +extern inline void LockEffectSlotList(ALCcontext *context); +extern inline void UnlockEffectSlotList(ALCcontext *context); + static UIntMap EffectStateFactoryMap; static inline ALeffectStateFactory *getFactoryByType(ALenum type) { @@ -48,11 +51,6 @@ static inline ALeffectStateFactory *getFactoryByType(ALenum type) static void ALeffectState_IncRef(ALeffectState *state); -static inline void LockEffectSlotList(ALCcontext *context) -{ almtx_lock(&context->EffectSlotLock); } -static inline void UnlockEffectSlotList(ALCcontext *context) -{ almtx_unlock(&context->EffectSlotLock); } - static inline ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id) { id--; @@ -275,15 +273,15 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param case AL_EFFECTSLOT_EFFECT: device = context->Device; - almtx_lock(&device->EffectLock); + LockEffectList(device); effect = (value ? LookupEffect(device, value) : NULL); if(!(value == 0 || effect != NULL)) { - almtx_unlock(&device->EffectLock); + UnlockEffectList(device); SETERR_GOTO(context, AL_INVALID_VALUE, done, "Invalid effect ID %u", value); } err = InitializeEffect(context, slot, effect); - almtx_unlock(&device->EffectLock); + UnlockEffectList(device); if(err != AL_NO_ERROR) SETERR_GOTO(context, err, done, "Effect initialization failed"); diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 0fa2ee08..e538433f 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -32,6 +32,10 @@ #include "alError.h" +extern inline void LockEffectList(ALCdevice *device); +extern inline void UnlockEffectList(ALCdevice *device); +extern inline ALboolean IsReverbEffect(ALenum type); + const struct EffectList EffectList[EFFECTLIST_SIZE] = { { "eaxreverb", EAXREVERB_EFFECT, AL_EFFECT_EAXREVERB }, { "reverb", REVERB_EFFECT, AL_EFFECT_REVERB }, @@ -48,17 +52,10 @@ const struct EffectList EffectList[EFFECTLIST_SIZE] = { ALboolean DisabledEffects[MAX_EFFECTS]; -extern inline ALboolean IsReverbEffect(ALenum type); - static ALeffect *AllocEffect(ALCcontext *context); static void FreeEffect(ALCdevice *device, ALeffect *effect); static void InitEffectParams(ALeffect *effect, ALenum type); -static inline void LockEffectList(ALCdevice *device) -{ almtx_lock(&device->EffectLock); } -static inline void UnlockEffectList(ALCdevice *device) -{ almtx_unlock(&device->EffectLock); } - static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) { EffectSubList *sublist; diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index 7a3513c3..de527fea 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -29,6 +29,8 @@ #include "alError.h" +extern inline void LockFilterList(ALCdevice *device); +extern inline void UnlockFilterList(ALCdevice *device); extern inline void ALfilterState_clear(ALfilterState *filter); extern inline void ALfilterState_copyParams(ALfilterState *restrict dst, const ALfilterState *restrict src); extern inline void ALfilterState_processPassthru(ALfilterState *filter, const ALfloat *restrict src, ALsizei numsamples); @@ -39,11 +41,6 @@ static ALfilter *AllocFilter(ALCcontext *context); static void FreeFilter(ALCdevice *device, ALfilter *filter); static void InitFilterParams(ALfilter *filter, ALenum type); -static inline void LockFilterList(ALCdevice *device) -{ almtx_lock(&device->FilterLock); } -static inline void UnlockFilterList(ALCdevice *device) -{ almtx_unlock(&device->FilterLock); } - static inline ALfilter *LookupFilter(ALCdevice *device, ALuint id) { FilterSubList *sublist; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 19017e51..b3e98bc9 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -908,10 +908,10 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_DIRECT_FILTER: - almtx_lock(&device->FilterLock); + LockFilterList(device); if(!(*values == 0 || (filter=LookupFilter(device, *values)) != NULL)) { - almtx_unlock(&device->FilterLock); + UnlockFilterList(device); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid filter ID %u", *values); } @@ -932,7 +932,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Direct.GainLF = filter->GainLF; Source->Direct.LFReference = filter->LFReference; } - almtx_unlock(&device->FilterLock); + UnlockFilterList(device); DO_UPDATEPROPS(); return AL_TRUE; @@ -994,23 +994,23 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_AUXILIARY_SEND_FILTER: - almtx_lock(&Context->EffectSlotLock); + LockEffectSlotList(Context); if(!(values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL)) { - almtx_unlock(&Context->EffectSlotLock); + UnlockEffectSlotList(Context); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid effect ID %u", values[0]); } if(!((ALuint)values[1] < (ALuint)device->NumAuxSends)) { - almtx_unlock(&Context->EffectSlotLock); + UnlockEffectSlotList(Context); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid send %u", values[1]); } - almtx_lock(&device->FilterLock); + LockFilterList(device); if(!(values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL)) { - almtx_unlock(&device->FilterLock); - almtx_unlock(&Context->EffectSlotLock); + UnlockFilterList(device); + UnlockEffectSlotList(Context); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid filter ID %u", values[2]); } @@ -1032,7 +1032,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].GainLF = filter->GainLF; Source->Send[values[1]].LFReference = filter->LFReference; } - almtx_unlock(&device->FilterLock); + UnlockFilterList(device); if(slot != Source->Send[values[1]].Slot && IsPlayingOrPaused(Source)) { @@ -1059,7 +1059,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].Slot = slot; DO_UPDATEPROPS(); } - almtx_unlock(&Context->EffectSlotLock); + UnlockEffectSlotList(Context); return AL_TRUE; -- cgit v1.2.3 From 0cd61fd197394bbbc867f1df87ea2f951f49822d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 Jan 2018 23:07:29 -0800 Subject: Don't allocate more effect slots than allowed --- OpenAL32/alAuxEffectSlot.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 70025409..f5362e94 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -84,6 +84,7 @@ static inline ALeffect *LookupEffect(ALCdevice *device, ALuint id) AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { + ALCdevice *device; ALCcontext *context; ALeffectslot **tmpslots = NULL; ALsizei cur; @@ -96,7 +97,14 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effect slots", n); tmpslots = al_malloc(DEF_ALIGN, sizeof(ALeffectslot*)*n); + device = context->Device; LockEffectSlotList(context); + if(device->AuxiliaryEffectSlotMax - VECTOR_SIZE(context->EffectSlotList) > (ALuint)n) + { + UnlockEffectSlotList(context); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, "Exceeding %u auxiliary effect slot limit", + device->AuxiliaryEffectSlotMax); + } for(cur = 0;cur < n;cur++) { ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList); -- cgit v1.2.3 From dcc5a10c7b8bbe6be82c992b6540fd1ad745b7a7 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Jan 2018 00:10:12 -0800 Subject: Use a fixed array for the effect state factory list --- Alc/ALc.c | 4 --- OpenAL32/Include/alAuxEffectSlot.h | 3 --- OpenAL32/alAuxEffectSlot.c | 52 ++++++++++++++++++-------------------- 3 files changed, 24 insertions(+), 35 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 7ec5ec8d..ea387c6d 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1127,8 +1127,6 @@ static void alc_initconfig(void) } while(next++); } - InitEffectFactoryMap(); - InitEffect(&DefaultEffect); str = getenv("ALSOFT_DEFAULT_REVERB"); if((str && str[0]) || ConfigValueStr(NULL, NULL, "default-reverb", &str)) @@ -1229,8 +1227,6 @@ 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/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index e4e954a0..aa3a0118 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -171,9 +171,6 @@ ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void); ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect); -void InitEffectFactoryMap(void); -void DeinitEffectFactoryMap(void); - void ALeffectState_DecRef(ALeffectState *state); #ifdef __cplusplus diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index f5362e94..cd028bb0 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -39,12 +39,32 @@ extern inline void LockEffectSlotList(ALCcontext *context); extern inline void UnlockEffectSlotList(ALCcontext *context); -static UIntMap EffectStateFactoryMap; +static const struct { + ALenum Type; + ALeffectStateFactory* (*GetFactory)(void); +} FactoryList[] = { + { AL_EFFECT_NULL, ALnullStateFactory_getFactory }, + { AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory }, + { AL_EFFECT_REVERB, ALreverbStateFactory_getFactory }, + { AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory }, + { AL_EFFECT_COMPRESSOR, ALcompressorStateFactory_getFactory }, + { AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory }, + { AL_EFFECT_ECHO, ALechoStateFactory_getFactory }, + { AL_EFFECT_EQUALIZER, ALequalizerStateFactory_getFactory }, + { AL_EFFECT_FLANGER, ALflangerStateFactory_getFactory }, + { AL_EFFECT_RING_MODULATOR, ALmodulatorStateFactory_getFactory }, + { AL_EFFECT_DEDICATED_DIALOGUE, ALdedicatedStateFactory_getFactory }, + { AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, ALdedicatedStateFactory_getFactory } +}; + static inline ALeffectStateFactory *getFactoryByType(ALenum type) { - ALeffectStateFactory* (*getFactory)(void) = LookupUIntMapKey(&EffectStateFactoryMap, type); - if(getFactory != NULL) - return getFactory(); + size_t i; + for(i = 0;i < COUNTOF(FactoryList);i++) + { + if(FactoryList[i].Type == type) + return FactoryList[i].GetFactory(); + } return NULL; } @@ -517,30 +537,6 @@ done: } -void InitEffectFactoryMap(void) -{ - InitUIntMap(&EffectStateFactoryMap, INT_MAX); - - InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnullStateFactory_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_COMPRESSOR, ALcompressorStateFactory_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); -} - -void DeinitEffectFactoryMap(void) -{ - ResetUIntMap(&EffectStateFactoryMap); -} - - ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect) { ALCdevice *Device = Context->Device; -- cgit v1.2.3 From a24a22c39aa3ee474197f4f9b12e4351fc836b39 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Jan 2018 17:56:47 -0800 Subject: Fix the effect slot limit check --- OpenAL32/alAuxEffectSlot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index cd028bb0..5400a914 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -119,7 +119,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo device = context->Device; LockEffectSlotList(context); - if(device->AuxiliaryEffectSlotMax - VECTOR_SIZE(context->EffectSlotList) > (ALuint)n) + if(device->AuxiliaryEffectSlotMax - VECTOR_SIZE(context->EffectSlotList) < (ALuint)n) { UnlockEffectSlotList(context); SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, "Exceeding %u auxiliary effect slot limit", -- cgit v1.2.3 From 80cc32d77b73e7c7625c35e37340c14e430c2618 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 2 Feb 2018 22:59:06 -0800 Subject: Remove the unused thunk code --- Alc/ALc.c | 4 -- CMakeLists.txt | 1 - OpenAL32/Include/alThunk.h | 20 --------- OpenAL32/alAuxEffectSlot.c | 1 - OpenAL32/alBuffer.c | 1 - OpenAL32/alEffect.c | 1 - OpenAL32/alFilter.c | 1 - OpenAL32/alSource.c | 1 - OpenAL32/alThunk.c | 108 --------------------------------------------- 9 files changed, 138 deletions(-) delete mode 100644 OpenAL32/Include/alThunk.h delete mode 100644 OpenAL32/alThunk.c (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 8ed10ac6..dfda8381 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -32,7 +32,6 @@ #include "alMain.h" #include "alSource.h" #include "alListener.h" -#include "alThunk.h" #include "alSource.h" #include "alBuffer.h" #include "alAuxEffectSlot.h" @@ -882,8 +881,6 @@ static void alc_init(void) ret = almtx_init(&ListLock, almtx_recursive); assert(ret == althrd_success); - - ThunkInit(); } static void alc_initconfig(void) @@ -1237,7 +1234,6 @@ static void alc_deinit_safe(void) FreeHrtfs(); FreeALConfig(); - ThunkExit(); almtx_destroy(&ListLock); altss_delete(LocalContext); diff --git a/CMakeLists.txt b/CMakeLists.txt index b5c65c55..5d665e72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -707,7 +707,6 @@ SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c OpenAL32/alListener.c OpenAL32/alSource.c OpenAL32/alState.c - OpenAL32/alThunk.c OpenAL32/event.c OpenAL32/sample_cvt.c ) diff --git a/OpenAL32/Include/alThunk.h b/OpenAL32/Include/alThunk.h deleted file mode 100644 index adc77dec..00000000 --- a/OpenAL32/Include/alThunk.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef ALTHUNK_H -#define ALTHUNK_H - -#include "alMain.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void ThunkInit(void); -void ThunkExit(void); -ALenum NewThunkEntry(ALuint *index); -void FreeThunkEntry(ALuint index); - -#ifdef __cplusplus -} -#endif - -#endif //ALTHUNK_H - diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 5400a914..038adbb0 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -27,7 +27,6 @@ #include "AL/alc.h" #include "alMain.h" #include "alAuxEffectSlot.h" -#include "alThunk.h" #include "alError.h" #include "alListener.h" #include "alSource.h" diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 02071abf..ed712434 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -32,7 +32,6 @@ #include "alu.h" #include "alError.h" #include "alBuffer.h" -#include "alThunk.h" #include "sample_cvt.h" diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 39f6f330..f4258e60 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -28,7 +28,6 @@ #include "AL/alc.h" #include "alMain.h" #include "alEffect.h" -#include "alThunk.h" #include "alError.h" diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index de527fea..70ae901c 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -25,7 +25,6 @@ #include "alMain.h" #include "alu.h" #include "alFilter.h" -#include "alThunk.h" #include "alError.h" diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 7c978b98..e56e252c 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -31,7 +31,6 @@ #include "alError.h" #include "alSource.h" #include "alBuffer.h" -#include "alThunk.h" #include "alAuxEffectSlot.h" #include "backends/base.h" diff --git a/OpenAL32/alThunk.c b/OpenAL32/alThunk.c deleted file mode 100644 index 0d90760a..00000000 --- a/OpenAL32/alThunk.c +++ /dev/null @@ -1,108 +0,0 @@ -/** - * 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., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include - -#include "alMain.h" -#include "alThunk.h" - -#include "almalloc.h" - - -static ATOMIC_FLAG *ThunkArray; -static ALsizei ThunkArraySize; -static RWLock ThunkLock; - -void ThunkInit(void) -{ - RWLockInit(&ThunkLock); - ThunkArraySize = 1024; - ThunkArray = al_calloc(16, ThunkArraySize * sizeof(*ThunkArray)); -} - -void ThunkExit(void) -{ - al_free(ThunkArray); - ThunkArray = NULL; - ThunkArraySize = 0; -} - -ALenum NewThunkEntry(ALuint *index) -{ - void *NewList; - ALsizei i; - - ReadLock(&ThunkLock); - for(i = 0;i < ThunkArraySize;i++) - { - if(!ATOMIC_FLAG_TEST_AND_SET(&ThunkArray[i], almemory_order_acq_rel)) - { - ReadUnlock(&ThunkLock); - *index = i+1; - return AL_NO_ERROR; - } - } - ReadUnlock(&ThunkLock); - - WriteLock(&ThunkLock); - /* Double-check that there's still no free entries, in case another - * invocation just came through and increased the size of the array. - */ - for(;i < ThunkArraySize;i++) - { - if(!ATOMIC_FLAG_TEST_AND_SET(&ThunkArray[i], almemory_order_acq_rel)) - { - WriteUnlock(&ThunkLock); - *index = i+1; - return AL_NO_ERROR; - } - } - - NewList = al_calloc(16, ThunkArraySize*2 * sizeof(*ThunkArray)); - if(!NewList) - { - WriteUnlock(&ThunkLock); - ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2); - return AL_OUT_OF_MEMORY; - } - memcpy(NewList, ThunkArray, ThunkArraySize*sizeof(*ThunkArray)); - al_free(ThunkArray); - ThunkArray = NewList; - ThunkArraySize *= 2; - - ATOMIC_FLAG_TEST_AND_SET(&ThunkArray[i], almemory_order_seq_cst); - *index = ++i; - - for(;i < ThunkArraySize;i++) - ATOMIC_FLAG_CLEAR(&ThunkArray[i], almemory_order_relaxed); - WriteUnlock(&ThunkLock); - - return AL_NO_ERROR; -} - -void FreeThunkEntry(ALuint index) -{ - ReadLock(&ThunkLock); - if(index > 0 && (ALsizei)index <= ThunkArraySize) - ATOMIC_FLAG_CLEAR(&ThunkArray[index-1], almemory_order_release); - ReadUnlock(&ThunkLock); -} -- cgit v1.2.3 From 14bdc6c2ef295dd4c7a22faab1e834def125177d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 22 Feb 2018 12:03:52 -0800 Subject: Use separate functions to add and remove active effect slots --- OpenAL32/alAuxEffectSlot.c | 139 +++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 56 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 038adbb0..d5c39051 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -38,6 +38,9 @@ extern inline void LockEffectSlotList(ALCcontext *context); extern inline void UnlockEffectSlotList(ALCcontext *context); +static void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *context); +static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *context); + static const struct { ALenum Type; ALeffectStateFactory* (*GetFactory)(void); @@ -105,7 +108,6 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo { ALCdevice *device; ALCcontext *context; - ALeffectslot **tmpslots = NULL; ALsizei cur; ALenum err; @@ -114,10 +116,10 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo if(!(n >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Generating %d effect slots", n); - tmpslots = al_malloc(DEF_ALIGN, sizeof(ALeffectslot*)*n); + if(n == 0) goto done; - device = context->Device; LockEffectSlotList(context); + device = context->Device; if(device->AuxiliaryEffectSlotMax - VECTOR_SIZE(context->EffectSlotList) < (ALuint)n) { UnlockEffectSlotList(context); @@ -162,33 +164,12 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo slot->id = (iter - VECTOR_BEGIN(context->EffectSlotList)) + 1; *iter = slot; - tmpslots[cur] = slot; effectslots[cur] = slot->id; } - if(n > 0) - { - struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); - struct ALeffectslotArray *newarray = NULL; - ALsizei newcount = curarray->count + n; - ALCdevice *device; - - newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); - newarray->count = newcount; - memcpy(newarray->slot, tmpslots, sizeof(ALeffectslot*)*n); - if(curarray) - memcpy(newarray->slot+n, curarray->slot, sizeof(ALeffectslot*)*curarray->count); - - newarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, - almemory_order_acq_rel); - device = context->Device; - while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) - althrd_yield(); - al_free(newarray); - } + AddActiveEffectSlots(effectslots, n, context); UnlockEffectSlotList(context); done: - al_free(tmpslots); ALCcontext_DecRef(context); } @@ -204,6 +185,8 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * LockEffectSlotList(context); if(!(n >= 0)) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effect slots", n); + if(n == 0) goto done; + for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) @@ -215,37 +198,7 @@ AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint * } // All effectslots are valid - if(n > 0) - { - struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); - struct ALeffectslotArray *newarray = NULL; - ALsizei newcount = curarray->count - n; - ALCdevice *device; - ALsizei j, k; - - assert(newcount >= 0); - newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); - newarray->count = newcount; - for(i = j = 0;i < newarray->count;) - { - slot = curarray->slot[j++]; - for(k = 0;k < n;k++) - { - if(slot->id == effectslots[k]) - break; - } - if(k == n) - newarray->slot[i++] = slot; - } - - newarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, - almemory_order_acq_rel); - device = context->Device; - while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) - althrd_yield(); - al_free(newarray); - } - + RemoveActiveEffectSlots(effectslots, n, context); for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) @@ -630,6 +583,80 @@ void ALeffectState_Destruct(ALeffectState *UNUSED(state)) } +static void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *context) +{ + struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, + almemory_order_acquire); + struct ALeffectslotArray *newarray = NULL; + ALsizei newcount = curarray->count + count; + ALCdevice *device = context->Device; + ALsizei i, j; + + /* Insert the new effect slots into the head of the array, followed by the + * existing ones. + */ + newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); + newarray->count = newcount; + for(i = 0;i < count;i++) + newarray->slot[i] = LookupEffectSlot(context, slotids[i]); + for(j = 0;i < newcount;) + newarray->slot[i++] = curarray->slot[j++]; + /* Remove any duplicates (first instance of each will be kept). */ + for(i = 1;i < newcount;i++) + { + for(j = i;j != 0;) + { + if(newarray->slot[i] == newarray->slot[--j]) + break; + } + if(j != 0) + { + newcount--; + for(j = i;j < newcount;j++) + newarray->slot[j] = newarray->slot[j+1]; + i--; + } + } + newarray->count = newcount; + + curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel); + while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) + althrd_yield(); + al_free(curarray); +} + +static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *context) +{ + struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, + almemory_order_acquire); + struct ALeffectslotArray *newarray = NULL; + ALsizei newcount = curarray->count - count; + ALCdevice *device = context->Device; + ALsizei i, j; + + assert(newcount >= 0); + newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); + newarray->count = newcount; + for(i = j = 0;i < newarray->count;) + { + ALeffectslot *slot = curarray->slot[j++]; + ALsizei k = count; + while(k != 0) + { + if(slot->id == slotids[--k]) + break; + } + if(k == 0) + newarray->slot[i++] = slot; + } + + curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel); + while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) + althrd_yield(); + al_free(curarray); +} + + ALenum InitEffectSlot(ALeffectslot *slot) { ALeffectStateFactory *factory; -- cgit v1.2.3 From a211c2f5e4d14678a77ab11d5d1879b2f442fe4c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Feb 2018 19:37:12 -0800 Subject: Avoid AL prefix on internal effect state factory types Also avoid using the generic V/V0 macros for them --- Alc/effects/chorus.c | 32 ++++++++++++++--------------- Alc/effects/compressor.c | 16 +++++++-------- Alc/effects/dedicated.c | 16 +++++++-------- Alc/effects/distortion.c | 16 +++++++-------- Alc/effects/echo.c | 16 +++++++-------- Alc/effects/equalizer.c | 16 +++++++-------- Alc/effects/modulator.c | 16 +++++++-------- Alc/effects/null.c | 18 ++++++++--------- Alc/effects/reverb.c | 16 +++++++-------- OpenAL32/Include/alAuxEffectSlot.h | 41 +++++++++++++++++++------------------- OpenAL32/alAuxEffectSlot.c | 38 +++++++++++++++++------------------ 11 files changed, 121 insertions(+), 120 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index 666933a8..4f8c7ce3 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -285,11 +285,11 @@ static ALvoid ALchorusState_process(ALchorusState *state, ALsizei SamplesToDo, c } -typedef struct ALchorusStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALchorusStateFactory; +typedef struct ChorusStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} ChorusStateFactory; -static ALeffectState *ALchorusStateFactory_create(ALchorusStateFactory *UNUSED(factory)) +static ALeffectState *ChorusStateFactory_create(ChorusStateFactory *UNUSED(factory)) { ALchorusState *state; @@ -299,14 +299,14 @@ static ALeffectState *ALchorusStateFactory_create(ALchorusStateFactory *UNUSED(f return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALchorusStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(ChorusStateFactory); -ALeffectStateFactory *ALchorusStateFactory_getFactory(void) +EffectStateFactory *ChorusStateFactory_getFactory(void) { - static ALchorusStateFactory ChorusFactory = { { GET_VTABLE2(ALchorusStateFactory, ALeffectStateFactory) } }; + static ChorusStateFactory ChorusFactory = { { GET_VTABLE2(ChorusStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &ChorusFactory); + return STATIC_CAST(EffectStateFactory, &ChorusFactory); } @@ -422,11 +422,11 @@ DEFINE_ALEFFECT_VTABLE(ALchorus); /* Flanger is basically a chorus with a really short delay. They can both use * the same processing functions, so piggyback flanger on the chorus functions. */ -typedef struct ALflangerStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALflangerStateFactory; +typedef struct FlangerStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} FlangerStateFactory; -ALeffectState *ALflangerStateFactory_create(ALflangerStateFactory *UNUSED(factory)) +ALeffectState *FlangerStateFactory_create(FlangerStateFactory *UNUSED(factory)) { ALchorusState *state; @@ -436,13 +436,13 @@ ALeffectState *ALflangerStateFactory_create(ALflangerStateFactory *UNUSED(factor return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALflangerStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(FlangerStateFactory); -ALeffectStateFactory *ALflangerStateFactory_getFactory(void) +EffectStateFactory *FlangerStateFactory_getFactory(void) { - static ALflangerStateFactory FlangerFactory = { { GET_VTABLE2(ALflangerStateFactory, ALeffectStateFactory) } }; + static FlangerStateFactory FlangerFactory = { { GET_VTABLE2(FlangerStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &FlangerFactory); + return STATIC_CAST(EffectStateFactory, &FlangerFactory); } diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index bb9be8b9..4ec28f9a 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -179,11 +179,11 @@ static ALvoid ALcompressorState_process(ALcompressorState *state, ALsizei Sample } -typedef struct ALcompressorStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALcompressorStateFactory; +typedef struct CompressorStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} CompressorStateFactory; -static ALeffectState *ALcompressorStateFactory_create(ALcompressorStateFactory *UNUSED(factory)) +static ALeffectState *CompressorStateFactory_create(CompressorStateFactory *UNUSED(factory)) { ALcompressorState *state; @@ -193,13 +193,13 @@ static ALeffectState *ALcompressorStateFactory_create(ALcompressorStateFactory * return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALcompressorStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(CompressorStateFactory); -ALeffectStateFactory *ALcompressorStateFactory_getFactory(void) +EffectStateFactory *CompressorStateFactory_getFactory(void) { - static ALcompressorStateFactory CompressorFactory = { { GET_VTABLE2(ALcompressorStateFactory, ALeffectStateFactory) } }; + static CompressorStateFactory CompressorFactory = { { GET_VTABLE2(CompressorStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &CompressorFactory); + return STATIC_CAST(EffectStateFactory, &CompressorFactory); } diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 70a97ea9..b9dd7db3 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -114,11 +114,11 @@ static ALvoid ALdedicatedState_process(ALdedicatedState *state, ALsizei SamplesT } -typedef struct ALdedicatedStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALdedicatedStateFactory; +typedef struct DedicatedStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} DedicatedStateFactory; -ALeffectState *ALdedicatedStateFactory_create(ALdedicatedStateFactory *UNUSED(factory)) +ALeffectState *DedicatedStateFactory_create(DedicatedStateFactory *UNUSED(factory)) { ALdedicatedState *state; @@ -128,14 +128,14 @@ ALeffectState *ALdedicatedStateFactory_create(ALdedicatedStateFactory *UNUSED(fa return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdedicatedStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(DedicatedStateFactory); -ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void) +EffectStateFactory *DedicatedStateFactory_getFactory(void) { - static ALdedicatedStateFactory DedicatedFactory = { { GET_VTABLE2(ALdedicatedStateFactory, ALeffectStateFactory) } }; + static DedicatedStateFactory DedicatedFactory = { { GET_VTABLE2(DedicatedStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &DedicatedFactory); + return STATIC_CAST(EffectStateFactory, &DedicatedFactory); } diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index 6ee89594..b112032c 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -176,11 +176,11 @@ static ALvoid ALdistortionState_process(ALdistortionState *state, ALsizei Sample } -typedef struct ALdistortionStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALdistortionStateFactory; +typedef struct DistortionStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} DistortionStateFactory; -static ALeffectState *ALdistortionStateFactory_create(ALdistortionStateFactory *UNUSED(factory)) +static ALeffectState *DistortionStateFactory_create(DistortionStateFactory *UNUSED(factory)) { ALdistortionState *state; @@ -190,14 +190,14 @@ static ALeffectState *ALdistortionStateFactory_create(ALdistortionStateFactory * return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALdistortionStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(DistortionStateFactory); -ALeffectStateFactory *ALdistortionStateFactory_getFactory(void) +EffectStateFactory *DistortionStateFactory_getFactory(void) { - static ALdistortionStateFactory DistortionFactory = { { GET_VTABLE2(ALdistortionStateFactory, ALeffectStateFactory) } }; + static DistortionStateFactory DistortionFactory = { { GET_VTABLE2(DistortionStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &DistortionFactory); + return STATIC_CAST(EffectStateFactory, &DistortionFactory); } diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index d8cbd214..34010c47 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -206,11 +206,11 @@ static ALvoid ALechoState_process(ALechoState *state, ALsizei SamplesToDo, const } -typedef struct ALechoStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALechoStateFactory; +typedef struct EchoStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} EchoStateFactory; -ALeffectState *ALechoStateFactory_create(ALechoStateFactory *UNUSED(factory)) +ALeffectState *EchoStateFactory_create(EchoStateFactory *UNUSED(factory)) { ALechoState *state; @@ -220,13 +220,13 @@ ALeffectState *ALechoStateFactory_create(ALechoStateFactory *UNUSED(factory)) return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALechoStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(EchoStateFactory); -ALeffectStateFactory *ALechoStateFactory_getFactory(void) +EffectStateFactory *EchoStateFactory_getFactory(void) { - static ALechoStateFactory EchoFactory = { { GET_VTABLE2(ALechoStateFactory, ALeffectStateFactory) } }; + static EchoStateFactory EchoFactory = { { GET_VTABLE2(EchoStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &EchoFactory); + return STATIC_CAST(EffectStateFactory, &EchoFactory); } diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index 8c2b31e2..22db5d54 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -196,11 +196,11 @@ static ALvoid ALequalizerState_process(ALequalizerState *state, ALsizei SamplesT } -typedef struct ALequalizerStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALequalizerStateFactory; +typedef struct EqualizerStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} EqualizerStateFactory; -ALeffectState *ALequalizerStateFactory_create(ALequalizerStateFactory *UNUSED(factory)) +ALeffectState *EqualizerStateFactory_create(EqualizerStateFactory *UNUSED(factory)) { ALequalizerState *state; @@ -210,13 +210,13 @@ ALeffectState *ALequalizerStateFactory_create(ALequalizerStateFactory *UNUSED(fa return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALequalizerStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(EqualizerStateFactory); -ALeffectStateFactory *ALequalizerStateFactory_getFactory(void) +EffectStateFactory *EqualizerStateFactory_getFactory(void) { - static ALequalizerStateFactory EqualizerFactory = { { GET_VTABLE2(ALequalizerStateFactory, ALeffectStateFactory) } }; + static EqualizerStateFactory EqualizerFactory = { { GET_VTABLE2(EqualizerStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &EqualizerFactory); + return STATIC_CAST(EffectStateFactory, &EqualizerFactory); } diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index ed0851d6..74a0d0c5 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -186,11 +186,11 @@ static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALsizei SamplesT } -typedef struct ALmodulatorStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALmodulatorStateFactory; +typedef struct ModulatorStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} ModulatorStateFactory; -static ALeffectState *ALmodulatorStateFactory_create(ALmodulatorStateFactory *UNUSED(factory)) +static ALeffectState *ModulatorStateFactory_create(ModulatorStateFactory *UNUSED(factory)) { ALmodulatorState *state; @@ -200,13 +200,13 @@ static ALeffectState *ALmodulatorStateFactory_create(ALmodulatorStateFactory *UN return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALmodulatorStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(ModulatorStateFactory); -ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void) +EffectStateFactory *ModulatorStateFactory_getFactory(void) { - static ALmodulatorStateFactory ModulatorFactory = { { GET_VTABLE2(ALmodulatorStateFactory, ALeffectStateFactory) } }; + static ModulatorStateFactory ModulatorFactory = { { GET_VTABLE2(ModulatorStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &ModulatorFactory); + return STATIC_CAST(EffectStateFactory, &ModulatorFactory); } diff --git a/Alc/effects/null.c b/Alc/effects/null.c index f9583011..e57359e3 100644 --- a/Alc/effects/null.c +++ b/Alc/effects/null.c @@ -85,12 +85,12 @@ static void ALnullState_Delete(void *ptr) } -typedef struct ALnullStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALnullStateFactory; +typedef struct NullStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} NullStateFactory; /* Creates ALeffectState objects of the appropriate type. */ -ALeffectState *ALnullStateFactory_create(ALnullStateFactory *UNUSED(factory)) +ALeffectState *NullStateFactory_create(NullStateFactory *UNUSED(factory)) { ALnullState *state; @@ -100,13 +100,13 @@ ALeffectState *ALnullStateFactory_create(ALnullStateFactory *UNUSED(factory)) return STATIC_CAST(ALeffectState, state); } -/* Define the ALeffectStateFactory vtable for this type. */ -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALnullStateFactory); +/* Define the EffectStateFactory vtable for this type. */ +DEFINE_EFFECTSTATEFACTORY_VTABLE(NullStateFactory); -ALeffectStateFactory *ALnullStateFactory_getFactory(void) +EffectStateFactory *NullStateFactory_getFactory(void) { - static ALnullStateFactory NullFactory = { { GET_VTABLE2(ALnullStateFactory, ALeffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &NullFactory); + static NullStateFactory NullFactory = { { GET_VTABLE2(NullStateFactory, EffectStateFactory) } }; + return STATIC_CAST(EffectStateFactory, &NullFactory); } diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index f6499bb7..f9650c8b 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -1691,11 +1691,11 @@ static ALvoid ALreverbState_process(ALreverbState *State, ALsizei SamplesToDo, c } -typedef struct ALreverbStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALreverbStateFactory; +typedef struct ReverbStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} ReverbStateFactory; -static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(factory)) +static ALeffectState *ReverbStateFactory_create(ReverbStateFactory* UNUSED(factory)) { ALreverbState *state; @@ -1705,13 +1705,13 @@ static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(f return STATIC_CAST(ALeffectState, state); } -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALreverbStateFactory); +DEFINE_EFFECTSTATEFACTORY_VTABLE(ReverbStateFactory); -ALeffectStateFactory *ALreverbStateFactory_getFactory(void) +EffectStateFactory *ReverbStateFactory_getFactory(void) { - static ALreverbStateFactory ReverbFactory = { { GET_VTABLE2(ALreverbStateFactory, ALeffectStateFactory) } }; + static ReverbStateFactory ReverbFactory = { { GET_VTABLE2(ReverbStateFactory, EffectStateFactory) } }; - return STATIC_CAST(ALeffectStateFactory, &ReverbFactory); + return STATIC_CAST(EffectStateFactory, &ReverbFactory); } diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index aa3a0118..29de7a14 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -59,21 +59,22 @@ static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \ } -struct ALeffectStateFactoryVtable; +struct EeffectStateFactoryVtable; -typedef struct ALeffectStateFactory { - const struct ALeffectStateFactoryVtable *vtbl; -} ALeffectStateFactory; +typedef struct EffectStateFactory { + const struct EffectStateFactoryVtable *vtab; +} EffectStateFactory; -struct ALeffectStateFactoryVtable { - ALeffectState *(*const create)(ALeffectStateFactory *factory); +struct EffectStateFactoryVtable { + ALeffectState *(*const create)(EffectStateFactory *factory); }; +#define EffectStateFactory_create(x) ((x)->vtab->create((x))) -#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \ -DECLARE_THUNK(T, ALeffectStateFactory, ALeffectState*, create) \ +#define DEFINE_EFFECTSTATEFACTORY_VTABLE(T) \ +DECLARE_THUNK(T, EffectStateFactory, ALeffectState*, create) \ \ -static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \ - T##_ALeffectStateFactory_create, \ +static const struct EffectStateFactoryVtable T##_EffectStateFactory_vtable = { \ + T##_EffectStateFactory_create, \ } @@ -156,17 +157,17 @@ void UpdateAllEffectSlotProps(ALCcontext *context); ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); -ALeffectStateFactory *ALnullStateFactory_getFactory(void); -ALeffectStateFactory *ALreverbStateFactory_getFactory(void); -ALeffectStateFactory *ALchorusStateFactory_getFactory(void); -ALeffectStateFactory *ALcompressorStateFactory_getFactory(void); -ALeffectStateFactory *ALdistortionStateFactory_getFactory(void); -ALeffectStateFactory *ALechoStateFactory_getFactory(void); -ALeffectStateFactory *ALequalizerStateFactory_getFactory(void); -ALeffectStateFactory *ALflangerStateFactory_getFactory(void); -ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void); +EffectStateFactory *NullStateFactory_getFactory(void); +EffectStateFactory *ReverbStateFactory_getFactory(void); +EffectStateFactory *ChorusStateFactory_getFactory(void); +EffectStateFactory *CompressorStateFactory_getFactory(void); +EffectStateFactory *DistortionStateFactory_getFactory(void); +EffectStateFactory *EchoStateFactory_getFactory(void); +EffectStateFactory *EqualizerStateFactory_getFactory(void); +EffectStateFactory *FlangerStateFactory_getFactory(void); +EffectStateFactory *ModulatorStateFactory_getFactory(void); -ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void); +EffectStateFactory *DedicatedStateFactory_getFactory(void); ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index d5c39051..04edcc09 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -43,23 +43,23 @@ static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcon static const struct { ALenum Type; - ALeffectStateFactory* (*GetFactory)(void); + EffectStateFactory* (*GetFactory)(void); } FactoryList[] = { - { AL_EFFECT_NULL, ALnullStateFactory_getFactory }, - { AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory }, - { AL_EFFECT_REVERB, ALreverbStateFactory_getFactory }, - { AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory }, - { AL_EFFECT_COMPRESSOR, ALcompressorStateFactory_getFactory }, - { AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory }, - { AL_EFFECT_ECHO, ALechoStateFactory_getFactory }, - { AL_EFFECT_EQUALIZER, ALequalizerStateFactory_getFactory }, - { AL_EFFECT_FLANGER, ALflangerStateFactory_getFactory }, - { AL_EFFECT_RING_MODULATOR, ALmodulatorStateFactory_getFactory }, - { AL_EFFECT_DEDICATED_DIALOGUE, ALdedicatedStateFactory_getFactory }, - { AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, ALdedicatedStateFactory_getFactory } + { AL_EFFECT_NULL, NullStateFactory_getFactory }, + { AL_EFFECT_EAXREVERB, ReverbStateFactory_getFactory }, + { AL_EFFECT_REVERB, ReverbStateFactory_getFactory }, + { AL_EFFECT_CHORUS, ChorusStateFactory_getFactory }, + { AL_EFFECT_COMPRESSOR, CompressorStateFactory_getFactory }, + { AL_EFFECT_DISTORTION, DistortionStateFactory_getFactory }, + { AL_EFFECT_ECHO, EchoStateFactory_getFactory }, + { AL_EFFECT_EQUALIZER, EqualizerStateFactory_getFactory }, + { AL_EFFECT_FLANGER, FlangerStateFactory_getFactory }, + { AL_EFFECT_RING_MODULATOR, ModulatorStateFactory_getFactory }, + { AL_EFFECT_DEDICATED_DIALOGUE, DedicatedStateFactory_getFactory }, + { AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, DedicatedStateFactory_getFactory } }; -static inline ALeffectStateFactory *getFactoryByType(ALenum type) +static inline EffectStateFactory *getFactoryByType(ALenum type) { size_t i; for(i = 0;i < COUNTOF(FactoryList);i++) @@ -498,7 +498,7 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect if(newtype != EffectSlot->Effect.Type) { - ALeffectStateFactory *factory; + EffectStateFactory *factory; factory = getFactoryByType(newtype); if(!factory) @@ -506,7 +506,7 @@ ALenum InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect ERR("Failed to find factory for effect type 0x%04x\n", newtype); return AL_INVALID_ENUM; } - State = V0(factory,create)(); + State = EffectStateFactory_create(factory); if(!State) return AL_OUT_OF_MEMORY; START_MIXER_MODE(); @@ -659,13 +659,13 @@ static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcon ALenum InitEffectSlot(ALeffectslot *slot) { - ALeffectStateFactory *factory; + EffectStateFactory *factory; slot->Effect.Type = AL_EFFECT_NULL; factory = getFactoryByType(AL_EFFECT_NULL); - if(!(slot->Effect.State=V0(factory,create)())) - return AL_OUT_OF_MEMORY; + slot->Effect.State = EffectStateFactory_create(factory); + if(!slot->Effect.State) return AL_OUT_OF_MEMORY; slot->Gain = 1.0; slot->AuxSendAuto = AL_TRUE; -- cgit v1.2.3 From 4e6c758daf1849741712eaf451f392264fd49244 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 3 Mar 2018 13:42:37 -0800 Subject: Use a plain mutex for the property lock --- Alc/ALc.c | 12 ++++---- OpenAL32/Include/alMain.h | 3 +- OpenAL32/alAuxEffectSlot.c | 8 +++--- OpenAL32/alListener.c | 48 +++++++++++++++---------------- OpenAL32/alSource.c | 72 ++++++++++++++++------------------------------ OpenAL32/alState.c | 24 ++++++++-------- 6 files changed, 72 insertions(+), 95 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 3fd3ab8f..ab21c356 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1629,7 +1629,7 @@ void ALCcontext_DeferUpdates(ALCcontext *context) */ void ALCcontext_ProcessUpdates(ALCcontext *context) { - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(ATOMIC_EXCHANGE_SEQ(&context->DeferUpdates, AL_FALSE)) { /* Tell the mixer to stop applying updates, then wait for any active @@ -1651,7 +1651,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) */ ATOMIC_STORE_SEQ(&context->HoldUpdates, AL_FALSE); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); } @@ -2244,7 +2244,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) UpdateEffectSlotProps(slot, context); } - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); almtx_lock(&context->EffectSlotLock); for(pos = 0;pos < (ALsizei)VECTOR_SIZE(context->EffectSlotList);pos++) { @@ -2342,7 +2342,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ATOMIC_FLAG_TEST_AND_SET(&context->Listener->PropsClean, almemory_order_release); UpdateListenerProps(context); UpdateAllSourceProps(context); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); context = ATOMIC_LOAD(&context->next, almemory_order_relaxed); } @@ -2581,7 +2581,7 @@ static ALvoid InitContext(ALCcontext *Context) InitRef(&Context->UpdateCount, 0); ATOMIC_INIT(&Context->HoldUpdates, AL_FALSE); Context->GainBoost = 1.0f; - RWLockInit(&Context->PropLock); + almtx_init(&Context->PropLock, almtx_plain); ATOMIC_INIT(&Context->LastError, AL_NO_ERROR); VECTOR_INIT(Context->SourceList); Context->NumSources = 0; @@ -2763,6 +2763,8 @@ static void FreeContext(ALCcontext *context) ll_ringbuffer_free(context->AsyncEvents); context->AsyncEvents = NULL; + almtx_destroy(&context->PropLock); + ALCdevice_DecRef(context->Device); context->Device = NULL; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index b21b76a3..6d6d661f 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -26,7 +26,6 @@ #include "static_assert.h" #include "align.h" #include "atomic.h" -#include "uintmap.h" #include "vector.h" #include "alstring.h" #include "almalloc.h" @@ -651,7 +650,7 @@ struct ALCcontext_struct { ATOMIC_FLAG PropsClean; ATOMIC(ALenum) DeferUpdates; - RWLock PropLock; + almtx_t PropLock; /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit * indicates if updates are currently happening). diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 04edcc09..6eb6187b 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -244,7 +244,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); LockEffectSlotList(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); @@ -282,7 +282,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param done: UnlockEffectSlotList(context); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -324,7 +324,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); LockEffectSlotList(context); if((slot=LookupEffectSlot(context, effectslot)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslot); @@ -344,7 +344,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param done: UnlockEffectSlotList(context); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 290ae8ca..f1ac3ff4 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -43,7 +43,7 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) if(!context) return; listener = context->Listener; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); switch(param) { case AL_GAIN: @@ -68,7 +68,7 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) } done: - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -82,7 +82,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val if(!context) return; listener = context->Listener; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); switch(param) { case AL_POSITION: @@ -108,7 +108,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val } done: - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -138,7 +138,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) if(!context) return; listener = context->Listener; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!values) SETERR_GOTO(context, AL_INVALID_VALUE, done, "NULL pointer"); switch(param) { @@ -161,7 +161,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) } done: - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -173,13 +173,13 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); switch(param) { default: alSetError(context, AL_INVALID_ENUM, "Invalid listener integer property"); } - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -200,13 +200,13 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); switch(param) { default: alSetError(context, AL_INVALID_ENUM, "Invalid listener 3-integer property"); } - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -241,7 +241,7 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!values) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -249,7 +249,7 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) default: alSetError(context, AL_INVALID_ENUM, "Invalid listener integer-vector property"); } - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -262,7 +262,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) context = GetContextRef(); if(!context) return; - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!value) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -278,7 +278,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) default: alSetError(context, AL_INVALID_ENUM, "Invalid listener float property"); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -291,7 +291,7 @@ AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat context = GetContextRef(); if(!context) return; - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!value1 || !value2 || !value3) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -311,7 +311,7 @@ AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat default: alSetError(context, AL_INVALID_ENUM, "Invalid listener 3-float property"); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -337,7 +337,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) context = GetContextRef(); if(!context) return; - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!values) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -355,7 +355,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) default: alSetError(context, AL_INVALID_ENUM, "Invalid listener float-vector property"); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -368,7 +368,7 @@ AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) context = GetContextRef(); if(!context) return; - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!value) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -376,7 +376,7 @@ AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) default: alSetError(context, AL_INVALID_ENUM, "Invalid listener integer property"); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -389,7 +389,7 @@ AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *valu context = GetContextRef(); if(!context) return; - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!value1 || !value2 || !value3) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -409,7 +409,7 @@ AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *valu default: alSetError(context, AL_INVALID_ENUM, "Invalid listener 3-integer property"); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -430,7 +430,7 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) context = GetContextRef(); if(!context) return; - ReadLock(&context->PropLock); + almtx_lock(&context->PropLock); if(!values) alSetError(context, AL_INVALID_VALUE, "NULL pointer"); else switch(param) @@ -448,7 +448,7 @@ AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) default: alSetError(context, AL_INVALID_ENUM, "Invalid listener integer-vector property"); } - ReadUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index b3cf9e3e..02511382 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -1757,7 +1757,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1766,7 +1766,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) else SetSourcefv(Source, Context, param, &value); UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1779,7 +1779,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1791,7 +1791,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 SetSourcefv(Source, Context, param, fvals); } UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1804,7 +1804,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1815,7 +1815,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat else SetSourcefv(Source, Context, param, values); UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1829,7 +1829,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1841,7 +1841,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va SetSourcefv(Source, Context, param, &fval); } UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1854,7 +1854,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1866,7 +1866,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v SetSourcefv(Source, Context, param, fvals); } UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1880,7 +1880,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1898,7 +1898,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo SetSourcefv(Source, Context, param, fvals); } UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1912,7 +1912,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1921,7 +1921,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) else SetSourceiv(Source, Context, param, &value); UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1934,7 +1934,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1946,7 +1946,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL SetSourceiv(Source, Context, param, ivals); } UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1959,7 +1959,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1970,7 +1970,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val else SetSourceiv(Source, Context, param, values); UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1984,7 +1984,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -1993,7 +1993,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO else SetSourcei64v(Source, Context, param, &value); UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2006,7 +2006,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2018,7 +2018,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF SetSourcei64v(Source, Context, param, i64vals); } UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2031,7 +2031,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin Context = GetContextRef(); if(!Context) return; - WriteLock(&Context->PropLock); + almtx_lock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2042,7 +2042,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin else SetSourcei64v(Source, Context, param, values); UnlockSourceList(Context); - WriteUnlock(&Context->PropLock); + almtx_unlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2056,7 +2056,6 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2071,7 +2070,6 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val *value = (ALfloat)dval; } UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2085,7 +2083,6 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2104,7 +2101,6 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va } } UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2119,7 +2115,6 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2138,7 +2133,6 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va } } UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2152,7 +2146,6 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2163,7 +2156,6 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * else GetSourcedv(Source, Context, param, value); UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2176,7 +2168,6 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2195,7 +2186,6 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble } } UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2208,7 +2198,6 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2219,7 +2208,6 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble else GetSourcedv(Source, Context, param, values); UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2233,7 +2221,6 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2244,7 +2231,6 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value else GetSourceiv(Source, Context, param, value); UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2258,7 +2244,6 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2277,7 +2262,6 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 } } UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2291,7 +2275,6 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2302,7 +2285,6 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values else GetSourceiv(Source, Context, param, values); UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2316,7 +2298,6 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2327,7 +2308,6 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S else GetSourcei64v(Source, Context, param, value); UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2340,7 +2320,6 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2359,7 +2338,6 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 } } UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2372,7 +2350,6 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; - ReadLock(&Context->PropLock); LockSourceList(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME, "Invalid source ID %u", source); @@ -2383,7 +2360,6 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 else GetSourcei64v(Source, Context, param, values); UnlockSourceList(Context); - ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 8448e548..460c93e0 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -79,7 +79,7 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); switch(capability) { case AL_SOURCE_DISTANCE_MODEL: @@ -90,7 +90,7 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) default: alSetError(context, AL_INVALID_VALUE, "Invalid enable property 0x%04x", capability); } - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -102,7 +102,7 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) context = GetContextRef(); if(!context) return; - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); switch(capability) { case AL_SOURCE_DISTANCE_MODEL: @@ -113,7 +113,7 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) default: alSetError(context, AL_INVALID_VALUE, "Invalid disable property 0x%04x", capability); } - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); ALCcontext_DecRef(context); } @@ -700,10 +700,10 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) alSetError(context, AL_INVALID_VALUE, "Doppler factor %f out of range", value); else { - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); context->DopplerFactor = value; DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); } ALCcontext_DecRef(context); @@ -734,10 +734,10 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) alSetError(context, AL_INVALID_VALUE, "Doppler velocity %f out of range", value); else { - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); context->DopplerVelocity = value; DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); } ALCcontext_DecRef(context); @@ -754,10 +754,10 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) alSetError(context, AL_INVALID_VALUE, "Speed of sound %f out of range", value); else { - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); context->SpeedOfSound = value; DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); } ALCcontext_DecRef(context); @@ -777,11 +777,11 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) alSetError(context, AL_INVALID_VALUE, "Distance model 0x%04x out of range", value); else { - WriteLock(&context->PropLock); + almtx_lock(&context->PropLock); context->DistanceModel = value; if(!context->SourceDistanceModel) DO_UPDATEPROPS(); - WriteUnlock(&context->PropLock); + almtx_unlock(&context->PropLock); } ALCcontext_DecRef(context); -- cgit v1.2.3 From 19281868dce20d47344bd059b5f3c4af5264baaa Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 4 Mar 2018 14:00:28 -0800 Subject: Properly limit the max number of effect slots to 2^31 - 1 --- Alc/ALc.c | 2 ++ OpenAL32/alAuxEffectSlot.c | 10 +--------- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index c72a1833..554a4951 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -4139,6 +4139,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax); if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64; + else device->AuxiliaryEffectSlotMax = minu(device->AuxiliaryEffectSlotMax, INT_MAX); if(ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends)) device->NumAuxSends = clampi( @@ -4487,6 +4488,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax); if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64; + else device->AuxiliaryEffectSlotMax = minu(device->AuxiliaryEffectSlotMax, INT_MAX); if(ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends)) device->NumAuxSends = clampi( diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 6eb6187b..9ccfaa36 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -109,7 +109,6 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo ALCdevice *device; ALCcontext *context; ALsizei cur; - ALenum err; context = GetContextRef(); if(!context) return; @@ -131,6 +130,7 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList); ALeffectslotPtr *end = VECTOR_END(context->EffectSlotList); ALeffectslot *slot = NULL; + ALenum err = AL_OUT_OF_MEMORY; for(;iter != end;iter++) { @@ -139,18 +139,10 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo } if(iter == end) { - if(VECTOR_SIZE(context->EffectSlotList) >= INT_MAX) - { - UnlockEffectSlotList(context); - - alDeleteAuxiliaryEffectSlots(cur, effectslots); - SETERR_GOTO(context, err, done, "Too many effect slot objects"); - } VECTOR_PUSH_BACK(context->EffectSlotList, NULL); iter = &VECTOR_BACK(context->EffectSlotList); } slot = al_calloc(16, sizeof(ALeffectslot)); - err = AL_OUT_OF_MEMORY; if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) { al_free(slot); -- cgit v1.2.3 From 9bd1678299433a1f569a0d7680a25fbf4de83450 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 4 Mar 2018 15:11:17 -0800 Subject: Fix adding to and removing from the active effect slots It wasn't properly removing all duplicates on insertion, and didn't remove the first effect slot when removing them. --- OpenAL32/alAuxEffectSlot.c | 56 +++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 9ccfaa36..d4e6bf75 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -598,18 +598,29 @@ static void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontex { for(j = i;j != 0;) { - if(newarray->slot[i] == newarray->slot[--j]) + if(UNLIKELY(newarray->slot[i] == newarray->slot[--j])) + { + newcount--; + for(j = i;j < newcount;j++) + newarray->slot[j] = newarray->slot[j+1]; + i--; break; - } - if(j != 0) - { - newcount--; - for(j = i;j < newcount;j++) - newarray->slot[j] = newarray->slot[j+1]; - i--; + } } } - newarray->count = newcount; + + /* Reallocate newarray if the new size ended up smaller from duplicate + * removal. + */ + if(UNLIKELY(newcount < newarray->count)) + { + struct ALeffectslotArray *tmpnewarray = al_calloc(DEF_ALIGN, + FAM_SIZE(struct ALeffectslotArray, slot, newcount)); + memcpy(tmpnewarray, newarray, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); + al_free(newarray); + newarray = tmpnewarray; + newarray->count = newcount; + } curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel); while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) @@ -622,26 +633,29 @@ static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcon struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots, almemory_order_acquire); struct ALeffectslotArray *newarray = NULL; - ALsizei newcount = curarray->count - count; ALCdevice *device = context->Device; ALsizei i, j; - assert(newcount >= 0); - newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount)); - newarray->count = newcount; - for(i = j = 0;i < newarray->count;) + /* Don't shrink the allocated array size since we don't know how many (if + * any) of the effect slots to remove are in the array. + */ + newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, curarray->count)); + newarray->count = 0; + for(i = 0;i < curarray->count;i++) { - ALeffectslot *slot = curarray->slot[j++]; - ALsizei k = count; - while(k != 0) + /* Insert this slot into the new array only if it's not one to remove. */ + ALeffectslot *slot = curarray->slot[i]; + for(j = count;j != 0;) { - if(slot->id == slotids[--k]) - break; + if(slot->id == slotids[--j]) + goto skip_ins; } - if(k == 0) - newarray->slot[i++] = slot; + newarray->slot[newarray->count++] = slot; + skip_ins: ; } + /* TODO: Could reallocate newarray now that we know it's needed size. */ + curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel); while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) althrd_yield(); -- cgit v1.2.3 From 8eb7a94e1c07a8b3d74f84886c493d1a7dada7de Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 11 Mar 2018 22:40:08 -0700 Subject: Apply a distance decay on the source send for the reverb's DecayLFRatio --- Alc/ALu.c | 12 ++++++++++-- OpenAL32/Include/alAuxEffectSlot.h | 1 + OpenAL32/alAuxEffectSlot.c | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index 12708cc5..1aa35cb7 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -457,6 +457,7 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f { slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; slot->Params.DecayTime = props->Props.Reverb.DecayTime; + slot->Params.DecayLFRatio = props->Props.Reverb.DecayLFRatio; slot->Params.DecayHFRatio = props->Props.Reverb.DecayHFRatio; slot->Params.DecayHFLimit = props->Props.Reverb.DecayHFLimit; slot->Params.AirAbsorptionGainHF = props->Props.Reverb.AirAbsorptionGainHF; @@ -465,6 +466,7 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f { slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; + slot->Params.DecayLFRatio = 0.0f; slot->Params.DecayHFRatio = 0.0f; slot->Params.DecayHFLimit = AL_FALSE; slot->Params.AirAbsorptionGainHF = 1.0f; @@ -1186,6 +1188,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop ALeffectslot *SendSlots[MAX_SENDS]; ALfloat RoomRolloff[MAX_SENDS]; ALfloat DecayDistance[MAX_SENDS]; + ALfloat DecayLFDistance[MAX_SENDS]; ALfloat DecayHFDistance[MAX_SENDS]; ALfloat DryGain, DryGainHF, DryGainLF; ALfloat WetGain[MAX_SENDS]; @@ -1210,6 +1213,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop SendSlots[i] = NULL; RoomRolloff[i] = 0.0f; DecayDistance[i] = 0.0f; + DecayLFDistance[i] = 0.0f; DecayHFDistance[i] = 0.0f; } else if(SendSlots[i]->Params.AuxSendAuto) @@ -1220,6 +1224,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop */ DecayDistance[i] = SendSlots[i]->Params.DecayTime * Listener->Params.ReverbSpeedOfSound; + DecayLFDistance[i] = DecayDistance[i] * SendSlots[i]->Params.DecayLFRatio; DecayHFDistance[i] = DecayDistance[i] * SendSlots[i]->Params.DecayHFRatio; if(SendSlots[i]->Params.DecayHFLimit) { @@ -1242,6 +1247,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop * effect slot is the same as the dry path, sans filter effects */ RoomRolloff[i] = props->RolloffFactor; DecayDistance[i] = 0.0f; + DecayLFDistance[i] = 0.0f; DecayHFDistance[i] = 0.0f; } @@ -1386,7 +1392,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop */ for(i = 0;i < NumSends;i++) { - ALfloat gain; + ALfloat gain, gainhf, gainlf; if(!(DecayDistance[i] > 0.0f)) continue; @@ -1398,8 +1404,10 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop */ if(gain > 0.0f) { - ALfloat gainhf = powf(REVERB_DECAY_GAIN, meters_base/DecayHFDistance[i]); + gainhf = powf(REVERB_DECAY_GAIN, meters_base/DecayHFDistance[i]); WetGainHF[i] *= minf(gainhf / gain, 1.0f); + gainlf = powf(REVERB_DECAY_GAIN, meters_base/DecayLFDistance[i]); + WetGainLF[i] *= minf(gainlf / gain, 1.0f); } } } diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 36f09782..61c72153 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -127,6 +127,7 @@ typedef struct ALeffectslot { ALfloat RoomRolloff; /* Added to the source's room rolloff, not multiplied. */ ALfloat DecayTime; + ALfloat DecayLFRatio; ALfloat DecayHFRatio; ALboolean DecayHFLimit; ALfloat AirAbsorptionGainHF; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index d4e6bf75..301244a0 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -686,6 +686,7 @@ ALenum InitEffectSlot(ALeffectslot *slot) slot->Params.EffectState = slot->Effect.State; slot->Params.RoomRolloff = 0.0f; slot->Params.DecayTime = 0.0f; + slot->Params.DecayLFRatio = 0.0f; slot->Params.DecayHFRatio = 0.0f; slot->Params.DecayHFLimit = AL_FALSE; slot->Params.AirAbsorptionGainHF = 1.0f; -- cgit v1.2.3 From 6fd23f09842b81788298e1840b8626252fdf5e18 Mon Sep 17 00:00:00 2001 From: Raulshc <33253777+Raulshc@users.noreply.github.com> Date: Sun, 18 Mar 2018 17:47:17 +0100 Subject: EFX:Pitch Shifter implementation Add pitch shifter effect using standard phase vocoder, based on work of Stephan Bernsee. Only mono signal processing by now. --- Alc/ALc.c | 5 +- Alc/effects/pshifter.c | 493 +++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 1 + OpenAL32/Include/alAuxEffectSlot.h | 1 + OpenAL32/Include/alEffect.h | 9 +- OpenAL32/alAuxEffectSlot.c | 1 + OpenAL32/alEffect.c | 6 + 7 files changed, 514 insertions(+), 2 deletions(-) create mode 100644 Alc/effects/pshifter.c (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index eee17768..8cfc7d25 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -547,10 +547,10 @@ static const struct { DECL(AL_EFFECT_DISTORTION), DECL(AL_EFFECT_ECHO), DECL(AL_EFFECT_FLANGER), + DECL(AL_EFFECT_PITCH_SHIFTER), #if 0 DECL(AL_EFFECT_FREQUENCY_SHIFTER), DECL(AL_EFFECT_VOCAL_MORPHER), - DECL(AL_EFFECT_PITCH_SHIFTER), #endif DECL(AL_EFFECT_RING_MODULATOR), #if 0 @@ -634,6 +634,9 @@ static const struct { DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF), DECL(AL_RING_MODULATOR_WAVEFORM), + DECL(AL_PITCH_SHIFTER_COARSE_TUNE), + DECL(AL_PITCH_SHIFTER_FINE_TUNE), + DECL(AL_COMPRESSOR_ONOFF), DECL(AL_EQUALIZER_LOW_GAIN), diff --git a/Alc/effects/pshifter.c b/Alc/effects/pshifter.c new file mode 100644 index 00000000..1a2ddef7 --- /dev/null +++ b/Alc/effects/pshifter.c @@ -0,0 +1,493 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2018 by Raul Herraiz. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 ALcomplex{ + + ALfloat Real; + ALfloat Imag; + +}ALcomplex; + +typedef struct ALphasor{ + + ALfloat Amplitude; + ALfloat Phase; + +}ALphasor; + +typedef struct ALFrequencyDomain{ + + ALfloat Amplitude; + ALfloat Frequency; + +}ALfrequencyDomain; + +typedef struct ALpshifterState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect gains for each channel */ + ALfloat Gain[MAX_OUTPUT_CHANNELS]; + + /* Effect parameters */ + ALsizei count; + ALsizei STFT_size; + ALsizei step; + ALsizei FIFOLatency; + ALsizei oversamp; + ALfloat PitchShift; + ALfloat Frequency; + + /*Effects buffers*/ + ALfloat InFIFO[BUFFERSIZE]; + ALfloat OutFIFO[BUFFERSIZE]; + ALfloat LastPhase[(BUFFERSIZE>>1) +1]; + ALfloat SumPhase[(BUFFERSIZE>>1) +1]; + ALfloat OutputAccum[BUFFERSIZE<<1]; + ALfloat window[BUFFERSIZE]; + + ALcomplex FFTbuffer[BUFFERSIZE]; + + ALfrequencyDomain Analysis_buffer[BUFFERSIZE]; + ALfrequencyDomain Syntesis_buffer[BUFFERSIZE]; + + +} ALpshifterState; + +static inline ALphasor rect2polar( ALcomplex number ); +static inline ALcomplex polar2rect( ALphasor number ); +static inline ALvoid FFT(ALcomplex *FFTBuffer, ALsizei FFTSize, ALint Sign); + +static ALvoid ALpshifterState_Destruct(ALpshifterState *state); +static ALboolean ALpshifterState_deviceUpdate(ALpshifterState *state, ALCdevice *device); +static ALvoid ALpshifterState_update(ALpshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props); +static ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALpshifterState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALpshifterState); + +static void ALpshifterState_Construct(ALpshifterState *state) +{ + ALsizei i; + + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALpshifterState, ALeffectState, state); + + /*Initializing parameters and set to zero the buffers */ + state->STFT_size = BUFFERSIZE>>1; + state->oversamp = 1<<2; + + state->step = state->STFT_size / state->oversamp ; + state->FIFOLatency = state->step * ( state->oversamp-1 ); + state->count = state->FIFOLatency; + + memset(state->InFIFO, 0, BUFFERSIZE*sizeof(ALfloat)); + memset(state->OutFIFO, 0, BUFFERSIZE*sizeof(ALfloat)); + memset(state->FFTbuffer, 0, BUFFERSIZE*sizeof(ALcomplex)); + memset(state->LastPhase, 0, ((BUFFERSIZE>>1) +1)*sizeof(ALfloat)); + memset(state->SumPhase, 0, ((BUFFERSIZE>>1) +1)*sizeof(ALfloat)); + memset(state->OutputAccum, 0, (BUFFERSIZE<<1)*sizeof(ALfloat)); + memset(state->Analysis_buffer, 0, BUFFERSIZE*sizeof(ALfrequencyDomain)); + + /* Create lockup table of the Hann window for the desired size, i.e. STFT_size */ + for ( i = 0; i < state->STFT_size>>1 ; i++ ) + { + state->window[i] = state->window[state->STFT_size-(i+1)] \ + = 0.5f * ( 1 - cosf(F_TAU*(ALfloat)i/(ALfloat)(state->STFT_size-1))); + } +} + +static ALvoid ALpshifterState_Destruct(ALpshifterState *state) +{ + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); +} + +static ALboolean ALpshifterState_deviceUpdate(ALpshifterState *UNUSED(state), ALCdevice *UNUSED(device)) +{ + return AL_TRUE; +} + +static ALvoid ALpshifterState_update(ALpshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) +{ + const ALCdevice *device = context->Device; + ALfloat coeffs[MAX_AMBI_COEFFS]; + const ALfloat adjust = 0.707945784384f; /*-3dB adjust*/ + + state->Frequency = (ALfloat)device->Frequency; + state->PitchShift = powf(2.0f,((ALfloat)props->Pshifter.CoarseTune + props->Pshifter.FineTune/100.0f)/12.0f); + + CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs); + ComputeDryPanGains(&device->Dry, coeffs, slot->Params.Gain * adjust, state->Gain); +} + +static ALvoid ALpshifterState_process(ALpshifterState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels) +{ + /*Pitch shifter engine based on the work of Stephan Bernsee. + * http://blogs.zynaptiq.com/bernsee/pitch-shifting-using-the-ft/ **/ + + ALsizei i, j, k, STFT_half_size; + ALfloat freq_bin, expected, tmp; + ALfloat bufferOut[BUFFERSIZE]; + ALphasor component; + + + STFT_half_size = state->STFT_size >> 1; + freq_bin = state->Frequency / (ALfloat)state->STFT_size; + expected = F_TAU / (ALfloat)state->oversamp; + + + for (i = 0; i < SamplesToDo; i++) + { + /* Fill FIFO buffer with samples data */ + state->InFIFO[state->count] = SamplesIn[0][i]; + bufferOut[i] = state->OutFIFO[state->count - state->FIFOLatency]; + + state->count++; + + /* Check whether FIFO buffer is filled */ + if ( state->count >= state->STFT_size ) + { + state->count = state->FIFOLatency; + + /* Real signal windowing and store in FFTbuffer */ + for ( k = 0; k < state->STFT_size; k++ ) + { + state->FFTbuffer[k].Real = state->InFIFO[k] * state->window[k]; + state->FFTbuffer[k].Imag = 0.0f; + } + + /* ANALYSIS */ + /* Apply FFT to FFTbuffer data */ + FFT( state->FFTbuffer, state->STFT_size, -1 ); + + /* Analyze the obtained data. Since the real FFT is symmetric, only STFT_half_size+1 samples are needed */ + for ( k = 0; k <= STFT_half_size; k++ ) + { + /* Compute amplitude and phase */ + component = rect2polar( state->FFTbuffer[k] ); + + /* Compute phase difference and subtract expected phase difference */ + tmp = ( component.Phase - state->LastPhase[k] ) - (ALfloat)k*expected; + + /* Map delta phase into +/- Pi interval */ + tmp -= F_PI*(ALfloat)( fastf2i(tmp/F_PI) + fastf2i(tmp/F_PI) % 2 ); + + /* Get deviation from bin frequency from the +/- Pi interval */ + tmp /= expected; + + /* Compute the k-th partials' true frequency, twice the amplitude for maintain the gain + (because half of bins are used) and store amplitude and true frequency in analysis buffer */ + state->Analysis_buffer[k].Amplitude = 2.0f * component.Amplitude; + state->Analysis_buffer[k].Frequency = ((ALfloat)k + tmp) * freq_bin; + + /* Store actual phase[k] for the calculations in the next frame*/ + state->LastPhase[k] = component.Phase; + + } + + /* PROCESSING */ + /* pitch shifting */ + memset(state->Syntesis_buffer, 0, state->STFT_size*sizeof(ALfrequencyDomain)); + + for (k = 0; k <= STFT_half_size; k++) + { + j = fastf2i( (ALfloat)k*state->PitchShift ); + + if ( j <= STFT_half_size ) + { + state->Syntesis_buffer[j].Amplitude += state->Analysis_buffer[k].Amplitude; + state->Syntesis_buffer[j].Frequency = state->Analysis_buffer[k].Frequency * state->PitchShift; + } + } + + /* SYNTHESIS */ + /* Synthesis the processing data */ + for ( k = 0; k <= STFT_half_size; k++ ) + { + /* Compute bin deviation from scaled freq */ + tmp = state->Syntesis_buffer[k].Frequency /freq_bin - (ALfloat)k; + + /* Calculate actual delta phase and accumulate it to get bin phase */ + state->SumPhase[k] += ((ALfloat)k + tmp) * expected; + + component.Amplitude = state->Syntesis_buffer[k].Amplitude; + component.Phase = state->SumPhase[k]; + + /* Compute phasor component to cartesian complex number and storage it into FFTbuffer*/ + state->FFTbuffer[k] = polar2rect( component ); + } + + /* zero negative frequencies for recontruct a real signal */ + memset( &state->FFTbuffer[STFT_half_size+1], 0, (STFT_half_size-1) * sizeof(ALcomplex) ); + + /* Apply iFFT to buffer data */ + FFT( state->FFTbuffer, state->STFT_size, 1 ); + + /* Windowing and add to output */ + for( k=0; k < state->STFT_size; k++ ) + { + state->OutputAccum[k] += 2.0f * state->window[k]*state->FFTbuffer[k].Real / (STFT_half_size * state->oversamp); + } + + /* Shift accumulator, input & output FIFO */ + memmove(state->OutFIFO , state->OutputAccum , state->step * sizeof(ALfloat)); + memmove(state->OutputAccum, state->OutputAccum + state->step, state->STFT_size * sizeof(ALfloat)); + memmove(state->InFIFO , state->InFIFO + state->step, state->FIFOLatency * sizeof(ALfloat)); + + } + } + + /* Now, mix the processed sound data to the output*/ + + for (j = 0; j < NumChannels; j++ ) + { + ALfloat gain = state->Gain[j]; + + if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD)) + continue; + + for(i = 0;i < SamplesToDo;i++) + SamplesOut[j][i] += gain * bufferOut[i]; + + } + + +} + +typedef struct PshifterStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} PshifterStateFactory; + +static ALeffectState *PshifterStateFactory_create(PshifterStateFactory *UNUSED(factory)) +{ + ALpshifterState *state; + + NEW_OBJ0(state, ALpshifterState)(); + if(!state) return NULL; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_EFFECTSTATEFACTORY_VTABLE(PshifterStateFactory); + +EffectStateFactory *PshifterStateFactory_getFactory(void) +{ + static PshifterStateFactory PshifterFactory = { { GET_VTABLE2(PshifterStateFactory, EffectStateFactory) } }; + + return STATIC_CAST(EffectStateFactory, &PshifterFactory); +} + + +void ALpshifter_setParamf(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat UNUSED(val)) +{ + alSetError( context, AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param ); +} + +void ALpshifter_setParamfv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALfloat *UNUSED(vals)) +{ + alSetError( context, AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x", param ); +} + +void ALpshifter_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_PITCH_SHIFTER_COARSE_TUNE: + if(!(val >= AL_PITCH_SHIFTER_MIN_COARSE_TUNE && val <= AL_PITCH_SHIFTER_MAX_COARSE_TUNE)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Pitch shifter coarse tune out of range"); + props->Pshifter.CoarseTune = val; + break; + + case AL_PITCH_SHIFTER_FINE_TUNE: + if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Pitch shifter fine tune out of range"); + props->Pshifter.FineTune = val; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x", param); + } +} +void ALpshifter_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALpshifter_setParami(effect, context, param, vals[0]); +} + +void ALpshifter_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_PITCH_SHIFTER_COARSE_TUNE: + *val = (ALint)props->Pshifter.CoarseTune; + break; + case AL_PITCH_SHIFTER_FINE_TUNE: + *val = (ALint)props->Pshifter.FineTune; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x", param); + } +} +void ALpshifter_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALpshifter_getParami(effect, context, param, vals); +} + +void ALpshifter_getParamf(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat *UNUSED(val)) +{ + alSetError(context, AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param); +} + +void ALpshifter_getParamfv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALfloat *UNUSED(vals)) +{ + alSetError(context, AL_INVALID_ENUM, "Invalid pitch shifter float vector-property 0x%04x", param); +} + +DEFINE_ALEFFECT_VTABLE(ALpshifter); + + +/* Converts ALcomplex to ALphasor*/ +static inline ALphasor rect2polar( ALcomplex number ) +{ + ALphasor polar; + + polar.Amplitude = sqrtf ( number.Real*number.Real + number.Imag*number.Imag ); + polar.Phase = atan2f( number.Imag , number.Real ); + + return polar; +} + +/* Converts ALphasor to ALcomplex*/ +static inline ALcomplex polar2rect( ALphasor number ) +{ + ALcomplex cartesian; + + cartesian.Real = number.Amplitude * cosf( number.Phase ); + cartesian.Imag = number.Amplitude * sinf( number.Phase ); + + return cartesian; +} + +/* Addition of two complex numbers (ALcomplex format)*/ +static inline ALcomplex complex_add( ALcomplex a, ALcomplex b ) +{ + ALcomplex result; + + result.Real = ( a.Real + b.Real ); + result.Imag = ( a.Imag + b.Imag ); + + return result; +} + +/* Substraction of two complex numbers (ALcomplex format)*/ +static inline ALcomplex complex_subst( ALcomplex a, ALcomplex b ) +{ + ALcomplex result; + + result.Real = ( a.Real - b.Real ); + result.Imag = ( a.Imag - b.Imag ); + + return result; +} + +/* Multiplication of two complex numbers (ALcomplex format)*/ +static inline ALcomplex complex_mult( ALcomplex a, ALcomplex b ) +{ + ALcomplex result; + + result.Real = ( a.Real * b.Real - a.Imag * b.Imag ); + result.Imag = ( a.Imag * b.Real + a.Real * b.Imag ); + + return result; +} + +/* Iterative implementation of 2-radix FFT (In-place algorithm). Sign = -1 is FFT and 1 is + iFFT (inverse). Fills FFTBuffer[0...FFTSize-1] with the Discrete Fourier Transform (DFT) + of the time domain data stored in FFTBuffer[0...FFTSize-1]. FFTBuffer is an array of + complex numbers (ALcomplex), FFTSize MUST BE power of two.*/ + +static inline ALvoid FFT(ALcomplex *FFTBuffer, ALsizei FFTSize, ALint Sign) +{ + ALfloat arg; + ALsizei i, j, k, mask, step, step2; + ALcomplex temp, u, w; + + /*bit-reversal permutation applied to a sequence of FFTSize items*/ + for (i = 1; i < FFTSize-1; i++ ) + { + + for ( mask = 0x1, j = 0; mask < FFTSize; mask <<= 1 ) + { + if ( ( i & mask ) != 0 ) j++; + + j <<= 1; + } + + j >>= 1; + + if ( i < j ) + { + temp = FFTBuffer[i]; + FFTBuffer[i] = FFTBuffer[j]; + FFTBuffer[j] = temp; + } + } + + /* Iterative form of Danielson–Lanczos lemma */ + for ( i = 1, step = 2; i < FFTSize; i<<=1, step <<= 1 ) + { + + step2 = step >> 1; + arg = F_PI / step2; + + w.Real = cosf( arg ); + w.Imag = sinf( arg ) * Sign; + + u.Real = 1.0f; + u.Imag = 0.0f; + + for ( j = 0; j < step2; j++ ) + { + + for ( k = j; k < FFTSize; k += step ) + { + + temp = complex_mult( FFTBuffer[k+step2], u ); + FFTBuffer[k+step2] = complex_subst( FFTBuffer[k], temp ); + FFTBuffer[k] = complex_add( FFTBuffer[k], temp ); + } + + u = complex_mult(u,w); + } + } +} diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a6d8ae0..986a6c32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -726,6 +726,7 @@ SET(ALC_OBJS Alc/ALc.c Alc/effects/equalizer.c Alc/effects/modulator.c Alc/effects/null.c + Alc/effects/pshifter.c Alc/effects/reverb.c Alc/helpers.c Alc/hrtf.c diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 61c72153..bb9aef59 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -167,6 +167,7 @@ EffectStateFactory *EchoStateFactory_getFactory(void); EffectStateFactory *EqualizerStateFactory_getFactory(void); EffectStateFactory *FlangerStateFactory_getFactory(void); EffectStateFactory *ModulatorStateFactory_getFactory(void); +EffectStateFactory *PshifterStateFactory_getFactory(void); EffectStateFactory *DedicatedStateFactory_getFactory(void); diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index 95fa035e..50b64ee1 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -19,6 +19,7 @@ enum { EQUALIZER_EFFECT, FLANGER_EFFECT, MODULATOR_EFFECT, + PSHIFTER_EFFECT, DEDICATED_EFFECT, MAX_EFFECTS @@ -32,7 +33,7 @@ struct EffectList { int type; ALenum val; }; -#define EFFECTLIST_SIZE 11 +#define EFFECTLIST_SIZE 12 extern const struct EffectList EffectList[EFFECTLIST_SIZE]; @@ -66,6 +67,7 @@ extern const struct ALeffectVtable ALequalizer_vtable; extern const struct ALeffectVtable ALflanger_vtable; extern const struct ALeffectVtable ALmodulator_vtable; extern const struct ALeffectVtable ALnull_vtable; +extern const struct ALeffectVtable ALpshifter_vtable; extern const struct ALeffectVtable ALdedicated_vtable; @@ -149,6 +151,11 @@ typedef union ALeffectProps { ALint Waveform; } Modulator; + struct { + ALint CoarseTune; + ALint FineTune; + } Pshifter; + struct { ALfloat Gain; } Dedicated; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 301244a0..d04fc4a7 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -55,6 +55,7 @@ static const struct { { AL_EFFECT_EQUALIZER, EqualizerStateFactory_getFactory }, { AL_EFFECT_FLANGER, FlangerStateFactory_getFactory }, { AL_EFFECT_RING_MODULATOR, ModulatorStateFactory_getFactory }, + { AL_EFFECT_PITCH_SHIFTER, PshifterStateFactory_getFactory}, { AL_EFFECT_DEDICATED_DIALOGUE, DedicatedStateFactory_getFactory }, { AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, DedicatedStateFactory_getFactory } }; diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 6b16fc56..e7dc6ace 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -45,6 +45,7 @@ const struct EffectList EffectList[EFFECTLIST_SIZE] = { { "equalizer", EQUALIZER_EFFECT, AL_EFFECT_EQUALIZER }, { "flanger", FLANGER_EFFECT, AL_EFFECT_FLANGER }, { "modulator", MODULATOR_EFFECT, AL_EFFECT_RING_MODULATOR }, + { "pshifter", PSHIFTER_EFFECT, AL_EFFECT_PITCH_SHIFTER }, { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_DIALOGUE }, }; @@ -589,6 +590,11 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM; effect->vtab = &ALmodulator_vtable; break; + case AL_EFFECT_PITCH_SHIFTER: + effect->Props.Pshifter.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE; + effect->Props.Pshifter.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE; + effect->vtab = &ALpshifter_vtable; + break; case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT: case AL_EFFECT_DEDICATED_DIALOGUE: effect->Props.Dedicated.Gain = 1.0f; -- cgit v1.2.3 From d3a81f4f28484b246084a5ec5cac5619adcfa819 Mon Sep 17 00:00:00 2001 From: Raulshc <33253777+Raulshc@users.noreply.github.com> Date: Sun, 20 May 2018 17:23:03 +0200 Subject: EFX: Frequency Shifter implementation Add frequency shifter effect using discrete Hilbert transform. Only mono signal processing by now (LEFT_DIRECTION). --- Alc/ALc.c | 6 +- Alc/effects/fshifter.c | 323 +++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 1 + OpenAL32/Include/alAuxEffectSlot.h | 1 + OpenAL32/Include/alEffect.h | 10 +- OpenAL32/alAuxEffectSlot.c | 1 + OpenAL32/alEffect.c | 7 + 7 files changed, 347 insertions(+), 2 deletions(-) create mode 100644 Alc/effects/fshifter.c (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 597cc890..1d001a55 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -550,8 +550,8 @@ static const struct { DECL(AL_EFFECT_ECHO), DECL(AL_EFFECT_FLANGER), DECL(AL_EFFECT_PITCH_SHIFTER), -#if 0 DECL(AL_EFFECT_FREQUENCY_SHIFTER), +#if 0 DECL(AL_EFFECT_VOCAL_MORPHER), #endif DECL(AL_EFFECT_RING_MODULATOR), @@ -632,6 +632,10 @@ static const struct { DECL(AL_FLANGER_FEEDBACK), DECL(AL_FLANGER_DELAY), + DECL(AL_FREQUENCY_SHIFTER_FREQUENCY), + DECL(AL_FREQUENCY_SHIFTER_LEFT_DIRECTION), + DECL(AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION), + DECL(AL_RING_MODULATOR_FREQUENCY), DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF), DECL(AL_RING_MODULATOR_WAVEFORM), diff --git a/Alc/effects/fshifter.c b/Alc/effects/fshifter.c new file mode 100644 index 00000000..2d1b64fe --- /dev/null +++ b/Alc/effects/fshifter.c @@ -0,0 +1,323 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2018 by Raul Herraiz. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" +#include "filters/defs.h" + +#include "alcomplex.h" + +#define HIL_SIZE 1024 +#define OVERSAMP (1<<2) + +#define HIL_STEP (HIL_SIZE / OVERSAMP) +#define FIFO_LATENCY (HIL_STEP * (OVERSAMP-1)) + + +typedef struct ALfshifterState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect parameters */ + ALsizei count; + ALdouble frac_freq; + ALdouble inc; + ALdouble ld_sign; + + /*Effects buffers*/ + ALfloat InFIFO[HIL_SIZE]; + ALcomplex OutFIFO[HIL_SIZE]; + ALcomplex OutputAccum[2*HIL_SIZE]; + ALcomplex Analytic[HIL_SIZE]; + ALcomplex Outdata[BUFFERSIZE]; + + alignas(16) ALfloat BufferOut[BUFFERSIZE]; + + /* Effect gains for each output channel */ + ALfloat CurrentGains[MAX_OUTPUT_CHANNELS]; + ALfloat TargetGains[MAX_OUTPUT_CHANNELS]; + +} ALfshifterState; + +static ALvoid ALfshifterState_Destruct(ALfshifterState *state); +static ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *device); +static ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props); +static ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALfshifterState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALfshifterState); + +/* Define a Hann window, used to filter the HIL input and output. */ +alignas(16) static ALdouble HannWindow[HIL_SIZE]; + +static void InitHannWindow(void) +{ + ALsizei i; + + /* Create lookup table of the Hann window for the desired size, i.e. HIL_SIZE */ + for(i = 0;i < HIL_SIZE>>1;i++) + { + ALdouble val = sin(M_PI * (ALdouble)i / (ALdouble)(HIL_SIZE-1)); + HannWindow[i] = HannWindow[HIL_SIZE-1-i] = val * val; + } +} + +static alonce_flag HannInitOnce = AL_ONCE_FLAG_INIT; + +static void ALfshifterState_Construct(ALfshifterState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALfshifterState, ALeffectState, state); + + alcall_once(&HannInitOnce, InitHannWindow); +} + +static ALvoid ALfshifterState_Destruct(ALfshifterState *state) +{ + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); +} + +static ALboolean ALfshifterState_deviceUpdate(ALfshifterState *state, ALCdevice *device) +{ + /* (Re-)initializing parameters and clear the buffers. */ + state->count = FIFO_LATENCY; + state->frac_freq = 0.0; + state->inc = 0.0; + state->ld_sign = -1.0; + + memset(state->InFIFO , 0, HIL_SIZE*sizeof(ALfloat)); + memset(state->OutFIFO , 0, HIL_SIZE*sizeof(ALcomplex)); + memset(state->OutputAccum, 0, 2*HIL_SIZE*sizeof(ALcomplex)); + memset(state->Analytic , 0, HIL_SIZE*sizeof(ALcomplex)); + + memset(state->CurrentGains, 0, sizeof(state->CurrentGains)); + memset(state->TargetGains, 0, sizeof(state->TargetGains)); + + return AL_TRUE; +} + +static ALvoid ALfshifterState_update(ALfshifterState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) +{ + const ALCdevice *device = context->Device; + ALfloat coeffs[MAX_AMBI_COEFFS]; + + state->frac_freq = props->Fshifter.Frequency/device->Frequency; + + switch (props->Fshifter.Left_direction) + { + case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN: + state->ld_sign = -1.0; + break; + + case AL_FREQUENCY_SHIFTER_DIRECTION_UP: + state->ld_sign = 1.0; + break; + + case AL_FREQUENCY_SHIFTER_DIRECTION_OFF: + state->frac_freq = 0.0; + break; + } + + CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs); + ComputeDryPanGains(&device->Dry, coeffs, slot->Params.Gain, state->TargetGains); +} + +static ALvoid ALfshifterState_process(ALfshifterState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels) +{ + ALsizei i,k; + ALfloat *restrict BufferOut = state->BufferOut; + + for (i = 0; i < SamplesToDo; i++){ + + /* Fill FIFO buffer with samples data */ + state->InFIFO[state->count] = SamplesIn[0][i]; + state->Outdata[i] = state->OutFIFO[state->count-FIFO_LATENCY]; + + state->count++; + + /* Check whether FIFO buffer is filled */ + if (state->count >= HIL_SIZE ) + { + state->count = FIFO_LATENCY; + + /* Real signal windowing and store in Analytic buffer */ + for (k = 0; k < HIL_SIZE;k++) + { + state->Analytic[k].Real = state->InFIFO[k] * HannWindow[k]; + state->Analytic[k].Imag = 0.0f; + } + /*Processing signal by Discrete Hilbert Transform (analytical signal)*/ + hilbert(HIL_SIZE, state->Analytic); + + /* Windowing and add to output accumulator */ + for(k=0; k < HIL_SIZE; k++) + { + state->OutputAccum[k].Real += 2.0f*HannWindow[k]*state->Analytic[k].Real / OVERSAMP; + state->OutputAccum[k].Imag += 2.0f*HannWindow[k]*state->Analytic[k].Imag / OVERSAMP; + } + for (k = 0; k < HIL_STEP; k++) + { + state->OutFIFO[k] = state->OutputAccum[k]; + } + + /* shift accumulator */ + memmove(state->OutputAccum, state->OutputAccum + HIL_STEP, HIL_SIZE*sizeof(ALcomplex)); + + /* move input FIFO */ + for (k = 0; k < FIFO_LATENCY; k++) state->InFIFO[k] = state->InFIFO[k + HIL_STEP]; + } + } + /*Process frequency shifter using the analytic signal obtained*/ + for ( k = 0; k < SamplesToDo; k++, state->inc += state->frac_freq ) + { + ALdouble phase; + + if( state->inc >= 1.0 ) state->inc -= 1.0; + + phase = (2.0*M_PI*state->inc); + + BufferOut[k] = (ALfloat)(state->Outdata[k].Real*cos(phase) + + state->ld_sign*state->Outdata[k].Imag*sin(phase)); + } + + /* Now, mix the processed sound data to the output. */ + MixSamples(BufferOut, NumChannels, SamplesOut, state->CurrentGains, state->TargetGains, + maxi(SamplesToDo, 512), 0, SamplesToDo); + +} + +typedef struct FshifterStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} FshifterStateFactory; + +static ALeffectState *FshifterStateFactory_create(FshifterStateFactory *UNUSED(factory)) +{ + ALfshifterState *state; + + NEW_OBJ0(state, ALfshifterState)(); + if(!state) return NULL; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_EFFECTSTATEFACTORY_VTABLE(FshifterStateFactory); + +EffectStateFactory *FshifterStateFactory_getFactory(void) +{ + static FshifterStateFactory FshifterFactory = { { GET_VTABLE2(FshifterStateFactory, EffectStateFactory) } }; + + return STATIC_CAST(EffectStateFactory, &FshifterFactory); +} + +void ALfshifter_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FREQUENCY_SHIFTER_FREQUENCY: + if(!(val >= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY && val <= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Frequency shifter frequency out of range"); + props->Fshifter.Frequency = (ALfloat) val; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x", param); + } +} + +void ALfshifter_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALfshifter_setParamf(effect, context, param, vals[0]); +} + +void ALfshifter_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION: + if(!(val >= AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION && val <= AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Frequency shifter left direction out of range"); + props->Fshifter.Left_direction = val; + break; + + case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION: + if(!(val >= AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION && val <= AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Frequency shifter right direction out of range"); + props->Fshifter.Right_direction = val; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter integer property 0x%04x", param); + } +} +void ALfshifter_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) +{ + ALfshifter_setParami(effect, context, param, vals[0]); +} + +void ALfshifter_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION: + *val = (ALint)props->Fshifter.Left_direction; + break; + case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION: + *val = (ALint)props->Fshifter.Right_direction; + break; + default: + alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter integer property 0x%04x", param); + } +} +void ALfshifter_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) +{ + ALfshifter_getParami(effect, context, param, vals); +} + +void ALfshifter_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_FREQUENCY_SHIFTER_FREQUENCY: + *val = (ALfloat)props->Fshifter.Frequency; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid frequency shifter float property 0x%04x", param); + } + +} + +void ALfshifter_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALfshifter_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALfshifter); diff --git a/CMakeLists.txt b/CMakeLists.txt index cd3ecbed..a6024bf4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -761,6 +761,7 @@ SET(ALC_OBJS Alc/effects/distortion.c Alc/effects/echo.c Alc/effects/equalizer.c + Alc/effects/fshifter.c Alc/effects/modulator.c Alc/effects/null.c Alc/effects/pshifter.c diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index bb9aef59..c1eae443 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -166,6 +166,7 @@ EffectStateFactory *DistortionStateFactory_getFactory(void); EffectStateFactory *EchoStateFactory_getFactory(void); EffectStateFactory *EqualizerStateFactory_getFactory(void); EffectStateFactory *FlangerStateFactory_getFactory(void); +EffectStateFactory *FshifterStateFactory_getFactory(void); EffectStateFactory *ModulatorStateFactory_getFactory(void); EffectStateFactory *PshifterStateFactory_getFactory(void); diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index 50b64ee1..206c495b 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -18,6 +18,7 @@ enum { ECHO_EFFECT, EQUALIZER_EFFECT, FLANGER_EFFECT, + FSHIFTER_EFFECT, MODULATOR_EFFECT, PSHIFTER_EFFECT, DEDICATED_EFFECT, @@ -33,7 +34,7 @@ struct EffectList { int type; ALenum val; }; -#define EFFECTLIST_SIZE 12 +#define EFFECTLIST_SIZE 13 extern const struct EffectList EffectList[EFFECTLIST_SIZE]; @@ -65,6 +66,7 @@ extern const struct ALeffectVtable ALdistortion_vtable; extern const struct ALeffectVtable ALecho_vtable; extern const struct ALeffectVtable ALequalizer_vtable; extern const struct ALeffectVtable ALflanger_vtable; +extern const struct ALeffectVtable ALfshifter_vtable; extern const struct ALeffectVtable ALmodulator_vtable; extern const struct ALeffectVtable ALnull_vtable; extern const struct ALeffectVtable ALpshifter_vtable; @@ -145,6 +147,12 @@ typedef union ALeffectProps { ALfloat HighGain; } Equalizer; + struct { + ALfloat Frequency; + ALint Left_direction; + ALint Right_direction; + } Fshifter; + struct { ALfloat Frequency; ALfloat HighPassCutoff; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index d04fc4a7..6f6ef163 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -54,6 +54,7 @@ static const struct { { AL_EFFECT_ECHO, EchoStateFactory_getFactory }, { AL_EFFECT_EQUALIZER, EqualizerStateFactory_getFactory }, { AL_EFFECT_FLANGER, FlangerStateFactory_getFactory }, + { AL_EFFECT_FREQUENCY_SHIFTER, FshifterStateFactory_getFactory }, { AL_EFFECT_RING_MODULATOR, ModulatorStateFactory_getFactory }, { AL_EFFECT_PITCH_SHIFTER, PshifterStateFactory_getFactory}, { AL_EFFECT_DEDICATED_DIALOGUE, DedicatedStateFactory_getFactory }, diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index e7dc6ace..a69bf70c 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -44,6 +44,7 @@ const struct EffectList EffectList[EFFECTLIST_SIZE] = { { "echo", ECHO_EFFECT, AL_EFFECT_ECHO }, { "equalizer", EQUALIZER_EFFECT, AL_EFFECT_EQUALIZER }, { "flanger", FLANGER_EFFECT, AL_EFFECT_FLANGER }, + { "fshifter", FSHIFTER_EFFECT, AL_EFFECT_FREQUENCY_SHIFTER }, { "modulator", MODULATOR_EFFECT, AL_EFFECT_RING_MODULATOR }, { "pshifter", PSHIFTER_EFFECT, AL_EFFECT_PITCH_SHIFTER }, { "dedicated", DEDICATED_EFFECT, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, @@ -584,6 +585,12 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Chorus.Delay = AL_FLANGER_DEFAULT_DELAY; effect->vtab = &ALflanger_vtable; break; + case AL_EFFECT_FREQUENCY_SHIFTER: + effect->Props.Fshifter.Frequency = AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY; + effect->Props.Fshifter.Left_direction = AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION; + effect->Props.Fshifter.Right_direction = AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION; + effect->vtab = &ALfshifter_vtable; + break; case AL_EFFECT_RING_MODULATOR: effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; -- cgit v1.2.3 From 83dba26ea6a1bbbd3c9ba266523204014446ef09 Mon Sep 17 00:00:00 2001 From: Raulshc <33253777+Raulshc@users.noreply.github.com> Date: Sun, 22 Jul 2018 00:48:54 +0200 Subject: EFX: Autowah implementation Add autowah effect using biquad peaking filter and envelope follower --- Alc/ALc.c | 7 +- Alc/effects/autowah.c | 266 +++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 1 + OpenAL32/Include/alAuxEffectSlot.h | 1 + OpenAL32/Include/alEffect.h | 11 +- OpenAL32/alAuxEffectSlot.c | 1 + OpenAL32/alEffect.c | 8 ++ 7 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 Alc/effects/autowah.c (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALc.c b/Alc/ALc.c index 97d62812..535f9475 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -555,9 +555,7 @@ static const struct { DECL(AL_EFFECT_VOCAL_MORPHER), #endif DECL(AL_EFFECT_RING_MODULATOR), -#if 0 DECL(AL_EFFECT_AUTOWAH), -#endif DECL(AL_EFFECT_COMPRESSOR), DECL(AL_EFFECT_EQUALIZER), DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT), @@ -658,6 +656,11 @@ static const struct { DECL(AL_DEDICATED_GAIN), + DECL(AL_AUTOWAH_ATTACK_TIME), + DECL(AL_AUTOWAH_RELEASE_TIME), + DECL(AL_AUTOWAH_RESONANCE), + DECL(AL_AUTOWAH_PEAK_GAIN), + DECL(AL_NUM_RESAMPLERS_SOFT), DECL(AL_DEFAULT_RESAMPLER_SOFT), DECL(AL_SOURCE_RESAMPLER_SOFT), diff --git a/Alc/effects/autowah.c b/Alc/effects/autowah.c new file mode 100644 index 00000000..e9dbf304 --- /dev/null +++ b/Alc/effects/autowah.c @@ -0,0 +1,266 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 2018 by Raul Herraiz. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include + +#include "alMain.h" +#include "alAuxEffectSlot.h" +#include "alError.h" +#include "alu.h" +#include "filters/defs.h" + +#define MIN_FREQ 20.0f +#define MAX_FREQ 2500.0f +#define Q_FACTOR 5.0f + + +typedef struct ALautowahState { + DERIVE_FROM_TYPE(ALeffectState); + + /* Effect parameters */ + ALfloat AttackRate; + ALfloat ReleaseRate; + ALfloat ResonanceGain; + ALfloat PeakGain; + ALfloat FreqMinNorm; + ALfloat BandwidthNorm; + ALfloat env_delay; + + BiquadFilter Filter; + + /*Effects buffers*/ + alignas(16) ALfloat BufferOut[BUFFERSIZE]; + + /* Effect gains for each output channel */ + ALfloat CurrentGains[MAX_OUTPUT_CHANNELS]; + ALfloat TargetGains[MAX_OUTPUT_CHANNELS]; +} ALautowahState; + +static ALvoid ALautowahState_Destruct(ALautowahState *state); +static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *device); +static ALvoid ALautowahState_update(ALautowahState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props); +static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels); +DECLARE_DEFAULT_ALLOCATORS(ALautowahState) + +DEFINE_ALEFFECTSTATE_VTABLE(ALautowahState); + +/*Envelope follewer described on the book: Audio Effects, Theory, Implementation and Application*/ +static inline ALfloat envelope_follower(ALautowahState *state, ALfloat SampleIn) +{ + ALfloat alpha, Sample; + + Sample = state->PeakGain*fabsf(SampleIn); + alpha = (Sample > state->env_delay) ? state->AttackRate : state->ReleaseRate; + state->env_delay = alpha*state->env_delay + (1.0f-alpha)*Sample; + + return state->env_delay; +} + +static void ALautowahState_Construct(ALautowahState *state) +{ + ALeffectState_Construct(STATIC_CAST(ALeffectState, state)); + SET_VTABLE2(ALautowahState, ALeffectState, state); +} + +static ALvoid ALautowahState_Destruct(ALautowahState *state) +{ + ALeffectState_Destruct(STATIC_CAST(ALeffectState,state)); +} + +static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *UNUSED(device)) +{ + /* (Re-)initializing parameters and clear the buffers. */ + state->AttackRate = 1.0f; + state->ReleaseRate = 1.0f; + state->ResonanceGain = 10.0f; + state->PeakGain = 4.5f; + state->FreqMinNorm = 4.5e-4f; + state->BandwidthNorm = 0.05f; + state->env_delay = 0.0f; + + BiquadFilter_clear(&state->Filter); + + memset(state->CurrentGains, 0, sizeof(state->CurrentGains)); + memset(state->TargetGains, 0, sizeof(state->TargetGains)); + + return AL_TRUE; +} + +static ALvoid ALautowahState_update(ALautowahState *state, const ALCcontext *context, const ALeffectslot *slot, const ALeffectProps *props) +{ + const ALCdevice *device = context->Device; + ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat ReleaseTime; + + ReleaseTime = clampf(props->Autowah.ReleaseTime,0.001f,1.0f); + + state->AttackRate = expf(-1.0f/(props->Autowah.AttackTime*device->Frequency)); + state->ReleaseRate = expf(-1.0f/(ReleaseTime*device->Frequency)); + state->ResonanceGain = 10.0f/3.0f*log10f(props->Autowah.Resonance);/*0-20dB Resonance Peak gain*/ + state->PeakGain = 1.0f -log10f(props->Autowah.PeakGain/AL_AUTOWAH_MAX_PEAK_GAIN); + state->FreqMinNorm = MIN_FREQ/device->Frequency; + state->BandwidthNorm = (MAX_FREQ - MIN_FREQ)/device->Frequency; + + CalcAngleCoeffs(0.0f, 0.0f, 0.0f, coeffs); + ComputeDryPanGains(&device->Dry, coeffs, slot->Params.Gain, state->TargetGains); +} + +static ALvoid ALautowahState_process(ALautowahState *state, ALsizei SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALsizei NumChannels) +{ + ALfloat *restrict BufferOut = state->BufferOut; + ALsizei i; + + for(i = 0;i < SamplesToDo;i++) + { + ALfloat env_out, f0norm, temp; + + env_out = envelope_follower(state, SamplesIn[0][i]); + f0norm = state->BandwidthNorm*env_out + state->FreqMinNorm; + + BiquadFilter_setParams(&state->Filter, BiquadType_Peaking, state->ResonanceGain, + f0norm, 1.0f/Q_FACTOR); + BiquadFilter_process(&state->Filter, &temp, &SamplesIn[0][i], 1); + + BufferOut[i] = temp; + } + /* Now, mix the processed sound data to the output. */ + MixSamples(BufferOut, NumChannels, SamplesOut, state->CurrentGains, state->TargetGains, + SamplesToDo, 0, SamplesToDo); + +} + +typedef struct AutowahStateFactory { + DERIVE_FROM_TYPE(EffectStateFactory); +} AutowahStateFactory; + +static ALeffectState *AutowahStateFactory_create(AutowahStateFactory *UNUSED(factory)) +{ + ALautowahState *state; + + NEW_OBJ0(state, ALautowahState)(); + if(!state) return NULL; + + return STATIC_CAST(ALeffectState, state); +} + +DEFINE_EFFECTSTATEFACTORY_VTABLE(AutowahStateFactory); + +EffectStateFactory *AutowahStateFactory_getFactory(void) +{ + static AutowahStateFactory AutowahFactory = { { GET_VTABLE2(AutowahStateFactory, EffectStateFactory) } }; + + return STATIC_CAST(EffectStateFactory, &AutowahFactory); +} + +void ALautowah_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) +{ + ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_AUTOWAH_ATTACK_TIME: + if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Autowah attack time out of range"); + props->Autowah.AttackTime = val; + break; + + case AL_AUTOWAH_RELEASE_TIME: + if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Autowah release time out of range"); + props->Autowah.ReleaseTime = val; + break; + + case AL_AUTOWAH_RESONANCE: + if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Autowah resonance out of range"); + props->Autowah.Resonance = val; + break; + + case AL_AUTOWAH_PEAK_GAIN: + if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN)) + SETERR_RETURN(context, AL_INVALID_VALUE,,"Autowah peak gain out of range"); + props->Autowah.PeakGain = val; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param); + } +} + +void ALautowah_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) +{ + ALautowah_setParamf(effect, context, param, vals[0]); +} + +void ALautowah_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint UNUSED(val)) +{ + alSetError(context, AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param); +} + +void ALautowah_setParamiv(ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, const ALint *UNUSED(vals)) +{ + alSetError(context, AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x", param); +} + +void ALautowah_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) +{ + alSetError(context, AL_INVALID_ENUM, "Invalid autowah integer property 0x%04x", param); +} +void ALautowah_getParamiv(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum param, ALint *UNUSED(vals)) +{ + alSetError(context, AL_INVALID_ENUM, "Invalid autowah integer vector property 0x%04x", param); +} + +void ALautowah_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) +{ + + const ALeffectProps *props = &effect->Props; + switch(param) + { + case AL_AUTOWAH_ATTACK_TIME: + *val = props->Autowah.AttackTime; + break; + + case AL_AUTOWAH_RELEASE_TIME: + *val = props->Autowah.ReleaseTime; + break; + + case AL_AUTOWAH_RESONANCE: + *val = props->Autowah.Resonance; + break; + + case AL_AUTOWAH_PEAK_GAIN: + *val = props->Autowah.PeakGain; + break; + + default: + alSetError(context, AL_INVALID_ENUM, "Invalid autowah float property 0x%04x", param); + } + +} + +void ALautowah_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) +{ + ALautowah_getParamf(effect, context, param, vals); +} + +DEFINE_ALEFFECT_VTABLE(ALautowah); diff --git a/CMakeLists.txt b/CMakeLists.txt index b7de4a69..a7d13777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -779,6 +779,7 @@ SET(ALC_OBJS Alc/mastering.h Alc/ringbuffer.c Alc/ringbuffer.h + Alc/effects/autowah.c Alc/effects/chorus.c Alc/effects/compressor.c Alc/effects/dedicated.c diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index c1eae443..c4d662f1 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -160,6 +160,7 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context); EffectStateFactory *NullStateFactory_getFactory(void); EffectStateFactory *ReverbStateFactory_getFactory(void); +EffectStateFactory *AutowahStateFactory_getFactory(void); EffectStateFactory *ChorusStateFactory_getFactory(void); EffectStateFactory *CompressorStateFactory_getFactory(void); EffectStateFactory *DistortionStateFactory_getFactory(void); diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h index 4d28a708..7b849c0c 100644 --- a/OpenAL32/Include/alEffect.h +++ b/OpenAL32/Include/alEffect.h @@ -12,6 +12,7 @@ struct ALeffect; enum { EAXREVERB_EFFECT = 0, REVERB_EFFECT, + AUTOWAH_EFFECT, CHORUS_EFFECT, COMPRESSOR_EFFECT, DISTORTION_EFFECT, @@ -34,7 +35,7 @@ struct EffectList { int type; ALenum val; }; -#define EFFECTLIST_SIZE 13 +#define EFFECTLIST_SIZE 14 extern const struct EffectList EffectList[EFFECTLIST_SIZE]; @@ -60,6 +61,7 @@ const struct ALeffectVtable T##_vtable = { \ extern const struct ALeffectVtable ALeaxreverb_vtable; extern const struct ALeffectVtable ALreverb_vtable; +extern const struct ALeffectVtable ALautowah_vtable; extern const struct ALeffectVtable ALchorus_vtable; extern const struct ALeffectVtable ALcompressor_vtable; extern const struct ALeffectVtable ALdistortion_vtable; @@ -103,6 +105,13 @@ typedef union ALeffectProps { ALfloat LFReference; } Reverb; + struct { + ALfloat AttackTime; + ALfloat ReleaseTime; + ALfloat Resonance; + ALfloat PeakGain; + } Autowah; + struct { ALint Waveform; ALint Phase; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 6f6ef163..815a8d5a 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -48,6 +48,7 @@ static const struct { { AL_EFFECT_NULL, NullStateFactory_getFactory }, { AL_EFFECT_EAXREVERB, ReverbStateFactory_getFactory }, { AL_EFFECT_REVERB, ReverbStateFactory_getFactory }, + { AL_EFFECT_AUTOWAH, AutowahStateFactory_getFactory }, { AL_EFFECT_CHORUS, ChorusStateFactory_getFactory }, { AL_EFFECT_COMPRESSOR, CompressorStateFactory_getFactory }, { AL_EFFECT_DISTORTION, DistortionStateFactory_getFactory }, diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index aacddd4c..c2a78a0c 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -38,6 +38,7 @@ extern inline ALboolean IsReverbEffect(ALenum type); const struct EffectList EffectList[EFFECTLIST_SIZE] = { { "eaxreverb", EAXREVERB_EFFECT, AL_EFFECT_EAXREVERB }, { "reverb", REVERB_EFFECT, AL_EFFECT_REVERB }, + { "autowah", AUTOWAH_EFFECT, AL_EFFECT_AUTOWAH }, { "chorus", CHORUS_EFFECT, AL_EFFECT_CHORUS }, { "compressor", COMPRESSOR_EFFECT, AL_EFFECT_COMPRESSOR }, { "distortion", DISTORTION_EFFECT, AL_EFFECT_DISTORTION }, @@ -534,6 +535,13 @@ static void InitEffectParams(ALeffect *effect, ALenum type) effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; effect->vtab = &ALreverb_vtable; break; + case AL_EFFECT_AUTOWAH: + effect->Props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME; + effect->Props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME; + effect->Props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE; + effect->Props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN; + effect->vtab = &ALautowah_vtable; + break; case AL_EFFECT_CHORUS: effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM; effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE; -- cgit v1.2.3 From a6734c7a91b1e2f2ef19ba163ceb2cb14571a9dd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 14 Sep 2018 14:53:35 -0700 Subject: Check the effect slot list size only when there's no free entries The list can contain (reuable) NULL entries, so the max - current_size doesn't indicate how many can be allocated. --- OpenAL32/alAuxEffectSlot.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 815a8d5a..b293b6a5 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -122,12 +122,6 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo LockEffectSlotList(context); device = context->Device; - if(device->AuxiliaryEffectSlotMax - VECTOR_SIZE(context->EffectSlotList) < (ALuint)n) - { - UnlockEffectSlotList(context); - SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, "Exceeding %u auxiliary effect slot limit", - device->AuxiliaryEffectSlotMax); - } for(cur = 0;cur < n;cur++) { ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList); @@ -142,6 +136,13 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo } if(iter == end) { + if(device->AuxiliaryEffectSlotMax == VECTOR_SIZE(context->EffectSlotList)) + { + UnlockEffectSlotList(context); + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SETERR_GOTO(context, AL_OUT_OF_MEMORY, done, + "Exceeding %u auxiliary effect slot limit", device->AuxiliaryEffectSlotMax); + } VECTOR_PUSH_BACK(context->EffectSlotList, NULL); iter = &VECTOR_BACK(context->EffectSlotList); } -- cgit v1.2.3 From b6d0ff02c2ec52d2c12a58f2be83b4c3eaa93afe Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 21 Sep 2018 02:37:37 -0700 Subject: Use an internal event to more timely release old effect states --- Alc/ALu.c | 38 +++++++++++++++++++++++++++++++++----- OpenAL32/Include/alMain.h | 4 ++++ OpenAL32/alAuxEffectSlot.c | 3 +++ OpenAL32/event.c | 7 +++++++ 4 files changed, 47 insertions(+), 5 deletions(-) (limited to 'OpenAL32/alAuxEffectSlot.c') diff --git a/Alc/ALu.c b/Alc/ALu.c index c8c583ef..3f61338f 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -462,12 +462,40 @@ static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool f slot->Params.AirAbsorptionGainHF = 1.0f; } - /* Swap effect states. No need to play with the ref counts since they - * keep the same number of refs. - */ state = props->State; - props->State = slot->Params.EffectState; - slot->Params.EffectState = state; + + if(state == slot->Params.EffectState) + { + /* If the effect state is the same as current, we can decrement its + * count safely to remove it from the update object (it can't reach + * 0 refs since the current params also hold a reference). + */ + DecrementRef(&state->Ref); + props->State = NULL; + } + else + { + /* Otherwise, replace it and send off the old one with a release + * event. + */ + AsyncEvent evt = ASYNC_EVENT(EventType_ReleaseEffectState); + evt.u.EffectState = slot->Params.EffectState; + + slot->Params.EffectState = state; + props->State = NULL; + + if(LIKELY(ll_ringbuffer_write(context->AsyncEvents, (const char*)&evt, 1) != 0)) + alsem_post(&context->EventSem); + else + { + /* If writing the event failed, the queue was probably full. + * Store the old state in the property object where it can + * eventually be cleaned up sometime later (not ideal, but + * better than blocking or leaking). + */ + props->State = evt.u.EffectState; + } + } ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &context->FreeEffectslotProps, props); } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 3a08e8c1..3e328157 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -760,6 +760,9 @@ enum { EventType_Performance = 1<<3, EventType_Deprecated = 1<<4, EventType_Disconnected = 1<<5, + + /* Internal events. */ + EventType_ReleaseEffectState = 65536, }; typedef struct AsyncEvent { @@ -772,6 +775,7 @@ typedef struct AsyncEvent { ALuint param; ALchar msg[1008]; } user; + struct ALeffectState *EffectState; } u; } AsyncEvent; #define ASYNC_EVENT(t) { t, { 0 } } diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index b293b6a5..8141e0f6 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -753,6 +753,9 @@ void UpdateEffectSlotProps(ALeffectslot *slot, ALCcontext *context) /* If there was an unused update container, put it back in the * freelist. */ + if(props->State) + ALeffectState_DecRef(props->State); + props->State = NULL; ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &context->FreeEffectslotProps, props); } diff --git a/OpenAL32/event.c b/OpenAL32/event.c index c0bf4204..4c9c0be2 100644 --- a/OpenAL32/event.c +++ b/OpenAL32/event.c @@ -6,6 +6,7 @@ #include "AL/alext.h" #include "alMain.h" #include "alError.h" +#include "alAuxEffectSlot.h" #include "ringbuffer.h" @@ -30,6 +31,12 @@ int EventThread(void *arg) quitnow = evt.EnumType == EventType_KillThread; if(quitnow) break; + if(evt.EnumType == EventType_ReleaseEffectState) + { + ALeffectState_DecRef(evt.u.EffectState); + continue; + } + enabledevts = ATOMIC_LOAD(&context->EnabledEvts, almemory_order_acquire); if(context->EventCb && (enabledevts&evt.EnumType) == evt.EnumType) context->EventCb(evt.u.user.type, evt.u.user.id, evt.u.user.param, -- cgit v1.2.3