voice.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  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 "voice.h"
  22. #include <algorithm>
  23. #include <array>
  24. #include <atomic>
  25. #include <cassert>
  26. #include <climits>
  27. #include <cstddef>
  28. #include <cstdint>
  29. #include <iterator>
  30. #include <memory>
  31. #include <new>
  32. #include <utility>
  33. #include "alcmain.h"
  34. #include "albyte.h"
  35. #include "alconfig.h"
  36. #include "alcontext.h"
  37. #include "alnumeric.h"
  38. #include "aloptional.h"
  39. #include "alspan.h"
  40. #include "alstring.h"
  41. #include "alu.h"
  42. #include "async_event.h"
  43. #include "buffer_storage.h"
  44. #include "core/cpu_caps.h"
  45. #include "core/devformat.h"
  46. #include "core/filters/biquad.h"
  47. #include "core/filters/nfc.h"
  48. #include "core/filters/splitter.h"
  49. #include "core/fmt_traits.h"
  50. #include "core/logging.h"
  51. #include "core/mixer/defs.h"
  52. #include "core/mixer/hrtfdefs.h"
  53. #include "hrtf.h"
  54. #include "inprogext.h"
  55. #include "opthelpers.h"
  56. #include "ringbuffer.h"
  57. #include "threads.h"
  58. #include "vector.h"
  59. #include "voice_change.h"
  60. struct CTag;
  61. #ifdef HAVE_SSE
  62. struct SSETag;
  63. #endif
  64. #ifdef HAVE_NEON
  65. struct NEONTag;
  66. #endif
  67. struct CopyTag;
  68. Resampler ResamplerDefault{Resampler::Linear};
  69. MixerFunc MixSamples{Mix_<CTag>};
  70. namespace {
  71. using HrtfMixerFunc = void(*)(const float *InSamples, float2 *AccumSamples, const uint IrSize,
  72. const MixHrtfFilter *hrtfparams, const size_t BufferSize);
  73. using HrtfMixerBlendFunc = void(*)(const float *InSamples, float2 *AccumSamples,
  74. const uint IrSize, const HrtfFilter *oldparams, const MixHrtfFilter *newparams,
  75. const size_t BufferSize);
  76. HrtfMixerFunc MixHrtfSamples{MixHrtf_<CTag>};
  77. HrtfMixerBlendFunc MixHrtfBlendSamples{MixHrtfBlend_<CTag>};
  78. inline MixerFunc SelectMixer()
  79. {
  80. #ifdef HAVE_NEON
  81. if((CPUCapFlags&CPU_CAP_NEON))
  82. return Mix_<NEONTag>;
  83. #endif
  84. #ifdef HAVE_SSE
  85. if((CPUCapFlags&CPU_CAP_SSE))
  86. return Mix_<SSETag>;
  87. #endif
  88. return Mix_<CTag>;
  89. }
  90. inline HrtfMixerFunc SelectHrtfMixer()
  91. {
  92. #ifdef HAVE_NEON
  93. if((CPUCapFlags&CPU_CAP_NEON))
  94. return MixHrtf_<NEONTag>;
  95. #endif
  96. #ifdef HAVE_SSE
  97. if((CPUCapFlags&CPU_CAP_SSE))
  98. return MixHrtf_<SSETag>;
  99. #endif
  100. return MixHrtf_<CTag>;
  101. }
  102. inline HrtfMixerBlendFunc SelectHrtfBlendMixer()
  103. {
  104. #ifdef HAVE_NEON
  105. if((CPUCapFlags&CPU_CAP_NEON))
  106. return MixHrtfBlend_<NEONTag>;
  107. #endif
  108. #ifdef HAVE_SSE
  109. if((CPUCapFlags&CPU_CAP_SSE))
  110. return MixHrtfBlend_<SSETag>;
  111. #endif
  112. return MixHrtfBlend_<CTag>;
  113. }
  114. } // namespace
  115. void aluInitMixer()
  116. {
  117. if(auto resopt = ConfigValueStr(nullptr, nullptr, "resampler"))
  118. {
  119. struct ResamplerEntry {
  120. const char name[16];
  121. const Resampler resampler;
  122. };
  123. constexpr ResamplerEntry ResamplerList[]{
  124. { "none", Resampler::Point },
  125. { "point", Resampler::Point },
  126. { "linear", Resampler::Linear },
  127. { "cubic", Resampler::Cubic },
  128. { "bsinc12", Resampler::BSinc12 },
  129. { "fast_bsinc12", Resampler::FastBSinc12 },
  130. { "bsinc24", Resampler::BSinc24 },
  131. { "fast_bsinc24", Resampler::FastBSinc24 },
  132. };
  133. const char *str{resopt->c_str()};
  134. if(al::strcasecmp(str, "bsinc") == 0)
  135. {
  136. WARN("Resampler option \"%s\" is deprecated, using bsinc12\n", str);
  137. str = "bsinc12";
  138. }
  139. else if(al::strcasecmp(str, "sinc4") == 0 || al::strcasecmp(str, "sinc8") == 0)
  140. {
  141. WARN("Resampler option \"%s\" is deprecated, using cubic\n", str);
  142. str = "cubic";
  143. }
  144. auto iter = std::find_if(std::begin(ResamplerList), std::end(ResamplerList),
  145. [str](const ResamplerEntry &entry) -> bool
  146. { return al::strcasecmp(str, entry.name) == 0; });
  147. if(iter == std::end(ResamplerList))
  148. ERR("Invalid resampler: %s\n", str);
  149. else
  150. ResamplerDefault = iter->resampler;
  151. }
  152. MixSamples = SelectMixer();
  153. MixHrtfBlendSamples = SelectHrtfBlendMixer();
  154. MixHrtfSamples = SelectHrtfMixer();
  155. }
  156. namespace {
  157. void SendSourceStoppedEvent(ALCcontext *context, uint id)
  158. {
  159. RingBuffer *ring{context->mAsyncEvents.get()};
  160. auto evt_vec = ring->getWriteVector();
  161. if(evt_vec.first.len < 1) return;
  162. AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_SourceStateChange}};
  163. evt->u.srcstate.id = id;
  164. evt->u.srcstate.state = VChangeState::Stop;
  165. ring->writeAdvance(1);
  166. }
  167. const float *DoFilters(BiquadFilter &lpfilter, BiquadFilter &hpfilter, float *dst,
  168. const al::span<const float> src, int type)
  169. {
  170. switch(type)
  171. {
  172. case AF_None:
  173. lpfilter.clear();
  174. hpfilter.clear();
  175. break;
  176. case AF_LowPass:
  177. lpfilter.process(src, dst);
  178. hpfilter.clear();
  179. return dst;
  180. case AF_HighPass:
  181. lpfilter.clear();
  182. hpfilter.process(src, dst);
  183. return dst;
  184. case AF_BandPass:
  185. DualBiquad{lpfilter, hpfilter}.process(src, dst);
  186. return dst;
  187. }
  188. return src.data();
  189. }
  190. void LoadSamples(float *RESTRICT dst, const al::byte *src, const size_t srcstep, FmtType srctype,
  191. const size_t samples) noexcept
  192. {
  193. #define HANDLE_FMT(T) case T: al::LoadSampleArray<T>(dst, src, srcstep, samples); break
  194. switch(srctype)
  195. {
  196. HANDLE_FMT(FmtUByte);
  197. HANDLE_FMT(FmtShort);
  198. HANDLE_FMT(FmtFloat);
  199. HANDLE_FMT(FmtDouble);
  200. HANDLE_FMT(FmtMulaw);
  201. HANDLE_FMT(FmtAlaw);
  202. }
  203. #undef HANDLE_FMT
  204. }
  205. float *LoadBufferStatic(VoiceBufferItem *buffer, VoiceBufferItem *&bufferLoopItem,
  206. const size_t numChannels, const FmtType sampleType, const size_t sampleSize, const size_t chan,
  207. size_t dataPosInt, al::span<float> srcBuffer)
  208. {
  209. const uint LoopStart{buffer->mLoopStart};
  210. const uint LoopEnd{buffer->mLoopEnd};
  211. ASSUME(LoopEnd > LoopStart);
  212. /* If current pos is beyond the loop range, do not loop */
  213. if(!bufferLoopItem || dataPosInt >= LoopEnd)
  214. {
  215. bufferLoopItem = nullptr;
  216. /* Load what's left to play from the buffer */
  217. const size_t DataRem{minz(srcBuffer.size(), buffer->mSampleLen-dataPosInt)};
  218. const al::byte *Data{buffer->mSamples + (dataPosInt*numChannels + chan)*sampleSize};
  219. LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem);
  220. srcBuffer = srcBuffer.subspan(DataRem);
  221. }
  222. else
  223. {
  224. /* Load what's left of this loop iteration */
  225. const size_t DataRem{minz(srcBuffer.size(), LoopEnd-dataPosInt)};
  226. const al::byte *Data{buffer->mSamples + (dataPosInt*numChannels + chan)*sampleSize};
  227. LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem);
  228. srcBuffer = srcBuffer.subspan(DataRem);
  229. /* Load any repeats of the loop we can to fill the buffer. */
  230. const auto LoopSize = static_cast<size_t>(LoopEnd - LoopStart);
  231. while(!srcBuffer.empty())
  232. {
  233. const size_t DataSize{minz(srcBuffer.size(), LoopSize)};
  234. Data = buffer->mSamples + (LoopStart*numChannels + chan)*sampleSize;
  235. LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataSize);
  236. srcBuffer = srcBuffer.subspan(DataSize);
  237. }
  238. }
  239. return srcBuffer.begin();
  240. }
  241. float *LoadBufferCallback(VoiceBufferItem *buffer, const size_t numChannels,
  242. const FmtType sampleType, const size_t sampleSize, const size_t chan,
  243. size_t numCallbackSamples, al::span<float> srcBuffer)
  244. {
  245. /* Load what's left to play from the buffer */
  246. const size_t DataRem{minz(srcBuffer.size(), numCallbackSamples)};
  247. const al::byte *Data{buffer->mSamples + chan*sampleSize};
  248. LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem);
  249. srcBuffer = srcBuffer.subspan(DataRem);
  250. return srcBuffer.begin();
  251. }
  252. float *LoadBufferQueue(VoiceBufferItem *buffer, VoiceBufferItem *bufferLoopItem,
  253. const size_t numChannels, const FmtType sampleType, const size_t sampleSize, const size_t chan,
  254. size_t dataPosInt, al::span<float> srcBuffer)
  255. {
  256. /* Crawl the buffer queue to fill in the temp buffer */
  257. while(buffer && !srcBuffer.empty())
  258. {
  259. if(dataPosInt >= buffer->mSampleLen)
  260. {
  261. dataPosInt -= buffer->mSampleLen;
  262. buffer = buffer->mNext.load(std::memory_order_acquire);
  263. if(!buffer) buffer = bufferLoopItem;
  264. continue;
  265. }
  266. const size_t DataSize{minz(srcBuffer.size(), buffer->mSampleLen-dataPosInt)};
  267. const al::byte *Data{buffer->mSamples + (dataPosInt*numChannels + chan)*sampleSize};
  268. LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataSize);
  269. srcBuffer = srcBuffer.subspan(DataSize);
  270. if(srcBuffer.empty()) break;
  271. dataPosInt = 0;
  272. buffer = buffer->mNext.load(std::memory_order_acquire);
  273. if(!buffer) buffer = bufferLoopItem;
  274. }
  275. return srcBuffer.begin();
  276. }
  277. void DoHrtfMix(const float *samples, const uint DstBufferSize, DirectParams &parms,
  278. const float TargetGain, const uint Counter, uint OutPos, const uint IrSize,
  279. ALCdevice *Device)
  280. {
  281. auto &HrtfSamples = Device->HrtfSourceData;
  282. /* Source HRTF mixing needs to include the direct delay so it remains
  283. * aligned with the direct mix's HRTF filtering.
  284. */
  285. float2 *AccumSamples{Device->HrtfAccumData + HrtfDirectDelay};
  286. /* Copy the HRTF history and new input samples into a temp buffer. */
  287. auto src_iter = std::copy(parms.Hrtf.History.begin(), parms.Hrtf.History.end(),
  288. std::begin(HrtfSamples));
  289. std::copy_n(samples, DstBufferSize, src_iter);
  290. /* Copy the last used samples back into the history buffer for later. */
  291. std::copy_n(std::begin(HrtfSamples) + DstBufferSize, parms.Hrtf.History.size(),
  292. parms.Hrtf.History.begin());
  293. /* If fading and this is the first mixing pass, fade between the IRs. */
  294. uint fademix{0u};
  295. if(Counter && OutPos == 0)
  296. {
  297. fademix = minu(DstBufferSize, Counter);
  298. float gain{TargetGain};
  299. /* The new coefficients need to fade in completely since they're
  300. * replacing the old ones. To keep the gain fading consistent,
  301. * interpolate between the old and new target gains given how much of
  302. * the fade time this mix handles.
  303. */
  304. if(Counter > fademix)
  305. {
  306. const float a{static_cast<float>(fademix) / static_cast<float>(Counter)};
  307. gain = lerp(parms.Hrtf.Old.Gain, TargetGain, a);
  308. }
  309. MixHrtfFilter hrtfparams;
  310. hrtfparams.Coeffs = &parms.Hrtf.Target.Coeffs;
  311. hrtfparams.Delay = parms.Hrtf.Target.Delay;
  312. hrtfparams.Gain = 0.0f;
  313. hrtfparams.GainStep = gain / static_cast<float>(fademix);
  314. MixHrtfBlendSamples(HrtfSamples, AccumSamples+OutPos, IrSize, &parms.Hrtf.Old, &hrtfparams,
  315. fademix);
  316. /* Update the old parameters with the result. */
  317. parms.Hrtf.Old = parms.Hrtf.Target;
  318. parms.Hrtf.Old.Gain = gain;
  319. OutPos += fademix;
  320. }
  321. if(fademix < DstBufferSize)
  322. {
  323. const uint todo{DstBufferSize - fademix};
  324. float gain{TargetGain};
  325. /* Interpolate the target gain if the gain fading lasts longer than
  326. * this mix.
  327. */
  328. if(Counter > DstBufferSize)
  329. {
  330. const float a{static_cast<float>(todo) / static_cast<float>(Counter-fademix)};
  331. gain = lerp(parms.Hrtf.Old.Gain, TargetGain, a);
  332. }
  333. MixHrtfFilter hrtfparams;
  334. hrtfparams.Coeffs = &parms.Hrtf.Target.Coeffs;
  335. hrtfparams.Delay = parms.Hrtf.Target.Delay;
  336. hrtfparams.Gain = parms.Hrtf.Old.Gain;
  337. hrtfparams.GainStep = (gain - parms.Hrtf.Old.Gain) / static_cast<float>(todo);
  338. MixHrtfSamples(HrtfSamples+fademix, AccumSamples+OutPos, IrSize, &hrtfparams, todo);
  339. /* Store the now-current gain for next time. */
  340. parms.Hrtf.Old.Gain = gain;
  341. }
  342. }
  343. void DoNfcMix(const al::span<const float> samples, FloatBufferLine *OutBuffer, DirectParams &parms,
  344. const float *TargetGains, const uint Counter, const uint OutPos, ALCdevice *Device)
  345. {
  346. using FilterProc = void (NfcFilter::*)(const al::span<const float>, float*);
  347. static constexpr FilterProc NfcProcess[MaxAmbiOrder+1]{
  348. nullptr, &NfcFilter::process1, &NfcFilter::process2, &NfcFilter::process3};
  349. float *CurrentGains{parms.Gains.Current.data()};
  350. MixSamples(samples, {OutBuffer, 1u}, CurrentGains, TargetGains, Counter, OutPos);
  351. ++OutBuffer;
  352. ++CurrentGains;
  353. ++TargetGains;
  354. const al::span<float> nfcsamples{Device->NfcSampleData, samples.size()};
  355. size_t order{1};
  356. while(const size_t chancount{Device->NumChannelsPerOrder[order]})
  357. {
  358. (parms.NFCtrlFilter.*NfcProcess[order])(samples, nfcsamples.data());
  359. MixSamples(nfcsamples, {OutBuffer, chancount}, CurrentGains, TargetGains, Counter, OutPos);
  360. OutBuffer += chancount;
  361. CurrentGains += chancount;
  362. TargetGains += chancount;
  363. if(++order == MaxAmbiOrder+1)
  364. break;
  365. }
  366. }
  367. } // namespace
  368. void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo)
  369. {
  370. static constexpr std::array<float,MAX_OUTPUT_CHANNELS> SilentTarget{};
  371. ASSUME(SamplesToDo > 0);
  372. /* Get voice info */
  373. uint DataPosInt{mPosition.load(std::memory_order_relaxed)};
  374. uint DataPosFrac{mPositionFrac.load(std::memory_order_relaxed)};
  375. VoiceBufferItem *BufferListItem{mCurrentBuffer.load(std::memory_order_relaxed)};
  376. VoiceBufferItem *BufferLoopItem{mLoopBuffer.load(std::memory_order_relaxed)};
  377. const FmtType SampleType{mFmtType};
  378. const uint SampleSize{mSampleSize};
  379. const uint increment{mStep};
  380. if UNLIKELY(increment < 1)
  381. {
  382. /* If the voice is supposed to be stopping but can't be mixed, just
  383. * stop it before bailing.
  384. */
  385. if(vstate == Stopping)
  386. mPlayState.store(Stopped, std::memory_order_release);
  387. return;
  388. }
  389. ASSUME(SampleSize > 0);
  390. const size_t FrameSize{mChans.size() * SampleSize};
  391. ASSUME(FrameSize > 0);
  392. ALCdevice *Device{Context->mDevice.get()};
  393. const uint NumSends{Device->NumAuxSends};
  394. const uint IrSize{Device->mIrSize};
  395. ResamplerFunc Resample{(increment == MixerFracOne && DataPosFrac == 0) ?
  396. Resample_<CopyTag,CTag> : mResampler};
  397. uint Counter{(mFlags&VoiceIsFading) ? SamplesToDo : 0};
  398. if(!Counter)
  399. {
  400. /* No fading, just overwrite the old/current params. */
  401. for(auto &chandata : mChans)
  402. {
  403. {
  404. DirectParams &parms = chandata.mDryParams;
  405. if(!(mFlags&VoiceHasHrtf))
  406. parms.Gains.Current = parms.Gains.Target;
  407. else
  408. parms.Hrtf.Old = parms.Hrtf.Target;
  409. }
  410. for(uint send{0};send < NumSends;++send)
  411. {
  412. if(mSend[send].Buffer.empty())
  413. continue;
  414. SendParams &parms = chandata.mWetParams[send];
  415. parms.Gains.Current = parms.Gains.Target;
  416. }
  417. }
  418. }
  419. float fadeCoeff{1.0f}, fadeGain{1.0f};
  420. if UNLIKELY(vstate == Stopping)
  421. {
  422. /* Calculate the multiplier for fading the resampled signal by -60dB
  423. * over 1ms.
  424. */
  425. fadeCoeff = std::pow(0.001f, 1000.0f/static_cast<float>(Device->Frequency));
  426. }
  427. uint buffers_done{0u};
  428. uint OutPos{0u};
  429. do {
  430. /* Figure out how many buffer samples will be needed */
  431. uint DstBufferSize{SamplesToDo - OutPos};
  432. uint SrcBufferSize;
  433. if(increment <= MixerFracOne)
  434. {
  435. /* Calculate the last written dst sample pos. */
  436. uint64_t DataSize64{DstBufferSize - 1};
  437. /* Calculate the last read src sample pos. */
  438. DataSize64 = (DataSize64*increment + DataPosFrac) >> MixerFracBits;
  439. /* +1 to get the src sample count, include padding. */
  440. DataSize64 += 1 + MaxResamplerPadding;
  441. /* Result is guaranteed to be <= BufferLineSize+MaxResamplerPadding
  442. * since we won't use more src samples than dst samples+padding.
  443. */
  444. SrcBufferSize = static_cast<uint>(DataSize64);
  445. }
  446. else
  447. {
  448. uint64_t DataSize64{DstBufferSize};
  449. /* Calculate the end src sample pos, include padding. */
  450. DataSize64 = (DataSize64*increment + DataPosFrac) >> MixerFracBits;
  451. DataSize64 += MaxResamplerPadding;
  452. if(DataSize64 <= BufferLineSize + MaxResamplerPadding)
  453. SrcBufferSize = static_cast<uint>(DataSize64);
  454. else
  455. {
  456. /* If the source size got saturated, we can't fill the desired
  457. * dst size. Figure out how many samples we can actually mix.
  458. */
  459. SrcBufferSize = BufferLineSize + MaxResamplerPadding;
  460. DataSize64 = SrcBufferSize - MaxResamplerPadding;
  461. DataSize64 = ((DataSize64<<MixerFracBits) - DataPosFrac) / increment;
  462. if(DataSize64 < DstBufferSize)
  463. {
  464. /* Some mixers require being 16-byte aligned, so also limit
  465. * to a multiple of 4 samples to maintain alignment.
  466. */
  467. DstBufferSize = static_cast<uint>(DataSize64) & ~3u;
  468. }
  469. }
  470. }
  471. if((mFlags&(VoiceIsCallback|VoiceCallbackStopped)) == VoiceIsCallback && BufferListItem)
  472. {
  473. /* Exclude resampler pre-padding from the needed size. */
  474. const uint toLoad{SrcBufferSize - (MaxResamplerPadding>>1)};
  475. if(toLoad > mNumCallbackSamples)
  476. {
  477. const size_t byteOffset{mNumCallbackSamples*FrameSize};
  478. const size_t needBytes{toLoad*FrameSize - byteOffset};
  479. const int gotBytes{BufferListItem->mCallback(BufferListItem->mUserData,
  480. &BufferListItem->mSamples[byteOffset], static_cast<int>(needBytes))};
  481. if(gotBytes < 1)
  482. mFlags |= VoiceCallbackStopped;
  483. else if(static_cast<uint>(gotBytes) < needBytes)
  484. {
  485. mFlags |= VoiceCallbackStopped;
  486. mNumCallbackSamples += static_cast<uint>(static_cast<uint>(gotBytes) /
  487. FrameSize);
  488. }
  489. else
  490. mNumCallbackSamples = toLoad;
  491. }
  492. }
  493. const float fadeVal{fadeGain};
  494. const size_t num_chans{mChans.size()};
  495. size_t chan_idx{0};
  496. ASSUME(DstBufferSize > 0);
  497. for(auto &chandata : mChans)
  498. {
  499. const al::span<float> SrcData{Device->SourceData, SrcBufferSize};
  500. /* Load the previous samples into the source data first, then load
  501. * what we can from the buffer queue.
  502. */
  503. auto srciter = std::copy_n(chandata.mPrevSamples.begin(), MaxResamplerPadding>>1,
  504. SrcData.begin());
  505. if UNLIKELY(!BufferListItem)
  506. srciter = std::copy(chandata.mPrevSamples.begin()+(MaxResamplerPadding>>1),
  507. chandata.mPrevSamples.end(), srciter);
  508. else if((mFlags&VoiceIsStatic))
  509. srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, num_chans, SampleType,
  510. SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()});
  511. else if((mFlags&VoiceIsCallback))
  512. srciter = LoadBufferCallback(BufferListItem, num_chans, SampleType, SampleSize,
  513. chan_idx, mNumCallbackSamples, {srciter, SrcData.end()});
  514. else
  515. srciter = LoadBufferQueue(BufferListItem, BufferLoopItem, num_chans, SampleType,
  516. SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()});
  517. if UNLIKELY(srciter != SrcData.end())
  518. {
  519. /* If the source buffer wasn't filled, copy the last sample for
  520. * the remaining buffer. Ideally it should have ended with
  521. * silence, but if not the gain fading should help avoid clicks
  522. * from sudden amplitude changes.
  523. */
  524. const float sample{*(srciter-1)};
  525. std::fill(srciter, SrcData.end(), sample);
  526. }
  527. /* Store the last source samples used for next time. */
  528. std::copy_n(&SrcData[(increment*DstBufferSize + DataPosFrac)>>MixerFracBits],
  529. chandata.mPrevSamples.size(), chandata.mPrevSamples.begin());
  530. /* Resample, then apply ambisonic upsampling as needed. */
  531. float *ResampledData{Resample(&mResampleState, &SrcData[MaxResamplerPadding>>1],
  532. DataPosFrac, increment, {Device->ResampledData, DstBufferSize})};
  533. if((mFlags&VoiceIsAmbisonic))
  534. chandata.mAmbiSplitter.processHfScale({ResampledData, DstBufferSize},
  535. chandata.mAmbiScale);
  536. if UNLIKELY(vstate == Stopping)
  537. {
  538. fadeGain = fadeVal;
  539. for(float &sample : al::span<float>{ResampledData, DstBufferSize})
  540. {
  541. fadeGain *= fadeCoeff;
  542. sample *= fadeGain;
  543. }
  544. }
  545. /* Now filter and mix to the appropriate outputs. */
  546. float (&FilterBuf)[BufferLineSize] = Device->FilteredData;
  547. {
  548. DirectParams &parms = chandata.mDryParams;
  549. const float *samples{DoFilters(parms.LowPass, parms.HighPass, FilterBuf,
  550. {ResampledData, DstBufferSize}, mDirect.FilterType)};
  551. if((mFlags&VoiceHasHrtf))
  552. {
  553. const float TargetGain{UNLIKELY(vstate == Stopping) ? 0.0f :
  554. parms.Hrtf.Target.Gain};
  555. DoHrtfMix(samples, DstBufferSize, parms, TargetGain, Counter, OutPos, IrSize,
  556. Device);
  557. }
  558. else if((mFlags&VoiceHasNfc))
  559. {
  560. const float *TargetGains{UNLIKELY(vstate == Stopping) ? SilentTarget.data()
  561. : parms.Gains.Target.data()};
  562. DoNfcMix({samples, DstBufferSize}, mDirect.Buffer.data(), parms, TargetGains,
  563. Counter, OutPos, Device);
  564. }
  565. else
  566. {
  567. const float *TargetGains{UNLIKELY(vstate == Stopping) ? SilentTarget.data()
  568. : parms.Gains.Target.data()};
  569. MixSamples({samples, DstBufferSize}, mDirect.Buffer,
  570. parms.Gains.Current.data(), TargetGains, Counter, OutPos);
  571. }
  572. }
  573. for(uint send{0};send < NumSends;++send)
  574. {
  575. if(mSend[send].Buffer.empty())
  576. continue;
  577. SendParams &parms = chandata.mWetParams[send];
  578. const float *samples{DoFilters(parms.LowPass, parms.HighPass, FilterBuf,
  579. {ResampledData, DstBufferSize}, mSend[send].FilterType)};
  580. const float *TargetGains{UNLIKELY(vstate == Stopping) ? SilentTarget.data()
  581. : parms.Gains.Target.data()};
  582. MixSamples({samples, DstBufferSize}, mSend[send].Buffer,
  583. parms.Gains.Current.data(), TargetGains, Counter, OutPos);
  584. }
  585. ++chan_idx;
  586. }
  587. /* Update positions */
  588. DataPosFrac += increment*DstBufferSize;
  589. const uint SrcSamplesDone{DataPosFrac>>MixerFracBits};
  590. DataPosInt += SrcSamplesDone;
  591. DataPosFrac &= MixerFracMask;
  592. OutPos += DstBufferSize;
  593. Counter = maxu(DstBufferSize, Counter) - DstBufferSize;
  594. if UNLIKELY(!BufferListItem)
  595. {
  596. /* Do nothing extra when there's no buffers. */
  597. }
  598. else if((mFlags&VoiceIsStatic))
  599. {
  600. if(BufferLoopItem)
  601. {
  602. /* Handle looping static source */
  603. const uint LoopStart{BufferListItem->mLoopStart};
  604. const uint LoopEnd{BufferListItem->mLoopEnd};
  605. if(DataPosInt >= LoopEnd)
  606. {
  607. assert(LoopEnd > LoopStart);
  608. DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
  609. }
  610. }
  611. else
  612. {
  613. /* Handle non-looping static source */
  614. if(DataPosInt >= BufferListItem->mSampleLen)
  615. {
  616. BufferListItem = nullptr;
  617. break;
  618. }
  619. }
  620. }
  621. else if((mFlags&VoiceIsCallback))
  622. {
  623. if(SrcSamplesDone < mNumCallbackSamples)
  624. {
  625. const size_t byteOffset{SrcSamplesDone*FrameSize};
  626. const size_t byteEnd{mNumCallbackSamples*FrameSize};
  627. al::byte *data{BufferListItem->mSamples};
  628. std::copy(data+byteOffset, data+byteEnd, data);
  629. mNumCallbackSamples -= SrcSamplesDone;
  630. }
  631. else
  632. {
  633. BufferListItem = nullptr;
  634. mNumCallbackSamples = 0;
  635. }
  636. }
  637. else
  638. {
  639. /* Handle streaming source */
  640. do {
  641. if(BufferListItem->mSampleLen > DataPosInt)
  642. break;
  643. DataPosInt -= BufferListItem->mSampleLen;
  644. ++buffers_done;
  645. BufferListItem = BufferListItem->mNext.load(std::memory_order_relaxed);
  646. if(!BufferListItem) BufferListItem = BufferLoopItem;
  647. } while(BufferListItem);
  648. }
  649. } while(OutPos < SamplesToDo);
  650. mFlags |= VoiceIsFading;
  651. /* Don't update positions and buffers if we were stopping. */
  652. if UNLIKELY(vstate == Stopping)
  653. {
  654. mPlayState.store(Stopped, std::memory_order_release);
  655. return;
  656. }
  657. /* Capture the source ID in case it's reset for stopping. */
  658. const uint SourceID{mSourceID.load(std::memory_order_relaxed)};
  659. /* Update voice info */
  660. mPosition.store(DataPosInt, std::memory_order_relaxed);
  661. mPositionFrac.store(DataPosFrac, std::memory_order_relaxed);
  662. mCurrentBuffer.store(BufferListItem, std::memory_order_relaxed);
  663. if(!BufferListItem)
  664. {
  665. mLoopBuffer.store(nullptr, std::memory_order_relaxed);
  666. mSourceID.store(0u, std::memory_order_relaxed);
  667. }
  668. std::atomic_thread_fence(std::memory_order_release);
  669. /* Send any events now, after the position/buffer info was updated. */
  670. const uint enabledevt{Context->mEnabledEvts.load(std::memory_order_acquire)};
  671. if(buffers_done > 0 && (enabledevt&EventType_BufferCompleted))
  672. {
  673. RingBuffer *ring{Context->mAsyncEvents.get()};
  674. auto evt_vec = ring->getWriteVector();
  675. if(evt_vec.first.len > 0)
  676. {
  677. AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_BufferCompleted}};
  678. evt->u.bufcomp.id = SourceID;
  679. evt->u.bufcomp.count = buffers_done;
  680. ring->writeAdvance(1);
  681. }
  682. }
  683. if(!BufferListItem)
  684. {
  685. /* If the voice just ended, set it to Stopping so the next render
  686. * ensures any residual noise fades to 0 amplitude.
  687. */
  688. mPlayState.store(Stopping, std::memory_order_release);
  689. if((enabledevt&EventType_SourceStateChange))
  690. SendSourceStoppedEvent(Context, SourceID);
  691. }
  692. }