diff --git a/src/libespeak-ng/speech.c b/src/libespeak-ng/speech.c index 86e3b0a0..45c9cfec 100644 --- a/src/libespeak-ng/speech.c +++ b/src/libespeak-ng/speech.c @@ -86,15 +86,18 @@ void WVoiceChanged(voice_t *wvoice) voice_samplerate = wvoice->samplerate; } -#ifdef USE_ASYNC - static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) { - int a_wave_can_be_played = fifo_is_command_enabled(); + int a_wave_can_be_played = 1; +#ifdef USE_ASYNC + if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) + a_wave_can_be_played = fifo_is_command_enabled(); +#endif switch (my_mode) { case ENOUTPUT_MODE_SPEAK_AUDIO: + case ENOUTPUT_MODE_SPEAK_AUDIO | ENOUTPUT_MODE_SYNCHRONOUS: { int event_type = 0; if (event) @@ -115,8 +118,12 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) err = ENS_AUDIO_ERROR; return -1; } - wave_set_callback_is_output_enabled(fifo_is_command_enabled); - event_init(); +#ifdef USE_ASYNC + if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) { + wave_set_callback_is_output_enabled(fifo_is_command_enabled); + event_init(); + } +#endif } } @@ -124,6 +131,7 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) wave_write(my_audio, (char *)outbuf, 2*length); } +#ifdef USE_ASYNC while (event && a_wave_can_be_played) { // TBD: some event are filtered here but some insight might be given // TBD: in synthesise.cpp for avoiding to create WORDs with size=0. @@ -132,12 +140,16 @@ static int dispatch_audio(short *outbuf, int length, espeak_EVENT *event) // TBD: the last one has its size=0. if ((event->type == espeakEVENT_WORD) && (event->length == 0)) break; - err = event_declare(event); - if (err != ENS_EVENT_BUFFER_FULL) + if ((my_mode & ENOUTPUT_MODE_SYNCHRONOUS) == 0) { + err = event_declare(event); + if (err != ENS_EVENT_BUFFER_FULL) + break; + usleep(10000); + a_wave_can_be_played = fifo_is_command_enabled(); + } else break; - usleep(10000); - a_wave_can_be_played = fifo_is_command_enabled(); } +#endif } break; case 0: @@ -175,6 +187,8 @@ static int create_events(short *outbuf, int length, espeak_EVENT *event_list, ui return finished; } +#ifdef USE_ASYNC + int sync_espeak_terminated_msg(uint32_t unique_identifier, void *user_data) { int finished = 0; @@ -212,15 +226,6 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_InitializeOutput(espeak_ng_OUTPUT_MODE option_waveout = 1; // inhibit portaudio callback from wavegen.cpp out_samplerate = 0; -#ifdef USE_ASYNC - if (output_mode == (ENOUTPUT_MODE_SYNCHRONOUS | ENOUTPUT_MODE_SPEAK_AUDIO)) { -#else - if ((output_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { -#endif - option_waveout = 0; - WavegenInitSound(); - } - // buflength is in mS, allocate 2 bytes per sample if ((buffer_length == 0) || (output_mode & ENOUTPUT_MODE_SPEAK_AUDIO)) buffer_length = 200; @@ -362,9 +367,7 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t int length; int finished = 0; int count_buffers = 0; -#ifdef USE_ASYNC uint32_t a_write_pos = 0; -#endif if ((outbuf == NULL) || (event_list == NULL)) return ENS_NOT_INITIALIZED; @@ -376,49 +379,14 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t count_samples = 0; -#ifdef USE_ASYNC if (my_mode == ENOUTPUT_MODE_SPEAK_AUDIO) a_write_pos = wave_get_write_position(my_audio); -#endif if (translator == NULL) espeak_SetVoiceByName("default"); SpeakNextClause(NULL, text, 0); -#ifdef USE_ASYNC - if (my_mode == (ENOUTPUT_MODE_SYNCHRONOUS | ENOUTPUT_MODE_SPEAK_AUDIO)) { -#else - if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { -#endif - bool continue_speaking = true; - while (continue_speaking) { -#ifdef PLATFORM_WINDOWS - Sleep(300); // 0.3s -#else -#ifdef USE_NANOSLEEP - struct timespec period; - struct timespec remaining; - period.tv_sec = 0; - period.tv_nsec = 300000000; // 0.3 sec - nanosleep(&period, &remaining); -#else - sleep(1); -#endif -#endif - do { - if (WcmdqUsed() > 0) - WavegenOpenSound(); - - if (Generate(phoneme_list, &n_phoneme_list, 1) == 0) { - if (SpeakNextClause(NULL, NULL, 1) == 0) - continue_speaking = WavegenCloseSound() == 0; - } - } while (skipping_text); - } - return ENS_OK; - } - for (;;) { out_ptr = outbuf; out_end = &outbuf[outbuf_size]; @@ -432,12 +400,10 @@ static espeak_ng_STATUS Synthesize(unsigned int unique_identifier, const void *t event_list[event_list_ix].user_data = my_user_data; count_buffers++; - if (my_mode == ENOUTPUT_MODE_SPEAK_AUDIO) { -#ifdef USE_ASYNC + if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { finished = create_events((short *)outbuf, length, event_list, a_write_pos); if (finished < 0) return ENS_AUDIO_ERROR; -#endif } else if (synth_callback) finished = synth_callback((short *)outbuf, length, event_list); if (finished) {