10 #include "alc/effects/base.h"
16 #include "al/eax/effect.h"
17 #include "al/eax/exception.h"
18 #include "al/eax/utils.h"
24 constexpr std::optional
<FShifterDirection
> DirectionFromEmum(ALenum value
) noexcept
28 case AL_FREQUENCY_SHIFTER_DIRECTION_DOWN
: return FShifterDirection::Down
;
29 case AL_FREQUENCY_SHIFTER_DIRECTION_UP
: return FShifterDirection::Up
;
30 case AL_FREQUENCY_SHIFTER_DIRECTION_OFF
: return FShifterDirection::Off
;
34 constexpr ALenum
EnumFromDirection(FShifterDirection dir
)
38 case FShifterDirection::Down
: return AL_FREQUENCY_SHIFTER_DIRECTION_DOWN
;
39 case FShifterDirection::Up
: return AL_FREQUENCY_SHIFTER_DIRECTION_UP
;
40 case FShifterDirection::Off
: return AL_FREQUENCY_SHIFTER_DIRECTION_OFF
;
42 throw std::runtime_error
{"Invalid direction: "+std::to_string(static_cast<int>(dir
))};
45 constexpr EffectProps
genDefaultProps() noexcept
47 FshifterProps props
{};
48 props
.Frequency
= AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY
;
49 props
.LeftDirection
= DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION
).value();
50 props
.RightDirection
= DirectionFromEmum(AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION
).value();
56 const EffectProps FshifterEffectProps
{genDefaultProps()};
58 void FshifterEffectHandler::SetParami(FshifterProps
&props
, ALenum param
, int val
)
62 case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION
:
63 if(auto diropt
= DirectionFromEmum(val
))
64 props
.LeftDirection
= *diropt
;
66 throw effect_exception
{AL_INVALID_VALUE
,
67 "Unsupported frequency shifter left direction: 0x%04x", val
};
70 case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION
:
71 if(auto diropt
= DirectionFromEmum(val
))
72 props
.RightDirection
= *diropt
;
74 throw effect_exception
{AL_INVALID_VALUE
,
75 "Unsupported frequency shifter right direction: 0x%04x", val
};
79 throw effect_exception
{AL_INVALID_ENUM
,
80 "Invalid frequency shifter integer property 0x%04x", param
};
83 void FshifterEffectHandler::SetParamiv(FshifterProps
&props
, ALenum param
, const int *vals
)
84 { SetParami(props
, param
, *vals
); }
86 void FshifterEffectHandler::SetParamf(FshifterProps
&props
, ALenum param
, float val
)
90 case AL_FREQUENCY_SHIFTER_FREQUENCY
:
91 if(!(val
>= AL_FREQUENCY_SHIFTER_MIN_FREQUENCY
&& val
<= AL_FREQUENCY_SHIFTER_MAX_FREQUENCY
))
92 throw effect_exception
{AL_INVALID_VALUE
, "Frequency shifter frequency out of range"};
93 props
.Frequency
= val
;
97 throw effect_exception
{AL_INVALID_ENUM
, "Invalid frequency shifter float property 0x%04x",
101 void FshifterEffectHandler::SetParamfv(FshifterProps
&props
, ALenum param
, const float *vals
)
102 { SetParamf(props
, param
, *vals
); }
104 void FshifterEffectHandler::GetParami(const FshifterProps
&props
, ALenum param
, int *val
)
108 case AL_FREQUENCY_SHIFTER_LEFT_DIRECTION
:
109 *val
= EnumFromDirection(props
.LeftDirection
);
111 case AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION
:
112 *val
= EnumFromDirection(props
.RightDirection
);
116 throw effect_exception
{AL_INVALID_ENUM
,
117 "Invalid frequency shifter integer property 0x%04x", param
};
120 void FshifterEffectHandler::GetParamiv(const FshifterProps
&props
, ALenum param
, int *vals
)
121 { GetParami(props
, param
, vals
); }
123 void FshifterEffectHandler::GetParamf(const FshifterProps
&props
, ALenum param
, float *val
)
127 case AL_FREQUENCY_SHIFTER_FREQUENCY
:
128 *val
= props
.Frequency
;
132 throw effect_exception
{AL_INVALID_ENUM
, "Invalid frequency shifter float property 0x%04x",
136 void FshifterEffectHandler::GetParamfv(const FshifterProps
&props
, ALenum param
, float *vals
)
137 { GetParamf(props
, param
, vals
); }
143 using FrequencyShifterCommitter
= EaxCommitter
<EaxFrequencyShifterCommitter
>;
145 struct FrequencyValidator
{
146 void operator()(float flFrequency
) const
148 eax_validate_range
<FrequencyShifterCommitter::Exception
>(
151 EAXFREQUENCYSHIFTER_MINFREQUENCY
,
152 EAXFREQUENCYSHIFTER_MAXFREQUENCY
);
154 }; // FrequencyValidator
156 struct LeftDirectionValidator
{
157 void operator()(unsigned long ulLeftDirection
) const
159 eax_validate_range
<FrequencyShifterCommitter::Exception
>(
162 EAXFREQUENCYSHIFTER_MINLEFTDIRECTION
,
163 EAXFREQUENCYSHIFTER_MAXLEFTDIRECTION
);
165 }; // LeftDirectionValidator
167 struct RightDirectionValidator
{
168 void operator()(unsigned long ulRightDirection
) const
170 eax_validate_range
<FrequencyShifterCommitter::Exception
>(
173 EAXFREQUENCYSHIFTER_MINRIGHTDIRECTION
,
174 EAXFREQUENCYSHIFTER_MAXRIGHTDIRECTION
);
176 }; // RightDirectionValidator
178 struct AllValidator
{
179 void operator()(const EAXFREQUENCYSHIFTERPROPERTIES
& all
) const
181 FrequencyValidator
{}(all
.flFrequency
);
182 LeftDirectionValidator
{}(all
.ulLeftDirection
);
183 RightDirectionValidator
{}(all
.ulRightDirection
);
190 struct FrequencyShifterCommitter::Exception
: public EaxException
{
191 explicit Exception(const char *message
) : EaxException
{"EAX_FREQUENCY_SHIFTER_EFFECT", message
}
196 [[noreturn
]] void FrequencyShifterCommitter::fail(const char *message
)
198 throw Exception
{message
};
201 bool EaxFrequencyShifterCommitter::commit(const EAXFREQUENCYSHIFTERPROPERTIES
&props
)
203 if(auto *cur
= std::get_if
<EAXFREQUENCYSHIFTERPROPERTIES
>(&mEaxProps
); cur
&& *cur
== props
)
208 auto get_direction
= [](unsigned long dir
) noexcept
210 if(dir
== EAX_FREQUENCYSHIFTER_DOWN
)
211 return FShifterDirection::Down
;
212 if(dir
== EAX_FREQUENCYSHIFTER_UP
)
213 return FShifterDirection::Up
;
214 return FShifterDirection::Off
;
219 ret
.Frequency
= props
.flFrequency
;
220 ret
.LeftDirection
= get_direction(props
.ulLeftDirection
);
221 ret
.RightDirection
= get_direction(props
.ulRightDirection
);
228 void EaxFrequencyShifterCommitter::SetDefaults(EaxEffectProps
&props
)
230 static constexpr EAXFREQUENCYSHIFTERPROPERTIES defprops
{[]
232 EAXFREQUENCYSHIFTERPROPERTIES ret
{};
233 ret
.flFrequency
= EAXFREQUENCYSHIFTER_DEFAULTFREQUENCY
;
234 ret
.ulLeftDirection
= EAXFREQUENCYSHIFTER_DEFAULTLEFTDIRECTION
;
235 ret
.ulRightDirection
= EAXFREQUENCYSHIFTER_DEFAULTRIGHTDIRECTION
;
241 void EaxFrequencyShifterCommitter::Get(const EaxCall
&call
, const EAXFREQUENCYSHIFTERPROPERTIES
&props
)
243 switch(call
.get_property_id())
245 case EAXFREQUENCYSHIFTER_NONE
: break;
246 case EAXFREQUENCYSHIFTER_ALLPARAMETERS
: call
.set_value
<Exception
>(props
); break;
247 case EAXFREQUENCYSHIFTER_FREQUENCY
: call
.set_value
<Exception
>(props
.flFrequency
); break;
248 case EAXFREQUENCYSHIFTER_LEFTDIRECTION
: call
.set_value
<Exception
>(props
.ulLeftDirection
); break;
249 case EAXFREQUENCYSHIFTER_RIGHTDIRECTION
: call
.set_value
<Exception
>(props
.ulRightDirection
); break;
250 default: fail_unknown_property_id();
254 void EaxFrequencyShifterCommitter::Set(const EaxCall
&call
, EAXFREQUENCYSHIFTERPROPERTIES
&props
)
256 switch(call
.get_property_id())
258 case EAXFREQUENCYSHIFTER_NONE
: break;
259 case EAXFREQUENCYSHIFTER_ALLPARAMETERS
: defer
<AllValidator
>(call
, props
); break;
260 case EAXFREQUENCYSHIFTER_FREQUENCY
: defer
<FrequencyValidator
>(call
, props
.flFrequency
); break;
261 case EAXFREQUENCYSHIFTER_LEFTDIRECTION
: defer
<LeftDirectionValidator
>(call
, props
.ulLeftDirection
); break;
262 case EAXFREQUENCYSHIFTER_RIGHTDIRECTION
: defer
<RightDirectionValidator
>(call
, props
.ulRightDirection
); break;
263 default: fail_unknown_property_id();