commit a48576a3640f9014760888bb30a924a3e2163e57
Author: Reece H. Dunn <msclrhd@gmail.com>
Date:   Fri Dec 23 18:56:58 2016 +0000

    Return ENS_SPEECH_STOPPED from Synthesize when the speech callback returns >1 to stop the audio.

diff --git a/src/include/espeak-ng/espeak_ng.h b/src/include/espeak-ng/espeak_ng.h
index cdf27ec5..942fe175 100644
--- a/src/include/espeak-ng/espeak_ng.h
+++ b/src/include/espeak-ng/espeak_ng.h
@@ -55,6 +55,7 @@ typedef enum {
 	ENS_UNSUPPORTED_PHON_FORMAT  = 0x10000BFF,
 	ENS_NO_SPECT_FRAMES          = 0x10000CFF,
 	ENS_EMPTY_PHONEME_MANIFEST   = 0x10000DFF,
+	ENS_SPEECH_STOPPED           = 0x10000EFF,
 } espeak_ng_STATUS;
 
 typedef enum {
diff --git a/src/libespeak-ng/espeak_api.c b/src/libespeak-ng/espeak_api.c
index 6ff855b8..ec926791 100644
--- a/src/libespeak-ng/espeak_api.c
+++ b/src/libespeak-ng/espeak_api.c
@@ -37,6 +37,7 @@ static espeak_ERROR status_to_espeak_error(espeak_ng_STATUS status)
 	switch (status)
 	{
 	case ENS_OK:                     return EE_OK;
+	case ENS_SPEECH_STOPPED:         return EE_OK;
 	case ENS_VOICE_NOT_FOUND:        return EE_NOT_FOUND;
 	case ENS_MBROLA_NOT_FOUND:       return EE_NOT_FOUND;
 	case ENS_MBROLA_VOICE_NOT_FOUND: return EE_NOT_FOUND;
diff --git a/src/libespeak-ng/speech.c b/src/libespeak-ng/speech.c
index a021bfc5..73d89a4d 100644
--- a/src/libespeak-ng/speech.c
+++ b/src/libespeak-ng/speech.c
@@ -410,7 +410,7 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t
 			finished = synth_callback((short *)outbuf, length, event_list);
 		if (finished) {
 			SpeakNextClause(NULL, 0, 2); // stop
-			break;
+			return ENS_SPEECH_STOPPED;
 		}
 
 		if (Generate(phoneme_list, &n_phoneme_list, 1) == 0) {
@@ -428,12 +428,11 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t
 							return ENS_AUDIO_ERROR;
 					} else if (synth_callback)
 						synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
-					break;
+					return ENS_OK;
 				}
 			}
 		}
 	}
-	return ENS_OK;
 }
 
 void MarkerEvent(int type, unsigned int char_position, int value, int value2, unsigned char *out_ptr)


commit bc674081cd0e787e364989baab82df0ce883abec
Author: Reece H. Dunn <msclrhd@gmail.com>
Date:   Fri Dec 23 19:17:18 2016 +0000

    Check the return from synth_callback in the second call to that function in Synthesize.

diff --git a/src/libespeak-ng/speech.c b/src/libespeak-ng/speech.c
index 73d89a4d..f181420c 100644
--- a/src/libespeak-ng/speech.c
+++ b/src/libespeak-ng/speech.c
@@ -423,11 +423,16 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t
 				event_list[0].user_data = my_user_data;
 
 				if (SpeakNextClause(NULL, NULL, 1) == 0) {
+					finished = 0;
 					if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) {
 						if (dispatch_audio(NULL, 0, NULL) < 0)
 							return ENS_AUDIO_ERROR;
 					} else if (synth_callback)
-						synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
+						finished = synth_callback(NULL, 0, event_list); // NULL buffer ptr indicates end of data
+					if (finished) {
+						SpeakNextClause(NULL, 0, 2); // stop
+						return ENS_SPEECH_STOPPED;
+					}
 					return ENS_OK;
 				}
 			}

commit d2478cc453750e4081e0b6eaeca1442b8abaa92f
Author: Reece H. Dunn <msclrhd@gmail.com>
Date:   Fri Dec 23 19:34:13 2016 +0000

    Flush the audio if speech has stopped, drain the audio if speech is still active.

diff --git a/src/libespeak-ng/speech.c b/src/libespeak-ng/speech.c
index f181420c..ef26dc48 100644
--- a/src/libespeak-ng/speech.c
+++ b/src/libespeak-ng/speech.c
@@ -503,7 +503,9 @@ espeak_ng_STATUS sync_espeak_Synth(unsigned int unique_identifier, const void *t
 	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) {
-		int error = audio_object_drain(my_audio);
+		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));
 	}
