| static int n_namedata = 0; | static int n_namedata = 0; | ||||
| char *namedata = NULL; | char *namedata = NULL; | ||||
| static FILE *f_input = NULL; | |||||
| static int ungot_char2 = 0; | static int ungot_char2 = 0; | ||||
| unsigned char *p_textinput; | unsigned char *p_textinput; | ||||
| wchar_t *p_wchar_input; | wchar_t *p_wchar_input; | ||||
| static void GetC_unget(int c) | static void GetC_unget(int c) | ||||
| { | { | ||||
| // This is only called with UTF8 input, not wchar input | // This is only called with UTF8 input, not wchar input | ||||
| if (f_input != NULL) | |||||
| ungetc(c, f_input); | |||||
| else { | |||||
| p_textinput--; | |||||
| *p_textinput = c; | |||||
| end_of_input = 0; | |||||
| } | |||||
| p_textinput--; | |||||
| *p_textinput = c; | |||||
| end_of_input = 0; | |||||
| } | } | ||||
| int Eof(void) | int Eof(void) | ||||
| if (ungot_char != 0) | if (ungot_char != 0) | ||||
| return 0; | return 0; | ||||
| if (f_input != 0) | |||||
| return feof(f_input); | |||||
| return end_of_input; | return end_of_input; | ||||
| } | } | ||||
| unsigned int c; | unsigned int c; | ||||
| unsigned int c2; | unsigned int c2; | ||||
| if (f_input != NULL) { | |||||
| c = fgetc(f_input); | |||||
| if (feof(f_input)) c = ' '; | |||||
| if (option_multibyte == espeakCHARS_16BIT) { | |||||
| c2 = fgetc(f_input); | |||||
| if (feof(f_input)) c2 = 0; | |||||
| c = c + (c2 << 8); | |||||
| } | |||||
| return c; | |||||
| } | |||||
| if (option_multibyte == espeakCHARS_WCHAR) { | if (option_multibyte == espeakCHARS_WCHAR) { | ||||
| if (*p_wchar_input == 0) { | if (*p_wchar_input == 0) { | ||||
| end_of_input = 1; | end_of_input = 1; | ||||
| { NULL, -1 } | { NULL, -1 } | ||||
| }; | }; | ||||
| int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change) | |||||
| int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change) | |||||
| { | { | ||||
| /* Find the end of the current clause. | /* Find the end of the current clause. | ||||
| Write the clause into buf | Write the clause into buf | ||||
| *tone_type = 0; | *tone_type = 0; | ||||
| *voice_change = 0; | *voice_change = 0; | ||||
| f_input = f_in; // for GetC etc | |||||
| if (ungot_word != NULL) { | if (ungot_word != NULL) { | ||||
| strcpy(buf, ungot_word); | strcpy(buf, ungot_word); | ||||
| ix += strlen(ungot_word); | ix += strlen(ungot_word); |
| if (translator == NULL) | if (translator == NULL) | ||||
| espeak_SetVoiceByName("default"); | espeak_SetVoiceByName("default"); | ||||
| SpeakNextClause(NULL, text, 0); | |||||
| SpeakNextClause(text, 0); | |||||
| for (;;) { | for (;;) { | ||||
| out_ptr = outbuf; | out_ptr = outbuf; | ||||
| } else if (synth_callback) | } else if (synth_callback) | ||||
| finished = synth_callback((short *)outbuf, length, event_list); | finished = synth_callback((short *)outbuf, length, event_list); | ||||
| if (finished) { | if (finished) { | ||||
| SpeakNextClause(NULL, 0, 2); // stop | |||||
| SpeakNextClause(0, 2); // stop | |||||
| return ENS_SPEECH_STOPPED; | return ENS_SPEECH_STOPPED; | ||||
| } | } | ||||
| event_list[0].unique_identifier = my_unique_identifier; | event_list[0].unique_identifier = my_unique_identifier; | ||||
| event_list[0].user_data = my_user_data; | event_list[0].user_data = my_user_data; | ||||
| if (SpeakNextClause(NULL, NULL, 1) == 0) { | |||||
| if (SpeakNextClause(NULL, 1) == 0) { | |||||
| finished = 0; | finished = 0; | ||||
| if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { | if ((my_mode & ENOUTPUT_MODE_SPEAK_AUDIO) == ENOUTPUT_MODE_SPEAK_AUDIO) { | ||||
| if (dispatch_audio(NULL, 0, NULL) < 0) | if (dispatch_audio(NULL, 0, NULL) < 0) | ||||
| } else if (synth_callback) | } else if (synth_callback) | ||||
| finished = 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) { | if (finished) { | ||||
| SpeakNextClause(NULL, 0, 2); // stop | |||||
| SpeakNextClause(0, 2); // stop | |||||
| return ENS_SPEECH_STOPPED; | return ENS_SPEECH_STOPPED; | ||||
| } | } | ||||
| return ENS_OK; | return ENS_OK; | ||||
| */ | */ | ||||
| option_multibyte = textmode & 7; | option_multibyte = textmode & 7; | ||||
| *textptr = TranslateClause(translator, NULL, *textptr, NULL, NULL); | |||||
| *textptr = TranslateClause(translator, *textptr, NULL, NULL); | |||||
| return GetTranslatedPhonemeString(phonememode); | return GetTranslatedPhonemeString(phonememode); | ||||
| } | } | ||||
| return 0; // finished the phoneme list | return 0; // finished the phoneme list | ||||
| } | } | ||||
| int SpeakNextClause(FILE *f_in, const void *text_in, int control) | |||||
| int SpeakNextClause(const void *text_in, int control) | |||||
| { | { | ||||
| // Speak text from file (f_in) or memory (text_in) | |||||
| // Speak text from memory (text_in) | |||||
| // control 0: start | // control 0: start | ||||
| // either f_in or text_in is set, the other must be NULL | |||||
| // text_in is set | |||||
| // The other calls have f_in and text_in = NULL | |||||
| // The other calls have text_in = NULL | |||||
| // control 1: speak next text | // control 1: speak next text | ||||
| // 2: stop | // 2: stop | ||||
| int clause_tone; | int clause_tone; | ||||
| char *voice_change; | char *voice_change; | ||||
| static FILE *f_text = NULL; | |||||
| static const void *p_text = NULL; | static const void *p_text = NULL; | ||||
| const char *phon_out; | const char *phon_out; | ||||
| if (control == 2) { | if (control == 2) { | ||||
| // stop speaking | // stop speaking | ||||
| p_text = NULL; | p_text = NULL; | ||||
| if (f_text != NULL) { | |||||
| fclose(f_text); | |||||
| f_text = NULL; | |||||
| } | |||||
| n_phoneme_list = 0; | n_phoneme_list = 0; | ||||
| WcmdqStop(); | WcmdqStop(); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| if ((f_in != NULL) || (text_in != NULL)) { | |||||
| f_text = f_in; | |||||
| if (text_in != NULL) { | |||||
| p_text = text_in; | p_text = text_in; | ||||
| } | } | ||||
| if ((f_text == NULL) && (p_text == NULL)) { | |||||
| if (p_text == NULL) { | |||||
| skipping_text = 0; | skipping_text = 0; | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| if ((f_text != NULL) && feof(f_text)) { | |||||
| fclose(f_text); | |||||
| f_text = NULL; | |||||
| return 0; | |||||
| } | |||||
| if (current_phoneme_table != voice->phoneme_tab_ix) | if (current_phoneme_table != voice->phoneme_tab_ix) | ||||
| SelectPhonemeTable(voice->phoneme_tab_ix); | SelectPhonemeTable(voice->phoneme_tab_ix); | ||||
| // read the next clause from the input text file, translate it, and generate | // read the next clause from the input text file, translate it, and generate | ||||
| // entries in the wavegen command queue | // entries in the wavegen command queue | ||||
| p_text = TranslateClause(translator, f_text, p_text, &clause_tone, &voice_change); | |||||
| p_text = TranslateClause(translator, p_text, &clause_tone, &voice_change); | |||||
| CalcPitches(translator, clause_tone); | CalcPitches(translator, clause_tone); | ||||
| CalcLengths(translator); | CalcLengths(translator); |
| void SynthesizeInit(void); | void SynthesizeInit(void); | ||||
| int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); | int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); | ||||
| void MakeWave2(PHONEME_LIST *p, int n_ph); | void MakeWave2(PHONEME_LIST *p, int n_ph); | ||||
| int SpeakNextClause(FILE *f_text, const void *text_in, int control); | |||||
| int SpeakNextClause(const void *text_in, int control); | |||||
| void SetSpeed(int control); | void SetSpeed(int control); | ||||
| void SetEmbedded(int control, int value); | void SetEmbedded(int control, int value); | ||||
| void SelectPhonemeTable(int number); | void SelectPhonemeTable(int number); |
| return 0; | return 0; | ||||
| } | } | ||||
| void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone_out, char **voice_change) | |||||
| void *TranslateClause(Translator *tr, const void *vp_input, int *tone_out, char **voice_change) | |||||
| { | { | ||||
| int ix; | int ix; | ||||
| int c; | int c; | ||||
| for (ix = 0; ix < N_TR_SOURCE; ix++) | for (ix = 0; ix < N_TR_SOURCE; ix++) | ||||
| charix[ix] = 0; | charix[ix] = 0; | ||||
| terminator = ReadClause(tr, f_text, source, charix, &charix_top, N_TR_SOURCE, &tone2, voice_change_name); | |||||
| terminator = ReadClause(tr, source, charix, &charix_top, N_TR_SOURCE, &tone2, voice_change_name); | |||||
| charix[charix_top+1] = 0; | charix[charix_top+1] = 0; | ||||
| charix[charix_top+2] = 0x7fff; | charix[charix_top+2] = 0x7fff; |
| void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int prev_stress); | void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int prev_stress); | ||||
| int TranslateRules(Translator *tr, char *p, char *phonemes, int size, char *end_phonemes, int end_flags, unsigned int *dict_flags); | int TranslateRules(Translator *tr, char *p, char *phonemes, int size, char *end_phonemes, int end_flags, unsigned int *dict_flags); | ||||
| int TranslateWord(Translator *tr, char *word1, WORD_TAB *wtab, char *word_out); | int TranslateWord(Translator *tr, char *word1, WORD_TAB *wtab, char *word_out); | ||||
| void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone, char **voice_change); | |||||
| int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change); | |||||
| void *TranslateClause(Translator *tr, const void *vp_input, int *tone, char **voice_change); | |||||
| int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change); | |||||
| void SetVoiceStack(espeak_VOICE *v, const char *variant_name); | void SetVoiceStack(espeak_VOICE *v, const char *variant_name); | ||||
| void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata); | void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata); |