pshifter.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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/effect.h"
  9. #include "al/eax/exception.h"
  10. #include "al/eax/utils.h"
  11. #endif // ALSOFT_EAX
  12. namespace {
  13. constexpr EffectProps genDefaultProps() noexcept
  14. {
  15. PshifterProps props{};
  16. props.CoarseTune = AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE;
  17. props.FineTune = AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE;
  18. return props;
  19. }
  20. } // namespace
  21. const EffectProps PshifterEffectProps{genDefaultProps()};
  22. void PshifterEffectHandler::SetParami(PshifterProps &props, ALenum param, int val)
  23. {
  24. switch(param)
  25. {
  26. case AL_PITCH_SHIFTER_COARSE_TUNE:
  27. if(!(val >= AL_PITCH_SHIFTER_MIN_COARSE_TUNE && val <= AL_PITCH_SHIFTER_MAX_COARSE_TUNE))
  28. throw effect_exception{AL_INVALID_VALUE, "Pitch shifter coarse tune out of range"};
  29. props.CoarseTune = val;
  30. break;
  31. case AL_PITCH_SHIFTER_FINE_TUNE:
  32. if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE))
  33. throw effect_exception{AL_INVALID_VALUE, "Pitch shifter fine tune out of range"};
  34. props.FineTune = val;
  35. break;
  36. default:
  37. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
  38. param};
  39. }
  40. }
  41. void PshifterEffectHandler::SetParamiv(PshifterProps &props, ALenum param, const int *vals)
  42. { SetParami(props, param, *vals); }
  43. void PshifterEffectHandler::SetParamf(PshifterProps&, ALenum param, float)
  44. { throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
  45. void PshifterEffectHandler::SetParamfv(PshifterProps&, ALenum param, const float*)
  46. {
  47. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float-vector property 0x%04x",
  48. param};
  49. }
  50. void PshifterEffectHandler::GetParami(const PshifterProps &props, ALenum param, int *val)
  51. {
  52. switch(param)
  53. {
  54. case AL_PITCH_SHIFTER_COARSE_TUNE: *val = props.CoarseTune; break;
  55. case AL_PITCH_SHIFTER_FINE_TUNE: *val = props.FineTune; break;
  56. default:
  57. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter integer property 0x%04x",
  58. param};
  59. }
  60. }
  61. void PshifterEffectHandler::GetParamiv(const PshifterProps &props, ALenum param, int *vals)
  62. { GetParami(props, param, vals); }
  63. void PshifterEffectHandler::GetParamf(const PshifterProps&, ALenum param, float*)
  64. { throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float property 0x%04x", param}; }
  65. void PshifterEffectHandler::GetParamfv(const PshifterProps&, ALenum param, float*)
  66. {
  67. throw effect_exception{AL_INVALID_ENUM, "Invalid pitch shifter float vector-property 0x%04x",
  68. param};
  69. }
  70. #ifdef ALSOFT_EAX
  71. namespace {
  72. using PitchShifterCommitter = EaxCommitter<EaxPitchShifterCommitter>;
  73. struct CoarseTuneValidator {
  74. void operator()(long lCoarseTune) const
  75. {
  76. eax_validate_range<PitchShifterCommitter::Exception>(
  77. "Coarse Tune",
  78. lCoarseTune,
  79. EAXPITCHSHIFTER_MINCOARSETUNE,
  80. EAXPITCHSHIFTER_MAXCOARSETUNE);
  81. }
  82. }; // CoarseTuneValidator
  83. struct FineTuneValidator {
  84. void operator()(long lFineTune) const
  85. {
  86. eax_validate_range<PitchShifterCommitter::Exception>(
  87. "Fine Tune",
  88. lFineTune,
  89. EAXPITCHSHIFTER_MINFINETUNE,
  90. EAXPITCHSHIFTER_MAXFINETUNE);
  91. }
  92. }; // FineTuneValidator
  93. struct AllValidator {
  94. void operator()(const EAXPITCHSHIFTERPROPERTIES& all) const
  95. {
  96. CoarseTuneValidator{}(all.lCoarseTune);
  97. FineTuneValidator{}(all.lFineTune);
  98. }
  99. }; // AllValidator
  100. } // namespace
  101. template<>
  102. struct PitchShifterCommitter::Exception : public EaxException {
  103. explicit Exception(const char *message) : EaxException{"EAX_PITCH_SHIFTER_EFFECT", message}
  104. { }
  105. };
  106. template<>
  107. [[noreturn]] void PitchShifterCommitter::fail(const char *message)
  108. {
  109. throw Exception{message};
  110. }
  111. bool EaxPitchShifterCommitter::commit(const EAXPITCHSHIFTERPROPERTIES &props)
  112. {
  113. if(auto *cur = std::get_if<EAXPITCHSHIFTERPROPERTIES>(&mEaxProps); cur && *cur == props)
  114. return false;
  115. mEaxProps = props;
  116. mAlProps = [&]{
  117. PshifterProps ret{};
  118. ret.CoarseTune = static_cast<int>(props.lCoarseTune);
  119. ret.FineTune = static_cast<int>(props.lFineTune);
  120. return ret;
  121. }();
  122. return true;
  123. }
  124. void EaxPitchShifterCommitter::SetDefaults(EaxEffectProps &props)
  125. {
  126. props = EAXPITCHSHIFTERPROPERTIES{EAXPITCHSHIFTER_DEFAULTCOARSETUNE,
  127. EAXPITCHSHIFTER_DEFAULTFINETUNE};
  128. }
  129. void EaxPitchShifterCommitter::Get(const EaxCall &call, const EAXPITCHSHIFTERPROPERTIES &props)
  130. {
  131. switch(call.get_property_id())
  132. {
  133. case EAXPITCHSHIFTER_NONE: break;
  134. case EAXPITCHSHIFTER_ALLPARAMETERS: call.set_value<Exception>(props); break;
  135. case EAXPITCHSHIFTER_COARSETUNE: call.set_value<Exception>(props.lCoarseTune); break;
  136. case EAXPITCHSHIFTER_FINETUNE: call.set_value<Exception>(props.lFineTune); break;
  137. default: fail_unknown_property_id();
  138. }
  139. }
  140. void EaxPitchShifterCommitter::Set(const EaxCall &call, EAXPITCHSHIFTERPROPERTIES &props)
  141. {
  142. switch(call.get_property_id())
  143. {
  144. case EAXPITCHSHIFTER_NONE: break;
  145. case EAXPITCHSHIFTER_ALLPARAMETERS: defer<AllValidator>(call, props); break;
  146. case EAXPITCHSHIFTER_COARSETUNE: defer<CoarseTuneValidator>(call, props.lCoarseTune); break;
  147. case EAXPITCHSHIFTER_FINETUNE: defer<FineTuneValidator>(call, props.lFineTune); break;
  148. default: fail_unknown_property_id();
  149. }
  150. }
  151. #endif // ALSOFT_EAX