diff -Nru espeak-ng-1.49.2+dfsg/debian/changelog espeak-ng-1.49.2+dfsg/debian/changelog --- espeak-ng-1.49.2+dfsg/debian/changelog 2018-10-23 23:28:37.000000000 +0000 +++ espeak-ng-1.49.2+dfsg/debian/changelog 2018-11-13 23:01:43.000000000 +0000 @@ -1,6 +1,19 @@ +espeak-ng (1.49.2+dfsg-8) unstable; urgency=medium + + * patches/fix-cancel: Do not open audio when audio speak mode is not + enabled. + + -- Samuel Thibault Wed, 14 Nov 2018 00:01:43 +0100 + +espeak-ng (1.49.2+dfsg-7) unstable; urgency=medium + + * nocancel: Fix hang on cancellation of threads holding mutexes. + + -- Samuel Thibault Tue, 13 Nov 2018 11:02:44 +0100 + espeak-ng (1.49.2+dfsg-6) unstable; urgency=medium - * rules: Fix binary-indep build. + * rules: Fix binary-indep build, thanks Santiago Vila for the notice. -- Samuel Thibault Wed, 24 Oct 2018 01:28:37 +0200 diff -Nru espeak-ng-1.49.2+dfsg/debian/patches/audio_reopen espeak-ng-1.49.2+dfsg/debian/patches/audio_reopen --- espeak-ng-1.49.2+dfsg/debian/patches/audio_reopen 2018-05-03 19:21:46.000000000 +0000 +++ espeak-ng-1.49.2+dfsg/debian/patches/audio_reopen 2018-11-13 22:58:19.000000000 +0000 @@ -13,26 +13,31 @@ } #endif } -@@ -109,6 +110,18 @@ void open_audio(void) - fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error)); - err = ENS_AUDIO_ERROR; - return -1; -+ } else { -+ out_samplerate = voice_samplerate; -+ } -+#endif -+} -+ +@@ -109,11 +110,23 @@ void open_audio(void) + if (error != 0) { + fprintf(stderr, "error: %s\n", audio_object_strerror(my_audio, error)); + err = ENS_AUDIO_ERROR; ++ } else { ++ out_samplerate = voice_samplerate; + } + } + #endif + } + +void check_audio(void) +{ +#ifdef HAVE_PCAUDIOLIB_AUDIO_H + if (out_samplerate == 0) { + /* Try to reopen audio */ + open_audio(); - } - #endif - } -@@ -138,12 +151,12 @@ static int dispatch_audio(short *outbuf, ++ } ++#endif ++} ++ + static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) + { + int a_wave_can_be_played = 1; +@@ -139,12 +152,12 @@ static int dispatch_audio(short *outbuf, if (out_samplerate != 0) { // sound was previously open with a different sample rate audio_object_close(my_audio); @@ -46,7 +51,7 @@ #ifdef HAVE_PCAUDIOLIB_AUDIO_H int error = audio_object_open(my_audio, AUDIO_OBJECT_FORMAT_S16LE, voice_samplerate, 1); if (error != 0) { -@@ -152,12 +165,14 @@ static int dispatch_audio(short *outbuf, +@@ -153,12 +166,14 @@ static int dispatch_audio(short *outbuf, return -1; } #endif diff -Nru espeak-ng-1.49.2+dfsg/debian/patches/fix-cancel espeak-ng-1.49.2+dfsg/debian/patches/fix-cancel --- espeak-ng-1.49.2+dfsg/debian/patches/fix-cancel 2018-01-06 23:41:08.000000000 +0000 +++ espeak-ng-1.49.2+dfsg/debian/patches/fix-cancel 2018-11-13 22:52:18.000000000 +0000 @@ -14,9 +14,9 @@ --- src/libespeak-ng/fifo.c | 4 ++++ - src/libespeak-ng/speech.c | 22 ++++++++++++++++++++++ + src/libespeak-ng/speech.c | 23 +++++++++++++++++++++++ src/libespeak-ng/speech.h | 3 +++ - 3 files changed, 29 insertions(+) + 3 files changed, 30 insertions(+) --- a/src/libespeak-ng/fifo.c +++ b/src/libespeak-ng/fifo.c @@ -33,7 +33,7 @@ init(1); --- a/src/libespeak-ng/speech.c +++ b/src/libespeak-ng/speech.c -@@ -93,6 +93,27 @@ void cancel_audio(void) +@@ -92,6 +92,28 @@ void cancel_audio(void) #endif } @@ -49,11 +49,12 @@ +void open_audio(void) +{ +#ifdef HAVE_PCAUDIOLIB_AUDIO_H -+ 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; -+ return -1; ++ if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { ++ 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; ++ } + } +#endif +} @@ -61,7 +62,7 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) { int a_wave_can_be_played = 1; -@@ -532,6 +553,7 @@ espeak_ng_STATUS sync_espeak_Synth(unsig +@@ -528,6 +550,7 @@ espeak_ng_STATUS sync_espeak_Synth(unsig espeak_ng_STATUS aStatus = Synthesize(unique_identifier, text, flags); #ifdef HAVE_PCAUDIOLIB_AUDIO_H if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { diff -Nru espeak-ng-1.49.2+dfsg/debian/patches/nocancel espeak-ng-1.49.2+dfsg/debian/patches/nocancel --- espeak-ng-1.49.2+dfsg/debian/patches/nocancel 1970-01-01 00:00:00.000000000 +0000 +++ espeak-ng-1.49.2+dfsg/debian/patches/nocancel 2018-11-12 23:17:19.000000000 +0000 @@ -0,0 +1,126 @@ +--- + src/libespeak-ng/event.c | 15 ++++++++++----- + src/libespeak-ng/fifo.c | 15 +++++++++------ + 2 files changed, 19 insertions(+), 11 deletions(-) + +--- a/src/libespeak-ng/event.c ++++ b/src/libespeak-ng/event.c +@@ -44,6 +44,7 @@ static pthread_cond_t my_cond_stop_is_re + static int my_stop_is_required = 0; + static pthread_cond_t my_cond_stop_is_acknowledged; + static int my_stop_is_acknowledged = 0; ++static int my_terminate_is_required = 0; + // my_thread: polls the audio duration and compares it to the duration of the first event. + static pthread_t my_thread; + static bool thread_inited; +@@ -254,13 +255,13 @@ static void *polling_thread(void *p) + { + (void)p; // unused + +- while (1) { ++ while (my_terminate_is_required == 0) { + int a_stop_is_required = 0; + + int a_status = pthread_mutex_lock(&my_mutex); + my_event_is_running = 0; + +- while (my_start_is_required == 0) { ++ while (my_start_is_required == 0 && my_terminate_is_required == 0) { + while ((pthread_cond_wait(&my_cond_start_is_required, &my_mutex) == -1) && errno == EINTR) + continue; // Restart when interrupted by handler + } +@@ -272,7 +273,7 @@ static void *polling_thread(void *p) + pthread_mutex_unlock(&my_mutex); + + // In this loop, my_event_is_running = 1 +- while (head && (a_stop_is_required == 0)) { ++ while (head && (a_stop_is_required == 0) && (my_terminate_is_required == 0)) { + espeak_EVENT *event = (espeak_EVENT *)(head->data); + assert(event); + +@@ -305,7 +306,7 @@ static void *polling_thread(void *p) + + a_status = pthread_mutex_unlock(&my_mutex); + +- if (a_stop_is_required > 0) { ++ if (a_stop_is_required > 0 || my_terminate_is_required) { + // no mutex required since the stop command is synchronous + // and waiting for my_cond_stop_is_acknowledged + init(); +@@ -385,8 +386,12 @@ static void init() + void event_terminate() + { + if (thread_inited) { +- pthread_cancel(my_thread); ++ my_terminate_is_required = 1; ++ pthread_cond_signal(&my_cond_start_is_required); ++ pthread_cond_signal(&my_cond_stop_is_required); + pthread_join(my_thread, NULL); ++ my_terminate_is_required = 0; ++ + pthread_mutex_destroy(&my_mutex); + pthread_cond_destroy(&my_cond_start_is_required); + pthread_cond_destroy(&my_cond_stop_is_required); +--- a/src/libespeak-ng/fifo.c ++++ b/src/libespeak-ng/fifo.c +@@ -45,6 +45,7 @@ static pthread_mutex_t my_mutex; + static int my_command_is_running = 0; + static pthread_cond_t my_cond_command_is_running; + static int my_stop_is_required = 0; ++static int my_terminate_is_required = 0; + + // my_thread: reads commands from the fifo, and runs them. + static pthread_t my_thread; +@@ -289,7 +290,7 @@ static void *say_thread(void *p) + + int look_for_inactivity = 0; + +- while (1) { ++ while (my_terminate_is_required == 0) { + int a_start_is_required = 0; + if (look_for_inactivity) { + a_start_is_required = sleep_until_start_request_or_inactivity(); +@@ -302,19 +303,18 @@ static void *say_thread(void *p) + assert(!a_status); + + if (!a_start_is_required) { +- while (my_start_is_required == 0) { ++ while (my_start_is_required == 0 && my_terminate_is_required == 0) { + while ((pthread_cond_wait(&my_cond_start_is_required, &my_mutex) == -1) && errno == EINTR) + continue; // Restart when interrupted by handler + } + } + +- + my_command_is_running = 1; + + assert(-1 != pthread_cond_broadcast(&my_cond_command_is_running)); + assert(-1 != pthread_mutex_unlock(&my_mutex)); + +- while (my_command_is_running) { ++ while (my_command_is_running && my_terminate_is_required == 0) { + int a_status = pthread_mutex_lock(&my_mutex); + assert(!a_status); + t_espeak_command *a_command = (t_espeak_command *)pop(); +@@ -335,7 +335,7 @@ static void *say_thread(void *p) + } + } + +- if (my_stop_is_required) { ++ if (my_stop_is_required || my_terminate_is_required) { + // restart the audio early, to be more responsive when using eSpeak NG + // for audio. + close_audio(); +@@ -440,8 +440,11 @@ static void init(int process_parameters) + + void fifo_terminate() + { +- pthread_cancel(my_thread); ++ my_terminate_is_required = 1; ++ pthread_cond_signal(&my_cond_start_is_required); + pthread_join(my_thread, NULL); ++ my_terminate_is_required = 0; ++ + pthread_mutex_destroy(&my_mutex); + pthread_cond_destroy(&my_cond_start_is_required); + pthread_cond_destroy(&my_cond_stop_is_acknowledged); diff -Nru espeak-ng-1.49.2+dfsg/debian/patches/series espeak-ng-1.49.2+dfsg/debian/patches/series --- espeak-ng-1.49.2+dfsg/debian/patches/series 2018-07-15 13:55:47.000000000 +0000 +++ espeak-ng-1.49.2+dfsg/debian/patches/series 2018-11-13 00:17:49.000000000 +0000 @@ -5,3 +5,4 @@ audio_reopen privacy lessgreat-punct +nocancel