mixer_c.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. #include "config.h"
  2. #include <assert.h>
  3. #include "alMain.h"
  4. #include "alu.h"
  5. #include "alSource.h"
  6. #include "alAuxEffectSlot.h"
  7. static inline ALfloat point32(const ALfloat *restrict vals, ALsizei UNUSED(frac))
  8. { return vals[0]; }
  9. static inline ALfloat lerp32(const ALfloat *restrict vals, ALsizei frac)
  10. { return lerp(vals[0], vals[1], frac * (1.0f/FRACTIONONE)); }
  11. static inline ALfloat fir4_32(const ALfloat *restrict vals, ALsizei frac)
  12. { return resample_fir4(vals[-1], vals[0], vals[1], vals[2], frac); }
  13. const ALfloat *Resample_copy32_C(const InterpState* UNUSED(state),
  14. const ALfloat *restrict src, ALsizei UNUSED(frac), ALint UNUSED(increment),
  15. ALfloat *restrict dst, ALsizei numsamples)
  16. {
  17. #if defined(HAVE_SSE) || defined(HAVE_NEON)
  18. /* Avoid copying the source data if it's aligned like the destination. */
  19. if((((intptr_t)src)&15) == (((intptr_t)dst)&15))
  20. return src;
  21. #endif
  22. memcpy(dst, src, numsamples*sizeof(ALfloat));
  23. return dst;
  24. }
  25. #define DECL_TEMPLATE(Sampler) \
  26. const ALfloat *Resample_##Sampler##_C(const InterpState* UNUSED(state), \
  27. const ALfloat *restrict src, ALsizei frac, ALint increment, \
  28. ALfloat *restrict dst, ALsizei numsamples) \
  29. { \
  30. ALsizei i; \
  31. for(i = 0;i < numsamples;i++) \
  32. { \
  33. dst[i] = Sampler(src, frac); \
  34. \
  35. frac += increment; \
  36. src += frac>>FRACTIONBITS; \
  37. frac &= FRACTIONMASK; \
  38. } \
  39. return dst; \
  40. }
  41. DECL_TEMPLATE(point32)
  42. DECL_TEMPLATE(lerp32)
  43. DECL_TEMPLATE(fir4_32)
  44. #undef DECL_TEMPLATE
  45. const ALfloat *Resample_bsinc32_C(const InterpState *state, const ALfloat *restrict src,
  46. ALsizei frac, ALint increment, ALfloat *restrict dst,
  47. ALsizei dstlen)
  48. {
  49. const ALfloat *fil, *scd, *phd, *spd;
  50. const ALfloat sf = state->bsinc.sf;
  51. const ALsizei m = state->bsinc.m;
  52. ALsizei j_f, pi, i;
  53. ALfloat pf, r;
  54. src += state->bsinc.l;
  55. for(i = 0;i < dstlen;i++)
  56. {
  57. // Calculate the phase index and factor.
  58. #define FRAC_PHASE_BITDIFF (FRACTIONBITS-BSINC_PHASE_BITS)
  59. pi = frac >> FRAC_PHASE_BITDIFF;
  60. pf = (frac & ((1<<FRAC_PHASE_BITDIFF)-1)) * (1.0f/(1<<FRAC_PHASE_BITDIFF));
  61. #undef FRAC_PHASE_BITDIFF
  62. fil = ASSUME_ALIGNED(state->bsinc.coeffs[pi].filter, 16);
  63. scd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].scDelta, 16);
  64. phd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].phDelta, 16);
  65. spd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].spDelta, 16);
  66. // Apply the scale and phase interpolated filter.
  67. r = 0.0f;
  68. for(j_f = 0;j_f < m;j_f++)
  69. r += (fil[j_f] + sf*scd[j_f] + pf*(phd[j_f] + sf*spd[j_f])) * src[j_f];
  70. dst[i] = r;
  71. frac += increment;
  72. src += frac>>FRACTIONBITS;
  73. frac &= FRACTIONMASK;
  74. }
  75. return dst;
  76. }
  77. void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *restrict src, ALsizei numsamples)
  78. {
  79. ALsizei i;
  80. if(numsamples > 1)
  81. {
  82. dst[0] = filter->b0 * src[0] +
  83. filter->b1 * filter->x[0] +
  84. filter->b2 * filter->x[1] -
  85. filter->a1 * filter->y[0] -
  86. filter->a2 * filter->y[1];
  87. dst[1] = filter->b0 * src[1] +
  88. filter->b1 * src[0] +
  89. filter->b2 * filter->x[0] -
  90. filter->a1 * dst[0] -
  91. filter->a2 * filter->y[0];
  92. for(i = 2;i < numsamples;i++)
  93. dst[i] = filter->b0 * src[i] +
  94. filter->b1 * src[i-1] +
  95. filter->b2 * src[i-2] -
  96. filter->a1 * dst[i-1] -
  97. filter->a2 * dst[i-2];
  98. filter->x[0] = src[i-1];
  99. filter->x[1] = src[i-2];
  100. filter->y[0] = dst[i-1];
  101. filter->y[1] = dst[i-2];
  102. }
  103. else if(numsamples == 1)
  104. {
  105. dst[0] = filter->b0 * src[0] +
  106. filter->b1 * filter->x[0] +
  107. filter->b2 * filter->x[1] -
  108. filter->a1 * filter->y[0] -
  109. filter->a2 * filter->y[1];
  110. filter->x[1] = filter->x[0];
  111. filter->x[0] = src[0];
  112. filter->y[1] = filter->y[0];
  113. filter->y[0] = dst[0];
  114. }
  115. }
  116. static inline void ApplyCoeffs(ALsizei Offset, ALfloat (*restrict Values)[2],
  117. const ALsizei IrSize,
  118. const ALfloat (*restrict Coeffs)[2],
  119. ALfloat left, ALfloat right)
  120. {
  121. ALsizei c;
  122. for(c = 0;c < IrSize;c++)
  123. {
  124. const ALsizei off = (Offset+c)&HRIR_MASK;
  125. Values[off][0] += Coeffs[c][0] * left;
  126. Values[off][1] += Coeffs[c][1] * right;
  127. }
  128. }
  129. #define MixHrtf MixHrtf_C
  130. #define MixHrtfBlend MixHrtfBlend_C
  131. #define MixDirectHrtf MixDirectHrtf_C
  132. #include "mixer_inc.c"
  133. #undef MixHrtf
  134. void Mix_C(const ALfloat *data, ALsizei OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE],
  135. ALfloat *CurrentGains, const ALfloat *TargetGains, ALsizei Counter, ALsizei OutPos,
  136. ALsizei BufferSize)
  137. {
  138. ALfloat gain, delta, step;
  139. ALsizei c;
  140. delta = (Counter > 0) ? 1.0f/(ALfloat)Counter : 0.0f;
  141. for(c = 0;c < OutChans;c++)
  142. {
  143. ALsizei pos = 0;
  144. gain = CurrentGains[c];
  145. step = (TargetGains[c] - gain) * delta;
  146. if(fabsf(step) > FLT_EPSILON)
  147. {
  148. ALsizei minsize = mini(BufferSize, Counter);
  149. for(;pos < minsize;pos++)
  150. {
  151. OutBuffer[c][OutPos+pos] += data[pos]*gain;
  152. gain += step;
  153. }
  154. if(pos == Counter)
  155. gain = TargetGains[c];
  156. CurrentGains[c] = gain;
  157. }
  158. if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
  159. continue;
  160. for(;pos < BufferSize;pos++)
  161. OutBuffer[c][OutPos+pos] += data[pos]*gain;
  162. }
  163. }
  164. /* Basically the inverse of the above. Rather than one input going to multiple
  165. * outputs (each with its own gain), it's multiple inputs (each with its own
  166. * gain) going to one output. This applies one row (vs one column) of a matrix
  167. * transform. And as the matrices are more or less static once set up, no
  168. * stepping is necessary.
  169. */
  170. void MixRow_C(ALfloat *OutBuffer, const ALfloat *Gains, const ALfloat (*restrict data)[BUFFERSIZE], ALsizei InChans, ALsizei InPos, ALsizei BufferSize)
  171. {
  172. ALsizei c, i;
  173. for(c = 0;c < InChans;c++)
  174. {
  175. ALfloat gain = Gains[c];
  176. if(!(fabsf(gain) > GAIN_SILENCE_THRESHOLD))
  177. continue;
  178. for(i = 0;i < BufferSize;i++)
  179. OutBuffer[i] += data[c][InPos+i] * gain;
  180. }
  181. }