hrtf.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #ifndef CORE_HRTF_H
  2. #define CORE_HRTF_H
  3. #include <array>
  4. #include <cstddef>
  5. #include <memory>
  6. #include <optional>
  7. #include <string>
  8. #include <string_view>
  9. #include <vector>
  10. #include "almalloc.h"
  11. #include "alspan.h"
  12. #include "atomic.h"
  13. #include "ambidefs.h"
  14. #include "bufferline.h"
  15. #include "flexarray.h"
  16. #include "intrusive_ptr.h"
  17. #include "mixer/hrtfdefs.h"
  18. struct alignas(16) HrtfStore {
  19. std::atomic<uint> mRef;
  20. uint mSampleRate : 24;
  21. uint mIrSize : 8;
  22. struct Field {
  23. float distance;
  24. ubyte evCount;
  25. };
  26. /* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and
  27. * field[fdCount-1] is the nearest.
  28. */
  29. al::span<const Field> mFields;
  30. struct Elevation {
  31. ushort azCount;
  32. ushort irOffset;
  33. };
  34. al::span<Elevation> mElev;
  35. al::span<const HrirArray> mCoeffs;
  36. al::span<const ubyte2> mDelays;
  37. void getCoeffs(float elevation, float azimuth, float distance, float spread,
  38. const HrirSpan coeffs, const al::span<uint,2> delays) const;
  39. void add_ref();
  40. void dec_ref();
  41. void *operator new(size_t) = delete;
  42. void *operator new[](size_t) = delete;
  43. void operator delete[](void*) noexcept = delete;
  44. void operator delete(gsl::owner<void*> block, void*) noexcept
  45. { ::operator delete[](block, std::align_val_t{alignof(HrtfStore)}); }
  46. void operator delete(gsl::owner<void*> block) noexcept
  47. { ::operator delete[](block, std::align_val_t{alignof(HrtfStore)}); }
  48. };
  49. using HrtfStorePtr = al::intrusive_ptr<HrtfStore>;
  50. struct EvRadians { float value; };
  51. struct AzRadians { float value; };
  52. struct AngularPoint {
  53. EvRadians Elev;
  54. AzRadians Azim;
  55. };
  56. struct DirectHrtfState {
  57. std::array<float,BufferLineSize> mTemp{};
  58. /* HRTF filter state for dry buffer content */
  59. uint mIrSize{0};
  60. al::FlexArray<HrtfChannelState> mChannels;
  61. DirectHrtfState(size_t numchans) : mChannels{numchans} { }
  62. /**
  63. * Produces HRTF filter coefficients for decoding B-Format, given a set of
  64. * virtual speaker positions, a matching decoding matrix, and per-order
  65. * high-frequency gains for the decoder. The calculated impulse responses
  66. * are ordered and scaled according to the matrix input.
  67. */
  68. void build(const HrtfStore *Hrtf, const uint irSize, const bool perHrirMin,
  69. const al::span<const AngularPoint> AmbiPoints,
  70. const al::span<const std::array<float,MaxAmbiChannels>> AmbiMatrix,
  71. const float XOverFreq, const al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain);
  72. static std::unique_ptr<DirectHrtfState> Create(size_t num_chans);
  73. DEF_FAM_NEWDEL(DirectHrtfState, mChannels)
  74. };
  75. std::vector<std::string> EnumerateHrtf(std::optional<std::string> pathopt);
  76. HrtfStorePtr GetLoadedHrtf(const std::string_view name, const uint devrate);
  77. #endif /* CORE_HRTF_H */