diff options
-rw-r--r-- | al/filter.cpp | 259 | ||||
-rw-r--r-- | al/filter.h | 57 |
2 files changed, 188 insertions, 128 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 diff --git a/al/filter.h b/al/filter.h index ee6aa30d..123e64b0 100644 --- a/al/filter.h +++ b/al/filter.h @@ -12,26 +12,6 @@ #define HIGHPASSFREQREF 250.0f -struct ALfilter; - -struct ALfilterVtable { - void (*const setParami )(ALfilter *filter, ALCcontext *ctx, ALenum param, int val); - void (*const setParamiv)(ALfilter *filter, ALCcontext *ctx, ALenum param, const int *vals); - void (*const setParamf )(ALfilter *filter, ALCcontext *ctx, ALenum param, float val); - void (*const setParamfv)(ALfilter *filter, ALCcontext *ctx, ALenum param, const float *vals); - - void (*const getParami )(const ALfilter *filter, ALCcontext *ctx, ALenum param, int *val); - void (*const getParamiv)(const ALfilter *filter, ALCcontext *ctx, ALenum param, int *vals); - void (*const getParamf )(const ALfilter *filter, ALCcontext *ctx, ALenum param, float *val); - void (*const getParamfv)(const ALfilter *filter, ALCcontext *ctx, ALenum param, float *vals); -}; - -#define DEFINE_ALFILTER_VTABLE(T) \ -const ALfilterVtable T##_vtable = { \ - T##_setParami, T##_setParamiv, T##_setParamf, T##_setParamfv, \ - T##_getParami, T##_getParamiv, T##_getParamf, T##_getParamfv, \ -} - struct ALfilter { ALenum type{AL_FILTER_NULL}; @@ -41,27 +21,30 @@ struct ALfilter { float GainLF{1.0f}; float LFReference{HIGHPASSFREQREF}; - const ALfilterVtable *vtab{nullptr}; + struct Vtable { + void (*const setParami )(ALfilter *filter, ALenum param, int val); + void (*const setParamiv)(ALfilter *filter, ALenum param, const int *vals); + void (*const setParamf )(ALfilter *filter, ALenum param, float val); + void (*const setParamfv)(ALfilter *filter, ALenum param, const float *vals); + + void (*const getParami )(const ALfilter *filter, ALenum param, int *val); + void (*const getParamiv)(const ALfilter *filter, ALenum param, int *vals); + void (*const getParamf )(const ALfilter *filter, ALenum param, float *val); + void (*const getParamfv)(const ALfilter *filter, ALenum param, float *vals); + }; + const Vtable *vtab{nullptr}; /* Self ID */ ALuint id{0}; - inline void setParami(ALCcontext *ctx, ALenum param, int value) - { vtab->setParami(this, ctx, param, value); } - inline void setParamiv(ALCcontext *ctx, ALenum param, const int *values) - { vtab->setParamiv(this, ctx, param, values); } - inline void setParamf(ALCcontext *ctx, ALenum param, float value) - { vtab->setParamf(this, ctx, param, value); } - inline void setParamfv(ALCcontext *ctx, ALenum param, const float *values) - { vtab->setParamfv(this, ctx, param, values); } - inline void getParami(ALCcontext *ctx, ALenum param, int *value) const - { vtab->getParami(this, ctx, param, value); } - inline void getParamiv(ALCcontext *ctx, ALenum param, int *values) const - { vtab->getParamiv(this, ctx, param, values); } - inline void getParamf(ALCcontext *ctx, ALenum param, float *value) const - { vtab->getParamf(this, ctx, param, value); } - inline void getParamfv(ALCcontext *ctx, ALenum param, float *values) const - { vtab->getParamfv(this, ctx, param, values); } + void setParami(ALenum param, int value) { vtab->setParami(this, param, value); } + void setParamiv(ALenum param, const int *values) { vtab->setParamiv(this, param, values); } + void setParamf(ALenum param, float value) { vtab->setParamf(this, param, value); } + void setParamfv(ALenum param, const float *values) { vtab->setParamfv(this, param, values); } + void getParami(ALenum param, int *value) const { vtab->getParami(this, param, value); } + void getParamiv(ALenum param, int *values) const { vtab->getParamiv(this, param, values); } + void getParamf(ALenum param, float *value) const { vtab->getParamf(this, param, value); } + void getParamfv(ALenum param, float *values) const { vtab->getParamfv(this, param, values); } DISABLE_ALLOC() }; |