alu.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #ifndef ALU_H
  2. #define ALU_H
  3. #include <array>
  4. #include <cmath>
  5. #include <cstddef>
  6. #include <type_traits>
  7. #include "alspan.h"
  8. #include "core/ambidefs.h"
  9. #include "core/bufferline.h"
  10. #include "core/devformat.h"
  11. struct ALCcontext;
  12. struct ALCdevice;
  13. struct EffectSlot;
  14. struct MixParams;
  15. #define MAX_SENDS 6
  16. using MixerFunc = void(*)(const al::span<const float> InSamples,
  17. const al::span<FloatBufferLine> OutBuffer, float *CurrentGains, const float *TargetGains,
  18. const size_t Counter, const size_t OutPos);
  19. extern MixerFunc MixSamples;
  20. constexpr float GainMixMax{1000.0f}; /* +60dB */
  21. constexpr float SpeedOfSoundMetersPerSec{343.3f};
  22. constexpr float AirAbsorbGainHF{0.99426f}; /* -0.05dB */
  23. /** Target gain for the reverb decay feedback reaching the decay time. */
  24. constexpr float ReverbDecayGain{0.001f}; /* -60 dB */
  25. enum HrtfRequestMode {
  26. Hrtf_Default = 0,
  27. Hrtf_Enable = 1,
  28. Hrtf_Disable = 2,
  29. };
  30. void aluInit(void);
  31. void aluInitMixer(void);
  32. /* aluInitRenderer
  33. *
  34. * Set up the appropriate panning method and mixing method given the device
  35. * properties.
  36. */
  37. void aluInitRenderer(ALCdevice *device, int hrtf_id, HrtfRequestMode hrtf_appreq,
  38. HrtfRequestMode hrtf_userreq);
  39. void aluInitEffectPanning(EffectSlot *slot, ALCcontext *context);
  40. /**
  41. * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
  42. * components, which must represent a normalized (unit length) vector, and the
  43. * spread is the angular width of the sound (0...tau).
  44. *
  45. * NOTE: The components use ambisonic coordinates. As a result:
  46. *
  47. * Ambisonic Y = OpenAL -X
  48. * Ambisonic Z = OpenAL Y
  49. * Ambisonic X = OpenAL -Z
  50. *
  51. * The components are ordered such that OpenAL's X, Y, and Z are the first,
  52. * second, and third parameters respectively -- simply negate X and Z.
  53. */
  54. std::array<float,MaxAmbiChannels> CalcAmbiCoeffs(const float y, const float z, const float x,
  55. const float spread);
  56. /**
  57. * CalcDirectionCoeffs
  58. *
  59. * Calculates ambisonic coefficients based on an OpenAL direction vector. The
  60. * vector must be normalized (unit length), and the spread is the angular width
  61. * of the sound (0...tau).
  62. */
  63. inline std::array<float,MaxAmbiChannels> CalcDirectionCoeffs(const float (&dir)[3],
  64. const float spread)
  65. {
  66. /* Convert from OpenAL coords to Ambisonics. */
  67. return CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread);
  68. }
  69. /**
  70. * CalcAngleCoeffs
  71. *
  72. * Calculates ambisonic coefficients based on azimuth and elevation. The
  73. * azimuth and elevation parameters are in radians, going right and up
  74. * respectively.
  75. */
  76. inline std::array<float,MaxAmbiChannels> CalcAngleCoeffs(const float azimuth,
  77. const float elevation, const float spread)
  78. {
  79. const float x{-std::sin(azimuth) * std::cos(elevation)};
  80. const float y{ std::sin(elevation)};
  81. const float z{ std::cos(azimuth) * std::cos(elevation)};
  82. return CalcAmbiCoeffs(x, y, z, spread);
  83. }
  84. /**
  85. * ComputePanGains
  86. *
  87. * Computes panning gains using the given channel decoder coefficients and the
  88. * pre-calculated direction or angle coefficients. For B-Format sources, the
  89. * coeffs are a 'slice' of a transform matrix for the input channel, used to
  90. * scale and orient the sound samples.
  91. */
  92. void ComputePanGains(const MixParams *mix, const float*RESTRICT coeffs, const float ingain,
  93. const al::span<float,MAX_OUTPUT_CHANNELS> gains);
  94. /** Helper to set an identity/pass-through panning for ambisonic mixing (3D input). */
  95. template<typename T, typename I, typename F>
  96. auto SetAmbiPanIdentity(T iter, I count, F func) -> std::enable_if_t<std::is_integral<I>::value>
  97. {
  98. if(count < 1) return;
  99. std::array<float,MaxAmbiChannels> coeffs{{1.0f}};
  100. func(*iter, coeffs);
  101. ++iter;
  102. for(I i{1};i < count;++i,++iter)
  103. {
  104. coeffs[i-1] = 0.0f;
  105. coeffs[i ] = 1.0f;
  106. func(*iter, coeffs);
  107. }
  108. }
  109. extern const float ConeScale;
  110. extern const float ZScale;
  111. #endif