mixer.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  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., 59 Temple Place - Suite 330,
  17. * Boston, MA 02111-1307, 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 "bs2b.h"
  35. static __inline ALfloat point32(const ALfloat *vals, ALint step, ALint frac)
  36. { return vals[0]; (void)step; (void)frac; }
  37. static __inline ALfloat lerp32(const ALfloat *vals, ALint step, ALint frac)
  38. { return lerp(vals[0], vals[step], frac * (1.0f/FRACTIONONE)); }
  39. static __inline ALfloat cubic32(const ALfloat *vals, ALint step, ALint frac)
  40. { return cubic(vals[-step], vals[0], vals[step], vals[step+step],
  41. frac * (1.0f/FRACTIONONE)); }
  42. #ifdef __GNUC__
  43. #define LIKELY(x) __builtin_expect(!!(x), 1)
  44. #define UNLIKELY(x) __builtin_expect(!!(x), 0)
  45. #else
  46. #define LIKELY(x) (x)
  47. #define UNLIKELY(x) (x)
  48. #endif
  49. #if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_H)
  50. #include <arm_neon.h>
  51. static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
  52. ALfloat (*RESTRICT Coeffs)[2],
  53. ALfloat left, ALfloat right)
  54. {
  55. ALuint c;
  56. float32x4_t leftright4;
  57. {
  58. float32x2_t leftright2 = vdup_n_f32(0.0);
  59. leftright2 = vset_lane_f32(left, leftright2, 0);
  60. leftright2 = vset_lane_f32(right, leftright2, 1);
  61. leftright4 = vcombine_f32(leftright2, leftright2);
  62. }
  63. for(c = 0;c < HRIR_LENGTH;c += 2)
  64. {
  65. const ALuint o0 = (Offset+c)&HRIR_MASK;
  66. const ALuint o1 = (o0+1)&HRIR_MASK;
  67. float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]),
  68. vld1_f32((float32_t*)&Values[o1][0]));
  69. float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]);
  70. vals = vmlaq_f32(vals, coefs, leftright4);
  71. vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals));
  72. vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals));
  73. }
  74. }
  75. #else
  76. static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
  77. ALfloat (*RESTRICT Coeffs)[2],
  78. ALfloat left, ALfloat right)
  79. {
  80. ALuint c;
  81. for(c = 0;c < HRIR_LENGTH;c++)
  82. {
  83. const ALuint off = (Offset+c)&HRIR_MASK;
  84. Values[off][0] += Coeffs[c][0] * left;
  85. Values[off][1] += Coeffs[c][1] * right;
  86. }
  87. }
  88. #endif
  89. #define DECL_TEMPLATE(T, sampler) \
  90. static void Mix_Hrtf_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
  91. const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
  92. ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
  93. { \
  94. const ALuint NumChannels = Source->NumChannels; \
  95. const T *RESTRICT data = srcdata; \
  96. const ALint *RESTRICT DelayStep = Source->Params.HrtfDelayStep; \
  97. ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
  98. ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
  99. ALfloat (*RESTRICT CoeffStep)[2] = Source->Params.HrtfCoeffStep; \
  100. ALuint pos, frac; \
  101. FILTER *DryFilter; \
  102. ALuint BufferIdx; \
  103. ALuint increment; \
  104. ALuint i, out, c; \
  105. ALfloat value; \
  106. \
  107. increment = Source->Params.Step; \
  108. \
  109. DryBuffer = Device->DryBuffer; \
  110. ClickRemoval = Device->ClickRemoval; \
  111. PendingClicks = Device->PendingClicks; \
  112. DryFilter = &Source->Params.iirFilter; \
  113. \
  114. pos = 0; \
  115. frac = *DataPosFrac; \
  116. \
  117. for(i = 0;i < NumChannels;i++) \
  118. { \
  119. ALfloat (*RESTRICT TargetCoeffs)[2] = Source->Params.HrtfCoeffs[i]; \
  120. ALuint *RESTRICT TargetDelay = Source->Params.HrtfDelay[i]; \
  121. ALfloat *RESTRICT History = Source->HrtfHistory[i]; \
  122. ALfloat (*RESTRICT Values)[2] = Source->HrtfValues[i]; \
  123. ALint Counter = maxu(Source->HrtfCounter, OutPos) - OutPos; \
  124. ALuint Offset = Source->HrtfOffset + OutPos; \
  125. ALfloat Coeffs[HRIR_LENGTH][2]; \
  126. ALuint Delay[2]; \
  127. ALfloat left, right; \
  128. \
  129. pos = 0; \
  130. frac = *DataPosFrac; \
  131. \
  132. for(c = 0;c < HRIR_LENGTH;c++) \
  133. { \
  134. Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter); \
  135. Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter); \
  136. } \
  137. \
  138. Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter) + 32768; \
  139. Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter) + 32768; \
  140. \
  141. if(LIKELY(OutPos == 0)) \
  142. { \
  143. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  144. value = lpFilter2PC(DryFilter, i, value); \
  145. \
  146. History[Offset&SRC_HISTORY_MASK] = value; \
  147. left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \
  148. right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \
  149. \
  150. ClickRemoval[FRONT_LEFT] -= Values[(Offset+1)&HRIR_MASK][0] + \
  151. Coeffs[0][0] * left; \
  152. ClickRemoval[FRONT_RIGHT] -= Values[(Offset+1)&HRIR_MASK][1] + \
  153. Coeffs[0][1] * right; \
  154. } \
  155. for(BufferIdx = 0;BufferIdx < BufferSize && Counter > 0;BufferIdx++) \
  156. { \
  157. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  158. value = lpFilter2P(DryFilter, i, value); \
  159. \
  160. History[Offset&SRC_HISTORY_MASK] = value; \
  161. left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \
  162. right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \
  163. \
  164. Delay[0] += DelayStep[0]; \
  165. Delay[1] += DelayStep[1]; \
  166. \
  167. Values[Offset&HRIR_MASK][0] = 0.0f; \
  168. Values[Offset&HRIR_MASK][1] = 0.0f; \
  169. Offset++; \
  170. \
  171. for(c = 0;c < HRIR_LENGTH;c++) \
  172. { \
  173. const ALuint off = (Offset+c)&HRIR_MASK; \
  174. Values[off][0] += Coeffs[c][0] * left; \
  175. Values[off][1] += Coeffs[c][1] * right; \
  176. Coeffs[c][0] += CoeffStep[c][0]; \
  177. Coeffs[c][1] += CoeffStep[c][1]; \
  178. } \
  179. \
  180. DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \
  181. DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \
  182. \
  183. frac += increment; \
  184. pos += frac>>FRACTIONBITS; \
  185. frac &= FRACTIONMASK; \
  186. OutPos++; \
  187. Counter--; \
  188. } \
  189. \
  190. Delay[0] >>= 16; \
  191. Delay[1] >>= 16; \
  192. for(;BufferIdx < BufferSize;BufferIdx++) \
  193. { \
  194. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  195. value = lpFilter2P(DryFilter, i, value); \
  196. \
  197. History[Offset&SRC_HISTORY_MASK] = value; \
  198. left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \
  199. right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \
  200. \
  201. Values[Offset&HRIR_MASK][0] = 0.0f; \
  202. Values[Offset&HRIR_MASK][1] = 0.0f; \
  203. Offset++; \
  204. \
  205. ApplyCoeffs(Offset, Values, Coeffs, left, right); \
  206. DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \
  207. DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \
  208. \
  209. frac += increment; \
  210. pos += frac>>FRACTIONBITS; \
  211. frac &= FRACTIONMASK; \
  212. OutPos++; \
  213. } \
  214. if(LIKELY(OutPos == SamplesToDo)) \
  215. { \
  216. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  217. value = lpFilter2PC(DryFilter, i, value); \
  218. \
  219. History[Offset&SRC_HISTORY_MASK] = value; \
  220. left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \
  221. right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \
  222. \
  223. PendingClicks[FRONT_LEFT] += Values[(Offset+1)&HRIR_MASK][0] + \
  224. Coeffs[0][0] * left; \
  225. PendingClicks[FRONT_RIGHT] += Values[(Offset+1)&HRIR_MASK][1] + \
  226. Coeffs[0][1] * right; \
  227. } \
  228. OutPos -= BufferSize; \
  229. } \
  230. \
  231. for(out = 0;out < Device->NumAuxSends;out++) \
  232. { \
  233. ALeffectslot *Slot = Source->Params.Send[out].Slot; \
  234. ALfloat WetSend; \
  235. ALfloat *RESTRICT WetBuffer; \
  236. ALfloat *RESTRICT WetClickRemoval; \
  237. ALfloat *RESTRICT WetPendingClicks; \
  238. FILTER *WetFilter; \
  239. \
  240. if(Slot == NULL) \
  241. continue; \
  242. \
  243. WetBuffer = Slot->WetBuffer; \
  244. WetClickRemoval = Slot->ClickRemoval; \
  245. WetPendingClicks = Slot->PendingClicks; \
  246. WetFilter = &Source->Params.Send[out].iirFilter; \
  247. WetSend = Source->Params.Send[out].WetGain; \
  248. \
  249. for(i = 0;i < NumChannels;i++) \
  250. { \
  251. pos = 0; \
  252. frac = *DataPosFrac; \
  253. \
  254. if(LIKELY(OutPos == 0)) \
  255. { \
  256. value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
  257. value = lpFilter1PC(WetFilter, i, value); \
  258. \
  259. WetClickRemoval[0] -= value * WetSend; \
  260. } \
  261. for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
  262. { \
  263. value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
  264. value = lpFilter1P(WetFilter, i, value); \
  265. \
  266. WetBuffer[OutPos] += value * WetSend; \
  267. \
  268. frac += increment; \
  269. pos += frac>>FRACTIONBITS; \
  270. frac &= FRACTIONMASK; \
  271. OutPos++; \
  272. } \
  273. if(LIKELY(OutPos == SamplesToDo)) \
  274. { \
  275. value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
  276. value = lpFilter1PC(WetFilter, i, value); \
  277. \
  278. WetPendingClicks[0] += value * WetSend; \
  279. } \
  280. OutPos -= BufferSize; \
  281. } \
  282. } \
  283. *DataPosInt += pos; \
  284. *DataPosFrac = frac; \
  285. }
  286. DECL_TEMPLATE(ALfloat, point32)
  287. DECL_TEMPLATE(ALfloat, lerp32)
  288. DECL_TEMPLATE(ALfloat, cubic32)
  289. #undef DECL_TEMPLATE
  290. #define DECL_TEMPLATE(T, sampler) \
  291. static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
  292. const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
  293. ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
  294. { \
  295. const ALuint NumChannels = Source->NumChannels; \
  296. const T *RESTRICT data = srcdata; \
  297. ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
  298. ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
  299. ALfloat DrySend[MAXCHANNELS]; \
  300. FILTER *DryFilter; \
  301. ALuint pos, frac; \
  302. ALuint BufferIdx; \
  303. ALuint increment; \
  304. ALuint i, out, c; \
  305. ALfloat value; \
  306. \
  307. increment = Source->Params.Step; \
  308. \
  309. DryBuffer = Device->DryBuffer; \
  310. ClickRemoval = Device->ClickRemoval; \
  311. PendingClicks = Device->PendingClicks; \
  312. DryFilter = &Source->Params.iirFilter; \
  313. \
  314. pos = 0; \
  315. frac = *DataPosFrac; \
  316. \
  317. for(i = 0;i < NumChannels;i++) \
  318. { \
  319. for(c = 0;c < MAXCHANNELS;c++) \
  320. DrySend[c] = Source->Params.DryGains[i][c]; \
  321. \
  322. pos = 0; \
  323. frac = *DataPosFrac; \
  324. \
  325. if(OutPos == 0) \
  326. { \
  327. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  328. \
  329. value = lpFilter2PC(DryFilter, i, value); \
  330. for(c = 0;c < MAXCHANNELS;c++) \
  331. ClickRemoval[c] -= value*DrySend[c]; \
  332. } \
  333. for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
  334. { \
  335. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  336. \
  337. value = lpFilter2P(DryFilter, i, value); \
  338. for(c = 0;c < MAXCHANNELS;c++) \
  339. DryBuffer[OutPos][c] += value*DrySend[c]; \
  340. \
  341. frac += increment; \
  342. pos += frac>>FRACTIONBITS; \
  343. frac &= FRACTIONMASK; \
  344. OutPos++; \
  345. } \
  346. if(OutPos == SamplesToDo) \
  347. { \
  348. value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
  349. \
  350. value = lpFilter2PC(DryFilter, i, value); \
  351. for(c = 0;c < MAXCHANNELS;c++) \
  352. PendingClicks[c] += value*DrySend[c]; \
  353. } \
  354. OutPos -= BufferSize; \
  355. } \
  356. \
  357. for(out = 0;out < Device->NumAuxSends;out++) \
  358. { \
  359. ALeffectslot *Slot = Source->Params.Send[out].Slot; \
  360. ALfloat WetSend; \
  361. ALfloat *WetBuffer; \
  362. ALfloat *WetClickRemoval; \
  363. ALfloat *WetPendingClicks; \
  364. FILTER *WetFilter; \
  365. \
  366. if(Slot == NULL) \
  367. continue; \
  368. \
  369. WetBuffer = Slot->WetBuffer; \
  370. WetClickRemoval = Slot->ClickRemoval; \
  371. WetPendingClicks = Slot->PendingClicks; \
  372. WetFilter = &Source->Params.Send[out].iirFilter; \
  373. WetSend = Source->Params.Send[out].WetGain; \
  374. \
  375. for(i = 0;i < NumChannels;i++) \
  376. { \
  377. pos = 0; \
  378. frac = *DataPosFrac; \
  379. \
  380. if(OutPos == 0) \
  381. { \
  382. value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
  383. \
  384. value = lpFilter1PC(WetFilter, i, value); \
  385. WetClickRemoval[0] -= value * WetSend; \
  386. } \
  387. for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
  388. { \
  389. value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
  390. \
  391. value = lpFilter1P(WetFilter, i, value); \
  392. WetBuffer[OutPos] += value * WetSend; \
  393. \
  394. frac += increment; \
  395. pos += frac>>FRACTIONBITS; \
  396. frac &= FRACTIONMASK; \
  397. OutPos++; \
  398. } \
  399. if(OutPos == SamplesToDo) \
  400. { \
  401. value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
  402. \
  403. value = lpFilter1PC(WetFilter, i, value); \
  404. WetPendingClicks[0] += value * WetSend; \
  405. } \
  406. OutPos -= BufferSize; \
  407. } \
  408. } \
  409. *DataPosInt += pos; \
  410. *DataPosFrac = frac; \
  411. }
  412. DECL_TEMPLATE(ALfloat, point32)
  413. DECL_TEMPLATE(ALfloat, lerp32)
  414. DECL_TEMPLATE(ALfloat, cubic32)
  415. #undef DECL_TEMPLATE
  416. MixerFunc SelectMixer(enum Resampler Resampler)
  417. {
  418. switch(Resampler)
  419. {
  420. case PointResampler:
  421. return Mix_ALfloat_point32;
  422. case LinearResampler:
  423. return Mix_ALfloat_lerp32;
  424. case CubicResampler:
  425. return Mix_ALfloat_cubic32;
  426. case ResamplerMax:
  427. break;
  428. }
  429. return NULL;
  430. }
  431. MixerFunc SelectHrtfMixer(enum Resampler Resampler)
  432. {
  433. switch(Resampler)
  434. {
  435. case PointResampler:
  436. return Mix_Hrtf_ALfloat_point32;
  437. case LinearResampler:
  438. return Mix_Hrtf_ALfloat_lerp32;
  439. case CubicResampler:
  440. return Mix_Hrtf_ALfloat_cubic32;
  441. case ResamplerMax:
  442. break;
  443. }
  444. return NULL;
  445. }
  446. static __inline ALfloat Sample_ALbyte(ALbyte val)
  447. { return val * (1.0f/127.0f); }
  448. static __inline ALfloat Sample_ALshort(ALshort val)
  449. { return val * (1.0f/32767.0f); }
  450. static __inline ALfloat Sample_ALfloat(ALfloat val)
  451. { return val; }
  452. #define DECL_TEMPLATE(T) \
  453. static void Load_##T(ALfloat *dst, const T *src, ALuint samples) \
  454. { \
  455. ALuint i; \
  456. for(i = 0;i < samples;i++) \
  457. dst[i] = Sample_##T(src[i]); \
  458. }
  459. DECL_TEMPLATE(ALbyte)
  460. DECL_TEMPLATE(ALshort)
  461. DECL_TEMPLATE(ALfloat)
  462. #undef DECL_TEMPLATE
  463. static void LoadStack(ALfloat *dst, const ALvoid *src, enum FmtType srctype, ALuint samples)
  464. {
  465. switch(srctype)
  466. {
  467. case FmtByte:
  468. Load_ALbyte(dst, src, samples);
  469. break;
  470. case FmtShort:
  471. Load_ALshort(dst, src, samples);
  472. break;
  473. case FmtFloat:
  474. Load_ALfloat(dst, src, samples);
  475. break;
  476. }
  477. }
  478. static void SilenceStack(ALfloat *dst, ALuint samples)
  479. {
  480. ALuint i;
  481. for(i = 0;i < samples;i++)
  482. dst[i] = 0.0f;
  483. }
  484. ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
  485. {
  486. ALbufferlistitem *BufferListItem;
  487. ALuint DataPosInt, DataPosFrac;
  488. ALuint BuffersPlayed;
  489. ALboolean Looping;
  490. ALuint increment;
  491. enum Resampler Resampler;
  492. ALenum State;
  493. ALuint OutPos;
  494. ALuint NumChannels;
  495. ALuint FrameSize;
  496. ALint64 DataSize64;
  497. ALuint i;
  498. /* Get source info */
  499. State = Source->state;
  500. BuffersPlayed = Source->BuffersPlayed;
  501. DataPosInt = Source->position;
  502. DataPosFrac = Source->position_fraction;
  503. Looping = Source->bLooping;
  504. increment = Source->Params.Step;
  505. Resampler = Source->Resampler;
  506. NumChannels = Source->NumChannels;
  507. FrameSize = NumChannels * Source->SampleSize;
  508. /* Get current buffer queue item */
  509. BufferListItem = Source->queue;
  510. for(i = 0;i < BuffersPlayed;i++)
  511. BufferListItem = BufferListItem->next;
  512. OutPos = 0;
  513. do {
  514. const ALuint BufferPrePadding = ResamplerPrePadding[Resampler];
  515. const ALuint BufferPadding = ResamplerPadding[Resampler];
  516. ALfloat StackData[STACK_DATA_SIZE/sizeof(ALfloat)];
  517. ALfloat *SrcData = StackData;
  518. ALuint SrcDataSize = 0;
  519. ALuint BufferSize;
  520. /* Figure out how many buffer bytes will be needed */
  521. DataSize64 = SamplesToDo-OutPos+1;
  522. DataSize64 *= increment;
  523. DataSize64 += DataPosFrac+FRACTIONMASK;
  524. DataSize64 >>= FRACTIONBITS;
  525. DataSize64 += BufferPadding+BufferPrePadding;
  526. DataSize64 *= NumChannels;
  527. BufferSize = (ALuint)mini64(DataSize64, STACK_DATA_SIZE/sizeof(ALfloat));
  528. BufferSize /= NumChannels;
  529. if(Source->lSourceType == AL_STATIC)
  530. {
  531. const ALbuffer *ALBuffer = Source->queue->buffer;
  532. const ALubyte *Data = ALBuffer->data;
  533. ALuint DataSize;
  534. ALuint pos;
  535. /* If current pos is beyond the loop range, do not loop */
  536. if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd)
  537. {
  538. Looping = AL_FALSE;
  539. if(DataPosInt >= BufferPrePadding)
  540. pos = DataPosInt - BufferPrePadding;
  541. else
  542. {
  543. DataSize = BufferPrePadding - DataPosInt;
  544. DataSize = minu(BufferSize, DataSize);
  545. SilenceStack(&SrcData[SrcDataSize*NumChannels],
  546. DataSize*NumChannels);
  547. SrcDataSize += DataSize;
  548. BufferSize -= DataSize;
  549. pos = 0;
  550. }
  551. /* Copy what's left to play in the source buffer, and clear the
  552. * rest of the temp buffer */
  553. DataSize = ALBuffer->SampleLen - pos;
  554. DataSize = minu(BufferSize, DataSize);
  555. LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
  556. ALBuffer->FmtType, DataSize*NumChannels);
  557. SrcDataSize += DataSize;
  558. BufferSize -= DataSize;
  559. SilenceStack(&SrcData[SrcDataSize*NumChannels],
  560. BufferSize*NumChannels);
  561. SrcDataSize += BufferSize;
  562. BufferSize -= BufferSize;
  563. }
  564. else
  565. {
  566. ALuint LoopStart = ALBuffer->LoopStart;
  567. ALuint LoopEnd = ALBuffer->LoopEnd;
  568. if(DataPosInt >= LoopStart)
  569. {
  570. pos = DataPosInt-LoopStart;
  571. while(pos < BufferPrePadding)
  572. pos += LoopEnd-LoopStart;
  573. pos -= BufferPrePadding;
  574. pos += LoopStart;
  575. }
  576. else if(DataPosInt >= BufferPrePadding)
  577. pos = DataPosInt - BufferPrePadding;
  578. else
  579. {
  580. DataSize = BufferPrePadding - DataPosInt;
  581. DataSize = minu(BufferSize, DataSize);
  582. SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
  583. SrcDataSize += DataSize;
  584. BufferSize -= DataSize;
  585. pos = 0;
  586. }
  587. /* Copy what's left of this loop iteration, then copy repeats
  588. * of the loop section */
  589. DataSize = LoopEnd - pos;
  590. DataSize = minu(BufferSize, DataSize);
  591. LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
  592. ALBuffer->FmtType, DataSize*NumChannels);
  593. SrcDataSize += DataSize;
  594. BufferSize -= DataSize;
  595. DataSize = LoopEnd-LoopStart;
  596. while(BufferSize > 0)
  597. {
  598. DataSize = minu(BufferSize, DataSize);
  599. LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[LoopStart*FrameSize],
  600. ALBuffer->FmtType, DataSize*NumChannels);
  601. SrcDataSize += DataSize;
  602. BufferSize -= DataSize;
  603. }
  604. }
  605. }
  606. else
  607. {
  608. /* Crawl the buffer queue to fill in the temp buffer */
  609. ALbufferlistitem *tmpiter = BufferListItem;
  610. ALuint pos;
  611. if(DataPosInt >= BufferPrePadding)
  612. pos = DataPosInt - BufferPrePadding;
  613. else
  614. {
  615. pos = BufferPrePadding - DataPosInt;
  616. while(pos > 0)
  617. {
  618. if(!tmpiter->prev && !Looping)
  619. {
  620. ALuint DataSize = minu(BufferSize, pos);
  621. SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
  622. SrcDataSize += DataSize;
  623. BufferSize -= DataSize;
  624. pos = 0;
  625. break;
  626. }
  627. if(tmpiter->prev)
  628. tmpiter = tmpiter->prev;
  629. else
  630. {
  631. while(tmpiter->next)
  632. tmpiter = tmpiter->next;
  633. }
  634. if(tmpiter->buffer)
  635. {
  636. if((ALuint)tmpiter->buffer->SampleLen > pos)
  637. {
  638. pos = tmpiter->buffer->SampleLen - pos;
  639. break;
  640. }
  641. pos -= tmpiter->buffer->SampleLen;
  642. }
  643. }
  644. }
  645. while(tmpiter && BufferSize > 0)
  646. {
  647. const ALbuffer *ALBuffer;
  648. if((ALBuffer=tmpiter->buffer) != NULL)
  649. {
  650. const ALubyte *Data = ALBuffer->data;
  651. ALuint DataSize = ALBuffer->SampleLen;
  652. /* Skip the data already played */
  653. if(DataSize <= pos)
  654. pos -= DataSize;
  655. else
  656. {
  657. Data += pos*FrameSize;
  658. DataSize -= pos;
  659. pos -= pos;
  660. DataSize = minu(BufferSize, DataSize);
  661. LoadStack(&SrcData[SrcDataSize*NumChannels], Data,
  662. ALBuffer->FmtType, DataSize*NumChannels);
  663. SrcDataSize += DataSize;
  664. BufferSize -= DataSize;
  665. }
  666. }
  667. tmpiter = tmpiter->next;
  668. if(!tmpiter && Looping)
  669. tmpiter = Source->queue;
  670. else if(!tmpiter)
  671. {
  672. SilenceStack(&SrcData[SrcDataSize*NumChannels], BufferSize*NumChannels);
  673. SrcDataSize += BufferSize;
  674. BufferSize -= BufferSize;
  675. }
  676. }
  677. }
  678. /* Figure out how many samples we can mix. */
  679. DataSize64 = SrcDataSize;
  680. DataSize64 -= BufferPadding+BufferPrePadding;
  681. DataSize64 <<= FRACTIONBITS;
  682. DataSize64 -= increment;
  683. DataSize64 -= DataPosFrac;
  684. BufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
  685. BufferSize = minu(BufferSize, (SamplesToDo-OutPos));
  686. SrcData += BufferPrePadding*NumChannels;
  687. Source->Params.DoMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac,
  688. OutPos, SamplesToDo, BufferSize);
  689. OutPos += BufferSize;
  690. /* Handle looping sources */
  691. while(1)
  692. {
  693. const ALbuffer *ALBuffer;
  694. ALuint DataSize = 0;
  695. ALuint LoopStart = 0;
  696. ALuint LoopEnd = 0;
  697. if((ALBuffer=BufferListItem->buffer) != NULL)
  698. {
  699. DataSize = ALBuffer->SampleLen;
  700. LoopStart = ALBuffer->LoopStart;
  701. LoopEnd = ALBuffer->LoopEnd;
  702. if(LoopEnd > DataPosInt)
  703. break;
  704. }
  705. if(Looping && Source->lSourceType == AL_STATIC)
  706. {
  707. DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
  708. break;
  709. }
  710. if(DataSize > DataPosInt)
  711. break;
  712. if(BufferListItem->next)
  713. {
  714. BufferListItem = BufferListItem->next;
  715. BuffersPlayed++;
  716. }
  717. else if(Looping)
  718. {
  719. BufferListItem = Source->queue;
  720. BuffersPlayed = 0;
  721. }
  722. else
  723. {
  724. State = AL_STOPPED;
  725. BufferListItem = Source->queue;
  726. BuffersPlayed = Source->BuffersInQueue;
  727. DataPosInt = 0;
  728. DataPosFrac = 0;
  729. break;
  730. }
  731. DataPosInt -= DataSize;
  732. }
  733. } while(State == AL_PLAYING && OutPos < SamplesToDo);
  734. /* Update source info */
  735. Source->state = State;
  736. Source->BuffersPlayed = BuffersPlayed;
  737. Source->position = DataPosInt;
  738. Source->position_fraction = DataPosFrac;
  739. Source->HrtfOffset += OutPos;
  740. if(State == AL_PLAYING)
  741. {
  742. Source->HrtfCounter = maxu(Source->HrtfCounter, OutPos) - OutPos;
  743. Source->HrtfMoving = AL_TRUE;
  744. }
  745. else
  746. {
  747. Source->HrtfCounter = 0;
  748. Source->HrtfMoving = AL_FALSE;
  749. }
  750. }