mixer.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #ifndef CORE_MIXER_H
  2. #define CORE_MIXER_H
  3. #include <array>
  4. #include <cmath>
  5. #include <cstddef>
  6. #include "alspan.h"
  7. #include "ambidefs.h"
  8. #include "bufferline.h"
  9. #include "opthelpers.h"
  10. struct MixParams;
  11. /* Mixer functions that handle one input and multiple output channels. */
  12. using MixerOutFunc = void(*)(const al::span<const float> InSamples,
  13. const al::span<FloatBufferLine> OutBuffer, const al::span<float> CurrentGains,
  14. const al::span<const float> TargetGains, const std::size_t Counter, const std::size_t OutPos);
  15. DECL_HIDDEN extern MixerOutFunc MixSamplesOut;
  16. inline void MixSamples(const al::span<const float> InSamples,
  17. const al::span<FloatBufferLine> OutBuffer, const al::span<float> CurrentGains,
  18. const al::span<const float> TargetGains, const std::size_t Counter, const std::size_t OutPos)
  19. { MixSamplesOut(InSamples, OutBuffer, CurrentGains, TargetGains, Counter, OutPos); }
  20. /* Mixer functions that handle one input and one output channel. */
  21. using MixerOneFunc = void(*)(const al::span<const float> InSamples,const al::span<float> OutBuffer,
  22. float &CurrentGain, const float TargetGain, const std::size_t Counter);
  23. DECL_HIDDEN extern MixerOneFunc MixSamplesOne;
  24. inline void MixSamples(const al::span<const float> InSamples, const al::span<float> OutBuffer,
  25. float &CurrentGain, const float TargetGain, const std::size_t Counter)
  26. { MixSamplesOne(InSamples, OutBuffer, CurrentGain, TargetGain, Counter); }
  27. /**
  28. * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
  29. * components, which must represent a normalized (unit length) vector, and the
  30. * spread is the angular width of the sound (0...tau).
  31. *
  32. * NOTE: The components use ambisonic coordinates. As a result:
  33. *
  34. * Ambisonic Y = OpenAL -X
  35. * Ambisonic Z = OpenAL Y
  36. * Ambisonic X = OpenAL -Z
  37. *
  38. * The components are ordered such that OpenAL's X, Y, and Z are the first,
  39. * second, and third parameters respectively -- simply negate X and Z.
  40. */
  41. std::array<float,MaxAmbiChannels> CalcAmbiCoeffs(const float y, const float z, const float x,
  42. const float spread);
  43. /**
  44. * CalcDirectionCoeffs
  45. *
  46. * Calculates ambisonic coefficients based on an OpenAL direction vector. The
  47. * vector must be normalized (unit length), and the spread is the angular width
  48. * of the sound (0...tau).
  49. */
  50. inline std::array<float,MaxAmbiChannels> CalcDirectionCoeffs(const al::span<const float,3> dir,
  51. const float spread)
  52. {
  53. /* Convert from OpenAL coords to Ambisonics. */
  54. return CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread);
  55. }
  56. /**
  57. * CalcDirectionCoeffs
  58. *
  59. * Calculates ambisonic coefficients based on an OpenAL direction vector. The
  60. * vector must be normalized (unit length).
  61. */
  62. constexpr std::array<float,MaxAmbiChannels> CalcDirectionCoeffs(const al::span<const float,3> dir)
  63. {
  64. /* Convert from OpenAL coords to Ambisonics. */
  65. return CalcAmbiCoeffs(-dir[0], dir[1], -dir[2]);
  66. }
  67. /**
  68. * CalcAngleCoeffs
  69. *
  70. * Calculates ambisonic coefficients based on azimuth and elevation. The
  71. * azimuth and elevation parameters are in radians, going right and up
  72. * respectively.
  73. */
  74. inline std::array<float,MaxAmbiChannels> CalcAngleCoeffs(const float azimuth,
  75. const float elevation, const float spread)
  76. {
  77. const float x{-std::sin(azimuth) * std::cos(elevation)};
  78. const float y{ std::sin(elevation)};
  79. const float z{ std::cos(azimuth) * std::cos(elevation)};
  80. return CalcAmbiCoeffs(x, y, z, spread);
  81. }
  82. /**
  83. * ComputePanGains
  84. *
  85. * Computes panning gains using the given channel decoder coefficients and the
  86. * pre-calculated direction or angle coefficients. For B-Format sources, the
  87. * coeffs are a 'slice' of a transform matrix for the input channel, used to
  88. * scale and orient the sound samples.
  89. */
  90. void ComputePanGains(const MixParams *mix, const al::span<const float,MaxAmbiChannels> coeffs,
  91. const float ingain, const al::span<float,MaxAmbiChannels> gains);
  92. #endif /* CORE_MIXER_H */