---
 src/libespeak-ng/speech.c |   34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

--- a/src/libespeak-ng/speech.c
+++ b/src/libespeak-ng/speech.c
@@ -35,6 +35,7 @@
 
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 #include <pcaudiolib/audio.h>
+#include <pthread.h>
 #endif
 
 #if defined(_WIN32) || defined(_WIN64)
@@ -88,11 +89,17 @@ int (*phoneme_callback)(const char *) =
 char path_home[N_PATH_HOME]; // this is the espeak-ng-data directory
 extern int saved_parameters[N_SPEECH_PARAM]; // Parameters saved on synthesis start
 
+#ifdef HAVE_PCAUDIOLIB_AUDIO_H
+static pthread_mutex_t pcaudiolib_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
 void cancel_audio(void)
 {
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
+		pthread_mutex_lock(&pcaudiolib_lock);
 		audio_object_flush(my_audio);
+		pthread_mutex_unlock(&pcaudiolib_lock);
 	}
 #endif
 }
@@ -101,7 +108,9 @@ void close_audio(void)
 {
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
+		pthread_mutex_lock(&pcaudiolib_lock);
 		audio_object_close(my_audio);
+		pthread_mutex_unlock(&pcaudiolib_lock);
 	}
 #endif
 }
@@ -110,11 +119,13 @@ void open_audio(void)
 {
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
+		pthread_mutex_lock(&pcaudiolib_lock);
 		int error = audio_object_open(my_audio, AUDIO_OBJECT_FORMAT_S16LE, voice_samplerate, 1);
 		if (error != 0) {
 			fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error));
 			err = ENS_AUDIO_ERROR;
 		}
+		pthread_mutex_unlock(&pcaudiolib_lock);
 	}
 #endif
 }
@@ -143,7 +154,9 @@ static int dispatch_audio(short *outbuf,
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 				if (out_samplerate != 0) {
 					// sound was previously open with a different sample rate
+					pthread_mutex_lock(&pcaudiolib_lock);
 					audio_object_close(my_audio);
+					pthread_mutex_unlock(&pcaudiolib_lock);
 					out_samplerate = 0;
 #ifdef HAVE_SLEEP
 					sleep(1);
@@ -151,12 +164,15 @@ static int dispatch_audio(short *outbuf,
 				}
 #endif
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
+				pthread_mutex_lock(&pcaudiolib_lock);
 				int error = audio_object_open(my_audio, AUDIO_OBJECT_FORMAT_S16LE, voice_samplerate, 1);
 				if (error != 0) {
 					fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error));
+					pthread_mutex_unlock(&pcaudiolib_lock);
 					err = ENS_AUDIO_ERROR;
 					return -1;
 				}
+				pthread_mutex_unlock(&pcaudiolib_lock);
 #endif
 				out_samplerate = voice_samplerate;
 #ifdef USE_ASYNC
@@ -168,21 +184,26 @@ static int dispatch_audio(short *outbuf,
 
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 		if (out_samplerate == 0) {
+			pthread_mutex_lock(&pcaudiolib_lock);
 			int error = audio_object_open(my_audio, AUDIO_OBJECT_FORMAT_S16LE, voice_samplerate, 1);
 			if (error != 0) {
 				fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error));
+				pthread_mutex_unlock(&pcaudiolib_lock);
 				err = ENS_AUDIO_ERROR;
 				return -1;
 			}
+			pthread_mutex_unlock(&pcaudiolib_lock);
 			out_samplerate = voice_samplerate;
 		}
 #endif
 
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 		if (outbuf && length && a_wave_can_be_played) {
+			pthread_mutex_lock(&pcaudiolib_lock);
 			int error = audio_object_write(my_audio, (char *)outbuf, 2*length);
 			if (error != 0)
 				fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error));
+			pthread_mutex_unlock(&pcaudiolib_lock);
 		}
 #endif
 
@@ -295,7 +316,11 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng
 
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 	if (my_audio == NULL)
+	{
+		pthread_mutex_lock(&pcaudiolib_lock);
 		my_audio = create_audio_device_object(device, "eSpeak", "Text-to-Speech");
+		pthread_mutex_unlock(&pcaudiolib_lock);
+	}
 #endif
 
 
@@ -593,11 +618,13 @@ espeak_ng_STATUS sync_espeak_Synth(unsig
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
 	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
 	    /* FIXME: This drain poses cancelling problems for end of speechs */
+		pthread_mutex_lock(&pcaudiolib_lock);
 		int error = (aStatus == ENS_SPEECH_STOPPED)
 		          ? audio_object_flush(my_audio)
 		          : audio_object_drain(my_audio);
 		if (error != 0)
 			fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error));
+		pthread_mutex_unlock(&pcaudiolib_lock);
 	}
 #endif
 
@@ -910,8 +937,11 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng
 #endif
 
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
-	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO)
+	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
+		pthread_mutex_lock(&pcaudiolib_lock);
 		audio_object_flush(my_audio);
+		pthread_mutex_unlock(&pcaudiolib_lock);
+	}
 #endif
 	embedded_value[EMBED_T] = 0; // reset echo for pronunciation announcements
 
@@ -951,8 +981,10 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng
 
 	if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
 #ifdef HAVE_PCAUDIOLIB_AUDIO_H
+		pthread_mutex_lock(&pcaudiolib_lock);
 		audio_object_close(my_audio);
 		audio_object_destroy(my_audio);
+		pthread_mutex_unlock(&pcaudiolib_lock);
 		my_audio = NULL;
 #endif
 		out_samplerate = 0;
