mixer_inc.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "config.h"
  2. #include "alMain.h"
  3. #include "alSource.h"
  4. #include "mixer_defs.h"
  5. #ifdef __GNUC__
  6. #define LIKELY(x) __builtin_expect(!!(x), 1)
  7. #define UNLIKELY(x) __builtin_expect(!!(x), 0)
  8. #else
  9. #define LIKELY(x) (x)
  10. #define UNLIKELY(x) (x)
  11. #endif
  12. #define REAL_MERGE2(a,b) a##b
  13. #define MERGE2(a,b) REAL_MERGE2(a,b)
  14. #define MixDirect_Hrtf MERGE2(MixDirect_Hrtf_,SUFFIX)
  15. static inline void ApplyCoeffsStep(const ALuint irSize,
  16. ALfloat (*restrict Coeffs)[2],
  17. const ALfloat (*restrict CoeffStep)[2]);
  18. static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2],
  19. const ALuint irSize,
  20. ALfloat (*restrict Coeffs)[2],
  21. ALfloat left, ALfloat right);
  22. void MixDirect_Hrtf(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan,
  23. ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
  24. {
  25. ALfloat (*restrict DryBuffer)[BUFFERSIZE] = params->OutBuffer;
  26. ALfloat *restrict ClickRemoval = params->ClickRemoval;
  27. ALfloat *restrict PendingClicks = params->PendingClicks;
  28. const ALuint IrSize = params->Hrtf.Params.IrSize;
  29. const ALint *restrict DelayStep = params->Hrtf.Params.DelayStep;
  30. const ALfloat (*restrict CoeffStep)[2] = params->Hrtf.Params.CoeffStep;
  31. const ALfloat (*restrict TargetCoeffs)[2] = params->Hrtf.Params.Coeffs[srcchan];
  32. const ALuint *restrict TargetDelay = params->Hrtf.Params.Delay[srcchan];
  33. ALfloat *restrict History = params->Hrtf.State->History[srcchan];
  34. ALfloat (*restrict Values)[2] = params->Hrtf.State->Values[srcchan];
  35. ALint Counter = maxu(params->Hrtf.State->Counter, OutPos) - OutPos;
  36. ALuint Offset = params->Hrtf.State->Offset + OutPos;
  37. ALIGN(16) ALfloat Coeffs[HRIR_LENGTH][2];
  38. ALuint Delay[2];
  39. ALfloat left, right;
  40. ALuint pos;
  41. ALuint c;
  42. pos = 0;
  43. for(c = 0;c < IrSize;c++)
  44. {
  45. Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter);
  46. Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter);
  47. }
  48. Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter);
  49. Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter);
  50. if(LIKELY(OutPos == 0))
  51. {
  52. History[Offset&SRC_HISTORY_MASK] = data[pos];
  53. left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
  54. History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
  55. (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
  56. right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
  57. History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
  58. (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
  59. ClickRemoval[FrontLeft] -= Values[(Offset+1)&HRIR_MASK][0] +
  60. Coeffs[0][0] * left;
  61. ClickRemoval[FrontRight] -= Values[(Offset+1)&HRIR_MASK][1] +
  62. Coeffs[0][1] * right;
  63. }
  64. for(pos = 0;pos < BufferSize && Counter > 0;pos++)
  65. {
  66. History[Offset&SRC_HISTORY_MASK] = data[pos];
  67. left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
  68. History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
  69. (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
  70. right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
  71. History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
  72. (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
  73. Delay[0] += DelayStep[0];
  74. Delay[1] += DelayStep[1];
  75. Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
  76. Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
  77. Offset++;
  78. ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right);
  79. DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
  80. DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
  81. ApplyCoeffsStep(IrSize, Coeffs, CoeffStep);
  82. OutPos++;
  83. Counter--;
  84. }
  85. Delay[0] >>= HRTFDELAY_BITS;
  86. Delay[1] >>= HRTFDELAY_BITS;
  87. for(;pos < BufferSize;pos++)
  88. {
  89. History[Offset&SRC_HISTORY_MASK] = data[pos];
  90. left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
  91. right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
  92. Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
  93. Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
  94. Offset++;
  95. ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right);
  96. DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
  97. DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
  98. OutPos++;
  99. }
  100. if(LIKELY(OutPos == SamplesToDo))
  101. {
  102. History[Offset&SRC_HISTORY_MASK] = data[pos];
  103. left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
  104. right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
  105. PendingClicks[FrontLeft] += Values[(Offset+1)&HRIR_MASK][0] +
  106. Coeffs[0][0] * left;
  107. PendingClicks[FrontRight] += Values[(Offset+1)&HRIR_MASK][1] +
  108. Coeffs[0][1] * right;
  109. }
  110. }
  111. #undef MixDirect_Hrtf
  112. #undef MERGE2
  113. #undef REAL_MERGE2
  114. #undef UNLIKELY
  115. #undef LIKELY