Throttle on EE_BUFFER_FULL errors

When espeak returns EE_BUFFER_FULL we should just wait a bit before
retrying. Also, we don't want to lose the current entry. We however want
to wake up as soon as possible on stop request.
This commit is contained in:
Samuel Thibault 2022-03-01 01:28:38 +01:00 committed by Alexander Epaneshnikov
commit 108c28ae08
4 changed files with 23 additions and 4 deletions

View file

@ -325,16 +325,16 @@ static void reinitialize_espeak(struct synth_t *s)
return;
}
static struct espeak_entry_t *current = NULL;
static void queue_process_entry(struct synth_t *s)
{
espeak_ERROR error;
espeak_ERROR error = EE_OK;
char markbuff[50];
static struct espeak_entry_t *current = NULL;
if (current != queue_peek(synth_queue)) {
if (current)
free_espeak_entry(current);
current = (struct espeak_entry_t *) queue_remove(synth_queue);
current = queue_peek(synth_queue);
}
pthread_mutex_unlock(&queue_guard);
@ -386,9 +386,25 @@ static void queue_process_entry(struct synth_t *s)
break;
}
pthread_mutex_lock(&queue_guard);
if (error == EE_OK) {
/* Processed, drop it */
struct espeak_entry_t *unqueued = queue_remove(synth_queue);
assert(unqueued == current);
free_espeak_entry(current);
current = NULL;
} else {
if (error == EE_BUFFER_FULL)
{
/* Give speak a little break before retrying */
struct timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec++;
/* But wake up immediately if we have to stop */
pthread_cond_timedwait(&wake_stop, &queue_guard, &timeout);
}
else
fprintf(stderr, "espeak error: %d\n", error);
}
}
@ -450,6 +466,7 @@ void *espeak_thread(void *arg)
pthread_cond_wait(&runner_awake, &queue_guard);
if (stop_requested) {
current = NULL;
stop_speech();
synth_queue_clear();
stop_requested = 0;
@ -458,7 +475,6 @@ void *espeak_thread(void *arg)
while (should_run && queue_peek(synth_queue) && !stop_requested) {
queue_process_entry(s);
pthread_mutex_lock(&queue_guard);
}
}
pthread_cond_signal(&stop_acknowledged);

View file

@ -40,6 +40,7 @@ volatile int should_run = 1;
espeak_AUDIO_OUTPUT audio_mode;
pthread_cond_t runner_awake = PTHREAD_COND_INITIALIZER;
pthread_cond_t wake_stop = PTHREAD_COND_INITIALIZER;
pthread_cond_t stop_acknowledged = PTHREAD_COND_INITIALIZER;
pthread_mutex_t queue_guard = PTHREAD_MUTEX_INITIALIZER;

View file

@ -99,6 +99,7 @@ extern int self_pipe_fds[2];
#define PIPE_WRITE_FD (self_pipe_fds[1])
extern pthread_cond_t runner_awake;
extern pthread_cond_t wake_stop;
extern pthread_cond_t stop_acknowledged;
extern pthread_mutex_t queue_guard;

View file

@ -228,6 +228,7 @@ static void request_espeak_stop(void)
pthread_mutex_lock(&queue_guard);
stop_requested = 1;
pthread_cond_signal(&runner_awake); // Wake runner, if necessary.
pthread_cond_signal(&wake_stop); // Wake runner, if necessary.
while (should_run && stop_requested)
// wait for acknowledgement.
pthread_cond_wait(&stop_acknowledged, &queue_guard);