🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
6.6 KiB

  1. #include "config.h"
  2. #include "AL/al.h"
  3. #include "AL/efx.h"
  4. #include "alc/effects/base.h"
  5. #include "effects.h"
  6. #ifdef ALSOFT_EAX
  7. #include "alnumeric.h"
  8. #include "al/eax/exception.h"
  9. #include "al/eax/utils.h"
  10. #endif // ALSOFT_EAX
  11. namespace {
  12. void Pshifter_setParamf(EffectProps*, ALenum param, float)
  13. { throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
  14. void Pshifter_setParamfv(EffectProps*, ALenum param, const float*)
  15. {
  16. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x",
  17. param};
  18. }
  19. void Pshifter_setParami(EffectProps *props, ALenum param, int val)
  20. {
  21. switch(param)
  22. {
  23. case AL_PITCH_SHIFTER_COARSE_TUNE:
  24. if(!(val >= AL_PITCH_SHIFTER_MIN_COARSE_TUNE && val <= AL_PITCH_SHIFTER_MAX_COARSE_TUNE))
  25. throw effect_exception{AL_INVALID_VALUE, "Pitch shifter coarse tune out of range"};
  26. props->Pshifter.CoarseTune = val;
  27. break;
  28. case AL_PITCH_SHIFTER_FINE_TUNE:
  29. if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE))
  30. throw effect_exception{AL_INVALID_VALUE, "Pitch shifter fine tune out of range"};
  31. props->Pshifter.FineTune = val;
  32. break;
  33. default:
  34. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
  35. param};
  36. }
  37. }
  38. void Pshifter_setParamiv(EffectProps *props, ALenum param, const int *vals)
  39. { Pshifter_setParami(props, param, vals[0]); }
  40. void Pshifter_getParami(const EffectProps *props, ALenum param, int *val)
  41. {
  42. switch(param)
  43. {
  44. case AL_PITCH_SHIFTER_COARSE_TUNE:
  45. *val = props->Pshifter.CoarseTune;
  46. break;
  47. case AL_PITCH_SHIFTER_FINE_TUNE:
  48. *val = props->Pshifter.FineTune;
  49. break;
  50. default:
  51. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
  52. param};
  53. }
  54. }
  55. void Pshifter_getParamiv(const EffectProps *props, ALenum param, int *vals)
  56. { Pshifter_getParami(props, param, vals); }
  57. void Pshifter_getParamf(const EffectProps*, ALenum param, float*)
  58. { throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
  59. void Pshifter_getParamfv(const EffectProps*, ALenum param, float*)
  60. {
  61. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float vector-property 0x%04x",
  62. param};
  63. }
  64. EffectProps genDefaultProps() noexcept
  65. {
  66. EffectProps props{};
  67. props.Pshifter.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
  68. props.Pshifter.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
  69. return props;
  70. }
  71. } // namespace
  72. DEFINE_ALEFFECT_VTABLE(Pshifter);
  73. const EffectProps PshifterEffectProps{genDefaultProps()};
  74. #ifdef ALSOFT_EAX
  75. namespace {
  76. class EaxPitchShifterEffectException : public EaxException
  77. {
  78. public:
  79. explicit EaxPitchShifterEffectException(const char* message)
  80. : EaxException{"EAX_PITCH_SHIFTER_EFFECT", message}
  81. {}
  82. }; // EaxPitchShifterEffectException
  83. class EaxPitchShifterEffect final : public EaxEffect4<EaxPitchShifterEffectException, EAXPITCHSHIFTERPROPERTIES> {
  84. public:
  85. EaxPitchShifterEffect(const EaxCall& call);
  86. private:
  87. struct CoarseTuneValidator {
  88. void operator()(long lCoarseTune) const
  89. {
  90. eax_validate_range<Exception>(
  91. "Coarse Tune",
  92. lCoarseTune,
  93. EAXPITCHSHIFTER_MINCOARSETUNE,
  94. EAXPITCHSHIFTER_MAXCOARSETUNE);
  95. }
  96. }; // CoarseTuneValidator
  97. struct FineTuneValidator {
  98. void operator()(long lFineTune) const
  99. {
  100. eax_validate_range<Exception>(
  101. "Fine Tune",
  102. lFineTune,
  103. EAXPITCHSHIFTER_MINFINETUNE,
  104. EAXPITCHSHIFTER_MAXFINETUNE);
  105. }
  106. }; // FineTuneValidator
  107. struct AllValidator {
  108. void operator()(const Props& all) const
  109. {
  110. CoarseTuneValidator{}(all.lCoarseTune);
  111. FineTuneValidator{}(all.lFineTune);
  112. }
  113. }; // AllValidator
  114. void set_defaults(Props& props) override;
  115. void set_efx_coarse_tune() noexcept;
  116. void set_efx_fine_tune() noexcept;
  117. void set_efx_defaults() override;
  118. void get(const EaxCall& call, const Props& props) override;
  119. void set(const EaxCall& call, Props& props) override;
  120. bool commit_props(const Props& old_i) override;
  121. }; // EaxPitchShifterEffect
  122. EaxPitchShifterEffect::EaxPitchShifterEffect(const EaxCall& call)
  123. : EaxEffect4{AL_EFFECT_PITCH_SHIFTER, call}
  124. {}
  125. void EaxPitchShifterEffect::set_defaults(Props& props)
  126. {
  127. props.lCoarseTune = EAXPITCHSHIFTER_DEFAULTCOARSETUNE;
  128. props.lFineTune = EAXPITCHSHIFTER_DEFAULTFINETUNE;
  129. }
  130. void EaxPitchShifterEffect::set_efx_coarse_tune() noexcept
  131. {
  132. al_effect_props_.Pshifter.CoarseTune = clamp(
  133. static_cast<ALint>(props_.lCoarseTune),
  134. AL_PITCH_SHIFTER_MIN_COARSE_TUNE,
  135. AL_PITCH_SHIFTER_MAX_COARSE_TUNE);
  136. }
  137. void EaxPitchShifterEffect::set_efx_fine_tune() noexcept
  138. {
  139. al_effect_props_.Pshifter.FineTune = clamp(
  140. static_cast<ALint>(props_.lFineTune),
  141. AL_PITCH_SHIFTER_MIN_FINE_TUNE,
  142. AL_PITCH_SHIFTER_MAX_FINE_TUNE);
  143. }
  144. void EaxPitchShifterEffect::set_efx_defaults()
  145. {
  146. set_efx_coarse_tune();
  147. set_efx_fine_tune();
  148. }
  149. void EaxPitchShifterEffect::get(const EaxCall& call, const Props& props)
  150. {
  151. switch(call.get_property_id())
  152. {
  153. case EAXPITCHSHIFTER_NONE: break;
  154. case EAXPITCHSHIFTER_ALLPARAMETERS: call.set_value<Exception>(props); break;
  155. case EAXPITCHSHIFTER_COARSETUNE: call.set_value<Exception>(props.lCoarseTune); break;
  156. case EAXPITCHSHIFTER_FINETUNE: call.set_value<Exception>(props.lFineTune); break;
  157. default: fail_unknown_property_id();
  158. }
  159. }
  160. void EaxPitchShifterEffect::set(const EaxCall& call, Props& props)
  161. {
  162. switch(call.get_property_id())
  163. {
  164. case EAXPITCHSHIFTER_NONE: break;
  165. case EAXPITCHSHIFTER_ALLPARAMETERS: defer<AllValidator>(call, props); break;
  166. case EAXPITCHSHIFTER_COARSETUNE: defer<CoarseTuneValidator>(call, props.lCoarseTune); break;
  167. case EAXPITCHSHIFTER_FINETUNE: defer<FineTuneValidator>(call, props.lFineTune); break;
  168. default: fail_unknown_property_id();
  169. }
  170. }
  171. bool EaxPitchShifterEffect::commit_props(const Props& props)
  172. {
  173. auto is_dirty = false;
  174. if (props_.lCoarseTune != props.lCoarseTune)
  175. {
  176. is_dirty = true;
  177. set_efx_coarse_tune();
  178. }
  179. if (props_.lFineTune != props.lFineTune)
  180. {
  181. is_dirty = true;
  182. set_efx_fine_tune();
  183. }
  184. return is_dirty;
  185. }
  186. } // namespace
  187. EaxEffectUPtr eax_create_eax_pitch_shifter_effect(const EaxCall& call)
  188. {
  189. return eax_create_eax4_effect<EaxPitchShifterEffect>(call);
  190. }
  191. #endif // ALSOFT_EAX