From ec218012c3372f192b5e371e9a81bcddc9f73371 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Wed, 8 Aug 2018 23:37:48 -0500 Subject: [PATCH] winepulse-PulseAudio_Support: Add patch. Should fix https://bugs.winehq.org/show_bug.cgi?id=45589. --- patches/patchinstall.sh | 2 + .../0008-winepulse-Fix-up-recording.patch | 163 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 patches/winepulse-PulseAudio_Support/0008-winepulse-Fix-up-recording.patch diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index f9008f81..e1d309ec 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -8106,6 +8106,7 @@ if test "$enable_winepulse_PulseAudio_Support" -eq 1; then patch_apply winepulse-PulseAudio_Support/0005-winepulse-implement-GetPropValue.patch patch_apply winepulse-PulseAudio_Support/0006-winepulse-fetch-actual-program-name-if-possible.patch patch_apply winepulse-PulseAudio_Support/0007-winepulse-return-PKEY_AudioEndpoint_PhysicalSpeakers.patch + patch_apply winepulse-PulseAudio_Support/0008-winepulse-Fix-up-recording.patch ( printf '%s\n' '+ { "Sebastian Lackner", "winepulse.drv: Use a separate mainloop and ctx for pulse_test_connect.", 1 },'; printf '%s\n' '+ { "Andrew Eikum", "winepulse: Don'\''t rely on pulseaudio callbacks for timing.", 1 },'; @@ -8114,6 +8115,7 @@ if test "$enable_winepulse_PulseAudio_Support" -eq 1; then printf '%s\n' '+ { "Mark Harmstone", "winepulse: Implement GetPropValue.", 1 },'; printf '%s\n' '+ { "Mark Harmstone", "winepulse: Fetch actual program name if possible.", 1 },'; printf '%s\n' '+ { "Mark Harmstone", "winepulse: Return PKEY_AudioEndpoint_PhysicalSpeakers device prop.", 1 },'; + printf '%s\n' '+ { "Andrew Eikum", "winepulse: Fix up recording.", 1 },'; ) >> "$patchlist" fi diff --git a/patches/winepulse-PulseAudio_Support/0008-winepulse-Fix-up-recording.patch b/patches/winepulse-PulseAudio_Support/0008-winepulse-Fix-up-recording.patch new file mode 100644 index 00000000..84ef383a --- /dev/null +++ b/patches/winepulse-PulseAudio_Support/0008-winepulse-Fix-up-recording.patch @@ -0,0 +1,163 @@ +From 80d921c3a7e93df6dcf34daa01829a13fac23179 Mon Sep 17 00:00:00 2001 +From: Andrew Eikum +Date: Tue, 7 Aug 2018 11:26:16 -0500 +Subject: [PATCH] winepulse: Fix up recording + +--- + dlls/winepulse.drv/mmdevdrv.c | 115 +++++++++++++++++------------------------- + 1 file changed, 46 insertions(+), 69 deletions(-) + +diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c +index 9c3ff0f..56f6c2b 100644 +--- a/dlls/winepulse.drv/mmdevdrv.c ++++ b/dlls/winepulse.drv/mmdevdrv.c +@@ -986,53 +986,70 @@ static void pulse_started_callback(pa_stream *s, void *userdata) + TRACE("%p: (Re)started playing\n", userdata); + } + +-static void pulse_rd_loop(ACImpl *This, size_t bytes) ++static void pulse_read(ACImpl *This) + { ++ size_t bytes = pa_stream_readable_size(This->stream); ++ ++ TRACE("Readable total: %zu, fragsize: %u\n", bytes, pa_stream_get_buffer_attr(This->stream)->fragsize); ++ ++ bytes += This->peek_len - This->peek_ofs; ++ + while (bytes >= This->period_bytes) { +- ACPacket *p, *next; +- LARGE_INTEGER stamp, freq; +- BYTE *dst, *src; ++ BYTE *dst = NULL, *src; + size_t src_len, copy, rem = This->period_bytes; +- if (!(p = (ACPacket*)list_head(&This->packet_free_head))) { +- p = (ACPacket*)list_head(&This->packet_filled_head); +- if (!p) return; +- if (!p->discont) { +- next = (ACPacket*)p->entry.next; +- next->discont = 1; +- } else +- p = (ACPacket*)list_tail(&This->packet_filled_head); +- } else { +- This->held_bytes += This->period_bytes; ++ ++ if (This->started) { ++ LARGE_INTEGER stamp, freq; ++ ACPacket *p, *next; ++ ++ if (!(p = (ACPacket*)list_head(&This->packet_free_head))) { ++ p = (ACPacket*)list_head(&This->packet_filled_head); ++ if (!p) return; ++ if (!p->discont) { ++ next = (ACPacket*)p->entry.next; ++ next->discont = 1; ++ } else ++ p = (ACPacket*)list_tail(&This->packet_filled_head); ++ } else { ++ This->held_bytes += This->period_bytes; ++ } ++ QueryPerformanceCounter(&stamp); ++ QueryPerformanceFrequency(&freq); ++ p->qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart; ++ p->discont = 0; ++ list_remove(&p->entry); ++ list_add_tail(&This->packet_filled_head, &p->entry); ++ ++ dst = p->data; + } +- QueryPerformanceCounter(&stamp); +- QueryPerformanceFrequency(&freq); +- p->qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart; +- p->discont = 0; +- list_remove(&p->entry); +- list_add_tail(&This->packet_filled_head, &p->entry); + +- dst = p->data; + while (rem) { + if (This->peek_len) { + copy = min(rem, This->peek_len - This->peek_ofs); + +- memcpy(dst, This->peek_buffer + This->peek_ofs, copy); ++ if (dst) { ++ memcpy(dst, This->peek_buffer + This->peek_ofs, copy); ++ dst += copy; ++ } + + rem -= copy; +- dst += copy; + This->peek_ofs += copy; + if(This->peek_len == This->peek_ofs) +- This->peek_len = 0; ++ This->peek_len = This->peek_ofs = 0; ++ + } else if (pa_stream_peek(This->stream, (const void**)&src, &src_len) == 0 && src_len) { + + copy = min(rem, src_len); + +- if(src) +- memcpy(dst, src, copy); +- else +- silence_buffer(This->ss.format, dst, copy); ++ if (dst) { ++ if(src) ++ memcpy(dst, src, copy); ++ else ++ silence_buffer(This->ss.format, dst, copy); ++ ++ dst += copy; ++ } + +- dst += copy; + rem -= copy; + + if (copy < src_len) { +@@ -1059,46 +1076,6 @@ static void pulse_rd_loop(ACImpl *This, size_t bytes) + } + } + +-static void pulse_rd_drop(ACImpl *This, size_t bytes) +-{ +- while (bytes >= This->period_bytes) { +- size_t src_len, copy, rem = This->period_bytes; +- while (rem) { +- const void *src; +- pa_stream_peek(This->stream, &src, &src_len); +- src_len -= This->peek_ofs; +- +- copy = rem; +- if (copy > src_len) +- copy = src_len; +- +- src_len -= copy; +- rem -= copy; +- +- if (!src_len) { +- This->peek_ofs = 0; +- pa_stream_drop(This->stream); +- } else +- This->peek_ofs += copy; +- bytes -= copy; +- } +- } +-} +- +-static void pulse_read(ACImpl *This) +-{ +- size_t bytes = pa_stream_readable_size(This->stream); +- TRACE("Readable total: %zu, fragsize: %u\n", bytes, pa_stream_get_buffer_attr(This->stream)->fragsize); +- bytes -= This->peek_ofs; +- if (bytes < This->period_bytes) +- return; +- +- if (This->started) +- pulse_rd_loop(This, bytes); +- else +- pulse_rd_drop(This, bytes); +-} +- + static DWORD WINAPI pulse_timer_cb(void *user) + { + DWORD delay; +-- +2.7.4 +