🛠️🐜 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.

121 lines
3.1 KiB

  1. #ifndef ALC_HRTF_H
  2. #define ALC_HRTF_H
  3. #include <array>
  4. #include <memory>
  5. #include <string>
  6. #include "AL/al.h"
  7. #include "AL/alc.h"
  8. #include "vector.h"
  9. #include "almalloc.h"
  10. #define HRTF_HISTORY_BITS (6)
  11. #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
  12. #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
  13. #define HRIR_BITS (7)
  14. #define HRIR_LENGTH (1<<HRIR_BITS)
  15. #define HRIR_MASK (HRIR_LENGTH-1)
  16. struct HrtfHandle;
  17. struct HrtfEntry {
  18. RefCount ref;
  19. ALuint sampleRate;
  20. ALsizei irSize;
  21. struct Field {
  22. ALfloat distance;
  23. ALubyte evCount;
  24. };
  25. /* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and
  26. * field[fdCount-1] is the nearest.
  27. */
  28. ALsizei fdCount;
  29. const Field *field;
  30. struct Elevation {
  31. ALushort azCount;
  32. ALushort irOffset;
  33. };
  34. Elevation *elev;
  35. const ALfloat (*coeffs)[2];
  36. const ALubyte (*delays)[2];
  37. void IncRef();
  38. void DecRef();
  39. static constexpr inline const char *CurrentPrefix() noexcept { return "HrtfEntry::"; }
  40. DEF_PLACE_NEWDEL()
  41. };
  42. struct EnumeratedHrtf {
  43. std::string name;
  44. HrtfHandle *hrtf;
  45. };
  46. using float2 = std::array<float,2>;
  47. template<typename T>
  48. using HrirArray = std::array<std::array<T,2>,HRIR_LENGTH>;
  49. struct HrtfState {
  50. alignas(16) std::array<ALfloat,HRTF_HISTORY_LENGTH> History;
  51. alignas(16) HrirArray<ALfloat> Values;
  52. };
  53. struct HrtfParams {
  54. alignas(16) HrirArray<ALfloat> Coeffs;
  55. ALsizei Delay[2];
  56. ALfloat Gain;
  57. };
  58. struct DirectHrtfState {
  59. /* HRTF filter state for dry buffer content */
  60. ALsizei IrSize{0};
  61. struct ChanData {
  62. alignas(16) HrirArray<ALfloat> Values;
  63. alignas(16) HrirArray<ALfloat> Coeffs;
  64. };
  65. al::FlexArray<ChanData> Chan;
  66. DirectHrtfState(size_t numchans) : Chan{numchans} { }
  67. DirectHrtfState(const DirectHrtfState&) = delete;
  68. DirectHrtfState& operator=(const DirectHrtfState&) = delete;
  69. static std::unique_ptr<DirectHrtfState> Create(size_t num_chans);
  70. static constexpr size_t Sizeof(size_t numchans) noexcept
  71. { return al::FlexArray<ChanData>::Sizeof(numchans, offsetof(DirectHrtfState, Chan)); }
  72. DEF_PLACE_NEWDEL()
  73. };
  74. struct AngularPoint {
  75. ALfloat Elev;
  76. ALfloat Azim;
  77. };
  78. al::vector<EnumeratedHrtf> EnumerateHrtf(const char *devname);
  79. HrtfEntry *GetLoadedHrtf(HrtfHandle *handle);
  80. void GetHrtfCoeffs(const HrtfEntry *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat distance,
  81. ALfloat spread, HrirArray<ALfloat> &coeffs, ALsizei (&delays)[2]);
  82. /**
  83. * Produces HRTF filter coefficients for decoding B-Format, given a set of
  84. * virtual speaker positions, a matching decoding matrix, and per-order high-
  85. * frequency gains for the decoder. The calculated impulse responses are
  86. * ordered and scaled according to the matrix input. Note the specified virtual
  87. * positions should be in degrees, not radians!
  88. */
  89. void BuildBFormatHrtf(const HrtfEntry *Hrtf, DirectHrtfState *state, const ALsizei NumChannels, const AngularPoint *AmbiPoints, const ALfloat (*RESTRICT AmbiMatrix)[MAX_AMBI_CHANNELS], const size_t AmbiCount, const ALfloat *RESTRICT AmbiOrderHFGain);
  90. #endif /* ALC_HRTF_H */