diff --git a/alsa.c b/alsa.c index ebfaeab..48de434 100644 --- a/alsa.c +++ b/alsa.c @@ -25,10 +25,23 @@ #include #include #include +#include #define ALSA_PCM_NEW_HW_PARAMS_API #include #include "espeakup.h" +static pthread_mutex_t audio_mutex = PTHREAD_MUTEX_INITIALIZER; + +void lock_audio_mutex(void) +{ + pthread_mutex_lock(&audio_mutex); +} + +void unlock_audio_mutex(void) +{ + pthread_mutex_unlock(&audio_mutex); +} + int minimum(int x, int y) { if (x <= y) @@ -57,11 +70,15 @@ static int alsa_play_callback(short *audio, int numsamples, snd_pcm_prepare(handle); while (numsamples > 0) { + lock_audio_mutex(); if (stopped) { snd_pcm_drop(handle); stopped = 0; + unlock_audio_mutex(); return 1; } + unlock_audio_mutex(); + avail = snd_pcm_avail_update(handle); if (avail <= 0) continue; diff --git a/espeak_sound.c b/espeak_sound.c index f89538a..c9dcd82 100644 --- a/espeak_sound.c +++ b/espeak_sound.c @@ -5,3 +5,18 @@ int init_audio(void) audio_callback = NULL; return 0; } + +/* + * lock_audio_mutex and unlock_audio_mutex are no-ops if we use native + * sound support. The stopped variable is never read; no need to protect it. + */ + +void lock_audio_mutex(void) +{ + return; +} + +void unlock_audio_mutex(void) +{ + return; +} diff --git a/espeakup.h b/espeakup.h index 5a31cdf..a289e32 100644 --- a/espeakup.h +++ b/espeakup.h @@ -79,6 +79,8 @@ extern void close_softsynth(void); extern void main_loop(struct synth_t *s); extern void *queue_runner(void *arg); extern int init_audio(void); +extern void lock_audio_mutex(void); +extern void unlock_audio_mutex(void); extern volatile int stopped; extern espeak_AUDIO_OUTPUT audio_mode; diff --git a/synth.c b/synth.c index f7f13c3..e19d95e 100644 --- a/synth.c +++ b/synth.c @@ -114,7 +114,9 @@ espeak_ERROR set_volume(struct synth_t * s, int vol, enum adjust_t adj) espeak_ERROR stop_speech(void) { + lock_audio_mutex(); stopped = 1; + unlock_audio_mutex(); return (espeak_Cancel()); } @@ -122,7 +124,9 @@ espeak_ERROR speak_text(struct synth_t * s) { espeak_ERROR rc; + lock_audio_mutex(); stopped = 0; + unlock_audio_mutex(); rc = espeak_Synth(s->buf, s->len + 1, 0, POS_CHARACTER, 0, 0, NULL, NULL); return rc;