mixer.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2007 by authors.
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <math.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <ctype.h>
  25. #include <assert.h>
  26. #include "alMain.h"
  27. #include "AL/al.h"
  28. #include "AL/alc.h"
  29. #include "alSource.h"
  30. #include "alBuffer.h"
  31. #include "alListener.h"
  32. #include "alAuxEffectSlot.h"
  33. #include "alu.h"
  34. #include "mixer_defs.h"
  35. static_assert((INT_MAX>>FRACTIONBITS)/MAX_PITCH > BUFFERSIZE,
  36. "MAX_PITCH and/or BUFFERSIZE are too large for FRACTIONBITS!");
  37. extern inline void InitiatePositionArrays(ALsizei frac, ALint increment, ALsizei *restrict frac_arr, ALint *restrict pos_arr, ALsizei size);
  38. /* BSinc requires up to 11 extra samples before the current position, and 12 after. */
  39. static_assert(MAX_PRE_SAMPLES >= 11, "MAX_PRE_SAMPLES must be at least 11!");
  40. static_assert(MAX_POST_SAMPLES >= 12, "MAX_POST_SAMPLES must be at least 12!");
  41. enum Resampler ResamplerDefault = LinearResampler;
  42. static MixerFunc MixSamples = Mix_C;
  43. static HrtfMixerFunc MixHrtfSamples = MixHrtf_C;
  44. HrtfMixerBlendFunc MixHrtfBlendSamples = MixHrtfBlend_C;
  45. MixerFunc SelectMixer(void)
  46. {
  47. #ifdef HAVE_NEON
  48. if((CPUCapFlags&CPU_CAP_NEON))
  49. return Mix_Neon;
  50. #endif
  51. #ifdef HAVE_SSE
  52. if((CPUCapFlags&CPU_CAP_SSE))
  53. return Mix_SSE;
  54. #endif
  55. return Mix_C;
  56. }
  57. RowMixerFunc SelectRowMixer(void)
  58. {
  59. #ifdef HAVE_NEON
  60. if((CPUCapFlags&CPU_CAP_NEON))
  61. return MixRow_Neon;
  62. #endif
  63. #ifdef HAVE_SSE
  64. if((CPUCapFlags&CPU_CAP_SSE))
  65. return MixRow_SSE;
  66. #endif
  67. return MixRow_C;
  68. }
  69. static inline HrtfMixerFunc SelectHrtfMixer(void)
  70. {
  71. #ifdef HAVE_NEON
  72. if((CPUCapFlags&CPU_CAP_NEON))
  73. return MixHrtf_Neon;
  74. #endif
  75. #ifdef HAVE_SSE
  76. if((CPUCapFlags&CPU_CAP_SSE))
  77. return MixHrtf_SSE;
  78. #endif
  79. return MixHrtf_C;
  80. }
  81. static inline HrtfMixerBlendFunc SelectHrtfBlendMixer(void)
  82. {
  83. #ifdef HAVE_NEON
  84. if((CPUCapFlags&CPU_CAP_NEON))
  85. return MixHrtfBlend_Neon;
  86. #endif
  87. #ifdef HAVE_SSE
  88. if((CPUCapFlags&CPU_CAP_SSE))
  89. return MixHrtfBlend_SSE;
  90. #endif
  91. return MixHrtfBlend_C;
  92. }
  93. ResamplerFunc SelectResampler(enum Resampler resampler)
  94. {
  95. switch(resampler)
  96. {
  97. case PointResampler:
  98. return Resample_point32_C;
  99. case LinearResampler:
  100. #ifdef HAVE_NEON
  101. if((CPUCapFlags&CPU_CAP_NEON))
  102. return Resample_lerp32_Neon;
  103. #endif
  104. #ifdef HAVE_SSE4_1
  105. if((CPUCapFlags&CPU_CAP_SSE4_1))
  106. return Resample_lerp32_SSE41;
  107. #endif
  108. #ifdef HAVE_SSE2
  109. if((CPUCapFlags&CPU_CAP_SSE2))
  110. return Resample_lerp32_SSE2;
  111. #endif
  112. return Resample_lerp32_C;
  113. case FIR4Resampler:
  114. #ifdef HAVE_NEON
  115. if((CPUCapFlags&CPU_CAP_NEON))
  116. return Resample_fir4_32_Neon;
  117. #endif
  118. #ifdef HAVE_SSE4_1
  119. if((CPUCapFlags&CPU_CAP_SSE4_1))
  120. return Resample_fir4_32_SSE41;
  121. #endif
  122. #ifdef HAVE_SSE3
  123. if((CPUCapFlags&CPU_CAP_SSE3))
  124. return Resample_fir4_32_SSE3;
  125. #endif
  126. return Resample_fir4_32_C;
  127. case BSincResampler:
  128. #ifdef HAVE_NEON
  129. if((CPUCapFlags&CPU_CAP_NEON))
  130. return Resample_bsinc32_Neon;
  131. #endif
  132. #ifdef HAVE_SSE
  133. if((CPUCapFlags&CPU_CAP_SSE))
  134. return Resample_bsinc32_SSE;
  135. #endif
  136. return Resample_bsinc32_C;
  137. }
  138. return Resample_point32_C;
  139. }
  140. void aluInitMixer(void)
  141. {
  142. const char *str;
  143. if(ConfigValueStr(NULL, NULL, "resampler", &str))
  144. {
  145. if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
  146. ResamplerDefault = PointResampler;
  147. else if(strcasecmp(str, "linear") == 0)
  148. ResamplerDefault = LinearResampler;
  149. else if(strcasecmp(str, "sinc4") == 0)
  150. ResamplerDefault = FIR4Resampler;
  151. else if(strcasecmp(str, "bsinc") == 0)
  152. ResamplerDefault = BSincResampler;
  153. else if(strcasecmp(str, "cubic") == 0 || strcasecmp(str, "sinc8") == 0)
  154. {
  155. WARN("Resampler option \"%s\" is deprecated, using sinc4\n", str);
  156. ResamplerDefault = FIR4Resampler;
  157. }
  158. else
  159. {
  160. char *end;
  161. long n = strtol(str, &end, 0);
  162. if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == FIR4Resampler))
  163. ResamplerDefault = n;
  164. else
  165. WARN("Invalid resampler: %s\n", str);
  166. }
  167. }
  168. MixHrtfBlendSamples = SelectHrtfBlendMixer();
  169. MixHrtfSamples = SelectHrtfMixer();
  170. MixSamples = SelectMixer();
  171. }
  172. static inline ALfloat Sample_ALbyte(ALbyte val)
  173. { return val * (1.0f/128.0f); }
  174. static inline ALfloat Sample_ALshort(ALshort val)
  175. { return val * (1.0f/32768.0f); }
  176. static inline ALfloat Sample_ALfloat(ALfloat val)
  177. { return val; }
  178. #define DECL_TEMPLATE(T) \
  179. static inline void Load_##T(ALfloat *dst, const T *src, ALint srcstep, ALsizei samples)\
  180. { \
  181. ALsizei i; \
  182. for(i = 0;i < samples;i++) \
  183. dst[i] = Sample_##T(src[i*srcstep]); \
  184. }
  185. DECL_TEMPLATE(ALbyte)
  186. DECL_TEMPLATE(ALshort)
  187. DECL_TEMPLATE(ALfloat)
  188. #undef DECL_TEMPLATE
  189. static void LoadSamples(ALfloat *dst, const ALvoid *src, ALint srcstep, enum FmtType srctype, ALsizei samples)
  190. {
  191. switch(srctype)
  192. {
  193. case FmtByte:
  194. Load_ALbyte(dst, src, srcstep, samples);
  195. break;
  196. case FmtShort:
  197. Load_ALshort(dst, src, srcstep, samples);
  198. break;
  199. case FmtFloat:
  200. Load_ALfloat(dst, src, srcstep, samples);
  201. break;
  202. }
  203. }
  204. static inline void SilenceSamples(ALfloat *dst, ALsizei samples)
  205. {
  206. ALsizei i;
  207. for(i = 0;i < samples;i++)
  208. dst[i] = 0.0f;
  209. }
  210. static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter,
  211. ALfloat *restrict dst, const ALfloat *restrict src,
  212. ALsizei numsamples, enum ActiveFilters type)
  213. {
  214. ALsizei i;
  215. switch(type)
  216. {
  217. case AF_None:
  218. ALfilterState_processPassthru(lpfilter, src, numsamples);
  219. ALfilterState_processPassthru(hpfilter, src, numsamples);
  220. break;
  221. case AF_LowPass:
  222. ALfilterState_process(lpfilter, dst, src, numsamples);
  223. ALfilterState_processPassthru(hpfilter, dst, numsamples);
  224. return dst;
  225. case AF_HighPass:
  226. ALfilterState_processPassthru(lpfilter, src, numsamples);
  227. ALfilterState_process(hpfilter, dst, src, numsamples);
  228. return dst;
  229. case AF_BandPass:
  230. for(i = 0;i < numsamples;)
  231. {
  232. ALfloat temp[256];
  233. ALsizei todo = mini(256, numsamples-i);
  234. ALfilterState_process(lpfilter, temp, src+i, todo);
  235. ALfilterState_process(hpfilter, dst+i, temp, todo);
  236. i += todo;
  237. }
  238. return dst;
  239. }
  240. return src;
  241. }
  242. ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei SamplesToDo)
  243. {
  244. ALbufferlistitem *BufferListItem;
  245. ALbufferlistitem *BufferLoopItem;
  246. ALsizei NumChannels, SampleSize;
  247. ResamplerFunc Resample;
  248. ALsizei DataPosInt;
  249. ALsizei DataPosFrac;
  250. ALint64 DataSize64;
  251. ALint increment;
  252. ALsizei Counter;
  253. ALsizei OutPos;
  254. ALsizei IrSize;
  255. bool isplaying;
  256. bool firstpass;
  257. ALsizei chan;
  258. ALsizei send;
  259. /* Get source info */
  260. isplaying = true; /* Will only be called while playing. */
  261. DataPosInt = ATOMIC_LOAD(&voice->position, almemory_order_acquire);
  262. DataPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed);
  263. BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed);
  264. BufferLoopItem = ATOMIC_LOAD(&voice->loop_buffer, almemory_order_relaxed);
  265. NumChannels = voice->NumChannels;
  266. SampleSize = voice->SampleSize;
  267. increment = voice->Step;
  268. IrSize = (Device->HrtfHandle ? Device->HrtfHandle->irSize : 0);
  269. Resample = ((increment == FRACTIONONE && DataPosFrac == 0) ?
  270. Resample_copy32_C : voice->Resampler);
  271. Counter = (voice->Flags&VOICE_IS_FADING) ? SamplesToDo : 0;
  272. firstpass = true;
  273. OutPos = 0;
  274. do {
  275. ALsizei SrcBufferSize, DstBufferSize;
  276. /* Figure out how many buffer samples will be needed */
  277. DataSize64 = SamplesToDo-OutPos;
  278. DataSize64 *= increment;
  279. DataSize64 += DataPosFrac+FRACTIONMASK;
  280. DataSize64 >>= FRACTIONBITS;
  281. DataSize64 += MAX_POST_SAMPLES+MAX_PRE_SAMPLES;
  282. SrcBufferSize = (ALsizei)mini64(DataSize64, BUFFERSIZE);
  283. /* Figure out how many samples we can actually mix from this. */
  284. DataSize64 = SrcBufferSize;
  285. DataSize64 -= MAX_POST_SAMPLES+MAX_PRE_SAMPLES;
  286. DataSize64 <<= FRACTIONBITS;
  287. DataSize64 -= DataPosFrac;
  288. DstBufferSize = (ALsizei)((DataSize64+(increment-1)) / increment);
  289. DstBufferSize = mini(DstBufferSize, (SamplesToDo-OutPos));
  290. /* Some mixers like having a multiple of 4, so try to give that unless
  291. * this is the last update. */
  292. if(OutPos+DstBufferSize < SamplesToDo)
  293. DstBufferSize &= ~3;
  294. for(chan = 0;chan < NumChannels;chan++)
  295. {
  296. const ALfloat *ResampledData;
  297. ALfloat *SrcData = Device->SourceData;
  298. ALsizei SrcDataSize;
  299. /* Load the previous samples into the source data first. */
  300. memcpy(SrcData, voice->PrevSamples[chan], MAX_PRE_SAMPLES*sizeof(ALfloat));
  301. SrcDataSize = MAX_PRE_SAMPLES;
  302. if(Source->SourceType == AL_STATIC)
  303. {
  304. const ALbuffer *ALBuffer = BufferListItem->buffer;
  305. const ALubyte *Data = ALBuffer->data;
  306. ALsizei DataSize;
  307. /* Offset buffer data to current channel */
  308. Data += chan*SampleSize;
  309. /* If current pos is beyond the loop range, do not loop */
  310. if(!BufferLoopItem || DataPosInt >= ALBuffer->LoopEnd)
  311. {
  312. BufferLoopItem = NULL;
  313. /* Load what's left to play from the source buffer, and
  314. * clear the rest of the temp buffer */
  315. DataSize = minu(SrcBufferSize - SrcDataSize,
  316. ALBuffer->SampleLen - DataPosInt);
  317. LoadSamples(&SrcData[SrcDataSize], &Data[DataPosInt * NumChannels*SampleSize],
  318. NumChannels, ALBuffer->FmtType, DataSize);
  319. SrcDataSize += DataSize;
  320. SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
  321. SrcDataSize += SrcBufferSize - SrcDataSize;
  322. }
  323. else
  324. {
  325. ALsizei LoopStart = ALBuffer->LoopStart;
  326. ALsizei LoopEnd = ALBuffer->LoopEnd;
  327. /* Load what's left of this loop iteration, then load
  328. * repeats of the loop section */
  329. DataSize = minu(SrcBufferSize - SrcDataSize, LoopEnd - DataPosInt);
  330. LoadSamples(&SrcData[SrcDataSize], &Data[DataPosInt * NumChannels*SampleSize],
  331. NumChannels, ALBuffer->FmtType, DataSize);
  332. SrcDataSize += DataSize;
  333. DataSize = LoopEnd-LoopStart;
  334. while(SrcBufferSize > SrcDataSize)
  335. {
  336. DataSize = mini(SrcBufferSize - SrcDataSize, DataSize);
  337. LoadSamples(&SrcData[SrcDataSize], &Data[LoopStart * NumChannels*SampleSize],
  338. NumChannels, ALBuffer->FmtType, DataSize);
  339. SrcDataSize += DataSize;
  340. }
  341. }
  342. }
  343. else
  344. {
  345. /* Crawl the buffer queue to fill in the temp buffer */
  346. ALbufferlistitem *tmpiter = BufferListItem;
  347. ALsizei pos = DataPosInt;
  348. while(tmpiter && SrcBufferSize > SrcDataSize)
  349. {
  350. const ALbuffer *ALBuffer;
  351. if((ALBuffer=tmpiter->buffer) != NULL)
  352. {
  353. const ALubyte *Data = ALBuffer->data;
  354. ALsizei DataSize = ALBuffer->SampleLen;
  355. /* Skip the data already played */
  356. if(DataSize <= pos)
  357. pos -= DataSize;
  358. else
  359. {
  360. Data += (pos*NumChannels + chan)*SampleSize;
  361. DataSize -= pos;
  362. pos -= pos;
  363. DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
  364. LoadSamples(&SrcData[SrcDataSize], Data, NumChannels,
  365. ALBuffer->FmtType, DataSize);
  366. SrcDataSize += DataSize;
  367. }
  368. }
  369. tmpiter = ATOMIC_LOAD(&tmpiter->next, almemory_order_acquire);
  370. if(!tmpiter && BufferLoopItem)
  371. tmpiter = BufferLoopItem;
  372. else if(!tmpiter)
  373. {
  374. SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
  375. SrcDataSize += SrcBufferSize - SrcDataSize;
  376. }
  377. }
  378. }
  379. /* Store the last source samples used for next time. */
  380. memcpy(voice->PrevSamples[chan],
  381. &SrcData[(increment*DstBufferSize + DataPosFrac)>>FRACTIONBITS],
  382. MAX_PRE_SAMPLES*sizeof(ALfloat)
  383. );
  384. /* Now resample, then filter and mix to the appropriate outputs. */
  385. ResampledData = Resample(&voice->ResampleState,
  386. &SrcData[MAX_PRE_SAMPLES], DataPosFrac, increment,
  387. Device->ResampledData, DstBufferSize
  388. );
  389. {
  390. DirectParams *parms = &voice->Direct.Params[chan];
  391. const ALfloat *samples;
  392. samples = DoFilters(
  393. &parms->LowPass, &parms->HighPass, Device->FilteredData,
  394. ResampledData, DstBufferSize, voice->Direct.FilterType
  395. );
  396. if(!(voice->Flags&VOICE_HAS_HRTF))
  397. {
  398. if(!Counter)
  399. memcpy(parms->Gains.Current, parms->Gains.Target,
  400. sizeof(parms->Gains.Current));
  401. if(!(voice->Flags&VOICE_HAS_NFC))
  402. MixSamples(samples, voice->Direct.Channels, voice->Direct.Buffer,
  403. parms->Gains.Current, parms->Gains.Target, Counter, OutPos,
  404. DstBufferSize
  405. );
  406. else
  407. {
  408. ALfloat *nfcsamples = Device->NFCtrlData;
  409. ALsizei chanoffset = 0;
  410. MixSamples(samples,
  411. voice->Direct.ChannelsPerOrder[0], voice->Direct.Buffer,
  412. parms->Gains.Current, parms->Gains.Target, Counter, OutPos,
  413. DstBufferSize
  414. );
  415. chanoffset += voice->Direct.ChannelsPerOrder[0];
  416. #define APPLY_NFC_MIX(order) \
  417. if(voice->Direct.ChannelsPerOrder[order] > 0) \
  418. { \
  419. NfcFilterUpdate##order(&parms->NFCtrlFilter[order-1], nfcsamples, \
  420. samples, DstBufferSize); \
  421. MixSamples(nfcsamples, voice->Direct.ChannelsPerOrder[order], \
  422. voice->Direct.Buffer+chanoffset, parms->Gains.Current+chanoffset, \
  423. parms->Gains.Target+chanoffset, Counter, OutPos, DstBufferSize \
  424. ); \
  425. chanoffset += voice->Direct.ChannelsPerOrder[order]; \
  426. }
  427. APPLY_NFC_MIX(1)
  428. APPLY_NFC_MIX(2)
  429. APPLY_NFC_MIX(3)
  430. #undef APPLY_NFC_MIX
  431. }
  432. }
  433. else
  434. {
  435. MixHrtfParams hrtfparams;
  436. ALsizei fademix = 0;
  437. int lidx, ridx;
  438. lidx = GetChannelIdxByName(Device->RealOut, FrontLeft);
  439. ridx = GetChannelIdxByName(Device->RealOut, FrontRight);
  440. assert(lidx != -1 && ridx != -1);
  441. if(!Counter)
  442. {
  443. /* No fading, just overwrite the old HRTF params. */
  444. parms->Hrtf.Old = parms->Hrtf.Target;
  445. }
  446. else if(!(parms->Hrtf.Old.Gain > GAIN_SILENCE_THRESHOLD))
  447. {
  448. /* The old HRTF params are silent, so overwrite the old
  449. * coefficients with the new, and reset the old gain to
  450. * 0. The future mix will then fade from silence.
  451. */
  452. parms->Hrtf.Old = parms->Hrtf.Target;
  453. parms->Hrtf.Old.Gain = 0.0f;
  454. }
  455. else if(firstpass)
  456. {
  457. ALfloat gain;
  458. /* Fade between the coefficients over 128 samples. */
  459. fademix = mini(DstBufferSize, 128);
  460. /* The new coefficients need to fade in completely
  461. * since they're replacing the old ones. To keep the
  462. * gain fading consistent, interpolate between the old
  463. * and new target gains given how much of the fade time
  464. * this mix handles.
  465. */
  466. gain = lerp(parms->Hrtf.Old.Gain, parms->Hrtf.Target.Gain,
  467. minf(1.0f, (ALfloat)fademix/Counter));
  468. hrtfparams.Coeffs = SAFE_CONST(ALfloat2*,parms->Hrtf.Target.Coeffs);
  469. hrtfparams.Delay[0] = parms->Hrtf.Target.Delay[0];
  470. hrtfparams.Delay[1] = parms->Hrtf.Target.Delay[1];
  471. hrtfparams.Gain = 0.0f;
  472. hrtfparams.GainStep = gain / (ALfloat)fademix;
  473. MixHrtfBlendSamples(
  474. voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx],
  475. samples, voice->Offset, OutPos, IrSize, &parms->Hrtf.Old,
  476. &hrtfparams, &parms->Hrtf.State, fademix
  477. );
  478. /* Update the old parameters with the result. */
  479. parms->Hrtf.Old = parms->Hrtf.Target;
  480. if(fademix < Counter)
  481. parms->Hrtf.Old.Gain = hrtfparams.Gain;
  482. }
  483. if(fademix < DstBufferSize)
  484. {
  485. ALsizei todo = DstBufferSize - fademix;
  486. ALfloat gain = parms->Hrtf.Target.Gain;
  487. /* Interpolate the target gain if the gain fading lasts
  488. * longer than this mix.
  489. */
  490. if(Counter > DstBufferSize)
  491. gain = lerp(parms->Hrtf.Old.Gain, gain,
  492. (ALfloat)todo/(Counter-fademix));
  493. hrtfparams.Coeffs = SAFE_CONST(ALfloat2*,parms->Hrtf.Target.Coeffs);
  494. hrtfparams.Delay[0] = parms->Hrtf.Target.Delay[0];
  495. hrtfparams.Delay[1] = parms->Hrtf.Target.Delay[1];
  496. hrtfparams.Gain = parms->Hrtf.Old.Gain;
  497. hrtfparams.GainStep = (gain - parms->Hrtf.Old.Gain) / (ALfloat)todo;
  498. MixHrtfSamples(
  499. voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx],
  500. samples+fademix, voice->Offset+fademix, OutPos+fademix, IrSize,
  501. &hrtfparams, &parms->Hrtf.State, todo
  502. );
  503. /* Store the interpolated gain or the final target gain
  504. * depending if the fade is done.
  505. */
  506. if(DstBufferSize < Counter)
  507. parms->Hrtf.Old.Gain = gain;
  508. else
  509. parms->Hrtf.Old.Gain = parms->Hrtf.Target.Gain;
  510. }
  511. }
  512. }
  513. for(send = 0;send < Device->NumAuxSends;send++)
  514. {
  515. SendParams *parms = &voice->Send[send].Params[chan];
  516. const ALfloat *samples;
  517. if(!voice->Send[send].Buffer)
  518. continue;
  519. samples = DoFilters(
  520. &parms->LowPass, &parms->HighPass, Device->FilteredData,
  521. ResampledData, DstBufferSize, voice->Send[send].FilterType
  522. );
  523. if(!Counter)
  524. memcpy(parms->Gains.Current, parms->Gains.Target,
  525. sizeof(parms->Gains.Current));
  526. MixSamples(samples, voice->Send[send].Channels, voice->Send[send].Buffer,
  527. parms->Gains.Current, parms->Gains.Target, Counter, OutPos, DstBufferSize
  528. );
  529. }
  530. }
  531. /* Update positions */
  532. DataPosFrac += increment*DstBufferSize;
  533. DataPosInt += DataPosFrac>>FRACTIONBITS;
  534. DataPosFrac &= FRACTIONMASK;
  535. OutPos += DstBufferSize;
  536. voice->Offset += DstBufferSize;
  537. Counter = maxi(DstBufferSize, Counter) - DstBufferSize;
  538. firstpass = false;
  539. /* Handle looping sources */
  540. while(1)
  541. {
  542. const ALbuffer *ALBuffer;
  543. ALsizei DataSize = 0;
  544. ALsizei LoopStart = 0;
  545. ALsizei LoopEnd = 0;
  546. if((ALBuffer=BufferListItem->buffer) != NULL)
  547. {
  548. DataSize = ALBuffer->SampleLen;
  549. LoopStart = ALBuffer->LoopStart;
  550. LoopEnd = ALBuffer->LoopEnd;
  551. if(LoopEnd > DataPosInt)
  552. break;
  553. }
  554. if(BufferLoopItem && Source->SourceType == AL_STATIC)
  555. {
  556. assert(LoopEnd > LoopStart);
  557. DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
  558. break;
  559. }
  560. if(DataSize > DataPosInt)
  561. break;
  562. BufferListItem = ATOMIC_LOAD(&BufferListItem->next, almemory_order_acquire);
  563. if(!BufferListItem)
  564. {
  565. BufferListItem = BufferLoopItem;
  566. if(!BufferListItem)
  567. {
  568. isplaying = false;
  569. DataPosInt = 0;
  570. DataPosFrac = 0;
  571. break;
  572. }
  573. }
  574. DataPosInt -= DataSize;
  575. }
  576. } while(isplaying && OutPos < SamplesToDo);
  577. voice->Flags |= VOICE_IS_FADING;
  578. /* Update source info */
  579. ATOMIC_STORE(&voice->position, DataPosInt, almemory_order_relaxed);
  580. ATOMIC_STORE(&voice->position_fraction, DataPosFrac, almemory_order_relaxed);
  581. ATOMIC_STORE(&voice->current_buffer, BufferListItem, almemory_order_release);
  582. return isplaying;
  583. }