aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-03-31 16:21:49 -0700
committerChris Robinson <[email protected]>2016-03-31 16:21:49 -0700
commit8145a26d07fd1a99c8cf72b1d02650e0988232b5 (patch)
treed25e7bf7c56676b9fc8a450e34d53b8ca65cda45 /Alc
parent93047e2a7a74030374c0a2f113c1a74f71f6fab4 (diff)
Add a hack to workaround erroneous prebuf values from pulse
Diffstat (limited to 'Alc')
-rw-r--r--Alc/backends/pulseaudio.c33
1 files changed, 28 insertions, 5 deletions
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;
}