diff options
author | Chris Robinson <[email protected]> | 2020-04-09 19:36:37 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-04-09 19:36:37 -0700 |
commit | c83609277bed4be4ef40ed306bf2c57fefa19519 (patch) | |
tree | e985bbd1ce22df236fe088c5e011096d89b04665 /al/filter.cpp | |
parent | 97c11577cdf6dab159bc120b3a3e16c479fffd79 (diff) |
Use exceptions for filter errors
Diffstat (limited to 'al/filter.cpp')
-rw-r--r-- | al/filter.cpp | 259 |
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 |