diff --git a/Alc/ALc.c b/Alc/ALc.c index a65a56b6..70663780 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2051,6 +2051,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->RealOut.NumChannels = 0; UpdateClockBase(device); + device->FixedLatency = 0; device->DitherSeed = DITHER_RNG_SEED; @@ -2253,6 +2254,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) al_free(device->Limiter); device->Limiter = CreateDeviceLimiter(device, log10f(thrshld) * 20.0f); + device->FixedLatency += (ALuint)(device->Limiter->LookAhead * DEVICE_CLOCK_RES / + device->Frequency); } else { @@ -2263,6 +2266,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) aluSelectPostProcess(device); + TRACE("Fixed device latency: %uns\n", device->FixedLatency); + /* Need to delay returning failure until replacement Send arrays have been * allocated with the appropriate size. */ @@ -2422,6 +2427,7 @@ static void InitDevice(ALCdevice *device, enum DeviceType type) device->ClockBase = 0; device->SamplesDone = 0; + device->FixedLatency = 0; device->SourcesMax = 0; device->AuxiliaryEffectSlotMax = 0; @@ -3637,7 +3643,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, values[i++] = ALC_OUTPUT_LIMITER_SOFT; values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE; - clock = V0(device->Backend,getClockLatency)(); + clock = GetClockLatency(device); values[i++] = ALC_DEVICE_CLOCK_SOFT; values[i++] = clock.ClockTime; @@ -3663,7 +3669,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, case ALC_DEVICE_LATENCY_SOFT: almtx_lock(&device->BackendLock); - clock = V0(device->Backend,getClockLatency)(); + clock = GetClockLatency(device); almtx_unlock(&device->BackendLock); *values = clock.Latency; break; @@ -3674,7 +3680,7 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, else { almtx_lock(&device->BackendLock); - clock = V0(device->Backend,getClockLatency)(); + clock = GetClockLatency(device); almtx_unlock(&device->BackendLock); values[0] = clock.ClockTime; values[1] = clock.Latency; diff --git a/Alc/backends/base.c b/Alc/backends/base.c index a451fee9..9d8614b1 100644 --- a/Alc/backends/base.c +++ b/Alc/backends/base.c @@ -12,6 +12,7 @@ extern inline ALuint64 GetDeviceClockTime(ALCdevice *device); extern inline void ALCdevice_Lock(ALCdevice *device); extern inline void ALCdevice_Unlock(ALCdevice *device); +extern inline ClockLatency GetClockLatency(ALCdevice *device); /* Base ALCbackend method implementations. */ void ALCbackend_Construct(ALCbackend *self, ALCdevice *device) diff --git a/Alc/backends/base.h b/Alc/backends/base.h index 0de4e590..03db56e9 100644 --- a/Alc/backends/base.h +++ b/Alc/backends/base.h @@ -162,6 +162,15 @@ inline void ALCdevice_Lock(ALCdevice *device) inline void ALCdevice_Unlock(ALCdevice *device) { V0(device->Backend,unlock)(); } + +inline ClockLatency GetClockLatency(ALCdevice *device) +{ + ClockLatency ret = V0(device->Backend,getClockLatency)(); + ret.Latency += device->FixedLatency; + return ret; +} + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/Alc/mastering.c b/Alc/mastering.c index 78f6038d..a957066a 100644 --- a/Alc/mastering.c +++ b/Alc/mastering.c @@ -344,10 +344,10 @@ Compressor* CompressorInit(const ALuint NumChans, const ALuint SampleRate, ALsizei hold; size_t size; - lookAhead = (ALsizei)minf(BUFFERSIZE, roundf(maxf(0.0f, LookAheadTime) * SampleRate)); - hold = (ALsizei)minf(BUFFERSIZE, roundf(maxf(0.0f, HoldTime) * SampleRate)); - size = sizeof(*Comp); + lookAhead = (ALsizei)clampf(roundf(LookAheadTime*SampleRate), 0.0f, BUFFERSIZE); + hold = (ALsizei)clampf(roundf(HoldTime*SampleRate), 0.0f, BUFFERSIZE); + size = sizeof(*Comp); if(lookAhead > 0) { size += sizeof(*Comp->Delay) * NumChans; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 3e328157..dce51301 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -676,6 +676,7 @@ struct ALCdevice_struct { ALuint64 ClockBase; ALuint SamplesDone; + ALuint FixedLatency; /* Temp storage used for mixer processing. */ alignas(16) ALfloat TempBuffer[4][BUFFERSIZE]; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 81d8c262..d7c68e4e 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -1295,7 +1295,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p */ values[0] = GetSourceSecOffset(Source, Context, &srcclock); almtx_lock(&device->BackendLock); - clocktime = V0(device->Backend,getClockLatency)(); + clocktime = GetClockLatency(device); almtx_unlock(&device->BackendLock); if(srcclock == (ALuint64)clocktime.ClockTime) values[1] = (ALdouble)clocktime.Latency / 1000000000.0; @@ -1559,7 +1559,7 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp */ values[0] = GetSourceSampleOffset(Source, Context, &srcclock); almtx_lock(&device->BackendLock); - clocktime = V0(device->Backend,getClockLatency)(); + clocktime = GetClockLatency(device); almtx_unlock(&device->BackendLock); if(srcclock == (ALuint64)clocktime.ClockTime) values[1] = clocktime.Latency;