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

208 lines
7.4 KiB

  1. #include "config.h"
  2. #include <cassert>
  3. #include <limits>
  4. #include "alMain.h"
  5. #include "alu.h"
  6. #include "alSource.h"
  7. #include "alAuxEffectSlot.h"
  8. #include "defs.h"
  9. #include "hrtfbase.h"
  10. static inline ALfloat do_point(const InterpState&, const ALfloat *RESTRICT vals, const ALsizei) noexcept
  11. { return vals[0]; }
  12. static inline ALfloat do_lerp(const InterpState&, const ALfloat *RESTRICT vals, const ALsizei frac) noexcept
  13. { return lerp(vals[0], vals[1], frac * (1.0f/FRACTIONONE)); }
  14. static inline ALfloat do_cubic(const InterpState&, const ALfloat *RESTRICT vals, const ALsizei frac) noexcept
  15. { return cubic(vals[0], vals[1], vals[2], vals[3], frac * (1.0f/FRACTIONONE)); }
  16. static inline ALfloat do_bsinc(const InterpState &istate, const ALfloat *RESTRICT vals, const ALsizei frac) noexcept
  17. {
  18. ASSUME(istate.bsinc.m > 0);
  19. // Calculate the phase index and factor.
  20. #define FRAC_PHASE_BITDIFF (FRACTIONBITS-BSINC_PHASE_BITS)
  21. const ALsizei pi{frac >> FRAC_PHASE_BITDIFF};
  22. const ALfloat pf{(frac & ((1<<FRAC_PHASE_BITDIFF)-1)) * (1.0f/(1<<FRAC_PHASE_BITDIFF))};
  23. #undef FRAC_PHASE_BITDIFF
  24. const ALfloat *fil{istate.bsinc.filter + istate.bsinc.m*pi*4};
  25. const ALfloat *scd{fil + istate.bsinc.m};
  26. const ALfloat *phd{scd + istate.bsinc.m};
  27. const ALfloat *spd{phd + istate.bsinc.m};
  28. // Apply the scale and phase interpolated filter.
  29. ALfloat r{0.0f};
  30. for(ALsizei j_f{0};j_f < istate.bsinc.m;j_f++)
  31. r += (fil[j_f] + istate.bsinc.sf*scd[j_f] + pf*(phd[j_f] + istate.bsinc.sf*spd[j_f])) * vals[j_f];
  32. return r;
  33. }
  34. using SamplerT = ALfloat(const InterpState&, const ALfloat*RESTRICT, const ALsizei);
  35. template<SamplerT &Sampler>
  36. static const ALfloat *DoResample(const InterpState *state, const ALfloat *RESTRICT src,
  37. ALsizei frac, ALint increment, ALfloat *RESTRICT dst,
  38. ALsizei numsamples)
  39. {
  40. ASSUME(numsamples > 0);
  41. ASSUME(increment > 0);
  42. ASSUME(frac >= 0);
  43. const InterpState istate{*state};
  44. auto proc_sample = [&src,&frac,istate,increment]() -> ALfloat
  45. {
  46. const ALfloat ret{Sampler(istate, src, frac)};
  47. frac += increment;
  48. src += frac>>FRACTIONBITS;
  49. frac &= FRACTIONMASK;
  50. return ret;
  51. };
  52. std::generate_n<ALfloat*RESTRICT>(dst, numsamples, proc_sample);
  53. return dst;
  54. }
  55. template<>
  56. const ALfloat *Resample_<CopyTag,CTag>(const InterpState* UNUSED(state),
  57. const ALfloat *RESTRICT src, ALsizei UNUSED(frac), ALint UNUSED(increment),
  58. ALfloat *RESTRICT dst, ALsizei dstlen)
  59. {
  60. ASSUME(dstlen > 0);
  61. #if defined(HAVE_SSE) || defined(HAVE_NEON)
  62. /* Avoid copying the source data if it's aligned like the destination. */
  63. if((reinterpret_cast<intptr_t>(src)&15) == (reinterpret_cast<intptr_t>(dst)&15))
  64. return src;
  65. #endif
  66. std::copy_n(src, dstlen, dst);
  67. return dst;
  68. }
  69. template<>
  70. const ALfloat *Resample_<PointTag,CTag>(const InterpState *state, const ALfloat *RESTRICT src,
  71. ALsizei frac, ALint increment, ALfloat *RESTRICT dst, ALsizei dstlen)
  72. { return DoResample<do_point>(state, src, frac, increment, dst, dstlen); }
  73. template<>
  74. const ALfloat *Resample_<LerpTag,CTag>(const InterpState *state, const ALfloat *RESTRICT src,
  75. ALsizei frac, ALint increment, ALfloat *RESTRICT dst, ALsizei dstlen)
  76. { return DoResample<do_lerp>(state, src, frac, increment, dst, dstlen); }
  77. template<>
  78. const ALfloat *Resample_<CubicTag,CTag>(const InterpState *state, const ALfloat *RESTRICT src,
  79. ALsizei frac, ALint increment, ALfloat *RESTRICT dst, ALsizei dstlen)
  80. { return DoResample<do_cubic>(state, src-1, frac, increment, dst, dstlen); }
  81. template<>
  82. const ALfloat *Resample_<BSincTag,CTag>(const InterpState *state, const ALfloat *RESTRICT src,
  83. ALsizei frac, ALint increment, ALfloat *RESTRICT dst, ALsizei dstlen)
  84. { return DoResample<do_bsinc>(state, src-state->bsinc.l, frac, increment, dst, dstlen); }
  85. static inline void ApplyCoeffs(ALsizei /*Offset*/, float2 *RESTRICT Values, const ALsizei IrSize,
  86. const HrirArray<ALfloat> &Coeffs, const ALfloat left, const ALfloat right)
  87. {
  88. ASSUME(IrSize >= 2);
  89. for(ALsizei c{0};c < IrSize;++c)
  90. {
  91. Values[c][0] += Coeffs[c][0] * left;
  92. Values[c][1] += Coeffs[c][1] * right;
  93. }
  94. }
  95. template<>
  96. void MixHrtf_<CTag>(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut, const ALfloat *data,
  97. float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
  98. MixHrtfParams *hrtfparams, const ALsizei BufferSize)
  99. {
  100. MixHrtfBase<ApplyCoeffs>(LeftOut, RightOut, data, AccumSamples, OutPos, IrSize, hrtfparams,
  101. BufferSize);
  102. }
  103. template<>
  104. void MixHrtfBlend_<CTag>(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  105. const ALfloat *data, float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
  106. const HrtfParams *oldparams, MixHrtfParams *newparams, const ALsizei BufferSize)
  107. {
  108. MixHrtfBlendBase<ApplyCoeffs>(LeftOut, RightOut, data, AccumSamples, OutPos, IrSize, oldparams,
  109. newparams, BufferSize);
  110. }
  111. template<>
  112. void MixDirectHrtf_<CTag>(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  113. const ALfloat (*data)[BUFFERSIZE], float2 *RESTRICT AccumSamples, DirectHrtfState *State,
  114. const ALsizei NumChans, const ALsizei BufferSize)
  115. {
  116. MixDirectHrtfBase<ApplyCoeffs>(LeftOut, RightOut, data, AccumSamples, State, NumChans,
  117. BufferSize);
  118. }
  119. template<>
  120. void Mix_<CTag>(const ALfloat *data, const ALsizei OutChans, ALfloat (*OutBuffer)[BUFFERSIZE],
  121. ALfloat *CurrentGains, const ALfloat *TargetGains, const ALsizei Counter, const ALsizei OutPos,
  122. const ALsizei BufferSize)
  123. {
  124. ASSUME(OutChans > 0);
  125. ASSUME(BufferSize > 0);
  126. const ALfloat delta{(Counter > 0) ? 1.0f / static_cast<ALfloat>(Counter) : 0.0f};
  127. for(ALsizei c{0};c < OutChans;c++)
  128. {
  129. ALfloat *RESTRICT dst{&OutBuffer[c][OutPos]};
  130. ALsizei pos{0};
  131. ALfloat gain{CurrentGains[c]};
  132. const ALfloat diff{TargetGains[c] - gain};
  133. if(std::fabs(diff) > std::numeric_limits<float>::epsilon())
  134. {
  135. ALsizei minsize{mini(BufferSize, Counter)};
  136. const ALfloat step{diff * delta};
  137. ALfloat step_count{0.0f};
  138. for(;pos < minsize;pos++)
  139. {
  140. dst[pos] += data[pos] * (gain + step*step_count);
  141. step_count += 1.0f;
  142. }
  143. if(pos == Counter)
  144. gain = TargetGains[c];
  145. else
  146. gain += step*step_count;
  147. CurrentGains[c] = gain;
  148. }
  149. if(!(std::fabs(gain) > GAIN_SILENCE_THRESHOLD))
  150. continue;
  151. for(;pos < BufferSize;pos++)
  152. dst[pos] += data[pos]*gain;
  153. }
  154. }
  155. /* Basically the inverse of the above. Rather than one input going to multiple
  156. * outputs (each with its own gain), it's multiple inputs (each with its own
  157. * gain) going to one output. This applies one row (vs one column) of a matrix
  158. * transform. And as the matrices are more or less static once set up, no
  159. * stepping is necessary.
  160. */
  161. template<>
  162. void MixRow_<CTag>(ALfloat *OutBuffer, const ALfloat *Gains, const ALfloat (*data)[BUFFERSIZE],
  163. const ALsizei InChans, const ALsizei InPos, const ALsizei BufferSize)
  164. {
  165. ASSUME(InChans > 0);
  166. ASSUME(BufferSize > 0);
  167. for(ALsizei c{0};c < InChans;c++)
  168. {
  169. const ALfloat *RESTRICT src{&data[c][InPos]};
  170. const ALfloat gain{Gains[c]};
  171. if(!(std::fabs(gain) > GAIN_SILENCE_THRESHOLD))
  172. continue;
  173. for(ALsizei i{0};i < BufferSize;i++)
  174. OutBuffer[i] += src[i] * gain;
  175. }
  176. }