convolution.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #include "config.h"
  2. #include <algorithm>
  3. #include <array>
  4. #include <cmath>
  5. #include "AL/al.h"
  6. #include "alc/context.h"
  7. #include "alc/inprogext.h"
  8. #include "alnumeric.h"
  9. #include "alspan.h"
  10. #include "effects.h"
  11. namespace {
  12. constexpr EffectProps genDefaultProps() noexcept
  13. {
  14. ConvolutionProps props{};
  15. props.OrientAt = {0.0f, 0.0f, -1.0f};
  16. props.OrientUp = {0.0f, 1.0f, 0.0f};
  17. return props;
  18. }
  19. } // namespace
  20. const EffectProps ConvolutionEffectProps{genDefaultProps()};
  21. void ConvolutionEffectHandler::SetParami(ALCcontext *context, ConvolutionProps& /*props*/, ALenum param, int /*val*/)
  22. { context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect integer property {:#04x}", as_unsigned(param)); }
  23. void ConvolutionEffectHandler::SetParamiv(ALCcontext *context, ConvolutionProps &props, ALenum param, const int *vals)
  24. { SetParami(context, props, param, *vals); }
  25. void ConvolutionEffectHandler::SetParamf(ALCcontext *context, ConvolutionProps& /*props*/, ALenum param, float /*val*/)
  26. { context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect float property {:#04x}", as_unsigned(param)); }
  27. void ConvolutionEffectHandler::SetParamfv(ALCcontext *context, ConvolutionProps &props, ALenum param, const float *values)
  28. {
  29. static constexpr auto finite_checker = [](float val) -> bool { return std::isfinite(val); };
  30. switch(param)
  31. {
  32. case AL_CONVOLUTION_ORIENTATION_SOFT:
  33. auto vals = al::span{values, 6_uz};
  34. if(!std::all_of(vals.cbegin(), vals.cend(), finite_checker))
  35. context->throw_error(AL_INVALID_VALUE, "Convolution orientation out of range", param);
  36. std::copy_n(vals.cbegin(), props.OrientAt.size(), props.OrientAt.begin());
  37. std::copy_n(vals.cbegin()+3, props.OrientUp.size(), props.OrientUp.begin());
  38. return;
  39. }
  40. SetParamf(context, props, param, *values);
  41. }
  42. void ConvolutionEffectHandler::GetParami(ALCcontext *context, const ConvolutionProps& /*props*/, ALenum param, int* /*val*/)
  43. { context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect integer property {:#04x}", as_unsigned(param)); }
  44. void ConvolutionEffectHandler::GetParamiv(ALCcontext *context, const ConvolutionProps &props, ALenum param, int *vals)
  45. { GetParami(context, props, param, vals); }
  46. void ConvolutionEffectHandler::GetParamf(ALCcontext *context, const ConvolutionProps& /*props*/, ALenum param, float* /*val*/)
  47. { context->throw_error(AL_INVALID_ENUM, "Invalid convolution effect float property {:#04x}", as_unsigned(param)); }
  48. void ConvolutionEffectHandler::GetParamfv(ALCcontext *context, const ConvolutionProps &props, ALenum param, float *values)
  49. {
  50. switch(param)
  51. {
  52. case AL_CONVOLUTION_ORIENTATION_SOFT:
  53. auto vals = al::span{values, 6_uz};
  54. std::copy(props.OrientAt.cbegin(), props.OrientAt.cend(), vals.begin());
  55. std::copy(props.OrientUp.cbegin(), props.OrientUp.cend(), vals.begin()+3);
  56. return;
  57. }
  58. GetParamf(context, props, param, values);
  59. }