aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alFilter.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-24 09:40:13 -0800
committerChris Robinson <[email protected]>2018-11-24 09:40:13 -0800
commit505e535655cb12af9a0d4dc8b2cae9a0db03e34e (patch)
treec5ad63ec8bca3b17132fe856d023c0f66dce0be6 /OpenAL32/alFilter.cpp
parent48154c94d7db164b2c587c1c1cca413f782102d9 (diff)
Use RAII more with alFilter.cpp
Diffstat (limited to 'OpenAL32/alFilter.cpp')
-rw-r--r--OpenAL32/alFilter.cpp746
1 files changed, 364 insertions, 382 deletions
diff --git a/OpenAL32/alFilter.cpp b/OpenAL32/alFilter.cpp
index b22729a2..62ceba97 100644
--- a/OpenAL32/alFilter.cpp
+++ b/OpenAL32/alFilter.cpp
@@ -31,320 +31,16 @@
#include "alError.h"
+namespace {
+
#define FILTER_MIN_GAIN 0.0f
#define FILTER_MAX_GAIN 4.0f /* +12dB */
-static ALfilter *AllocFilter(ALCcontext *context);
-static void FreeFilter(ALCdevice *device, ALfilter *filter);
-static void InitFilterParams(ALfilter *filter, ALenum type);
-
-static inline ALfilter *LookupFilter(ALCdevice *device, ALuint id)
-{
- ALuint lidx = (id-1) >> 6;
- ALsizei slidx = (id-1) & 0x3f;
-
- if(UNLIKELY(lidx >= device->FilterList.size()))
- return nullptr;
- FilterSubList &sublist = device->FilterList[lidx];
- if(UNLIKELY(sublist.FreeMask & (U64(1)<<slidx)))
- return nullptr;
- return sublist.Filters + slidx;
-}
-
-
-AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
-{
- ALCcontext *context;
- ALsizei cur = 0;
-
- context = GetContextRef();
- if(!context) return;
-
- if(n < 0)
- alSetError(context, AL_INVALID_VALUE, "Generating %d filters", n);
- else for(cur = 0;cur < n;cur++)
- {
- ALfilter *filter = AllocFilter(context);
- if(!filter)
- {
- alDeleteFilters(cur, filters);
- break;
- }
-
- filters[cur] = filter->id;
- }
-
- ALCcontext_DecRef(context);
-}
-
-AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters)
-{
- ALCdevice *device;
- ALCcontext *context;
- ALfilter *filter;
- ALsizei i;
-
- context = GetContextRef();
- if(!context) return;
-
- device = context->Device;
- LockFilterList(device);
- if(n < 0)
- 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, done, "Invalid filter ID %u", filters[i]);
- }
- for(i = 0;i < n;i++)
- {
- if((filter=LookupFilter(device, filters[i])) != NULL)
- FreeFilter(device, filter);
- }
-
-done:
- UnlockFilterList(device);
- ALCcontext_DecRef(context);
-}
-
-AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
-{
- ALCcontext *Context;
- ALboolean result;
-
- Context = GetContextRef();
- if(!Context) return AL_FALSE;
-
- LockFilterList(Context->Device);
- result = ((!filter || LookupFilter(Context->Device, filter)) ?
- AL_TRUE : AL_FALSE);
- UnlockFilterList(Context->Device);
-
- ALCcontext_DecRef(Context);
-
- return result;
-}
-
-AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- if(param == AL_FILTER_TYPE)
- {
- if(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS ||
- value == AL_FILTER_HIGHPASS || value == AL_FILTER_BANDPASS)
- InitFilterParams(ALFilter, value);
- else
- alSetError(Context, AL_INVALID_VALUE, "Invalid filter type 0x%04x", value);
- }
- else
- {
- /* Call the appropriate handler */
- ALfilter_setParami(ALFilter, Context, param, value);
- }
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *values)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- switch(param)
- {
- case AL_FILTER_TYPE:
- alFilteri(filter, param, values[0]);
- return;
- }
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- /* Call the appropriate handler */
- ALfilter_setParamiv(ALFilter, Context, param, values);
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- /* Call the appropriate handler */
- ALfilter_setParamf(ALFilter, Context, param, value);
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *values)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- /* Call the appropriate handler */
- ALfilter_setParamfv(ALFilter, Context, param, values);
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- if(param == AL_FILTER_TYPE)
- *value = ALFilter->type;
- else
- {
- /* Call the appropriate handler */
- ALfilter_getParami(ALFilter, Context, param, value);
- }
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *values)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- switch(param)
- {
- case AL_FILTER_TYPE:
- alGetFilteri(filter, param, values);
- return;
- }
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- /* Call the appropriate handler */
- ALfilter_getParamiv(ALFilter, Context, param, values);
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *value)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- /* Call the appropriate handler */
- ALfilter_getParamf(ALFilter, Context, param, value);
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *values)
-{
- ALCcontext *Context;
- ALCdevice *Device;
- ALfilter *ALFilter;
-
- Context = GetContextRef();
- if(!Context) return;
-
- Device = Context->Device;
- LockFilterList(Device);
- if((ALFilter=LookupFilter(Device, filter)) == NULL)
- alSetError(Context, AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
- {
- /* Call the appropriate handler */
- ALfilter_getParamfv(ALFilter, Context, param, values);
- }
- UnlockFilterList(Device);
-
- ALCcontext_DecRef(Context);
-}
-
-
-static void ALlowpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val))
+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))
+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)
+void ALlowpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
{
switch(param)
{
@@ -364,14 +60,14 @@ static void ALlowpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum pa
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)
+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 param, ALint *UNUSED(val))
+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))
+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)
+void ALlowpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
{
switch(param)
{
@@ -387,17 +83,17 @@ static void ALlowpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum pa
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)
+void ALlowpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
{ ALlowpass_getParamf(filter, context, param, vals); }
DEFINE_ALFILTER_VTABLE(ALlowpass);
-static void ALhighpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val))
+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))
+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)
+void ALhighpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
{
switch(param)
{
@@ -417,14 +113,14 @@ static void ALhighpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum p
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)
+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 param, ALint *UNUSED(val))
+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))
+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)
+void ALhighpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
{
switch(param)
{
@@ -440,17 +136,17 @@ static void ALhighpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum p
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)
+void ALhighpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
{ ALhighpass_getParamf(filter, context, param, vals); }
DEFINE_ALFILTER_VTABLE(ALhighpass);
-static void ALbandpass_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val))
+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))
+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)
+void ALbandpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val)
{
switch(param)
{
@@ -476,14 +172,14 @@ static void ALbandpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum p
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)
+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 param, ALint *UNUSED(val))
+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))
+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)
+void ALbandpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val)
{
switch(param)
{
@@ -503,34 +199,75 @@ static void ALbandpass_getParamf(ALfilter *filter, ALCcontext *context, ALenum p
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)
+void ALbandpass_getParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals)
{ ALbandpass_getParamf(filter, context, param, vals); }
DEFINE_ALFILTER_VTABLE(ALbandpass);
-static void ALnullfilter_setParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum param, ALint UNUSED(val))
+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))
+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))
+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))
+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))
+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))
+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))
+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))
+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);
-static ALfilter *AllocFilter(ALCcontext *context)
+void InitFilterParams(ALfilter *filter, ALenum type)
+{
+ if(type == AL_FILTER_LOWPASS)
+ {
+ filter->Gain = AL_LOWPASS_DEFAULT_GAIN;
+ filter->GainHF = AL_LOWPASS_DEFAULT_GAINHF;
+ filter->HFReference = LOWPASSFREQREF;
+ filter->GainLF = 1.0f;
+ filter->LFReference = HIGHPASSFREQREF;
+ filter->vtab = &ALlowpass_vtable;
+ }
+ else if(type == AL_FILTER_HIGHPASS)
+ {
+ filter->Gain = AL_HIGHPASS_DEFAULT_GAIN;
+ filter->GainHF = 1.0f;
+ filter->HFReference = LOWPASSFREQREF;
+ filter->GainLF = AL_HIGHPASS_DEFAULT_GAINLF;
+ filter->LFReference = HIGHPASSFREQREF;
+ filter->vtab = &ALhighpass_vtable;
+ }
+ else if(type == AL_FILTER_BANDPASS)
+ {
+ filter->Gain = AL_BANDPASS_DEFAULT_GAIN;
+ filter->GainHF = AL_BANDPASS_DEFAULT_GAINHF;
+ filter->HFReference = LOWPASSFREQREF;
+ filter->GainLF = AL_BANDPASS_DEFAULT_GAINLF;
+ filter->LFReference = HIGHPASSFREQREF;
+ filter->vtab = &ALbandpass_vtable;
+ }
+ else
+ {
+ filter->Gain = 1.0f;
+ filter->GainHF = 1.0f;
+ filter->HFReference = LOWPASSFREQREF;
+ filter->GainLF = 1.0f;
+ filter->LFReference = HIGHPASSFREQREF;
+ filter->vtab = &ALnullfilter_vtable;
+ }
+ filter->type = type;
+}
+
+ALfilter *AllocFilter(ALCcontext *context)
{
ALCdevice *device = context->Device;
almtx_lock(&device->FilterLock);
@@ -587,7 +324,7 @@ static ALfilter *AllocFilter(ALCcontext *context)
return filter;
}
-static void FreeFilter(ALCdevice *device, ALfilter *filter)
+void FreeFilter(ALCdevice *device, ALfilter *filter)
{
ALuint id = filter->id - 1;
ALsizei lidx = id >> 6;
@@ -598,66 +335,311 @@ static void FreeFilter(ALCdevice *device, ALfilter *filter)
device->FilterList[lidx].FreeMask |= U64(1) << slidx;
}
-void ReleaseALFilters(ALCdevice *device)
+
+inline ALfilter *LookupFilter(ALCdevice *device, ALuint id)
{
- size_t leftover = 0;
- for(auto &sublist : device->FilterList)
+ ALuint lidx = (id-1) >> 6;
+ ALsizei slidx = (id-1) & 0x3f;
+
+ if(UNLIKELY(lidx >= device->FilterList.size()))
+ return nullptr;
+ FilterSubList &sublist = device->FilterList[lidx];
+ if(UNLIKELY(sublist.FreeMask & (U64(1)<<slidx)))
+ return nullptr;
+ return sublist.Filters + slidx;
+}
+
+} // namespace
+
+AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ if(UNLIKELY(n < 0))
{
- ALuint64 usemask = ~sublist.FreeMask;
- while(usemask)
+ alSetError(context.get(), AL_INVALID_VALUE, "Generating %d filters", n);
+ return;
+ }
+
+ if(LIKELY(n == 1))
+ {
+ /* Special handling for the easy and normal case. */
+ ALfilter *filter = AllocFilter(context.get());
+ if(filter) filters[0] = filter->id;
+ }
+ else if(n > 1)
+ {
+ /* Store the allocated buffer IDs in a separate local list, to avoid
+ * modifying the user storage in case of failure.
+ */
+ std::vector<ALuint> ids;
+ ids.reserve(n);
+ do {
+ ALfilter *filter = AllocFilter(context.get());
+ if(!filter)
+ {
+ alDeleteFilters(ids.size(), ids.data());
+ return;
+ }
+
+ ids.emplace_back(filter->id);
+ } while(--n);
+ std::copy(ids.begin(), ids.end(), filters);
+ }
+}
+
+AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ if(UNLIKELY(n < 0))
+ {
+ alSetError(context.get(), AL_INVALID_VALUE, "Deleting %d filters", n);
+ return;
+ }
+ if(UNLIKELY(n == 0))
+ return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ /* First try to find any buffers that are invalid or in-use. */
+ const ALuint *filters_end = filters + n;
+ auto invflt = std::find_if(filters, filters_end,
+ [device, &context](ALuint fid) -> bool
{
- ALsizei idx = CTZ64(usemask);
- ALfilter *filter = sublist.Filters + idx;
+ if(!fid) return false;
+ ALfilter *filter{LookupFilter(device, fid)};
+ if(UNLIKELY(!filter))
+ {
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", fid);
+ return true;
+ }
+ return false;
+ }
+ );
+ if(LIKELY(invflt == filters_end))
+ {
+ /* All good. Delete non-0 buffer IDs. */
+ std::for_each(filters, filters_end,
+ [device](ALuint fid) -> void
+ {
+ ALfilter *filter{fid ? LookupFilter(device, fid) : nullptr};
+ if(filter) FreeFilter(device, filter);
+ }
+ );
+ }
+}
- filter->~ALfilter();
- ++leftover;
+AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
+{
+ ContextRef context{GetContextRef()};
+ if(LIKELY(context))
+ {
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+ if(!filter || LookupFilter(device, filter))
+ return AL_TRUE;
+ }
+ return AL_FALSE;
+}
- usemask &= ~(U64(1) << idx);
+
+AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
+ {
+ if(param == AL_FILTER_TYPE)
+ {
+ if(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS ||
+ value == AL_FILTER_HIGHPASS || value == AL_FILTER_BANDPASS)
+ InitFilterParams(alfilt, value);
+ else
+ alSetError(context.get(), AL_INVALID_VALUE, "Invalid filter type 0x%04x", value);
+ }
+ else
+ {
+ /* Call the appropriate handler */
+ ALfilter_setParami(alfilt, context.get(), param, value);
}
- sublist.FreeMask = ~usemask;
}
- if(leftover > 0)
- WARN("(%p) Deleted " SZFMT " Filter%s\n", device, leftover, (leftover==1)?"":"s");
}
+AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *values)
+{
+ switch(param)
+ {
+ case AL_FILTER_TYPE:
+ alFilteri(filter, param, values[0]);
+ return;
+ }
+
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
-static void InitFilterParams(ALfilter *filter, ALenum type)
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
+ {
+ /* Call the appropriate handler */
+ ALfilter_setParamiv(alfilt, context.get(), param, values);
+ }
+}
+
+AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value)
{
- if(type == AL_FILTER_LOWPASS)
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
{
- filter->Gain = AL_LOWPASS_DEFAULT_GAIN;
- filter->GainHF = AL_LOWPASS_DEFAULT_GAINHF;
- filter->HFReference = LOWPASSFREQREF;
- filter->GainLF = 1.0f;
- filter->LFReference = HIGHPASSFREQREF;
- filter->vtab = &ALlowpass_vtable;
+ /* Call the appropriate handler */
+ ALfilter_setParamf(alfilt, context.get(), param, value);
}
- else if(type == AL_FILTER_HIGHPASS)
+}
+
+AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *values)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
{
- filter->Gain = AL_HIGHPASS_DEFAULT_GAIN;
- filter->GainHF = 1.0f;
- filter->HFReference = LOWPASSFREQREF;
- filter->GainLF = AL_HIGHPASS_DEFAULT_GAINLF;
- filter->LFReference = HIGHPASSFREQREF;
- filter->vtab = &ALhighpass_vtable;
+ /* Call the appropriate handler */
+ ALfilter_setParamfv(alfilt, context.get(), param, values);
}
- else if(type == AL_FILTER_BANDPASS)
+}
+
+AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
{
- filter->Gain = AL_BANDPASS_DEFAULT_GAIN;
- filter->GainHF = AL_BANDPASS_DEFAULT_GAINHF;
- filter->HFReference = LOWPASSFREQREF;
- filter->GainLF = AL_BANDPASS_DEFAULT_GAINLF;
- filter->LFReference = HIGHPASSFREQREF;
- filter->vtab = &ALbandpass_vtable;
+ if(param == AL_FILTER_TYPE)
+ *value = alfilt->type;
+ else
+ {
+ /* Call the appropriate handler */
+ ALfilter_getParami(alfilt, context.get(), param, value);
+ }
}
+}
+
+AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *values)
+{
+ switch(param)
+ {
+ case AL_FILTER_TYPE:
+ alGetFilteri(filter, param, values);
+ return;
+ }
+
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
else
{
- filter->Gain = 1.0f;
- filter->GainHF = 1.0f;
- filter->HFReference = LOWPASSFREQREF;
- filter->GainLF = 1.0f;
- filter->LFReference = HIGHPASSFREQREF;
- filter->vtab = &ALnullfilter_vtable;
+ /* Call the appropriate handler */
+ ALfilter_getParamiv(alfilt, context.get(), param, values);
}
- filter->type = type;
+}
+
+AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *value)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
+ {
+ /* Call the appropriate handler */
+ ALfilter_getParamf(alfilt, context.get(), param, value);
+ }
+}
+
+AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *values)
+{
+ ContextRef context{GetContextRef()};
+ if(UNLIKELY(!context)) return;
+
+ ALCdevice *device{context->Device};
+ std::lock_guard<almtx_t> _{device->FilterLock};
+
+ ALfilter *alfilt{LookupFilter(device, filter)};
+ if(UNLIKELY(!alfilt))
+ alSetError(context.get(), AL_INVALID_NAME, "Invalid filter ID %u", filter);
+ else
+ {
+ /* Call the appropriate handler */
+ ALfilter_getParamfv(alfilt, context.get(), param, values);
+ }
+}
+
+
+void ReleaseALFilters(ALCdevice *device)
+{
+ size_t leftover = 0;
+ for(auto &sublist : device->FilterList)
+ {
+ ALuint64 usemask = ~sublist.FreeMask;
+ while(usemask)
+ {
+ ALsizei idx = CTZ64(usemask);
+ ALfilter *filter = sublist.Filters + idx;
+
+ filter->~ALfilter();
+ ++leftover;
+
+ usemask &= ~(U64(1) << idx);
+ }
+ sublist.FreeMask = ~usemask;
+ }
+ if(leftover > 0)
+ WARN("(%p) Deleted " SZFMT " Filter%s\n", device, leftover, (leftover==1)?"":"s");
}