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

132 lines
4.5 KiB

  1. #ifndef MIXER_HRTFBASE_H
  2. #define MIXER_HRTFBASE_H
  3. #include <algorithm>
  4. #include "alu.h"
  5. #include "../hrtf.h"
  6. #include "opthelpers.h"
  7. using ApplyCoeffsT = void(ALsizei Offset, float2 *RESTRICT Values, const ALsizei irSize,
  8. const HrirArray<ALfloat> &Coeffs, const ALfloat left, const ALfloat right);
  9. template<ApplyCoeffsT &ApplyCoeffs>
  10. inline void MixHrtfBase(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut, const ALfloat *data,
  11. float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
  12. MixHrtfParams *hrtfparams, const ALsizei BufferSize)
  13. {
  14. ASSUME(OutPos >= 0);
  15. ASSUME(IrSize >= 4);
  16. ASSUME(BufferSize > 0);
  17. const auto &Coeffs = *hrtfparams->Coeffs;
  18. const ALfloat gainstep{hrtfparams->GainStep};
  19. const ALfloat gain{hrtfparams->Gain};
  20. ALfloat stepcount{0.0f};
  21. ALsizei Delay[2]{
  22. HRTF_HISTORY_LENGTH - hrtfparams->Delay[0],
  23. HRTF_HISTORY_LENGTH - hrtfparams->Delay[1] };
  24. ASSUME(Delay[0] >= 0 && Delay[1] >= 0);
  25. for(ALsizei i{0};i < BufferSize;++i)
  26. {
  27. const ALfloat g{gain + gainstep*stepcount};
  28. const ALfloat left{data[Delay[0]++] * g};
  29. const ALfloat right{data[Delay[1]++] * g};
  30. ApplyCoeffs(i, AccumSamples+i, IrSize, Coeffs, left, right);
  31. stepcount += 1.0f;
  32. }
  33. for(ALsizei i{0};i < BufferSize;++i)
  34. LeftOut[OutPos+i] += AccumSamples[i][0];
  35. for(ALsizei i{0};i < BufferSize;++i)
  36. RightOut[OutPos+i] += AccumSamples[i][1];
  37. hrtfparams->Gain = gain + gainstep*stepcount;
  38. }
  39. template<ApplyCoeffsT &ApplyCoeffs>
  40. inline void MixHrtfBlendBase(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  41. const ALfloat *data, float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
  42. const HrtfParams *oldparams, MixHrtfParams *newparams, const ALsizei BufferSize)
  43. {
  44. const auto &OldCoeffs = oldparams->Coeffs;
  45. const ALfloat oldGain{oldparams->Gain};
  46. const ALfloat oldGainStep{-oldGain / static_cast<ALfloat>(BufferSize)};
  47. const auto &NewCoeffs = *newparams->Coeffs;
  48. const ALfloat newGainStep{newparams->GainStep};
  49. ALfloat stepcount{0.0f};
  50. ASSUME(OutPos >= 0);
  51. ASSUME(IrSize >= 4);
  52. ASSUME(BufferSize > 0);
  53. ALsizei OldDelay[2]{
  54. HRTF_HISTORY_LENGTH - oldparams->Delay[0],
  55. HRTF_HISTORY_LENGTH - oldparams->Delay[1] };
  56. ASSUME(OldDelay[0] >= 0 && OldDelay[1] >= 0);
  57. ALsizei NewDelay[2]{
  58. HRTF_HISTORY_LENGTH - newparams->Delay[0],
  59. HRTF_HISTORY_LENGTH - newparams->Delay[1] };
  60. ASSUME(NewDelay[0] >= 0 && NewDelay[1] >= 0);
  61. for(ALsizei i{0};i < BufferSize;++i)
  62. {
  63. ALfloat g{oldGain + oldGainStep*stepcount};
  64. ALfloat left{data[OldDelay[0]++] * g};
  65. ALfloat right{data[OldDelay[1]++] * g};
  66. ApplyCoeffs(i, AccumSamples+i, IrSize, OldCoeffs, left, right);
  67. g = newGainStep*stepcount;
  68. left = data[NewDelay[0]++] * g;
  69. right = data[NewDelay[1]++] * g;
  70. ApplyCoeffs(i, AccumSamples+i, IrSize, NewCoeffs, left, right);
  71. stepcount += 1.0f;
  72. }
  73. for(ALsizei i{0};i < BufferSize;++i)
  74. LeftOut[OutPos+i] += AccumSamples[i][0];
  75. for(ALsizei i{0};i < BufferSize;++i)
  76. RightOut[OutPos+i] += AccumSamples[i][1];
  77. newparams->Gain = newGainStep*stepcount;
  78. }
  79. template<ApplyCoeffsT &ApplyCoeffs>
  80. inline void MixDirectHrtfBase(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  81. const ALfloat (*data)[BUFFERSIZE], float2 *RESTRICT AccumSamples, DirectHrtfState *State,
  82. const ALsizei NumChans, const ALsizei BufferSize)
  83. {
  84. ASSUME(NumChans > 0);
  85. ASSUME(BufferSize > 0);
  86. const ALsizei IrSize{State->IrSize};
  87. ASSUME(IrSize >= 4);
  88. for(ALsizei c{0};c < NumChans;++c)
  89. {
  90. const ALfloat (&input)[BUFFERSIZE] = data[c];
  91. const auto &Coeffs = State->Chan[c].Coeffs;
  92. auto accum_iter = std::copy_n(State->Chan[c].Values.begin(),
  93. State->Chan[c].Values.size(), AccumSamples);
  94. std::fill_n(accum_iter, BufferSize, float2{});
  95. for(ALsizei i{0};i < BufferSize;++i)
  96. {
  97. const ALfloat insample{input[i]};
  98. ApplyCoeffs(i, AccumSamples+i, IrSize, Coeffs, insample, insample);
  99. }
  100. for(ALsizei i{0};i < BufferSize;++i)
  101. LeftOut[i] += AccumSamples[i][0];
  102. for(ALsizei i{0};i < BufferSize;++i)
  103. RightOut[i] += AccumSamples[i][1];
  104. std::copy_n(AccumSamples + BufferSize, State->Chan[c].Values.size(),
  105. State->Chan[c].Values.begin());
  106. }
  107. }
  108. #endif /* MIXER_HRTFBASE_H */