Skip to content

Commit

Permalink
Fix cancellation snappiness
Browse files Browse the repository at this point in the history
Screen reader users report getting late cancellation, or even mixtures
of speech. This is because the default buffering parameters of alsa or
pulseaudio are relatively large.

This change sets alsa and pulseaudio buffer sizes to 10ms worth of audio,
which is the human snappiness perception limit.
  • Loading branch information
sthibaul committed Oct 18, 2020
1 parent 891ccbb commit a41d46e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ alsa_object_open(struct audio_object *object,

snd_pcm_hw_params_t *params = NULL;
snd_pcm_hw_params_malloc(&params);
snd_pcm_uframes_t bufsize = (rate * channels * LATENCY) / 1000;

int err = 0;
if ((err = snd_pcm_open(&self->handle, self->device ? self->device : "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
Expand All @@ -113,6 +114,8 @@ alsa_object_open(struct audio_object *object,
goto error;
if ((err = snd_pcm_hw_params_set_channels(self->handle, params, channels)) < 0)
goto error;
if ((err = snd_pcm_hw_params_set_buffer_size_near(self->handle, params, &bufsize)) < 0)
goto error;
if ((err = snd_pcm_hw_params(self->handle, params)) < 0)
goto error;
if ((err = snd_pcm_prepare(self->handle)) < 0)
Expand Down
4 changes: 4 additions & 0 deletions src/audio_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ struct audio_object
int error);
};

/* We try to aim for 10ms cancelation latency, which will be perceived as
* "snappy" by users */
#define LATENCY 10

#if defined(_WIN32) || defined(_WIN64)

#include <windows.h>
Expand Down
9 changes: 8 additions & 1 deletion src/pulseaudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,21 @@ pulseaudio_object_open(struct audio_object *object,
}

int error = 0;
pa_buffer_attr battr;

battr.fragsize = (uint32_t) -1;
battr.maxlength = (uint32_t) -1;
battr.minreq = (uint32_t) -1;
battr.prebuf = (uint32_t) -1;
battr.tlength = pa_bytes_per_second(&self->ss) * LATENCY / 1000;
self->s = pa_simple_new(NULL,
self->application_name,
PA_STREAM_PLAYBACK,
self->device,
self->description,
&self->ss,
NULL,
NULL,
&battr,
&error);
return error;
}
Expand Down

0 comments on commit a41d46e

Please sign in to comment.