From 8145a26d07fd1a99c8cf72b1d02650e0988232b5 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 31 Mar 2016 16:21:49 -0700 Subject: Add a hack to workaround erroneous prebuf values from pulse --- Alc/backends/pulseaudio.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'Alc') diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index 9ad04a71..ca8441aa 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -1051,10 +1051,12 @@ static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self) { /* Server updated our playback rate, so modify the buffer attribs * accordingly. */ - device->NumUpdates = (ALuint)((ALdouble)device->NumUpdates / device->Frequency * - self->spec.rate + 0.5); + device->NumUpdates = (ALuint)clampd( + (ALdouble)device->NumUpdates/device->Frequency*self->spec.rate + 0.5, 2.0, 16.0 + ); + self->attr.minreq = device->UpdateSize * pa_frame_size(&self->spec); - self->attr.tlength = self->attr.minreq * clampu(device->NumUpdates, 2, 16); + self->attr.tlength = self->attr.minreq * device->NumUpdates; self->attr.maxlength = -1; self->attr.prebuf = 0; @@ -1069,10 +1071,31 @@ static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self) ALCpulsePlayback_bufferAttrCallback(self->stream, self); len = self->attr.minreq / pa_frame_size(&self->spec); - device->NumUpdates = (ALuint)((ALdouble)device->NumUpdates/len*device->UpdateSize + 0.5); - device->NumUpdates = clampu(device->NumUpdates, 2, 16); + device->NumUpdates = (ALuint)clampd( + (ALdouble)device->NumUpdates/len*device->UpdateSize + 0.5, 2.0, 16.0 + ); device->UpdateSize = len; + /* HACK: prebuf should be 0 as that's what we set it to. However on some + * systems it comes back as non-0, so we have to make sure the device will + * write enough audio to start playback. The lack of manual start control + * may have unintended consequences, but it's better than not starting at + * all. + */ + if(self->attr.prebuf != 0) + { + len = self->attr.prebuf / pa_frame_size(&self->spec); + if(len <= device->UpdateSize*device->NumUpdates) + ERR("Non-0 prebuf, %u samples (%u bytes), device has %u samples\n", + len, self->attr.prebuf, device->UpdateSize*device->NumUpdates); + else + { + ERR("Large prebuf, %u samples (%u bytes), increasing device from %u samples", + len, self->attr.prebuf, device->UpdateSize*device->NumUpdates); + device->NumUpdates = (len+device->UpdateSize-1) / device->UpdateSize; + } + } + pa_threaded_mainloop_unlock(self->loop); return ALC_TRUE; } -- cgit v1.2.3