From 6d4380a48c28f21d271d4eb5e668443bc8a0f50e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 28 May 2016 00:43:14 -0700 Subject: [PATCH] Change the backend getLatency method to return the clock time too This will also allow backends to better synchronize the tracked clock time with the device output latency, without necessarily needing to lock if the backend API can allow for it. --- Alc/backends/alsa.c | 30 ++++++++++++++++++++++-------- Alc/backends/base.c | 19 +++++++++++++++---- Alc/backends/base.h | 23 +++++++++++++++++++---- Alc/backends/dsound.c | 4 ++-- Alc/backends/jack.c | 12 +++++++----- Alc/backends/loopback.c | 2 +- Alc/backends/mmdevapi.c | 15 +++++++++++---- Alc/backends/null.c | 2 +- Alc/backends/oss.c | 4 ++-- Alc/backends/portaudio.c | 4 ++-- Alc/backends/pulseaudio.c | 38 +++++++++++++++++++++++++------------- Alc/backends/solaris.c | 2 +- Alc/backends/wave.c | 2 +- Alc/backends/winmm.c | 4 ++-- OpenAL32/alSource.c | 11 ++++++++--- 15 files changed, 119 insertions(+), 53 deletions(-) diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index 7d23ecc3..280f5019 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -410,7 +410,7 @@ static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self); static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self); static DECLARE_FORWARD2(ALCplaybackAlsa, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, ALCuint, availableSamples) -static ALint64 ALCplaybackAlsa_getLatency(ALCplaybackAlsa *self); +static ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self); static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, lock) static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCplaybackAlsa) @@ -891,18 +891,25 @@ static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self) self->buffer = NULL; } -static ALint64 ALCplaybackAlsa_getLatency(ALCplaybackAlsa *self) +static ClockLatency ALCplaybackAlsa_getClockLatency(ALCplaybackAlsa *self) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; snd_pcm_sframes_t delay = 0; + ClockLatency ret; int err; + ALCplaybackAlsa_lock(self); + ret.ClockTime = GetDeviceClockTime(device); if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0) { ERR("Failed to get pcm delay: %s\n", snd_strerror(err)); - return 0; + delay = 0; } - return maxi64((ALint64)delay*1000000000/device->Frequency, 0); + if(delay < 0) delay = 0; + ret.Latency = delay * DEVICE_CLOCK_RES / device->Frequency; + ALCplaybackAlsa_unlock(self); + + return ret; } @@ -929,7 +936,7 @@ static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self); static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self); static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self); -static ALint64 ALCcaptureAlsa_getLatency(ALCcaptureAlsa *self); +static ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self); static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, lock) static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCcaptureAlsa) @@ -1277,18 +1284,25 @@ static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self) return ll_ringbuffer_read_space(self->ring); } -static ALint64 ALCcaptureAlsa_getLatency(ALCcaptureAlsa *self) +static ClockLatency ALCcaptureAlsa_getClockLatency(ALCcaptureAlsa *self) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; snd_pcm_sframes_t delay = 0; + ClockLatency ret; int err; + ALCcaptureAlsa_lock(self); + ret.ClockTime = GetDeviceClockTime(device); if((err=snd_pcm_delay(self->pcmHandle, &delay)) < 0) { ERR("Failed to get pcm delay: %s\n", snd_strerror(err)); - return 0; + delay = 0; } - return maxi64((ALint64)delay*1000000000/device->Frequency, 0); + if(delay < 0) delay = 0; + ret.Latency = delay * DEVICE_CLOCK_RES / device->Frequency; + ALCcaptureAlsa_unlock(self); + + return ret; } diff --git a/Alc/backends/base.c b/Alc/backends/base.c index ebeb31bf..07c33ba1 100644 --- a/Alc/backends/base.c +++ b/Alc/backends/base.c @@ -8,6 +8,8 @@ #include "backends/base.h" +extern inline ALuint64 GetDeviceClockTime(ALCdevice *device); + /* Base ALCbackend method implementations. */ void ALCbackend_Construct(ALCbackend *self, ALCdevice *device) { @@ -37,9 +39,18 @@ ALCuint ALCbackend_availableSamples(ALCbackend* UNUSED(self)) return 0; } -ALint64 ALCbackend_getLatency(ALCbackend* UNUSED(self)) +ClockLatency ALCbackend_getClockLatency(ALCbackend *self) { - return 0; + ALCdevice *device = self->mDevice; + ClockLatency ret; + + almtx_lock(&self->mMutex); + ret.ClockTime = GetDeviceClockTime(device); + // TODO: Perhaps should be NumUpdates-1 worth of UpdateSize? + ret.Latency = 0; + almtx_unlock(&self->mMutex); + + return ret; } void ALCbackend_lock(ALCbackend *self) @@ -77,7 +88,7 @@ static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self); static void PlaybackWrapper_stop(PlaybackWrapper *self); static DECLARE_FORWARD2(PlaybackWrapper, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, lock) static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(PlaybackWrapper) @@ -137,7 +148,7 @@ static ALCboolean CaptureWrapper_start(CaptureWrapper *self); static void CaptureWrapper_stop(CaptureWrapper *self); static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples); static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self); -static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, lock) static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(CaptureWrapper) diff --git a/Alc/backends/base.h b/Alc/backends/base.h index f6b4b80a..04795b36 100644 --- a/Alc/backends/base.h +++ b/Alc/backends/base.h @@ -5,6 +5,21 @@ #include "threads.h" +typedef struct ClockLatency { + ALint64 ClockTime; + ALint64 Latency; +} ClockLatency; + +/* Helper to get the current clock time from the device's ClockBase, and + * SamplesDone converted from the sample rate. + */ +inline ALuint64 GetDeviceClockTime(ALCdevice *device) +{ + return device->ClockBase + (device->SamplesDone * DEVICE_CLOCK_RES / + device->Frequency); +} + + struct ALCbackendVtable; typedef struct ALCbackend { @@ -20,7 +35,7 @@ void ALCbackend_Destruct(ALCbackend *self); ALCboolean ALCbackend_reset(ALCbackend *self); ALCenum ALCbackend_captureSamples(ALCbackend *self, void *buffer, ALCuint samples); ALCuint ALCbackend_availableSamples(ALCbackend *self); -ALint64 ALCbackend_getLatency(ALCbackend *self); +ClockLatency ALCbackend_getClockLatency(ALCbackend *self); void ALCbackend_lock(ALCbackend *self); void ALCbackend_unlock(ALCbackend *self); @@ -37,7 +52,7 @@ struct ALCbackendVtable { ALCenum (*const captureSamples)(ALCbackend*, void*, ALCuint); ALCuint (*const availableSamples)(ALCbackend*); - ALint64 (*const getLatency)(ALCbackend*); + ClockLatency (*const getClockLatency)(ALCbackend*); void (*const lock)(ALCbackend*); void (*const unlock)(ALCbackend*); @@ -54,7 +69,7 @@ DECLARE_THUNK(T, ALCbackend, ALCboolean, start) \ DECLARE_THUNK(T, ALCbackend, void, stop) \ DECLARE_THUNK2(T, ALCbackend, ALCenum, captureSamples, void*, ALCuint) \ DECLARE_THUNK(T, ALCbackend, ALCuint, availableSamples) \ -DECLARE_THUNK(T, ALCbackend, ALint64, getLatency) \ +DECLARE_THUNK(T, ALCbackend, ClockLatency, getClockLatency) \ DECLARE_THUNK(T, ALCbackend, void, lock) \ DECLARE_THUNK(T, ALCbackend, void, unlock) \ static void T##_ALCbackend_Delete(void *ptr) \ @@ -70,7 +85,7 @@ static const struct ALCbackendVtable T##_ALCbackend_vtable = { \ T##_ALCbackend_stop, \ T##_ALCbackend_captureSamples, \ T##_ALCbackend_availableSamples, \ - T##_ALCbackend_getLatency, \ + T##_ALCbackend_getClockLatency, \ T##_ALCbackend_lock, \ T##_ALCbackend_unlock, \ \ diff --git a/Alc/backends/dsound.c b/Alc/backends/dsound.c index 454f7fa0..1ff99352 100644 --- a/Alc/backends/dsound.c +++ b/Alc/backends/dsound.c @@ -199,7 +199,7 @@ static ALCboolean ALCdsoundPlayback_start(ALCdsoundPlayback *self); static void ALCdsoundPlayback_stop(ALCdsoundPlayback *self); static DECLARE_FORWARD2(ALCdsoundPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, lock) static DECLARE_FORWARD(ALCdsoundPlayback, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCdsoundPlayback) @@ -666,7 +666,7 @@ static ALCboolean ALCdsoundCapture_start(ALCdsoundCapture *self); static void ALCdsoundCapture_stop(ALCdsoundCapture *self); static ALCenum ALCdsoundCapture_captureSamples(ALCdsoundCapture *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCdsoundCapture_availableSamples(ALCdsoundCapture *self); -static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, lock) static DECLARE_FORWARD(ALCdsoundCapture, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCdsoundCapture) diff --git a/Alc/backends/jack.c b/Alc/backends/jack.c index 69d1277a..cfdc62e8 100644 --- a/Alc/backends/jack.c +++ b/Alc/backends/jack.c @@ -148,7 +148,7 @@ static ALCboolean ALCjackPlayback_start(ALCjackPlayback *self); static void ALCjackPlayback_stop(ALCjackPlayback *self); static DECLARE_FORWARD2(ALCjackPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCjackPlayback, ALCbackend, ALCuint, availableSamples) -static ALint64 ALCjackPlayback_getLatency(ALCjackPlayback *self); +static ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self); static void ALCjackPlayback_lock(ALCjackPlayback *self); static void ALCjackPlayback_unlock(ALCjackPlayback *self); DECLARE_DEFAULT_ALLOCATORS(ALCjackPlayback) @@ -506,16 +506,18 @@ static void ALCjackPlayback_stop(ALCjackPlayback *self) } -static ALint64 ALCjackPlayback_getLatency(ALCjackPlayback *self) +static ClockLatency ALCjackPlayback_getClockLatency(ALCjackPlayback *self) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - ALint64 latency; + ClockLatency ret; ALCjackPlayback_lock(self); - latency = ll_ringbuffer_read_space(self->Ring); + ret.ClockTime = GetDeviceClockTime(device); + ret.Latency = ll_ringbuffer_read_space(self->Ring) * DEVICE_CLOCK_RES / + device->Frequency; ALCjackPlayback_unlock(self); - return latency * 1000000000 / device->Frequency; + return ret; } diff --git a/Alc/backends/loopback.c b/Alc/backends/loopback.c index 3e577f78..0164bc5a 100644 --- a/Alc/backends/loopback.c +++ b/Alc/backends/loopback.c @@ -41,7 +41,7 @@ static ALCboolean ALCloopback_start(ALCloopback *self); static void ALCloopback_stop(ALCloopback *self); static DECLARE_FORWARD2(ALCloopback, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCloopback, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCloopback, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCloopback, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCloopback, ALCbackend, void, lock) static DECLARE_FORWARD(ALCloopback, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCloopback) diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c index 938488ac..f102e385 100644 --- a/Alc/backends/mmdevapi.c +++ b/Alc/backends/mmdevapi.c @@ -508,7 +508,7 @@ static void ALCmmdevPlayback_stop(ALCmmdevPlayback *self); static void ALCmmdevPlayback_stopProxy(ALCmmdevPlayback *self); static DECLARE_FORWARD2(ALCmmdevPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) static DECLARE_FORWARD(ALCmmdevPlayback, ALCbackend, ALCuint, availableSamples) -static ALint64 ALCmmdevPlayback_getLatency(ALCmmdevPlayback *self); +static ClockLatency ALCmmdevPlayback_getClockLatency(ALCmmdevPlayback *self); static DECLARE_FORWARD(ALCmmdevPlayback, ALCbackend, void, lock) static DECLARE_FORWARD(ALCmmdevPlayback, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCmmdevPlayback) @@ -1139,10 +1139,17 @@ static void ALCmmdevPlayback_stopProxy(ALCmmdevPlayback *self) } -static ALint64 ALCmmdevPlayback_getLatency(ALCmmdevPlayback *self) +static ClockLatency ALCmmdevPlayback_getClockLatency(ALCmmdevPlayback *self) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return (ALint64)self->Padding * 1000000000 / device->Frequency; + ClockLatency ret; + + ALCmmdevPlayback_lock(self); + ret.ClockTime = GetDeviceClockTime(device); + ret.Latency = self->Padding * DEVICE_CLOCK_RES / device->Frequency; + ALCmmdevPlayback_unlock(self); + + return ret; } @@ -1181,7 +1188,7 @@ static void ALCmmdevCapture_stop(ALCmmdevCapture *self); static void ALCmmdevCapture_stopProxy(ALCmmdevCapture *self); static ALCenum ALCmmdevCapture_captureSamples(ALCmmdevCapture *self, ALCvoid *buffer, ALCuint samples); static ALuint ALCmmdevCapture_availableSamples(ALCmmdevCapture *self); -static DECLARE_FORWARD(ALCmmdevCapture, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCmmdevCapture, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCmmdevCapture, ALCbackend, void, lock) static DECLARE_FORWARD(ALCmmdevCapture, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCmmdevCapture) diff --git a/Alc/backends/null.c b/Alc/backends/null.c index 99729c0a..5b153cd9 100644 --- a/Alc/backends/null.c +++ b/Alc/backends/null.c @@ -51,7 +51,7 @@ static ALCboolean ALCnullBackend_start(ALCnullBackend *self); static void ALCnullBackend_stop(ALCnullBackend *self); static DECLARE_FORWARD2(ALCnullBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCnullBackend, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, lock) static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCnullBackend) diff --git a/Alc/backends/oss.c b/Alc/backends/oss.c index a61b4859..432c75f2 100644 --- a/Alc/backends/oss.c +++ b/Alc/backends/oss.c @@ -257,7 +257,7 @@ static ALCboolean ALCplaybackOSS_start(ALCplaybackOSS *self); static void ALCplaybackOSS_stop(ALCplaybackOSS *self); static DECLARE_FORWARD2(ALCplaybackOSS, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, lock) static DECLARE_FORWARD(ALCplaybackOSS, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCplaybackOSS) @@ -502,7 +502,7 @@ static ALCboolean ALCcaptureOSS_start(ALCcaptureOSS *self); static void ALCcaptureOSS_stop(ALCcaptureOSS *self); static ALCenum ALCcaptureOSS_captureSamples(ALCcaptureOSS *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCcaptureOSS_availableSamples(ALCcaptureOSS *self); -static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, lock) static DECLARE_FORWARD(ALCcaptureOSS, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCcaptureOSS) diff --git a/Alc/backends/portaudio.c b/Alc/backends/portaudio.c index f45833c6..1dbca941 100644 --- a/Alc/backends/portaudio.c +++ b/Alc/backends/portaudio.c @@ -145,7 +145,7 @@ static ALCboolean ALCportPlayback_start(ALCportPlayback *self); static void ALCportPlayback_stop(ALCportPlayback *self); static DECLARE_FORWARD2(ALCportPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) static DECLARE_FORWARD(ALCportPlayback, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCportPlayback, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCportPlayback, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCportPlayback, ALCbackend, void, lock) static DECLARE_FORWARD(ALCportPlayback, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCportPlayback) @@ -340,7 +340,7 @@ static ALCboolean ALCportCapture_start(ALCportCapture *self); static void ALCportCapture_stop(ALCportCapture *self); static ALCenum ALCportCapture_captureSamples(ALCportCapture *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCportCapture_availableSamples(ALCportCapture *self); -static DECLARE_FORWARD(ALCportCapture, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCportCapture, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCportCapture, ALCbackend, void, lock) static DECLARE_FORWARD(ALCportCapture, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCportCapture) diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index ccce2e00..d317b576 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -489,7 +489,7 @@ static ALCboolean ALCpulsePlayback_start(ALCpulsePlayback *self); static void ALCpulsePlayback_stop(ALCpulsePlayback *self); static DECLARE_FORWARD2(ALCpulsePlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) static DECLARE_FORWARD(ALCpulsePlayback, ALCbackend, ALCuint, availableSamples) -static ALint64 ALCpulsePlayback_getLatency(ALCpulsePlayback *self); +static ClockLatency ALCpulsePlayback_getClockLatency(ALCpulsePlayback *self); static void ALCpulsePlayback_lock(ALCpulsePlayback *self); static void ALCpulsePlayback_unlock(ALCpulsePlayback *self); DECLARE_DEFAULT_ALLOCATORS(ALCpulsePlayback) @@ -1136,11 +1136,14 @@ static void ALCpulsePlayback_stop(ALCpulsePlayback *self) } -static ALint64 ALCpulsePlayback_getLatency(ALCpulsePlayback *self) +static ClockLatency ALCpulsePlayback_getClockLatency(ALCpulsePlayback *self) { pa_usec_t latency = 0; + ClockLatency ret; int neg, err; + pa_threaded_mainloop_lock(self->loop); + ret.ClockTime = GetDeviceClockTime(STATIC_CAST(ALCbackend,self)->mDevice); if((err=pa_stream_get_latency(self->stream, &latency, &neg)) != 0) { /* FIXME: if err = -PA_ERR_NODATA, it means we were called too soon @@ -1149,11 +1152,14 @@ static ALint64 ALCpulsePlayback_getLatency(ALCpulsePlayback *self) * dummy value? Either way, it shouldn't be 0. */ if(err != -PA_ERR_NODATA) ERR("Failed to get stream latency: 0x%x\n", err); - return 0; + latency = 0; + neg = 0; } - if(neg) latency = 0; - return (ALint64)minu64(latency, U64(0x7fffffffffffffff)/1000) * 1000; + ret.Latency = minu64(latency, U64(0xffffffffffffffff)/1000) * 1000; + pa_threaded_mainloop_unlock(self->loop); + + return ret; } @@ -1209,7 +1215,7 @@ static ALCboolean ALCpulseCapture_start(ALCpulseCapture *self); static void ALCpulseCapture_stop(ALCpulseCapture *self); static ALCenum ALCpulseCapture_captureSamples(ALCpulseCapture *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self); -static ALint64 ALCpulseCapture_getLatency(ALCpulseCapture *self); +static ClockLatency ALCpulseCapture_getClockLatency(ALCpulseCapture *self); static void ALCpulseCapture_lock(ALCpulseCapture *self); static void ALCpulseCapture_unlock(ALCpulseCapture *self); DECLARE_DEFAULT_ALLOCATORS(ALCpulseCapture) @@ -1639,19 +1645,25 @@ static ALCuint ALCpulseCapture_availableSamples(ALCpulseCapture *self) } -static ALint64 ALCpulseCapture_getLatency(ALCpulseCapture *self) +static ClockLatency ALCpulseCapture_getClockLatency(ALCpulseCapture *self) { pa_usec_t latency = 0; - int neg; + ClockLatency ret; + int neg, err; - if(pa_stream_get_latency(self->stream, &latency, &neg) != 0) + pa_threaded_mainloop_lock(self->loop); + ret.ClockTime = GetDeviceClockTime(STATIC_CAST(ALCbackend,self)->mDevice); + if((err=pa_stream_get_latency(self->stream, &latency, &neg)) != 0) { - ERR("Failed to get stream latency!\n"); - return 0; + ERR("Failed to get stream latency: 0x%x\n", err); + latency = 0; + neg = 0; } - if(neg) latency = 0; - return (ALint64)minu64(latency, U64(0x7fffffffffffffff)/1000) * 1000; + ret.Latency = minu64(latency, U64(0xffffffffffffffff)/1000) * 1000; + pa_threaded_mainloop_unlock(self->loop); + + return ret; } diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c index 6eaf1ee5..01472e6a 100644 --- a/Alc/backends/solaris.c +++ b/Alc/backends/solaris.c @@ -65,7 +65,7 @@ static ALCboolean ALCsolarisBackend_start(ALCsolarisBackend *self); static void ALCsolarisBackend_stop(ALCsolarisBackend *self); static DECLARE_FORWARD2(ALCsolarisBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, void, lock) static DECLARE_FORWARD(ALCsolarisBackend, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCsolarisBackend) diff --git a/Alc/backends/wave.c b/Alc/backends/wave.c index 3b87d645..af996233 100644 --- a/Alc/backends/wave.c +++ b/Alc/backends/wave.c @@ -91,7 +91,7 @@ static ALCboolean ALCwaveBackend_start(ALCwaveBackend *self); static void ALCwaveBackend_stop(ALCwaveBackend *self); static DECLARE_FORWARD2(ALCwaveBackend, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCwaveBackend, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCwaveBackend, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCwaveBackend, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCwaveBackend, ALCbackend, void, lock) static DECLARE_FORWARD(ALCwaveBackend, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCwaveBackend) diff --git a/Alc/backends/winmm.c b/Alc/backends/winmm.c index 664b3dfe..180f764b 100644 --- a/Alc/backends/winmm.c +++ b/Alc/backends/winmm.c @@ -164,7 +164,7 @@ static ALCboolean ALCwinmmPlayback_start(ALCwinmmPlayback *self); static void ALCwinmmPlayback_stop(ALCwinmmPlayback *self); static DECLARE_FORWARD2(ALCwinmmPlayback, ALCbackend, ALCenum, captureSamples, ALCvoid*, ALCuint) static DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, ALCuint, availableSamples) -static DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, void, lock) static DECLARE_FORWARD(ALCwinmmPlayback, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCwinmmPlayback) @@ -451,7 +451,7 @@ static ALCboolean ALCwinmmCapture_start(ALCwinmmCapture *self); static void ALCwinmmCapture_stop(ALCwinmmCapture *self); static ALCenum ALCwinmmCapture_captureSamples(ALCwinmmCapture *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCwinmmCapture_availableSamples(ALCwinmmCapture *self); -static DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, ALint64, getLatency) +static DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, ClockLatency, getClockLatency) static DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, void, lock) static DECLARE_FORWARD(ALCwinmmCapture, ALCbackend, void, unlock) DECLARE_DEFAULT_ALLOCATORS(ALCwinmmCapture) diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index ec32ac8d..e04199b3 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -1006,6 +1006,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p { ALCdevice *device = Context->Device; ALbufferlistitem *BufferList; + ClockLatency clocktime; ALint ivals[3]; ALboolean err; @@ -1107,9 +1108,10 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_OFFSET_LATENCY_SOFT: LockContext(Context); + clocktime = V0(device->Backend,getClockLatency)(); + values[0] = GetSourceSecOffset(Source); - values[1] = (ALdouble)(V0(device->Backend,getLatency)()) / - 1000000000.0; + values[1] = (ALdouble)clocktime.Latency / 1000000000.0; UnlockContext(Context); return AL_TRUE; @@ -1382,6 +1384,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values) { ALCdevice *device = Context->Device; + ClockLatency clocktime; ALdouble dvals[6]; ALint ivals[3]; ALboolean err; @@ -1390,8 +1393,10 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp { case AL_SAMPLE_OFFSET_LATENCY_SOFT: LockContext(Context); + clocktime = V0(device->Backend,getClockLatency)(); + values[0] = GetSourceSampleOffset(Source); - values[1] = V0(device->Backend,getLatency)(); + values[1] = clocktime.Latency; UnlockContext(Context); return AL_TRUE; -- 2.11.4.GIT