voice.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  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. else if UNLIKELY(!BufferListItem)
  420. Counter = std::min(Counter, 64u);
  421. uint buffers_done{0u};
  422. uint OutPos{0u};
  423. do {
  424. /* Figure out how many buffer samples will be needed */
  425. uint DstBufferSize{SamplesToDo - OutPos};
  426. uint SrcBufferSize;
  427. if(increment <= MixerFracOne)
  428. {
  429. /* Calculate the last written dst sample pos. */
  430. uint64_t DataSize64{DstBufferSize - 1};
  431. /* Calculate the last read src sample pos. */
  432. DataSize64 = (DataSize64*increment + DataPosFrac) >> MixerFracBits;
  433. /* +1 to get the src sample count, include padding. */
  434. DataSize64 += 1 + MaxResamplerPadding;
  435. /* Result is guaranteed to be <= BufferLineSize+MaxResamplerPadding
  436. * since we won't use more src samples than dst samples+padding.
  437. */
  438. SrcBufferSize = static_cast<uint>(DataSize64);
  439. }
  440. else
  441. {
  442. uint64_t DataSize64{DstBufferSize};
  443. /* Calculate the end src sample pos, include padding. */
  444. DataSize64 = (DataSize64*increment + DataPosFrac) >> MixerFracBits;
  445. DataSize64 += MaxResamplerPadding;
  446. if(DataSize64 <= BufferLineSize + MaxResamplerPadding)
  447. SrcBufferSize = static_cast<uint>(DataSize64);
  448. else
  449. {
  450. /* If the source size got saturated, we can't fill the desired
  451. * dst size. Figure out how many samples we can actually mix.
  452. */
  453. SrcBufferSize = BufferLineSize + MaxResamplerPadding;
  454. DataSize64 = SrcBufferSize - MaxResamplerPadding;
  455. DataSize64 = ((DataSize64<<MixerFracBits) - DataPosFrac) / increment;
  456. if(DataSize64 < DstBufferSize)
  457. {
  458. /* Some mixers require being 16-byte aligned, so also limit
  459. * to a multiple of 4 samples to maintain alignment.
  460. */
  461. DstBufferSize = static_cast<uint>(DataSize64) & ~3u;
  462. }
  463. }
  464. }
  465. if((mFlags&(VoiceIsCallback|VoiceCallbackStopped)) == VoiceIsCallback && BufferListItem)
  466. {
  467. /* Exclude resampler pre-padding from the needed size. */
  468. const uint toLoad{SrcBufferSize - (MaxResamplerPadding>>1)};
  469. if(toLoad > mNumCallbackSamples)
  470. {
  471. const size_t byteOffset{mNumCallbackSamples*FrameSize};
  472. const size_t needBytes{toLoad*FrameSize - byteOffset};
  473. const int gotBytes{BufferListItem->mCallback(BufferListItem->mUserData,
  474. &BufferListItem->mSamples[byteOffset], static_cast<int>(needBytes))};
  475. if(gotBytes < 1)
  476. mFlags |= VoiceCallbackStopped;
  477. else if(static_cast<uint>(gotBytes) < needBytes)
  478. {
  479. mFlags |= VoiceCallbackStopped;
  480. mNumCallbackSamples += static_cast<uint>(static_cast<uint>(gotBytes) /
  481. FrameSize);
  482. }
  483. else
  484. mNumCallbackSamples = toLoad;
  485. }
  486. }
  487. const size_t num_chans{mChans.size()};
  488. size_t chan_idx{0};
  489. ASSUME(DstBufferSize > 0);
  490. for(auto &chandata : mChans)
  491. {
  492. const al::span<float> SrcData{Device->SourceData, SrcBufferSize};
  493. /* Load the previous samples into the source data first, then load
  494. * what we can from the buffer queue.
  495. */
  496. auto srciter = std::copy_n(chandata.mPrevSamples.begin(), MaxResamplerPadding>>1,
  497. SrcData.begin());
  498. if UNLIKELY(!BufferListItem)
  499. {
  500. /* When loading from a voice that ended prematurely, only take
  501. * the samples that get closest to 0 amplitude. This helps
  502. * certain sounds fade out better.
  503. */
  504. auto abs_lt = [](const float lhs, const float rhs) noexcept -> bool
  505. { return std::abs(lhs) < std::abs(rhs); };
  506. auto input = chandata.mPrevSamples.begin() + (MaxResamplerPadding>>1);
  507. auto in_end = std::min_element(input, chandata.mPrevSamples.end(), abs_lt);
  508. srciter = std::copy(input, in_end, srciter);
  509. }
  510. else if((mFlags&VoiceIsStatic))
  511. srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, num_chans, SampleType,
  512. SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()});
  513. else if((mFlags&VoiceIsCallback))
  514. srciter = LoadBufferCallback(BufferListItem, num_chans, SampleType, SampleSize,
  515. chan_idx, mNumCallbackSamples, {srciter, SrcData.end()});
  516. else
  517. srciter = LoadBufferQueue(BufferListItem, BufferLoopItem, num_chans, SampleType,
  518. SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()});
  519. if UNLIKELY(srciter != SrcData.end())
  520. {
  521. /* If the source buffer wasn't filled, copy the last sample for
  522. * the remaining buffer. Ideally it should have ended with
  523. * silence, but if not the gain fading should help avoid clicks
  524. * from sudden amplitude changes.
  525. */
  526. const float sample{*(srciter-1)};
  527. std::fill(srciter, SrcData.end(), sample);
  528. }
  529. /* Store the last source samples used for next time. */
  530. std::copy_n(&SrcData[(increment*DstBufferSize + DataPosFrac)>>MixerFracBits],
  531. chandata.mPrevSamples.size(), chandata.mPrevSamples.begin());
  532. /* Resample, then apply ambisonic upsampling as needed. */
  533. float *ResampledData{Resample(&mResampleState, &SrcData[MaxResamplerPadding>>1],
  534. DataPosFrac, increment, {Device->ResampledData, DstBufferSize})};
  535. if((mFlags&VoiceIsAmbisonic))
  536. chandata.mAmbiSplitter.processHfScale({ResampledData, DstBufferSize},
  537. chandata.mAmbiScale);
  538. /* Now filter and mix to the appropriate outputs. */
  539. float (&FilterBuf)[BufferLineSize] = Device->FilteredData;
  540. {
  541. DirectParams &parms = chandata.mDryParams;
  542. const float *samples{DoFilters(parms.LowPass, parms.HighPass, FilterBuf,
  543. {ResampledData, DstBufferSize}, mDirect.FilterType)};
  544. if((mFlags&VoiceHasHrtf))
  545. {
  546. const float TargetGain{UNLIKELY(vstate == Stopping) ? 0.0f :
  547. parms.Hrtf.Target.Gain};
  548. DoHrtfMix(samples, DstBufferSize, parms, TargetGain, Counter, OutPos, IrSize,
  549. Device);
  550. }
  551. else if((mFlags&VoiceHasNfc))
  552. {
  553. const float *TargetGains{UNLIKELY(vstate == Stopping) ? SilentTarget.data()
  554. : parms.Gains.Target.data()};
  555. DoNfcMix({samples, DstBufferSize}, mDirect.Buffer.data(), parms, TargetGains,
  556. Counter, OutPos, Device);
  557. }
  558. else
  559. {
  560. const float *TargetGains{UNLIKELY(vstate == Stopping) ? SilentTarget.data()
  561. : parms.Gains.Target.data()};
  562. MixSamples({samples, DstBufferSize}, mDirect.Buffer,
  563. parms.Gains.Current.data(), TargetGains, Counter, OutPos);
  564. }
  565. }
  566. for(uint send{0};send < NumSends;++send)
  567. {
  568. if(mSend[send].Buffer.empty())
  569. continue;
  570. SendParams &parms = chandata.mWetParams[send];
  571. const float *samples{DoFilters(parms.LowPass, parms.HighPass, FilterBuf,
  572. {ResampledData, DstBufferSize}, mSend[send].FilterType)};
  573. const float *TargetGains{UNLIKELY(vstate == Stopping) ? SilentTarget.data()
  574. : parms.Gains.Target.data()};
  575. MixSamples({samples, DstBufferSize}, mSend[send].Buffer,
  576. parms.Gains.Current.data(), TargetGains, Counter, OutPos);
  577. }
  578. ++chan_idx;
  579. }
  580. /* Update positions */
  581. DataPosFrac += increment*DstBufferSize;
  582. const uint SrcSamplesDone{DataPosFrac>>MixerFracBits};
  583. DataPosInt += SrcSamplesDone;
  584. DataPosFrac &= MixerFracMask;
  585. OutPos += DstBufferSize;
  586. Counter = maxu(DstBufferSize, Counter) - DstBufferSize;
  587. if UNLIKELY(!BufferListItem)
  588. {
  589. /* Do nothing extra when there's no buffers. */
  590. }
  591. else if((mFlags&VoiceIsStatic))
  592. {
  593. if(BufferLoopItem)
  594. {
  595. /* Handle looping static source */
  596. const uint LoopStart{BufferListItem->mLoopStart};
  597. const uint LoopEnd{BufferListItem->mLoopEnd};
  598. if(DataPosInt >= LoopEnd)
  599. {
  600. assert(LoopEnd > LoopStart);
  601. DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
  602. }
  603. }
  604. else
  605. {
  606. /* Handle non-looping static source */
  607. if(DataPosInt >= BufferListItem->mSampleLen)
  608. {
  609. BufferListItem = nullptr;
  610. break;
  611. }
  612. }
  613. }
  614. else if((mFlags&VoiceIsCallback))
  615. {
  616. if(SrcSamplesDone < mNumCallbackSamples)
  617. {
  618. const size_t byteOffset{SrcSamplesDone*FrameSize};
  619. const size_t byteEnd{mNumCallbackSamples*FrameSize};
  620. al::byte *data{BufferListItem->mSamples};
  621. std::copy(data+byteOffset, data+byteEnd, data);
  622. mNumCallbackSamples -= SrcSamplesDone;
  623. }
  624. else
  625. {
  626. BufferListItem = nullptr;
  627. mNumCallbackSamples = 0;
  628. }
  629. }
  630. else
  631. {
  632. /* Handle streaming source */
  633. do {
  634. if(BufferListItem->mSampleLen > DataPosInt)
  635. break;
  636. DataPosInt -= BufferListItem->mSampleLen;
  637. ++buffers_done;
  638. BufferListItem = BufferListItem->mNext.load(std::memory_order_relaxed);
  639. if(!BufferListItem) BufferListItem = BufferLoopItem;
  640. } while(BufferListItem);
  641. }
  642. } while(OutPos < SamplesToDo);
  643. mFlags |= VoiceIsFading;
  644. /* Don't update positions and buffers if we were stopping. */
  645. if UNLIKELY(vstate == Stopping)
  646. {
  647. mPlayState.store(Stopped, std::memory_order_release);
  648. return;
  649. }
  650. /* Capture the source ID in case it's reset for stopping. */
  651. const uint SourceID{mSourceID.load(std::memory_order_relaxed)};
  652. /* Update voice info */
  653. mPosition.store(DataPosInt, std::memory_order_relaxed);
  654. mPositionFrac.store(DataPosFrac, std::memory_order_relaxed);
  655. mCurrentBuffer.store(BufferListItem, std::memory_order_relaxed);
  656. if(!BufferListItem)
  657. {
  658. mLoopBuffer.store(nullptr, std::memory_order_relaxed);
  659. mSourceID.store(0u, std::memory_order_relaxed);
  660. }
  661. std::atomic_thread_fence(std::memory_order_release);
  662. /* Send any events now, after the position/buffer info was updated. */
  663. const uint enabledevt{Context->mEnabledEvts.load(std::memory_order_acquire)};
  664. if(buffers_done > 0 && (enabledevt&EventType_BufferCompleted))
  665. {
  666. RingBuffer *ring{Context->mAsyncEvents.get()};
  667. auto evt_vec = ring->getWriteVector();
  668. if(evt_vec.first.len > 0)
  669. {
  670. AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_BufferCompleted}};
  671. evt->u.bufcomp.id = SourceID;
  672. evt->u.bufcomp.count = buffers_done;
  673. ring->writeAdvance(1);
  674. }
  675. }
  676. if(!BufferListItem)
  677. {
  678. /* If the voice just ended, set it to Stopping so the next render
  679. * ensures any residual noise fades to 0 amplitude.
  680. */
  681. mPlayState.store(Stopping, std::memory_order_release);
  682. if((enabledevt&EventType_SourceStateChange))
  683. SendSourceStoppedEvent(Context, SourceID);
  684. }
  685. }