base.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #include "config.h"
  2. #include "base.h"
  3. #include <atomic>
  4. #include <thread>
  5. #include "AL/al.h"
  6. #include "alcmain.h"
  7. #include "alexcpt.h"
  8. #include "alnumeric.h"
  9. #include "atomic.h"
  10. ClockLatency GetClockLatency(ALCdevice *device)
  11. {
  12. BackendBase *backend{device->Backend.get()};
  13. ClockLatency ret{backend->getClockLatency()};
  14. ret.Latency += device->FixedLatency;
  15. return ret;
  16. }
  17. /* BackendBase method implementations. */
  18. BackendBase::BackendBase(ALCdevice *device) noexcept : mDevice{device}
  19. { }
  20. BackendBase::~BackendBase() = default;
  21. bool BackendBase::reset()
  22. { throw al::backend_exception{ALC_INVALID_DEVICE, "Invalid BackendBase call"}; }
  23. ALCenum BackendBase::captureSamples(al::byte*, ALCuint)
  24. { return ALC_INVALID_DEVICE; }
  25. ALCuint BackendBase::availableSamples()
  26. { return 0; }
  27. ClockLatency BackendBase::getClockLatency()
  28. {
  29. ClockLatency ret;
  30. ALuint refcount;
  31. do {
  32. while(((refcount=ReadRef(mDevice->MixCount))&1) != 0)
  33. std::this_thread::yield();
  34. ret.ClockTime = GetDeviceClockTime(mDevice);
  35. std::atomic_thread_fence(std::memory_order_acquire);
  36. } while(refcount != ReadRef(mDevice->MixCount));
  37. /* NOTE: The device will generally have about all but one periods filled at
  38. * any given time during playback. Without a more accurate measurement from
  39. * the output, this is an okay approximation.
  40. */
  41. ret.Latency = std::max(std::chrono::seconds{mDevice->BufferSize-mDevice->UpdateSize},
  42. std::chrono::seconds::zero());
  43. ret.Latency /= mDevice->Frequency;
  44. return ret;
  45. }