pshifter.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include "config.h"
  2. #include "AL/al.h"
  3. #include "AL/efx.h"
  4. #include "alc/context.h"
  5. #include "alnumeric.h"
  6. #include "effects.h"
  7. #if ALSOFT_EAX
  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(ALCcontext *context, 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. context->throw_error(AL_INVALID_VALUE, "Pitch shifter coarse tune out of range");
  29. props.CoarseTune = val;
  30. return;
  31. case AL_PITCH_SHIFTER_FINE_TUNE:
  32. if(!(val >= AL_PITCH_SHIFTER_MIN_FINE_TUNE && val <= AL_PITCH_SHIFTER_MAX_FINE_TUNE))
  33. context->throw_error(AL_INVALID_VALUE, "Pitch shifter fine tune out of range");
  34. props.FineTune = val;
  35. return;
  36. }
  37. context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter integer property {:#04x}",
  38. as_unsigned(param));
  39. }
  40. void PshifterEffectHandler::SetParamiv(ALCcontext *context, PshifterProps &props, ALenum param, const int *vals)
  41. { SetParami(context, props, param, *vals); }
  42. void PshifterEffectHandler::SetParamf(ALCcontext *context, PshifterProps&, ALenum param, float)
  43. { context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter float property {:#04x}", as_unsigned(param)); }
  44. void PshifterEffectHandler::SetParamfv(ALCcontext *context, PshifterProps &props, ALenum param, const float *vals)
  45. { SetParamf(context, props, param, *vals); }
  46. void PshifterEffectHandler::GetParami(ALCcontext *context, const PshifterProps &props, ALenum param, int *val)
  47. {
  48. switch(param)
  49. {
  50. case AL_PITCH_SHIFTER_COARSE_TUNE: *val = props.CoarseTune; return;
  51. case AL_PITCH_SHIFTER_FINE_TUNE: *val = props.FineTune; return;
  52. }
  53. context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter integer property {:#04x}",
  54. as_unsigned(param));
  55. }
  56. void PshifterEffectHandler::GetParamiv(ALCcontext *context, const PshifterProps &props, ALenum param, int *vals)
  57. { GetParami(context, props, param, vals); }
  58. void PshifterEffectHandler::GetParamf(ALCcontext *context, const PshifterProps&, ALenum param, float*)
  59. { context->throw_error(AL_INVALID_ENUM, "Invalid pitch shifter float property {:#04x}", as_unsigned(param)); }
  60. void PshifterEffectHandler::GetParamfv(ALCcontext *context, const PshifterProps &props, ALenum param, float *vals)
  61. { GetParamf(context, props, param, vals); }
  62. #if ALSOFT_EAX
  63. namespace {
  64. using PitchShifterCommitter = EaxCommitter<EaxPitchShifterCommitter>;
  65. struct CoarseTuneValidator {
  66. void operator()(long lCoarseTune) const
  67. {
  68. eax_validate_range<PitchShifterCommitter::Exception>(
  69. "Coarse Tune",
  70. lCoarseTune,
  71. EAXPITCHSHIFTER_MINCOARSETUNE,
  72. EAXPITCHSHIFTER_MAXCOARSETUNE);
  73. }
  74. }; // CoarseTuneValidator
  75. struct FineTuneValidator {
  76. void operator()(long lFineTune) const
  77. {
  78. eax_validate_range<PitchShifterCommitter::Exception>(
  79. "Fine Tune",
  80. lFineTune,
  81. EAXPITCHSHIFTER_MINFINETUNE,
  82. EAXPITCHSHIFTER_MAXFINETUNE);
  83. }
  84. }; // FineTuneValidator
  85. struct AllValidator {
  86. void operator()(const EAXPITCHSHIFTERPROPERTIES& all) const
  87. {
  88. CoarseTuneValidator{}(all.lCoarseTune);
  89. FineTuneValidator{}(all.lFineTune);
  90. }
  91. }; // AllValidator
  92. } // namespace
  93. template<>
  94. struct PitchShifterCommitter::Exception : public EaxException {
  95. explicit Exception(const char *message) : EaxException{"EAX_PITCH_SHIFTER_EFFECT", message}
  96. { }
  97. };
  98. template<>
  99. [[noreturn]] void PitchShifterCommitter::fail(const char *message)
  100. {
  101. throw Exception{message};
  102. }
  103. bool EaxPitchShifterCommitter::commit(const EAXPITCHSHIFTERPROPERTIES &props)
  104. {
  105. if(auto *cur = std::get_if<EAXPITCHSHIFTERPROPERTIES>(&mEaxProps); cur && *cur == props)
  106. return false;
  107. mEaxProps = props;
  108. mAlProps = [&]{
  109. PshifterProps ret{};
  110. ret.CoarseTune = static_cast<int>(props.lCoarseTune);
  111. ret.FineTune = static_cast<int>(props.lFineTune);
  112. return ret;
  113. }();
  114. return true;
  115. }
  116. void EaxPitchShifterCommitter::SetDefaults(EaxEffectProps &props)
  117. {
  118. props = EAXPITCHSHIFTERPROPERTIES{EAXPITCHSHIFTER_DEFAULTCOARSETUNE,
  119. EAXPITCHSHIFTER_DEFAULTFINETUNE};
  120. }
  121. void EaxPitchShifterCommitter::Get(const EaxCall &call, const EAXPITCHSHIFTERPROPERTIES &props)
  122. {
  123. switch(call.get_property_id())
  124. {
  125. case EAXPITCHSHIFTER_NONE: break;
  126. case EAXPITCHSHIFTER_ALLPARAMETERS: call.set_value<Exception>(props); break;
  127. case EAXPITCHSHIFTER_COARSETUNE: call.set_value<Exception>(props.lCoarseTune); break;
  128. case EAXPITCHSHIFTER_FINETUNE: call.set_value<Exception>(props.lFineTune); break;
  129. default: fail_unknown_property_id();
  130. }
  131. }
  132. void EaxPitchShifterCommitter::Set(const EaxCall &call, EAXPITCHSHIFTERPROPERTIES &props)
  133. {
  134. switch(call.get_property_id())
  135. {
  136. case EAXPITCHSHIFTER_NONE: break;
  137. case EAXPITCHSHIFTER_ALLPARAMETERS: defer<AllValidator>(call, props); break;
  138. case EAXPITCHSHIFTER_COARSETUNE: defer<CoarseTuneValidator>(call, props.lCoarseTune); break;
  139. case EAXPITCHSHIFTER_FINETUNE: defer<FineTuneValidator>(call, props.lFineTune); break;
  140. default: fail_unknown_property_id();
  141. }
  142. }
  143. #endif // ALSOFT_EAX