mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-22 05:34:46 +00:00
keeping the alt 87514151c4 (diff-73a8dc1ce58605f6c5ea53548454c3bae516ec5132a29c9d7ff7edf9730c75be)
232 lines
7.6 KiB
C++
232 lines
7.6 KiB
C++
|
|
#include "config.h"
|
|
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
|
|
#include "AL/efx.h"
|
|
|
|
#include "alc/context.h"
|
|
#include "alnumeric.h"
|
|
#include "effects.h"
|
|
|
|
#if ALSOFT_EAX
|
|
#include "al/eax/effect.h"
|
|
#include "al/eax/exception.h"
|
|
#include "al/eax/utils.h"
|
|
#endif // ALSOFT_EAX
|
|
|
|
|
|
namespace {
|
|
|
|
constexpr EffectProps genDefaultProps() noexcept
|
|
{
|
|
AutowahProps props{};
|
|
props.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME;
|
|
props.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME;
|
|
props.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE;
|
|
props.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN;
|
|
return props;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
const EffectProps AutowahEffectProps{genDefaultProps()};
|
|
|
|
void AutowahEffectHandler::SetParami(ALCcontext *context, AutowahProps&, ALenum param, int)
|
|
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer property {:#04x}", as_unsigned(param)); }
|
|
void AutowahEffectHandler::SetParamiv(ALCcontext *context, AutowahProps&, ALenum param, const int*)
|
|
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer vector property {:#04x}", as_unsigned(param)); }
|
|
|
|
void AutowahEffectHandler::SetParamf(ALCcontext *context, AutowahProps &props, ALenum param, float val)
|
|
{
|
|
switch(param)
|
|
{
|
|
case AL_AUTOWAH_ATTACK_TIME:
|
|
if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME))
|
|
context->throw_error(AL_INVALID_VALUE, "Autowah attack time out of range");
|
|
props.AttackTime = val;
|
|
return;
|
|
|
|
case AL_AUTOWAH_RELEASE_TIME:
|
|
if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME))
|
|
context->throw_error(AL_INVALID_VALUE, "Autowah release time out of range");
|
|
props.ReleaseTime = val;
|
|
return;
|
|
|
|
case AL_AUTOWAH_RESONANCE:
|
|
if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE))
|
|
context->throw_error(AL_INVALID_VALUE, "Autowah resonance out of range");
|
|
props.Resonance = val;
|
|
return;
|
|
|
|
case AL_AUTOWAH_PEAK_GAIN:
|
|
if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN))
|
|
context->throw_error(AL_INVALID_VALUE, "Autowah peak gain out of range");
|
|
props.PeakGain = val;
|
|
return;
|
|
}
|
|
|
|
context->throw_error(AL_INVALID_ENUM, "Invalid autowah float property {:#04x}",
|
|
as_unsigned(param));
|
|
}
|
|
void AutowahEffectHandler::SetParamfv(ALCcontext *context, AutowahProps &props, ALenum param, const float *vals)
|
|
{ SetParamf(context, props, param, *vals); }
|
|
|
|
void AutowahEffectHandler::GetParami(ALCcontext *context, const AutowahProps&, ALenum param, int*)
|
|
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer property {:#04x}", as_unsigned(param)); }
|
|
void AutowahEffectHandler::GetParamiv(ALCcontext *context, const AutowahProps&, ALenum param, int*)
|
|
{ context->throw_error(AL_INVALID_ENUM, "Invalid autowah integer vector property {:#04x}", as_unsigned(param)); }
|
|
|
|
void AutowahEffectHandler::GetParamf(ALCcontext *context, const AutowahProps &props, ALenum param, float *val)
|
|
{
|
|
switch(param)
|
|
{
|
|
case AL_AUTOWAH_ATTACK_TIME: *val = props.AttackTime; return;
|
|
case AL_AUTOWAH_RELEASE_TIME: *val = props.ReleaseTime; return;
|
|
case AL_AUTOWAH_RESONANCE: *val = props.Resonance; return;
|
|
case AL_AUTOWAH_PEAK_GAIN: *val = props.PeakGain; return;
|
|
}
|
|
|
|
context->throw_error(AL_INVALID_ENUM, "Invalid autowah float property {:#04x}",
|
|
as_unsigned(param));
|
|
}
|
|
void AutowahEffectHandler::GetParamfv(ALCcontext *context, const AutowahProps &props, ALenum param, float *vals)
|
|
{ GetParamf(context, props, param, vals); }
|
|
|
|
#if ALSOFT_EAX
|
|
namespace {
|
|
|
|
using AutowahCommitter = EaxCommitter<EaxAutowahCommitter>;
|
|
|
|
struct AttackTimeValidator {
|
|
void operator()(float flAttackTime) const
|
|
{
|
|
eax_validate_range<AutowahCommitter::Exception>(
|
|
"Attack Time",
|
|
flAttackTime,
|
|
EAXAUTOWAH_MINATTACKTIME,
|
|
EAXAUTOWAH_MAXATTACKTIME);
|
|
}
|
|
}; // AttackTimeValidator
|
|
|
|
struct ReleaseTimeValidator {
|
|
void operator()(float flReleaseTime) const
|
|
{
|
|
eax_validate_range<AutowahCommitter::Exception>(
|
|
"Release Time",
|
|
flReleaseTime,
|
|
EAXAUTOWAH_MINRELEASETIME,
|
|
EAXAUTOWAH_MAXRELEASETIME);
|
|
}
|
|
}; // ReleaseTimeValidator
|
|
|
|
struct ResonanceValidator {
|
|
void operator()(long lResonance) const
|
|
{
|
|
eax_validate_range<AutowahCommitter::Exception>(
|
|
"Resonance",
|
|
lResonance,
|
|
EAXAUTOWAH_MINRESONANCE,
|
|
EAXAUTOWAH_MAXRESONANCE);
|
|
}
|
|
}; // ResonanceValidator
|
|
|
|
struct PeakLevelValidator {
|
|
void operator()(long lPeakLevel) const
|
|
{
|
|
eax_validate_range<AutowahCommitter::Exception>(
|
|
"Peak Level",
|
|
lPeakLevel,
|
|
EAXAUTOWAH_MINPEAKLEVEL,
|
|
EAXAUTOWAH_MAXPEAKLEVEL);
|
|
}
|
|
}; // PeakLevelValidator
|
|
|
|
struct AllValidator {
|
|
void operator()(const EAXAUTOWAHPROPERTIES& all) const
|
|
{
|
|
AttackTimeValidator{}(all.flAttackTime);
|
|
ReleaseTimeValidator{}(all.flReleaseTime);
|
|
ResonanceValidator{}(all.lResonance);
|
|
PeakLevelValidator{}(all.lPeakLevel);
|
|
}
|
|
}; // AllValidator
|
|
|
|
} // namespace
|
|
|
|
template<>
|
|
struct AutowahCommitter::Exception : public EaxException
|
|
{
|
|
explicit Exception(const char *message) : EaxException{"EAX_AUTOWAH_EFFECT", message}
|
|
{ }
|
|
};
|
|
|
|
template<>
|
|
[[noreturn]] void AutowahCommitter::fail(const char *message)
|
|
{
|
|
throw Exception{message};
|
|
}
|
|
|
|
bool EaxAutowahCommitter::commit(const EAXAUTOWAHPROPERTIES &props)
|
|
{
|
|
if(auto *cur = std::get_if<EAXAUTOWAHPROPERTIES>(&mEaxProps); cur && *cur == props)
|
|
return false;
|
|
|
|
mEaxProps = props;
|
|
mAlProps = [&]{
|
|
AutowahProps ret{};
|
|
ret.AttackTime = props.flAttackTime;
|
|
ret.ReleaseTime = props.flReleaseTime;
|
|
ret.Resonance = level_mb_to_gain(static_cast<float>(props.lResonance));
|
|
ret.PeakGain = level_mb_to_gain(static_cast<float>(props.lPeakLevel));
|
|
return ret;
|
|
}();
|
|
|
|
return true;
|
|
}
|
|
|
|
void EaxAutowahCommitter::SetDefaults(EaxEffectProps &props)
|
|
{
|
|
static constexpr EAXAUTOWAHPROPERTIES defprops{[]
|
|
{
|
|
EAXAUTOWAHPROPERTIES ret{};
|
|
ret.flAttackTime = EAXAUTOWAH_DEFAULTATTACKTIME;
|
|
ret.flReleaseTime = EAXAUTOWAH_DEFAULTRELEASETIME;
|
|
ret.lResonance = EAXAUTOWAH_DEFAULTRESONANCE;
|
|
ret.lPeakLevel = EAXAUTOWAH_DEFAULTPEAKLEVEL;
|
|
return ret;
|
|
}()};
|
|
props = defprops;
|
|
}
|
|
|
|
void EaxAutowahCommitter::Get(const EaxCall &call, const EAXAUTOWAHPROPERTIES &props)
|
|
{
|
|
switch(call.get_property_id())
|
|
{
|
|
case EAXAUTOWAH_NONE: break;
|
|
case EAXAUTOWAH_ALLPARAMETERS: call.set_value<Exception>(props); break;
|
|
case EAXAUTOWAH_ATTACKTIME: call.set_value<Exception>(props.flAttackTime); break;
|
|
case EAXAUTOWAH_RELEASETIME: call.set_value<Exception>(props.flReleaseTime); break;
|
|
case EAXAUTOWAH_RESONANCE: call.set_value<Exception>(props.lResonance); break;
|
|
case EAXAUTOWAH_PEAKLEVEL: call.set_value<Exception>(props.lPeakLevel); break;
|
|
default: fail_unknown_property_id();
|
|
}
|
|
}
|
|
|
|
void EaxAutowahCommitter::Set(const EaxCall &call, EAXAUTOWAHPROPERTIES &props)
|
|
{
|
|
switch(call.get_property_id())
|
|
{
|
|
case EAXAUTOWAH_NONE: break;
|
|
case EAXAUTOWAH_ALLPARAMETERS: defer<AllValidator>(call, props); break;
|
|
case EAXAUTOWAH_ATTACKTIME: defer<AttackTimeValidator>(call, props.flAttackTime); break;
|
|
case EAXAUTOWAH_RELEASETIME: defer<ReleaseTimeValidator>(call, props.flReleaseTime); break;
|
|
case EAXAUTOWAH_RESONANCE: defer<ResonanceValidator>(call, props.lResonance); break;
|
|
case EAXAUTOWAH_PEAKLEVEL: defer<PeakLevelValidator>(call, props.lPeakLevel); break;
|
|
default: fail_unknown_property_id();
|
|
}
|
|
}
|
|
|
|
#endif // ALSOFT_EAX
|