63 lines
1.5 KiB
C++
Raw Normal View History

#include "config.h"
2019-07-29 19:59:48 -07:00
#include "base.h"
2019-07-29 19:59:48 -07:00
#include <atomic>
2018-11-26 23:06:49 -08:00
#include <thread>
2019-07-29 19:59:48 -07:00
#include "AL/al.h"
2019-07-29 19:59:48 -07:00
#include "alcmain.h"
#include "alexcpt.h"
2019-07-29 19:59:48 -07:00
#include "alnumeric.h"
#include "atomic.h"
2018-11-13 19:45:26 -08:00
ClockLatency GetClockLatency(ALCdevice *device)
{
2018-12-29 02:16:16 -08:00
BackendBase *backend{device->Backend.get()};
ClockLatency ret{backend->getClockLatency()};
ret.Latency += device->FixedLatency;
2018-11-13 19:45:26 -08:00
return ret;
}
/* BackendBase method implementations. */
BackendBase::BackendBase(ALCdevice *device) noexcept : mDevice{device}
{ }
BackendBase::~BackendBase() = default;
bool BackendBase::reset()
2019-10-07 22:42:54 -07:00
{ throw al::backend_exception{ALC_INVALID_DEVICE, "Invalid BackendBase call"}; }
ALCenum BackendBase::captureSamples(al::byte*, ALCuint)
{ return ALC_INVALID_DEVICE; }
ALCuint BackendBase::availableSamples()
{ return 0; }
ClockLatency BackendBase::getClockLatency()
{
ClockLatency ret;
ALuint refcount;
do {
while(((refcount=ReadRef(mDevice->MixCount))&1) != 0)
2018-11-26 23:06:49 -08:00
std::this_thread::yield();
ret.ClockTime = GetDeviceClockTime(mDevice);
2018-11-19 05:04:17 -08:00
std::atomic_thread_fence(std::memory_order_acquire);
} while(refcount != ReadRef(mDevice->MixCount));
/* NOTE: The device will generally have about all but one periods filled at
* any given time during playback. Without a more accurate measurement from
* the output, this is an okay approximation.
*/
2019-09-13 12:51:16 -07:00
ret.Latency = std::max(std::chrono::seconds{mDevice->BufferSize-mDevice->UpdateSize},
std::chrono::seconds::zero());
ret.Latency /= mDevice->Frequency;
return ret;
}