diff options
author | Chris Robinson <[email protected]> | 2017-06-15 21:39:09 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-06-15 21:39:09 -0700 |
commit | d4f3490a880f779f460332689a396ade69840f50 (patch) | |
tree | 0aae54a7a101294c48550c892b369c24138a7b9e | |
parent | 1e8feeff038ab0b2449a7b1b689a6c2500c0a4d3 (diff) |
Limit device buffer based on PulseAudio's tlength
Unfortunately PulseAudio has a habit of limiting tlength, and trying to
calculate the device's buffer length to write regardless of tlength could
result in some amount always being writable.
-rw-r--r-- | Alc/backends/pulseaudio.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/Alc/backends/pulseaudio.c b/Alc/backends/pulseaudio.c index 43761e23..8c5469b2 100644 --- a/Alc/backends/pulseaudio.c +++ b/Alc/backends/pulseaudio.c @@ -817,7 +817,6 @@ static int ALCpulsePlayback_mixerProc(void *ptr) pa_threaded_mainloop_lock(self->loop); frame_size = pa_frame_size(&self->spec); - buffer_size = device->UpdateSize * device->NumUpdates * frame_size; while(!self->killNow && device->Connected) { @@ -830,15 +829,17 @@ static int ALCpulsePlayback_mixerProc(void *ptr) } /* Make sure we're going to write at least 2 'periods' (minreqs), in - * case the server increased it since starting playback. + * case the server increased it since starting playback. Also round up + * the number of writable periods if it's not an integer count. */ - buffer_size = maxu(buffer_size, self->attr.minreq*2); + buffer_size = maxu((self->attr.tlength + self->attr.minreq/2) / self->attr.minreq, 2) * + self->attr.minreq; /* NOTE: This assumes pa_stream_writable_size returns between 0 and * tlength, else there will be more latency than intended. */ len = mini(len - (ssize_t)self->attr.tlength, 0) + buffer_size; - if(len < self->attr.minreq) + if(len < (int32_t)self->attr.minreq) { if(pa_stream_is_corked(self->stream)) { @@ -968,7 +969,6 @@ static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self) const char *mapname = NULL; pa_channel_map chanmap; pa_operation *o; - ALuint len; pa_threaded_mainloop_lock(self->loop); @@ -1107,11 +1107,10 @@ static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self) pa_stream_set_buffer_attr_callback(self->stream, ALCpulsePlayback_bufferAttrCallback, self); ALCpulsePlayback_bufferAttrCallback(self->stream, self); - len = self->attr.minreq / pa_frame_size(&self->spec); - device->NumUpdates = (ALuint)clampd( - (ALdouble)device->NumUpdates/len*device->UpdateSize + 0.5, 2.0, 16.0 + device->NumUpdates = (ALuint)clampu64( + (self->attr.tlength + self->attr.minreq/2) / self->attr.minreq, 2, 16 ); - device->UpdateSize = len; + device->UpdateSize = self->attr.minreq / pa_frame_size(&self->spec); /* 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 @@ -1121,7 +1120,7 @@ static ALCboolean ALCpulsePlayback_reset(ALCpulsePlayback *self) */ if(self->attr.prebuf != 0) { - len = self->attr.prebuf / pa_frame_size(&self->spec); + ALuint 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); |