Use proper time types for the device clock time and latency
This commit is contained in:
parent
84f0f74d07
commit
d26b5d9467
10
Alc/alc.cpp
10
Alc/alc.cpp
@ -3416,10 +3416,10 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
|
||||
|
||||
ClockLatency clock{GetClockLatency(device)};
|
||||
values[i++] = ALC_DEVICE_CLOCK_SOFT;
|
||||
values[i++] = clock.ClockTime;
|
||||
values[i++] = clock.ClockTime.count();
|
||||
|
||||
values[i++] = ALC_DEVICE_LATENCY_SOFT;
|
||||
values[i++] = clock.Latency;
|
||||
values[i++] = clock.Latency.count();
|
||||
|
||||
values[i++] = 0;
|
||||
}
|
||||
@ -3444,7 +3444,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
|
||||
case ALC_DEVICE_LATENCY_SOFT:
|
||||
{ std::lock_guard<almtx_t> _{device->BackendLock};
|
||||
ClockLatency clock{GetClockLatency(device)};
|
||||
*values = clock.Latency;
|
||||
*values = clock.Latency.count();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3455,8 +3455,8 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
|
||||
{
|
||||
std::lock_guard<almtx_t> _{device->BackendLock};
|
||||
ClockLatency clock{GetClockLatency(device)};
|
||||
values[0] = clock.ClockTime;
|
||||
values[1] = clock.Latency;
|
||||
values[0] = clock.ClockTime.count();
|
||||
values[1] = clock.Latency.count();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -915,7 +915,8 @@ ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self)
|
||||
ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
|
||||
delay = 0;
|
||||
}
|
||||
ret.Latency = std::max<snd_pcm_sframes_t>(0, delay) * DEVICE_CLOCK_RES / device->Frequency;
|
||||
ret.Latency = std::chrono::seconds{std::max<snd_pcm_sframes_t>(0, delay)};
|
||||
ret.Latency /= device->Frequency;
|
||||
ALCplaybackAlsa_unlock(self);
|
||||
|
||||
return ret;
|
||||
@ -1286,7 +1287,8 @@ ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self)
|
||||
ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
|
||||
delay = 0;
|
||||
}
|
||||
ret.Latency = std::max<snd_pcm_sframes_t>(0, delay) * DEVICE_CLOCK_RES / device->Frequency;
|
||||
ret.Latency = std::chrono::seconds{std::max<snd_pcm_sframes_t>(0, delay)};
|
||||
ret.Latency /= device->Frequency;
|
||||
ALCcaptureAlsa_unlock(self);
|
||||
|
||||
return ret;
|
||||
|
@ -18,7 +18,7 @@ void ALCdevice_Unlock(ALCdevice *device)
|
||||
ClockLatency GetClockLatency(ALCdevice *device)
|
||||
{
|
||||
ClockLatency ret = V0(device->Backend,getClockLatency)();
|
||||
ret.Latency += device->FixedLatency.count();
|
||||
ret.Latency += device->FixedLatency;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -65,8 +65,8 @@ ClockLatency ALCbackend_getClockLatency(ALCbackend *self)
|
||||
* any given time during playback. Without a more accurate measurement from
|
||||
* the output, this is an okay approximation.
|
||||
*/
|
||||
ret.Latency = device->UpdateSize * DEVICE_CLOCK_RES / device->Frequency *
|
||||
maxu(device->NumUpdates-1, 1);
|
||||
ret.Latency = std::chrono::seconds{device->UpdateSize*maxi(device->NumUpdates-1, 0)};
|
||||
ret.Latency /= device->Frequency;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -3,28 +3,26 @@
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
struct ClockLatency {
|
||||
/* FIXME: These should be nanoseconds. Will require changing backends that
|
||||
* provide this info.
|
||||
*/
|
||||
ALint64 ClockTime;
|
||||
ALint64 Latency;
|
||||
std::chrono::nanoseconds ClockTime;
|
||||
std::chrono::nanoseconds Latency;
|
||||
};
|
||||
|
||||
/* Helper to get the current clock time from the device's ClockBase, and
|
||||
* SamplesDone converted from the sample rate.
|
||||
*/
|
||||
inline ALuint64 GetDeviceClockTime(ALCdevice *device)
|
||||
inline std::chrono::nanoseconds GetDeviceClockTime(ALCdevice *device)
|
||||
{
|
||||
using std::chrono::seconds;
|
||||
using std::chrono::nanoseconds;
|
||||
using std::chrono::duration_cast;
|
||||
|
||||
auto ns = duration_cast<nanoseconds>(seconds{device->SamplesDone}) / device->Frequency;
|
||||
return (device->ClockBase + ns).count();
|
||||
return device->ClockBase + ns;
|
||||
}
|
||||
|
||||
void ALCdevice_Lock(ALCdevice *device);
|
||||
|
@ -503,8 +503,8 @@ static ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self)
|
||||
|
||||
ALCjackPlayback_lock(self);
|
||||
ret.ClockTime = GetDeviceClockTime(device);
|
||||
ret.Latency = ll_ringbuffer_read_space(self->Ring) * DEVICE_CLOCK_RES /
|
||||
device->Frequency;
|
||||
ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->Ring)};
|
||||
ret.Latency /= device->Frequency;
|
||||
ALCjackPlayback_unlock(self);
|
||||
|
||||
return ret;
|
||||
|
@ -654,8 +654,8 @@ static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
|
||||
|
||||
ALCopenslPlayback_lock(self);
|
||||
ret.ClockTime = GetDeviceClockTime(device);
|
||||
ret.Latency = ll_ringbuffer_read_space(self->mRing)*device->UpdateSize *
|
||||
DEVICE_CLOCK_RES / device->Frequency;
|
||||
ret.Latency = std::chrono::seconds{ll_ringbuffer_read_space(self->mRing)*device->UpdateSize};
|
||||
ret.Latency /= device->Frequency;
|
||||
ALCopenslPlayback_unlock(self);
|
||||
|
||||
return ret;
|
||||
|
@ -1213,7 +1213,7 @@ ClockLatency PulsePlayback_getClockLatency(PulsePlayback *self)
|
||||
}
|
||||
else if(UNLIKELY(neg))
|
||||
latency = 0;
|
||||
ret.Latency = (ALint64)minu64(latency, U64(0x7fffffffffffffff)/1000) * 1000;
|
||||
ret.Latency = std::chrono::microseconds{latency};
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1714,7 +1714,7 @@ ClockLatency PulseCapture_getClockLatency(PulseCapture *self)
|
||||
}
|
||||
else if(UNLIKELY(neg))
|
||||
latency = 0;
|
||||
ret.Latency = (ALint64)minu64(latency, U64(0x7fffffffffffffff)/1000) * 1000;
|
||||
ret.Latency = std::chrono::microseconds{latency};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1145,8 +1145,8 @@ ClockLatency ALCwasapiPlayback_getClockLatency(ALCwasapiPlayback *self)
|
||||
ALCwasapiPlayback_lock(self);
|
||||
ALCdevice *device{STATIC_CAST(ALCbackend, self)->mDevice};
|
||||
ret.ClockTime = GetDeviceClockTime(device);
|
||||
ret.Latency = self->mPadding.load(std::memory_order_relaxed) * DEVICE_CLOCK_RES /
|
||||
device->Frequency;
|
||||
ret.Latency = std::chrono::seconds{self->mPadding.load(std::memory_order_relaxed)};
|
||||
ret.Latency /= device->Frequency;
|
||||
ALCwasapiPlayback_unlock(self);
|
||||
|
||||
return ret;
|
||||
|
@ -147,7 +147,7 @@ void UpdateSourceProps(ALsource *source, ALvoice *voice, ALCcontext *context)
|
||||
* samples. The offset is relative to the start of the queue (not the start of
|
||||
* the current buffer).
|
||||
*/
|
||||
ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime)
|
||||
ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, std::chrono::nanoseconds *clocktime)
|
||||
{
|
||||
ALCdevice *device{context->Device};
|
||||
const ALbufferlistitem *Current;
|
||||
@ -193,7 +193,7 @@ ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *c
|
||||
* Gets the current read offset for the given Source, in seconds. The offset is
|
||||
* relative to the start of the queue (not the start of the current buffer).
|
||||
*/
|
||||
ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime)
|
||||
ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, std::chrono::nanoseconds *clocktime)
|
||||
{
|
||||
ALCdevice *device{context->Device};
|
||||
const ALbufferlistitem *Current;
|
||||
@ -1654,7 +1654,7 @@ ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, AL
|
||||
{
|
||||
ALCdevice *device{Context->Device};
|
||||
ClockLatency clocktime;
|
||||
ALuint64 srcclock;
|
||||
std::chrono::nanoseconds srcclock;
|
||||
ALint ivals[3];
|
||||
ALboolean err;
|
||||
|
||||
@ -1739,23 +1739,23 @@ ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp prop, AL
|
||||
{ std::lock_guard<almtx_t> _{device->BackendLock};
|
||||
clocktime = GetClockLatency(device);
|
||||
}
|
||||
if(srcclock == (ALuint64)clocktime.ClockTime)
|
||||
values[1] = (ALdouble)clocktime.Latency / 1000000000.0;
|
||||
if(srcclock == clocktime.ClockTime)
|
||||
values[1] = (ALdouble)clocktime.Latency.count() / 1000000000.0;
|
||||
else
|
||||
{
|
||||
/* If the clock time incremented, reduce the latency by that
|
||||
* much since it's that much closer to the source offset it got
|
||||
* earlier.
|
||||
*/
|
||||
ALuint64 diff = clocktime.ClockTime - srcclock;
|
||||
values[1] = (ALdouble)(clocktime.Latency - minu64(clocktime.Latency, diff)) /
|
||||
std::chrono::nanoseconds diff = clocktime.ClockTime - srcclock;
|
||||
values[1] = (ALdouble)(clocktime.Latency - std::min(clocktime.Latency, diff)).count() /
|
||||
1000000000.0;
|
||||
}
|
||||
return AL_TRUE;
|
||||
|
||||
case AL_SEC_OFFSET_CLOCK_SOFT:
|
||||
values[0] = GetSourceSecOffset(Source, Context, &srcclock);
|
||||
values[1] = srcclock / 1000000000.0;
|
||||
values[1] = srcclock.count() / 1000000000.0;
|
||||
return AL_TRUE;
|
||||
|
||||
case AL_POSITION:
|
||||
@ -1987,7 +1987,7 @@ ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
ClockLatency clocktime;
|
||||
ALuint64 srcclock;
|
||||
std::chrono::nanoseconds srcclock;
|
||||
ALdouble dvals[6];
|
||||
ALint ivals[3];
|
||||
ALboolean err;
|
||||
@ -2002,22 +2002,22 @@ ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop,
|
||||
{ std::lock_guard<almtx_t> _{device->BackendLock};
|
||||
clocktime = GetClockLatency(device);
|
||||
}
|
||||
if(srcclock == (ALuint64)clocktime.ClockTime)
|
||||
values[1] = clocktime.Latency;
|
||||
if(srcclock == clocktime.ClockTime)
|
||||
values[1] = clocktime.Latency.count();
|
||||
else
|
||||
{
|
||||
/* If the clock time incremented, reduce the latency by that
|
||||
* much since it's that much closer to the source offset it got
|
||||
* earlier.
|
||||
*/
|
||||
ALuint64 diff{clocktime.ClockTime - srcclock};
|
||||
values[1] = clocktime.Latency - minu64(clocktime.Latency, diff);
|
||||
auto diff = clocktime.ClockTime - srcclock;
|
||||
values[1] = (clocktime.Latency - std::min(clocktime.Latency, diff)).count();
|
||||
}
|
||||
return AL_TRUE;
|
||||
|
||||
case AL_SAMPLE_OFFSET_CLOCK_SOFT:
|
||||
values[0] = GetSourceSampleOffset(Source, Context, &srcclock);
|
||||
values[1] = srcclock;
|
||||
values[1] = srcclock.count();
|
||||
return AL_TRUE;
|
||||
|
||||
/* 1x float/double */
|
||||
|
Loading…
Reference in New Issue
Block a user