From: Dzmitry Keremsha <vyro@lumencoil.com> --- dlls/winepulse.drv/pulse.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 7c8d872c604..bd247cdb030 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -85,6 +85,7 @@ struct pulse_stream struct list packet_free_head; struct list packet_filled_head; + pa_usec_t last_timer_tick; }; typedef struct _ACPacket @@ -1180,7 +1181,7 @@ static NTSTATUS pulse_create_stream(void *args) stream->bufsize_frames = ceil((params->duration / 10000000.) * params->fmt->nSamplesPerSec); bufsize_bytes = stream->bufsize_frames * pa_frame_size(&stream->ss); - stream->mmdev_period_usec = params->period / 10; + stream->mmdev_period_usec = params->period / 50; stream->share = params->share; stream->flags = params->flags; @@ -1573,6 +1574,7 @@ static NTSTATUS pulse_timer_loop(void *args) LARGE_INTEGER delay; pa_usec_t last_time; UINT32 adv_bytes; + UINT32 bytes_passed; int success; pulse_lock(); @@ -1582,8 +1584,9 @@ static NTSTATUS pulse_timer_loop(void *args) while (!stream->please_quit) { - pa_usec_t now, adv_usec = 0; + pa_usec_t now, diff, adv_usec = 0; int err; + adv_bytes=0; NtDelayExecution(FALSE, &delay); @@ -1613,6 +1616,7 @@ static NTSTATUS pulse_timer_loop(void *args) { stream->just_started = FALSE; last_time = now; + stream->last_timer_tick = now; } } else @@ -1634,12 +1638,15 @@ static NTSTATUS pulse_timer_loop(void *args) if (stream->dataflow == eRender) { pulse_write(stream); - - /* regardless of what PA does, advance one period */ - adv_bytes = min(stream->period_bytes, stream->held_bytes); + + diff = now - stream->last_timer_tick; + if (now < stream->last_timer_tick) diff = 0; + bytes_passed = muldiv(diff, stream->ss.rate, 1000000) * pa_frame_size(&stream->ss); + adv_bytes = min(bytes_passed, (UINT32)stream->held_bytes); stream->lcl_offs_bytes += adv_bytes; stream->lcl_offs_bytes %= stream->real_bufsize_bytes; stream->held_bytes -= adv_bytes; + stream->last_timer_tick += muldiv(adv_bytes / pa_frame_size(&stream->ss), 1000000, stream->ss.rate); } else if(stream->dataflow == eCapture) { @@ -1653,8 +1660,14 @@ static NTSTATUS pulse_timer_loop(void *args) } } - if (stream->event) - NtSetEvent(stream->event, NULL); + if (stream->event) + { + if (stream->held_bytes == 0 || + ((stream->held_bytes + adv_bytes) / stream->period_bytes != stream->held_bytes / stream->period_bytes)) + { + NtSetEvent(stream->event, NULL); + } + } TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n", stream, (int)adv_usec, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9840