From: Dzmitry Keremsha <vyro@lumencoil.com> Signed-off-by: Dzmitry Keremsha <vyro@lumencoil.com> --- dlls/winepulse.drv/pulse.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 93f10499c01..b25b8eb6802 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 @@ -1451,9 +1452,6 @@ static void pulse_write(struct pulse_stream *stream) to_write = stream->real_bufsize_bytes - stream->pa_offs_bytes; TRACE("writing small chunk of %u bytes\n", to_write); write_buffer(stream, buf, to_write); - stream->held_bytes -= to_write; - stream->lcl_offs_bytes += to_write; - stream->lcl_offs_bytes %= stream->real_bufsize_bytes; stream->pa_held_bytes -= to_write; to_write = bytes - to_write; stream->pa_offs_bytes = 0; @@ -1464,9 +1462,6 @@ static void pulse_write(struct pulse_stream *stream) TRACE("writing main chunk of %u bytes\n", to_write); write_buffer(stream, buf, to_write); - stream->held_bytes -= to_write; - stream->lcl_offs_bytes += to_write; - stream->lcl_offs_bytes %= stream->real_bufsize_bytes; stream->pa_offs_bytes += to_write; stream->pa_offs_bytes %= stream->real_bufsize_bytes; stream->pa_held_bytes -= to_write; @@ -1578,6 +1573,8 @@ static NTSTATUS pulse_timer_loop(void *args) struct pulse_stream *stream = handle_get_stream(params->stream); LARGE_INTEGER delay; pa_usec_t last_time; + UINT32 adv_bytes; + UINT32 bytes_passed; int success; pulse_lock(); @@ -1587,7 +1584,7 @@ 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; NtDelayExecution(FALSE, &delay); @@ -1618,6 +1615,7 @@ static NTSTATUS pulse_timer_loop(void *args) { stream->just_started = FALSE; last_time = now; + stream->last_timer_tick = now; } } else @@ -1639,6 +1637,14 @@ static NTSTATUS pulse_timer_loop(void *args) if (stream->dataflow == eRender) { pulse_write(stream); + + diff = now - stream->last_timer_tick; + 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) { @@ -1652,8 +1658,11 @@ static NTSTATUS pulse_timer_loop(void *args) } } - if (stream->event) - NtSetEvent(stream->event, NULL); + if (stream->event) + { + if (stream->held_bytes < (stream->period_bytes * 7 / 4)) + 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