From f65e83c3499ed26ee3dea4b0a1ca0282d47ae7cc Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 14 Mar 2018 03:21:26 -0700 Subject: [PATCH] Avoid using pa_stream_begin_write with PulseAudio It seems to actually have a negative performance impact when the system is under load. Without having actual measurements for any potential benefits, simply go with the recommended (and previous fallback) method of allocating space for the write and passing the free method. Ideally some kind of ring buffer could be used, so rather than constantly allocating and freeing blocks of memory, it uses the same memory over again with the callback marking each one as reusable. Unfortunately the callback isn't given much information to work with, and the update size (minreq) can potentially change during playback, which complicates things. --- Alc/backends/pulseaudio.c | 32 +++++++++----------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index 96794e20..be785707 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -833,6 +833,9 @@ static int ALCpulsePlayback_mixerProc(void *ptr) while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) && ATOMIC_LOAD(&device->Connected, almemory_order_acquire)) { + void *buf; + int ret; + len = pa_stream_writable_size(self->stream); if(len < 0) { @@ -863,33 +866,16 @@ static int ALCpulsePlayback_mixerProc(void *ptr) pa_threaded_mainloop_wait(self->loop); continue; } + len -= len%self->attr.minreq; + len -= len%frame_size; - while(len > 0) - { - size_t newlen = len; - int ret; - void *buf; - pa_free_cb_t free_func = NULL; + buf = pa_xmalloc(len); - if(pa_stream_begin_write(self->stream, &buf, &newlen) < 0) - { - buf = pa_xmalloc(newlen); - free_func = pa_xfree; - } + aluMixData(device, buf, len/frame_size); - newlen /= frame_size; - aluMixData(device, buf, newlen); - - newlen *= frame_size; - ret = pa_stream_write(self->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE); - if(ret != PA_OK) - { - ERR("Failed to write to stream: %d, %s\n", ret, pa_strerror(ret)); - break; - } - len -= newlen; - } + ret = pa_stream_write(self->stream, buf, len, pa_xfree, 0, PA_SEEK_RELATIVE); + if(ret != PA_OK) ERR("Failed to write to stream: %d, %s\n", ret, pa_strerror(ret)); } pa_threaded_mainloop_unlock(self->loop);