diff options
author | Chris Robinson <[email protected]> | 2016-03-31 16:21:49 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-03-31 16:21:49 -0700 |
commit | 8145a26d07fd1a99c8cf72b1d02650e0988232b5 (patch) | |
tree | d25e7bf7c56676b9fc8a450e34d53b8ca65cda45 /Alc/backends | |
parent | 93047e2a7a74030374c0a2f113c1a74f71f6fab4 (diff) |
Add a hack to workaround erroneous prebuf values from pulse
Diffstat (limited to 'Alc/backends')
-rw-r--r-- | Alc/backends/pulseaudio.c | 33 |
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; } |