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); |