aboutsummaryrefslogtreecommitdiffstats
path: root/al/filter.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2020-04-09 19:36:37 -0700
committerChris Robinson <[email protected]>2020-04-09 19:36:37 -0700
commitc83609277bed4be4ef40ed306bf2c57fefa19519 (patch)
treee985bbd1ce22df236fe088c5e011096d89b04665 /al/filter.cpp
parent97c11577cdf6dab159bc120b3a3e16c479fffd79 (diff)
Use exceptions for filter errors
Diffstat (limited to 'al/filter.cpp')
-rw-r--r--al/filter.cpp259
1 files changed, 168 insertions, 91 deletions
diff --git a/al/filter.cpp b/al/filter.cpp
index 3746c1be..88aa3ce9 100644
--- a/al/filter.cpp
+++ b/al/filter.cpp
@@ -24,6 +24,7 @@
#include <algorithm>
#include <cstdint>
+#include <cstdio>
#include <iterator>
#include <memory>
#include <mutex>
@@ -45,41 +46,81 @@
namespace {
+class filter_exception final : public std::exception {
+ std::string mMessage;
+ ALenum mErrorCode;
+
+public:
+ filter_exception(ALenum code, const char *msg, ...) ALEXCPT_FORMAT(printf, 3,4);
+
+ const char *what() const noexcept override { return mMessage.c_str(); }
+ ALenum errorCode() const noexcept { return mErrorCode; }
+};
+
+filter_exception::filter_exception(ALenum code, const char *msg, ...) : mErrorCode{code}
+{
+ va_list args, args2;
+ va_start(args, msg);
+ va_copy(args2, args);
+ int msglen{std::vsnprintf(nullptr, 0, msg, args)};
+ if LIKELY(msglen > 0)
+ {
+ mMessage.resize(static_cast<size_t>(msglen)+1);
+ std::vsnprintf(&mMessage[0], mMessage.length(), msg, args2);
+ mMessage.pop_back();
+ }
+ va_end(args2);
+ va_end(args);
+}
+
+
#define FILTER_MIN_GAIN 0.0f
#define FILTER_MAX_GAIN 4.0f /* +12dB */
-void ALlowpass_setParami(ALfilter*, ALCcontext *context, ALenum param, int)
-{ context->setError(AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param); }
-void ALlowpass_setParamiv(ALfilter*, ALCcontext *context, ALenum param, const int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid low-pass integer-vector property 0x%04x", param); }
-void ALlowpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, float val)
+#define DEFINE_ALFILTER_VTABLE(T) \
+const ALfilter::Vtable T##_vtable = { \
+ T##_setParami, T##_setParamiv, T##_setParamf, T##_setParamfv, \
+ T##_getParami, T##_getParamiv, T##_getParamf, T##_getParamfv, \
+}
+
+void ALlowpass_setParami(ALfilter*, ALenum param, int)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param}; }
+void ALlowpass_setParamiv(ALfilter*, ALenum param, const int*)
+{
+ throw filter_exception{AL_INVALID_ENUM, "Invalid low-pass integer-vector property 0x%04x",
+ param};
+}
+void ALlowpass_setParamf(ALfilter *filter, ALenum param, float val)
{
switch(param)
{
case AL_LOWPASS_GAIN:
if(!(val >= FILTER_MIN_GAIN && val <= FILTER_MAX_GAIN))
- SETERR_RETURN(context, AL_INVALID_VALUE,, "Low-pass gain %f out of range", val);
+ throw filter_exception{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,, "Low-pass gainhf %f out of range", val);
+ throw filter_exception{AL_INVALID_VALUE, "Low-pass gainhf %f out of range", val};
filter->GainHF = val;
break;
default:
- context->setError(AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param);
+ throw filter_exception{AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param};
}
}
-void ALlowpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const float *vals)
-{ ALlowpass_setParamf(filter, context, param, vals[0]); }
-
-void ALlowpass_getParami(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param); }
-void ALlowpass_getParamiv(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid low-pass integer-vector property 0x%04x", param); }
-void ALlowpass_getParamf(const ALfilter *filter, ALCcontext *context, ALenum param, float *val)
+void ALlowpass_setParamfv(ALfilter *filter, ALenum param, const float *vals)
+{ ALlowpass_setParamf(filter, param, vals[0]); }
+
+void ALlowpass_getParami(const ALfilter*, ALenum param, int*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid low-pass integer property 0x%04x", param}; }
+void ALlowpass_getParamiv(const ALfilter*, ALenum param, int*)
+{
+ throw filter_exception{AL_INVALID_ENUM, "Invalid low-pass integer-vector property 0x%04x",
+ param};
+}
+void ALlowpass_getParamf(const ALfilter *filter, ALenum param, float *val)
{
switch(param)
{
@@ -92,47 +133,53 @@ void ALlowpass_getParamf(const ALfilter *filter, ALCcontext *context, ALenum par
break;
default:
- context->setError(AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param);
+ throw filter_exception{AL_INVALID_ENUM, "Invalid low-pass float property 0x%04x", param};
}
}
-void ALlowpass_getParamfv(const ALfilter *filter, ALCcontext *context, ALenum param, float *vals)
-{ ALlowpass_getParamf(filter, context, param, vals); }
+void ALlowpass_getParamfv(const ALfilter *filter, ALenum param, float *vals)
+{ ALlowpass_getParamf(filter, param, vals); }
DEFINE_ALFILTER_VTABLE(ALlowpass);
-void ALhighpass_setParami(ALfilter*, ALCcontext *context, ALenum param, int)
-{ context->setError(AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param); }
-void ALhighpass_setParamiv(ALfilter*, ALCcontext *context, ALenum param, const int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid high-pass integer-vector property 0x%04x", param); }
-void ALhighpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, float val)
+void ALhighpass_setParami(ALfilter*, ALenum param, int)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param}; }
+void ALhighpass_setParamiv(ALfilter*, ALenum param, const int*)
+{
+ throw filter_exception{AL_INVALID_ENUM, "Invalid high-pass integer-vector property 0x%04x",
+ param};
+}
+void ALhighpass_setParamf(ALfilter *filter, ALenum param, float val)
{
switch(param)
{
case AL_HIGHPASS_GAIN:
if(!(val >= FILTER_MIN_GAIN && val <= FILTER_MAX_GAIN))
- SETERR_RETURN(context, AL_INVALID_VALUE,, "High-pass gain out of range");
+ throw filter_exception{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,, "High-pass gainlf out of range");
+ throw filter_exception{AL_INVALID_VALUE, "High-pass gainlf out of range"};
filter->GainLF = val;
break;
default:
- context->setError(AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param);
+ throw filter_exception{AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param};
}
}
-void ALhighpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const float *vals)
-{ ALhighpass_setParamf(filter, context, param, vals[0]); }
-
-void ALhighpass_getParami(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param); }
-void ALhighpass_getParamiv(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid high-pass integer-vector property 0x%04x", param); }
-void ALhighpass_getParamf(const ALfilter *filter, ALCcontext *context, ALenum param, float *val)
+void ALhighpass_setParamfv(ALfilter *filter, ALenum param, const float *vals)
+{ ALhighpass_setParamf(filter, param, vals[0]); }
+
+void ALhighpass_getParami(const ALfilter*, ALenum param, int*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid high-pass integer property 0x%04x", param}; }
+void ALhighpass_getParamiv(const ALfilter*, ALenum param, int*)
+{
+ throw filter_exception{AL_INVALID_ENUM, "Invalid high-pass integer-vector property 0x%04x",
+ param};
+}
+void ALhighpass_getParamf(const ALfilter *filter, ALenum param, float *val)
{
switch(param)
{
@@ -145,53 +192,59 @@ void ALhighpass_getParamf(const ALfilter *filter, ALCcontext *context, ALenum pa
break;
default:
- context->setError(AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param);
+ throw filter_exception{AL_INVALID_ENUM, "Invalid high-pass float property 0x%04x", param};
}
}
-void ALhighpass_getParamfv(const ALfilter *filter, ALCcontext *context, ALenum param, float *vals)
-{ ALhighpass_getParamf(filter, context, param, vals); }
+void ALhighpass_getParamfv(const ALfilter *filter, ALenum param, float *vals)
+{ ALhighpass_getParamf(filter, param, vals); }
DEFINE_ALFILTER_VTABLE(ALhighpass);
-void ALbandpass_setParami(ALfilter*, ALCcontext *context, ALenum param, int)
-{ context->setError(AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param); }
-void ALbandpass_setParamiv(ALfilter*, ALCcontext *context, ALenum param, const int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid band-pass integer-vector property 0x%04x", param); }
-void ALbandpass_setParamf(ALfilter *filter, ALCcontext *context, ALenum param, float val)
+void ALbandpass_setParami(ALfilter*, ALenum param, int)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param}; }
+void ALbandpass_setParamiv(ALfilter*, ALenum param, const int*)
+{
+ throw filter_exception{AL_INVALID_ENUM, "Invalid band-pass integer-vector property 0x%04x",
+ param};
+}
+void ALbandpass_setParamf(ALfilter *filter, ALenum param, float val)
{
switch(param)
{
case AL_BANDPASS_GAIN:
if(!(val >= FILTER_MIN_GAIN && val <= FILTER_MAX_GAIN))
- SETERR_RETURN(context, AL_INVALID_VALUE,, "Band-pass gain out of range");
+ throw filter_exception{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,, "Band-pass gainhf out of range");
+ throw filter_exception{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,, "Band-pass gainlf out of range");
+ throw filter_exception{AL_INVALID_VALUE, "Band-pass gainlf out of range"};
filter->GainLF = val;
break;
default:
- context->setError(AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param);
+ throw filter_exception{AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param};
}
}
-void ALbandpass_setParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const float *vals)
-{ ALbandpass_setParamf(filter, context, param, vals[0]); }
-
-void ALbandpass_getParami(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param); }
-void ALbandpass_getParamiv(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid band-pass integer-vector property 0x%04x", param); }
-void ALbandpass_getParamf(const ALfilter *filter, ALCcontext *context, ALenum param, float *val)
+void ALbandpass_setParamfv(ALfilter *filter, ALenum param, const float *vals)
+{ ALbandpass_setParamf(filter, param, vals[0]); }
+
+void ALbandpass_getParami(const ALfilter*, ALenum param, int*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid band-pass integer property 0x%04x", param}; }
+void ALbandpass_getParamiv(const ALfilter*, ALenum param, int*)
+{
+ throw filter_exception{AL_INVALID_ENUM, "Invalid band-pass integer-vector property 0x%04x",
+ param};
+}
+void ALbandpass_getParamf(const ALfilter *filter, ALenum param, float *val)
{
switch(param)
{
@@ -208,32 +261,32 @@ void ALbandpass_getParamf(const ALfilter *filter, ALCcontext *context, ALenum pa
break;
default:
- context->setError(AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param);
+ throw filter_exception{AL_INVALID_ENUM, "Invalid band-pass float property 0x%04x", param};
}
}
-void ALbandpass_getParamfv(const ALfilter *filter, ALCcontext *context, ALenum param, float *vals)
-{ ALbandpass_getParamf(filter, context, param, vals); }
+void ALbandpass_getParamfv(const ALfilter *filter, ALenum param, float *vals)
+{ ALbandpass_getParamf(filter, param, vals); }
DEFINE_ALFILTER_VTABLE(ALbandpass);
-void ALnullfilter_setParami(ALfilter*, ALCcontext *context, ALenum param, int)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-void ALnullfilter_setParamiv(ALfilter*, ALCcontext *context, ALenum param, const int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-void ALnullfilter_setParamf(ALfilter*, ALCcontext *context, ALenum param, float)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-void ALnullfilter_setParamfv(ALfilter*, ALCcontext *context, ALenum param, const float*)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-
-void ALnullfilter_getParami(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-void ALnullfilter_getParamiv(const ALfilter*, ALCcontext *context, ALenum param, int*)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-void ALnullfilter_getParamf(const ALfilter*, ALCcontext *context, ALenum param, float*)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
-void ALnullfilter_getParamfv(const ALfilter*, ALCcontext *context, ALenum param, float*)
-{ context->setError(AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param); }
+void ALnullfilter_setParami(ALfilter*, ALenum param, int)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+void ALnullfilter_setParamiv(ALfilter*, ALenum param, const int*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+void ALnullfilter_setParamf(ALfilter*, ALenum param, float)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+void ALnullfilter_setParamfv(ALfilter*, ALenum param, const float*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+
+void ALnullfilter_getParami(const ALfilter*, ALenum param, int*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+void ALnullfilter_getParamiv(const ALfilter*, ALenum param, int*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+void ALnullfilter_getParamf(const ALfilter*, ALenum param, float*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
+void ALnullfilter_getParamfv(const ALfilter*, ALenum param, float*)
+{ throw filter_exception{AL_INVALID_ENUM, "Invalid null filter property 0x%04x", param}; }
DEFINE_ALFILTER_VTABLE(ALnullfilter);
@@ -466,10 +519,13 @@ START_API_FUNC
else
context->setError(AL_INVALID_VALUE, "Invalid filter type 0x%04x", value);
}
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->setParami(context.get(), param, value);
+ alfilt->setParami(param, value);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
}
@@ -494,10 +550,13 @@ START_API_FUNC
ALfilter *alfilt{LookupFilter(device, filter)};
if UNLIKELY(!alfilt)
context->setError(AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->setParamiv(context.get(), param, values);
+ alfilt->setParamiv(param, values);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
END_API_FUNC
@@ -514,10 +573,13 @@ START_API_FUNC
ALfilter *alfilt{LookupFilter(device, filter)};
if UNLIKELY(!alfilt)
context->setError(AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->setParamf(context.get(), param, value);
+ alfilt->setParamf(param, value);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
END_API_FUNC
@@ -534,10 +596,13 @@ START_API_FUNC
ALfilter *alfilt{LookupFilter(device, filter)};
if UNLIKELY(!alfilt)
context->setError(AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->setParamfv(context.get(), param, values);
+ alfilt->setParamfv(param, values);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
END_API_FUNC
@@ -558,10 +623,13 @@ START_API_FUNC
{
if(param == AL_FILTER_TYPE)
*value = alfilt->type;
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->getParami(context.get(), param, value);
+ alfilt->getParami(param, value);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
}
@@ -586,10 +654,13 @@ START_API_FUNC
const ALfilter *alfilt{LookupFilter(device, filter)};
if UNLIKELY(!alfilt)
context->setError(AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->getParamiv(context.get(), param, values);
+ alfilt->getParamiv(param, values);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
END_API_FUNC
@@ -606,10 +677,13 @@ START_API_FUNC
const ALfilter *alfilt{LookupFilter(device, filter)};
if UNLIKELY(!alfilt)
context->setError(AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->getParamf(context.get(), param, value);
+ alfilt->getParamf(param, value);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
END_API_FUNC
@@ -626,10 +700,13 @@ START_API_FUNC
const ALfilter *alfilt{LookupFilter(device, filter)};
if UNLIKELY(!alfilt)
context->setError(AL_INVALID_NAME, "Invalid filter ID %u", filter);
- else
+ else try
{
/* Call the appropriate handler */
- alfilt->getParamfv(context.get(), param, values);
+ alfilt->getParamfv(param, values);
+ }
+ catch(filter_exception &e) {
+ context->setError(e.errorCode(), "%s", e.what());
}
}
END_API_FUNC