| @@ -298,6 +298,25 @@ int Read4Bytes(FILE *f) | |||
| return acc; | |||
| } | |||
| unsigned int StringToWord(const char *string) | |||
| { | |||
| // Pack 4 characters into a word | |||
| int ix; | |||
| unsigned char c; | |||
| unsigned int word; | |||
| if (string == NULL) | |||
| return 0; | |||
| word = 0; | |||
| for (ix = 0; ix < 4; ix++) { | |||
| if (string[ix] == 0) break; | |||
| c = string[ix]; | |||
| word |= (c << (ix*8)); | |||
| } | |||
| return word; | |||
| } | |||
| int towlower2(unsigned int c, Translator *translator) | |||
| { | |||
| // check for non-standard upper to lower case conversions | |||
| @@ -34,6 +34,7 @@ int IsSpace(unsigned int c); | |||
| int isspace2(unsigned int c); | |||
| int is_str_totally_null(const char* str, int size); // Tests if all bytes of str up to size are null | |||
| int Read4Bytes(FILE *f); | |||
| unsigned int StringToWord(const char *string); | |||
| int towlower2(unsigned int c, Translator *translator); // Supports Turkish I | |||
| ESPEAK_NG_API int utf8_in(int *c, const char *buf); | |||
| @@ -35,7 +35,7 @@ | |||
| #include <espeak-ng/speak_lib.h> | |||
| #include <espeak-ng/encoding.h> | |||
| #include "common.h" // for GetFileLength, strncpy0, ... | |||
| #include "common.h" // for GetFileLength, strncpy0, ...c | |||
| #include "error.h" // for create_file_error_context | |||
| #include "mnemonics.h" // for LookupMnemName, MNEM_TAB | |||
| #include "phoneme.h" // for PHONEME_TAB, PHONEME_TAB_LIST | |||
| @@ -502,25 +502,6 @@ static void error_from_status(espeak_ng_STATUS status, const char *context) | |||
| error("%s.", message); | |||
| } | |||
| static unsigned int StringToWord(const char *string) | |||
| { | |||
| // Pack 4 characters into a word | |||
| int ix; | |||
| unsigned char c; | |||
| unsigned int word; | |||
| if (string == NULL) | |||
| return 0; | |||
| word = 0; | |||
| for (ix = 0; ix < 4; ix++) { | |||
| if (string[ix] == 0) break; | |||
| c = string[ix]; | |||
| word |= (c << (ix*8)); | |||
| } | |||
| return word; | |||
| } | |||
| static const MNEM_TAB reserved_phonemes[] = { | |||
| { "_\001", phonCONTROL }, // NOT USED | |||
| { "%", phonSTRESS_U }, | |||
| @@ -31,6 +31,7 @@ | |||
| #include "mbrola.h" | |||
| #include "error.h" // for create_file_error_context | |||
| #include "common.h" // for StringToWord | |||
| #include "mbrola.h" // for MBROLA_TAB | |||
| #include "phoneme.h" // for N_PHONEME_TAB | |||
| #include "speech.h" // for path_home | |||
| @@ -44,25 +45,6 @@ static const char *basename(const char *filename) | |||
| return current == filename ? current : current + 1; | |||
| } | |||
| static unsigned int StringToWord(const char *string) | |||
| { | |||
| // Pack 4 characters into a word | |||
| int ix; | |||
| unsigned char c; | |||
| unsigned int word; | |||
| if (string == NULL) | |||
| return 0; | |||
| word = 0; | |||
| for (ix = 0; ix < 4; ix++) { | |||
| if (string[ix] == 0) break; | |||
| c = string[ix]; | |||
| word |= (c << (ix*8)); | |||
| } | |||
| return word; | |||
| } | |||
| #pragma GCC visibility push(default) | |||
| espeak_ng_STATUS espeak_ng_CompileMbrolaVoice(const char *filepath, FILE *log, espeak_ng_ERROR_CONTEXT *context) | |||
| { | |||
| @@ -1473,19 +1473,13 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ | |||
| int ix; | |||
| int match_type; // left, right, or consume | |||
| int failed; | |||
| int unpron_ignore; | |||
| int consumed; // number of letters consumed from input | |||
| int syllable_count; | |||
| int vowel; | |||
| int letter_group; | |||
| int distance_right; | |||
| int distance_left; | |||
| int lg_pts; | |||
| int n_bytes; | |||
| int add_points; | |||
| int command; | |||
| bool check_atstart; | |||
| unsigned int *flags; | |||
| MatchRecord match; | |||
| @@ -1516,13 +1510,15 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ | |||
| // search through dictionary rules | |||
| while (rule[0] != RULE_GROUP_END) { | |||
| unpron_ignore = word_flags & FLAG_UNPRON_TEST; | |||
| bool check_atstart = false; | |||
| int consumed = 0; // number of letters consumed from input | |||
| int distance_left = -2; | |||
| int distance_right = -6; // used to reduce points for matches further away the current letter | |||
| int failed = 0; | |||
| int unpron_ignore = word_flags & FLAG_UNPRON_TEST; | |||
| match_type = 0; | |||
| consumed = 0; | |||
| letter_w = 0; | |||
| distance_right = -6; // used to reduce points for matches further away the current letter | |||
| distance_left = -2; | |||
| check_atstart = false; | |||
| match.points = 1; | |||
| match.end_type = 0; | |||
| @@ -1534,9 +1530,9 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ | |||
| // work through next rule until end, or until no-match proved | |||
| rule_start = rule; | |||
| failed = 0; | |||
| while (!failed) { | |||
| rb = *rule++; | |||
| add_points = 0; | |||
| if (rb <= RULE_LINENUM) { | |||
| switch (rb) | |||
| @@ -1603,8 +1599,6 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ | |||
| continue; | |||
| } | |||
| add_points = 0; | |||
| switch (match_type) | |||
| { | |||
| case 0: | |||
| @@ -2079,12 +2073,10 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c | |||
| unsigned char c, c2; | |||
| unsigned int c12; | |||
| int wc = 0; | |||
| int wc_bytes; | |||
| char *p2; // copy of p for use in double letter chain match | |||
| int found; | |||
| int g; // group chain number | |||
| int g1; // first group for this letter | |||
| int n; | |||
| int letter; | |||
| int any_alpha = 0; | |||
| int ix; | |||
| @@ -2133,11 +2125,11 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c | |||
| end_phonemes[0] = 0; | |||
| while (((c = *p) != ' ') && (c != 0)) { | |||
| wc_bytes = utf8_in(&wc, p); | |||
| int wc_bytes = utf8_in(&wc, p); | |||
| if (IsAlpha(wc)) | |||
| any_alpha++; | |||
| n = tr->groups2_count[c]; | |||
| int n = tr->groups2_count[c]; | |||
| if (IsDigit(wc) && ((tr->langopts.tone_numbers == 0) || !any_alpha)) { | |||
| // lookup the number in *_list not *_rules | |||
| char string[8]; | |||
| @@ -2331,8 +2323,6 @@ int TransposeAlphabet(Translator *tr, char *text) | |||
| // return: number of bytes, bit 6: 1=used compression | |||
| int c; | |||
| int c2; | |||
| int ix; | |||
| int offset; | |||
| int min; | |||
| int max; | |||
| @@ -2340,10 +2330,7 @@ int TransposeAlphabet(Translator *tr, char *text) | |||
| char *p = text; | |||
| char *p2; | |||
| bool all_alpha = true; | |||
| int bits; | |||
| int acc; | |||
| int pairs_start; | |||
| const short *pairs_list; | |||
| int bufix; | |||
| char buf[N_WORD_BYTES+1]; | |||
| @@ -2380,14 +2367,16 @@ int TransposeAlphabet(Translator *tr, char *text) | |||
| if (all_alpha) { | |||
| // compress to 6 bits per character | |||
| acc = 0; | |||
| bits = 0; | |||
| int ix; | |||
| int acc = 0; | |||
| int bits = 0; | |||
| p = buf; | |||
| p2 = buf; | |||
| while ((c = *p++) != 0) { | |||
| const short *pairs_list; | |||
| if ((pairs_list = tr->frequent_pairs) != NULL) { | |||
| c2 = c + (*p << 8); | |||
| int c2 = c + (*p << 8); | |||
| for (ix = 0; c2 >= pairs_list[ix]; ix++) { | |||
| if (c2 == pairs_list[ix]) { | |||
| // found an encoding for a 2-character pair | |||
| @@ -2849,9 +2838,7 @@ int Lookup(Translator *tr, const char *word, char *ph_out) | |||
| int flags0; | |||
| unsigned int flags[2]; | |||
| int say_as; | |||
| char *word1 = (char *)word; | |||
| char text[80]; | |||
| flags[0] = 0; | |||
| flags[1] = FLAG_LOOKUP_SYMBOL; | |||
| @@ -2859,11 +2846,13 @@ int Lookup(Translator *tr, const char *word, char *ph_out) | |||
| flags0 = flags[0]; | |||
| if (flags[0] & FLAG_TEXTMODE) { | |||
| say_as = option_sayas; | |||
| int say_as = option_sayas; | |||
| option_sayas = 0; // don't speak replacement word as letter names | |||
| // NOTE: TranslateRoman checks text[-2] and IsLetterGroup looks | |||
| // for a heading \0, so pad the start of text to prevent | |||
| // it reading data on the stack. | |||
| char text[80]; | |||
| text[0] = 0; | |||
| text[1] = ' '; | |||
| text[2] = ' '; | |||
| @@ -2902,8 +2891,6 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) | |||
| char *word_end; | |||
| int len_ending; | |||
| int end_flags; | |||
| const char *p; | |||
| int len; | |||
| char ending[50] = {0}; | |||
| // these lists are language specific, but are only relevant if the 'e' suffix flag is used | |||
| @@ -2972,16 +2959,18 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) | |||
| if (IsLetter(tr, word_end[-1], LETTERGP_VOWEL2) && IsLetter(tr, word_end[0], 1)) { | |||
| // vowel(incl.'y') + hard.consonant | |||
| const char *p; | |||
| for (i = 0; (p = add_e_exceptions[i]) != NULL; i++) { | |||
| len = strlen(p); | |||
| int len = strlen(p); | |||
| if (memcmp(p, &word_end[1-len], len) == 0) | |||
| break; | |||
| } | |||
| if (p == NULL) | |||
| end_flags |= FLAG_SUFX_E_ADDED; // no exception found | |||
| } else { | |||
| const char *p; | |||
| for (i = 0; (p = add_e_additions[i]) != NULL; i++) { | |||
| len = strlen(p); | |||
| int len = strlen(p); | |||
| if (memcmp(p, &word_end[1-len], len) == 0) { | |||
| end_flags |= FLAG_SUFX_E_ADDED; | |||
| break; | |||
| @@ -1000,9 +1000,7 @@ static void SetSynth_Klatt(int length, frame_t *fr1, frame_t *fr2, voice_t *wvoi | |||
| if ((cmd == WCMD_WAVE) || (cmd == WCMD_PAUSE)) | |||
| break; // next is not from spectrum, so continue until end of wave cycle | |||
| } | |||
| } | |||
| if (control & 1) { | |||
| for (ix = 1; ix < 6; ix++) { | |||
| if (prev_fr.ffreq[ix] != fr1->ffreq[ix]) { | |||
| // Discontinuity in formants. | |||
| @@ -98,8 +98,8 @@ static espeak_ng_STATUS LoadSoundFile(const char *fname, int index, espeak_ng_ER | |||
| strcpy(fname_temp, tmpnam(NULL)); | |||
| #endif | |||
| sprintf(command, "sox \"%s\" -r %d -c1 -b 16 -t wav %s\n", fname, samplerate, fname_temp); | |||
| if (system(command) == 0) | |||
| // sprintf(command, "sox \"%s\" -r %d -c1 -b 16 -t wav %s\n", fname, samplerate, fname_temp); | |||
| // if (system(command) == 0) | |||
| fname = fname_temp; | |||
| } | |||
| } | |||
| @@ -63,6 +63,8 @@ | |||
| #include "voice.h" // for FreeVoiceList, VoiceReset, current_... | |||
| #include "wavegen.h" // for WavegenFill, WavegenInit, WcmdqUsed | |||
| static espeak_ng_STATUS StatusCreateTerminatedMsg(t_espeak_command *c1, unsigned int *unique_identifier, void *user_data); | |||
| unsigned char *outbuf = NULL; | |||
| int outbuf_size = 0; | |||
| unsigned char *out_start; | |||
| @@ -686,22 +688,7 @@ espeak_ng_Synthesize(const void *text, size_t size, | |||
| *unique_identifier = c1->u.my_text.unique_identifier; | |||
| } | |||
| // Create the "terminated msg" command (same uid) | |||
| t_espeak_command *c2 = create_espeak_terminated_msg(*unique_identifier, user_data); | |||
| // Try to add these 2 commands (single transaction) | |||
| if (c1 && c2) { | |||
| espeak_ng_STATUS status = fifo_add_commands(c1, c2); | |||
| if (status != ENS_OK) { | |||
| delete_espeak_command(c1); | |||
| delete_espeak_command(c2); | |||
| } | |||
| return status; | |||
| } | |||
| delete_espeak_command(c1); | |||
| delete_espeak_command(c2); | |||
| return ENOMEM; | |||
| return StatusCreateTerminatedMsg(c1, unique_identifier, user_data); | |||
| #else | |||
| return sync_espeak_Synth(0, text, position, position_type, end_position, flags, user_data); | |||
| #endif | |||
| @@ -736,22 +723,7 @@ espeak_ng_SynthesizeMark(const void *text, | |||
| *unique_identifier = c1->u.my_mark.unique_identifier; | |||
| } | |||
| // Create the "terminated msg" command (same uid) | |||
| t_espeak_command *c2 = create_espeak_terminated_msg(*unique_identifier, user_data); | |||
| // Try to add these 2 commands (single transaction) | |||
| if (c1 && c2) { | |||
| espeak_ng_STATUS status = fifo_add_commands(c1, c2); | |||
| if (status != ENS_OK) { | |||
| delete_espeak_command(c1); | |||
| delete_espeak_command(c2); | |||
| } | |||
| return status; | |||
| } | |||
| delete_espeak_command(c1); | |||
| delete_espeak_command(c2); | |||
| return ENOMEM; | |||
| return StatusCreateTerminatedMsg(c1, unique_identifier, user_data); | |||
| #else | |||
| return sync_espeak_Synth_Mark(0, text, index_mark, end_position, flags, user_data); | |||
| #endif | |||
| @@ -964,4 +936,25 @@ ESPEAK_API const char *espeak_Info(const char **ptr) | |||
| return version_string; | |||
| } | |||
| #pragma GCC visibility pop | |||
| static espeak_ng_STATUS StatusCreateTerminatedMsg(t_espeak_command *c1, unsigned int *unique_identifier, void *user_data) { | |||
| // Create the "terminated msg" command (same uid) | |||
| t_espeak_command *c2 = create_espeak_terminated_msg(*unique_identifier, user_data); | |||
| // Try to add these 2 commands (single transaction) | |||
| if (c1 && c2) { | |||
| espeak_ng_STATUS status = fifo_add_commands(c1, c2); | |||
| if (status != ENS_OK) { | |||
| delete_espeak_command(c1); | |||
| delete_espeak_command(c2); | |||
| } | |||
| return status; | |||
| } | |||
| delete_espeak_command(c1); | |||
| delete_espeak_command(c2); | |||
| return ENOMEM; | |||
| } | |||
| @@ -102,7 +102,6 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size, esp | |||
| espeak_ng_STATUS LoadPhData(int *srate, espeak_ng_ERROR_CONTEXT *context) | |||
| { | |||
| int ix; | |||
| int n_phonemes; | |||
| int version; | |||
| int length = 0; | |||
| int rate; | |||
| @@ -137,7 +136,7 @@ espeak_ng_STATUS LoadPhData(int *srate, espeak_ng_ERROR_CONTEXT *context) | |||
| p += 4; | |||
| for (ix = 0; ix < n_phoneme_tables; ix++) { | |||
| n_phonemes = p[0]; | |||
| int n_phonemes = p[0]; | |||
| phoneme_tab_list[ix].n_phonemes = p[0]; | |||
| phoneme_tab_list[ix].includes = p[1]; | |||
| p += 4; | |||
| @@ -183,14 +182,13 @@ int PhonemeCode(unsigned int mnem) | |||
| int LookupPhonemeString(const char *string) | |||
| { | |||
| int ix; | |||
| unsigned char c; | |||
| unsigned int mnem; | |||
| // Pack up to 4 characters into a word | |||
| mnem = 0; | |||
| for (ix = 0; ix < 4; ix++) { | |||
| if (string[ix] == 0) break; | |||
| c = string[ix]; | |||
| unsigned char c = string[ix]; | |||
| mnem |= (c << (ix*8)); | |||
| } | |||
| @@ -205,8 +203,6 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, | |||
| int seq_break; | |||
| frameref_t *frames; | |||
| int length1; | |||
| int length_std; | |||
| int length_factor; | |||
| SPECT_SEQ *seq, *seq2; | |||
| SPECT_SEQK *seqk, *seqk2; | |||
| frame_t *frame; | |||
| @@ -279,11 +275,12 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, | |||
| } | |||
| if (length1 > 0) { | |||
| int length_factor; | |||
| if (which == 2) { | |||
| // adjust the length of the main part to match the standard length specified for the vowel | |||
| // less the front part of the vowel and any added suffix | |||
| length_std = fmt_params->std_length + seq_len_adjust - 45; | |||
| int length_std = fmt_params->std_length + seq_len_adjust - 45; | |||
| if (length_std < 10) | |||
| length_std = 10; | |||
| if (plist->synthflags & SFLAG_LENGTHEN) | |||
| @@ -335,7 +332,6 @@ static void SetUpPhonemeTable(int number) | |||
| { | |||
| int ix; | |||
| int includes; | |||
| int ph_code; | |||
| PHONEME_TAB *phtab; | |||
| if ((includes = phoneme_tab_list[number].includes) > 0) { | |||
| @@ -346,7 +342,7 @@ static void SetUpPhonemeTable(int number) | |||
| // now add the phonemes from this table | |||
| phtab = phoneme_tab_list[number].phoneme_tab_ptr; | |||
| for (ix = 0; ix < phoneme_tab_list[number].n_phonemes; ix++) { | |||
| ph_code = phtab[ix].code; | |||
| int ph_code = phtab[ix].code; | |||
| phoneme_tab[ph_code] = &phtab[ix]; | |||
| if (ph_code > n_phoneme_tab) { | |||
| memset(&phoneme_tab[n_phoneme_tab+1], 0, (ph_code - (n_phoneme_tab+1)) * sizeof(*phoneme_tab)); | |||
| @@ -458,14 +454,9 @@ static int CountVowelPosition(PHONEME_LIST *plist) | |||
| static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, unsigned short *p_prog, WORD_PH_DATA *worddata) | |||
| { | |||
| int which; | |||
| int ix; | |||
| unsigned int data; | |||
| int instn; | |||
| int instn2; | |||
| bool check_endtype = false; | |||
| PHONEME_TAB *ph; | |||
| PHONEME_LIST *plist_this; | |||
| // instruction: 2xxx, 3xxx | |||
| @@ -480,8 +471,9 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
| instn2 = instn >> 8; | |||
| if (instn2 < 14) { | |||
| PHONEME_LIST *plist_this; | |||
| plist_this = plist; | |||
| which = (instn2) % 7; | |||
| int which = (instn2) % 7; | |||
| if (which == 6) { | |||
| // the 'which' code is in the next instruction | |||
| @@ -505,6 +497,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
| return false; | |||
| } | |||
| bool check_endtype = false; | |||
| switch (which) | |||
| { | |||
| case 0: // prevPh | |||
| @@ -540,7 +533,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
| check_endtype = true; | |||
| break; | |||
| case 9: // next3PhW | |||
| for (ix = 1; ix <= 3; ix++) { | |||
| for (int ix = 1; ix <= 3; ix++) { | |||
| if (plist[ix].sourceix) | |||
| return false; | |||
| } | |||
| @@ -565,6 +558,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
| // "change phonemes" pass | |||
| plist->ph = phoneme_tab[plist->phcode]; | |||
| } | |||
| PHONEME_TAB *ph; | |||
| ph = plist->ph; | |||
| if (instn2 < 7) { | |||
| @@ -653,9 +647,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
| static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, unsigned short **p_prog, int instn_type) | |||
| { | |||
| unsigned short *prog; | |||
| int voweltype; | |||
| signed char x; | |||
| if (instn_type == 2) { | |||
| phdata->pd_control |= pd_FORNEXTPH; | |||
| @@ -665,6 +658,9 @@ static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, unsigne | |||
| voweltype -= phonVOWELTYPES; | |||
| if ((voweltype >= 0) && (voweltype < 6)) { | |||
| unsigned short *prog; | |||
| signed char x; | |||
| prog = *p_prog + voweltype*2; | |||
| phdata->sound_addr[instn_type] = (((prog[1] & 0xf) << 16) + prog[2]) * 4; | |||
| x = (prog[1] >> 4) & 0xff; | |||
| @@ -728,8 +724,6 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ | |||
| PHONEME_TAB *ph; | |||
| unsigned short *prog; | |||
| unsigned short instn; | |||
| int instn2; | |||
| int or_flag; | |||
| bool truth; | |||
| bool truth2; | |||
| @@ -759,6 +753,9 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ | |||
| end_flag = 0; | |||
| for (prog = &phoneme_index[ph->program]; end_flag != 1; prog++) { | |||
| unsigned short instn; | |||
| int instn2; | |||
| instn = *prog; | |||
| instn2 = (instn >> 8) & 0xf; | |||
| @@ -193,7 +193,6 @@ static void DoPause(int length, int control) | |||
| // control = 1, less shortening at fast speeds | |||
| unsigned int len; | |||
| int srate2; | |||
| if (length == 0) | |||
| len = 0; | |||
| @@ -203,7 +202,7 @@ static void DoPause(int length, int control) | |||
| if (len < 90000) | |||
| len = (len * samplerate) / 1000; // convert from mS to number of samples | |||
| else { | |||
| srate2 = samplerate / 25; // avoid overflow | |||
| int srate2 = samplerate / 25; // avoid overflow | |||
| len = (len * srate2) / 40; | |||
| } | |||
| } | |||
| @@ -402,7 +401,6 @@ static void set_frame_rms(frame_t *fr, int new_rms) | |||
| // RMS just adjust the formant amplitudes by the appropriate ratio | |||
| int x; | |||
| int h; | |||
| int ix; | |||
| static const short sqrt_tab[200] = { | |||
| @@ -434,6 +432,7 @@ static void set_frame_rms(frame_t *fr, int new_rms) | |||
| x = sqrt_tab[x]; // sqrt(new_rms/fr->rms)*0x200; | |||
| for (ix = 0; ix < 8; ix++) { | |||
| int h; | |||
| h = fr->fheight[ix] * x; | |||
| fr->fheight[ix] = h/0x200; | |||
| } | |||
| @@ -442,13 +441,11 @@ static void set_frame_rms(frame_t *fr, int new_rms) | |||
| static void formants_reduce_hf(frame_t *fr, int level) | |||
| { | |||
| // change height of peaks 2 to 8, percentage | |||
| int ix; | |||
| int x; | |||
| if (voice->klattv[0]) | |||
| return; | |||
| for (ix = 2; ix < 8; ix++) { | |||
| for (int ix = 2; ix < 8; ix++) { | |||
| int x; | |||
| x = fr->fheight[ix] * level; | |||
| fr->fheight[ix] = x/100; | |||
| } | |||
| @@ -541,10 +538,6 @@ static int VowelCloseness(frame_t *fr) | |||
| int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsigned int data2, PHONEME_TAB *other_ph, int which) | |||
| { | |||
| int ix; | |||
| int formant; | |||
| int next_rms; | |||
| int len; | |||
| int rms; | |||
| int f1; | |||
| @@ -593,7 +586,7 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig | |||
| seq[0].frflags |= FRFLAG_LEN_MOD2; // reduce length modification | |||
| fr->frflags |= FRFLAG_LEN_MOD2; | |||
| next_rms = seq[1].frame->rms; | |||
| int next_rms = seq[1].frame->rms; | |||
| if (voice->klattv[0]) | |||
| fr->klattp[KLATT_AV] = seq[1].frame->klattp[KLATT_AV] - 4; | |||
| @@ -637,11 +630,11 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig | |||
| set_frame_rms(fr, rms); | |||
| if ((vcolour > 0) && (vcolour <= N_VCOLOUR)) { | |||
| for (ix = 0; ix < *n_frames; ix++) { | |||
| for (int ix = 0; ix < *n_frames; ix++) { | |||
| fr = CopyFrame(seq[ix].frame, 0); | |||
| seq[ix].frame = fr; | |||
| for (formant = 1; formant <= 5; formant++) { | |||
| for (int formant = 1; formant <= 5; formant++) { | |||
| int x; | |||
| x = fr->ffreq[formant] * vcolouring[vcolour-1][formant-1]; | |||
| fr->ffreq[formant] = x / 256; | |||
| @@ -854,12 +847,8 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L | |||
| int frameix; | |||
| frame_t *frame1; | |||
| frame_t *frame2; | |||
| frame_t *fr; | |||
| int ix; | |||
| intptr_t *q; | |||
| int len; | |||
| int frame_length; | |||
| int length_factor; | |||
| int length_mod; | |||
| int length_sum; | |||
| int length_min; | |||
| @@ -927,8 +916,9 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L | |||
| if (last_frame->frflags & FRFLAG_BREAK_LF) { | |||
| // but flag indicates keep HF peaks in last segment | |||
| frame_t *fr; | |||
| fr = CopyFrame(frame1, 1); | |||
| for (ix = 3; ix < 8; ix++) { | |||
| for (int ix = 3; ix < 8; ix++) { | |||
| if (ix < 7) | |||
| fr->ffreq[ix] = last_frame->ffreq[ix]; | |||
| fr->fheight[ix] = last_frame->fheight[ix]; | |||
| @@ -947,13 +937,13 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L | |||
| length_sum = 0; | |||
| for (frameix = 1; frameix < n_frames; frameix++) { | |||
| length_factor = length_mod; | |||
| int length_factor = length_mod; | |||
| if (frames[frameix-1].frflags & FRFLAG_LEN_MOD) // reduce effect of length mod | |||
| length_factor = (length_mod*(256-speed.lenmod_factor) + 256*speed.lenmod_factor)/256; | |||
| else if (frames[frameix-1].frflags & FRFLAG_LEN_MOD2) // reduce effect of length mod, used for the start of a vowel | |||
| length_factor = (length_mod*(256-speed.lenmod2_factor) + 256*speed.lenmod2_factor)/256; | |||
| frame_length = frames[frameix-1].length; | |||
| int frame_length = frames[frameix-1].length; | |||
| len = (frame_length * samplerate)/1000; | |||
| len = (len * length_factor)/256; | |||
| length_sum += len; | |||
| @@ -1078,10 +1068,11 @@ void DoEmbedded(int *embix, int sourceix) | |||
| { | |||
| // There were embedded commands in the text at this point | |||
| unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command | |||
| unsigned int value; | |||
| int command; | |||
| do { | |||
| unsigned int value; | |||
| int command; | |||
| word = embedded_list[*embix]; | |||
| value = word >> 8; | |||
| command = word & 0x7f; | |||
| @@ -1133,9 +1124,6 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
| static int ix; | |||
| static int embedded_ix; | |||
| static int word_count; | |||
| PHONEME_LIST *prev; | |||
| PHONEME_LIST *next; | |||
| PHONEME_LIST *next2; | |||
| PHONEME_LIST *p; | |||
| bool released; | |||
| int stress; | |||
| @@ -1147,7 +1135,6 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
| unsigned char *amp_env; | |||
| PHONEME_TAB *ph; | |||
| int use_ipa = 0; | |||
| bool done_phoneme_marker; | |||
| int vowelstart_prev; | |||
| char phoneme_name[16]; | |||
| static int sourceix = 0; | |||
| @@ -1202,6 +1189,10 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
| if (WcmdqFree() <= free_min) | |||
| return 1; // wait | |||
| PHONEME_LIST *prev; | |||
| PHONEME_LIST *next; | |||
| PHONEME_LIST *next2; | |||
| prev = &phoneme_list[ix-1]; | |||
| next = &phoneme_list[ix+1]; | |||
| next2 = &phoneme_list[ix+2]; | |||
| @@ -1229,7 +1220,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, bool resume) | |||
| if ((p->prepause > 0) && !(p->ph->phflags & phPREVOICE)) | |||
| DoPause(p->prepause, 1); | |||
| done_phoneme_marker = false; | |||
| bool done_phoneme_marker = false; | |||
| if (option_phoneme_events && (p->ph->code != phonEND_WORD)) { | |||
| if ((p->type == phVOWEL) && (prev->type == phLIQUID || prev->type == phNASAL)) { | |||
| // For vowels following a liquid or nasal, do the phoneme event after the vowel-start | |||
| @@ -1547,7 +1538,6 @@ int SpeakNextClause(int control) | |||
| int clause_tone; | |||
| char *voice_change; | |||
| const char *phon_out; | |||
| if (control == 2) { | |||
| // stop speaking | |||
| @@ -1573,6 +1563,7 @@ int SpeakNextClause(int control) | |||
| CalcLengths(translator); | |||
| if ((option_phonemes & 0xf) || (phoneme_callback != NULL)) { | |||
| const char *phon_out; | |||
| phon_out = GetTranslatedPhonemeString(option_phonemes); | |||
| if (option_phonemes & 0xf) | |||
| fprintf(f_trans, "%s\n", phon_out); | |||
| @@ -763,7 +763,7 @@ static const char *FindReplacementChars(Translator *tr, const char **pfrom, unsi | |||
| nmatched++; | |||
| } | |||
| if (*from == 0 && matched) { | |||
| if (matched) { | |||
| *ignore_next_n = nmatched; | |||
| return from + 1; | |||
| } | |||
| @@ -1065,7 +1065,7 @@ static int CheckDottedAbbrev(char *word1) | |||
| nbytes += 2; // delete the final dot (eg. u.s.a.'s) | |||
| ok = 2; | |||
| } | |||
| } else if ((count > 0) && (word[nbytes] == ' ')) | |||
| } else if ((count > 0)) | |||
| ok = 2; | |||
| } | |||
| @@ -52,6 +52,7 @@ | |||
| #include "translate.h" // for LANGUAGE_OPTIONS, DeleteTranslator | |||
| #include "wavegen.h" // for InitBreath | |||
| static int AddToVoicesList(const char *fname, int len_path_voices, int is_language_file); | |||
| static const MNEM_TAB genders[] = { | |||
| @@ -1175,9 +1176,6 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found) | |||
| static void GetVoices(const char *path, int len_path_voices, int is_language_file) | |||
| { | |||
| FILE *f_voice; | |||
| espeak_VOICE *voice_data; | |||
| int ftype; | |||
| char fname[sizeof(path_home)+100]; | |||
| #ifdef PLATFORM_WINDOWS | |||
| @@ -1198,22 +1196,8 @@ static void GetVoices(const char *path, int len_path_voices, int is_language_fil | |||
| if (FindFileData.cFileName[0] != '.') { | |||
| sprintf(fname, "%s%c%s", path, PATHSEP, FindFileData.cFileName); | |||
| ftype = GetFileLength(fname); | |||
| if (ftype == -EISDIR) { | |||
| // a sub-directory | |||
| GetVoices(fname, len_path_voices, is_language_file); | |||
| } else if (ftype > 0) { | |||
| // a regular file, add it to the voices list | |||
| if ((f_voice = fopen(fname, "r")) == NULL) | |||
| continue; | |||
| // pass voice file name within the voices directory | |||
| voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, is_language_file); | |||
| fclose(f_voice); | |||
| if (voice_data != NULL) | |||
| voices_list[n_voices_list++] = voice_data; | |||
| if (AddToVoicesList(fname, len_path_voices, is_language_file) != 0) { | |||
| continue; | |||
| } | |||
| } | |||
| } while (FindNextFileA(hFind, &FindFileData) != 0); | |||
| @@ -1234,25 +1218,11 @@ static void GetVoices(const char *path, int len_path_voices, int is_language_fil | |||
| if (ent->d_name[0] == '.') | |||
| continue; | |||
| sprintf(fname, "%s%c%s", path, PATHSEP, ent->d_name); | |||
| ftype = GetFileLength(fname); | |||
| if (ftype == -EISDIR) { | |||
| // a sub-directory | |||
| GetVoices(fname, len_path_voices, is_language_file); | |||
| } else if (ftype > 0) { | |||
| // a regular file, add it to the voices list | |||
| if ((f_voice = fopen(fname, "r")) == NULL) | |||
| sprintf(fname, "%s%c%s", path, PATHSEP, ent->d_name); | |||
| if (AddToVoicesList(fname, len_path_voices, is_language_file) != 0) { | |||
| continue; | |||
| } | |||
| // pass voice file name within the voices directory | |||
| voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, is_language_file); | |||
| fclose(f_voice); | |||
| if (voice_data != NULL) | |||
| voices_list[n_voices_list++] = voice_data; | |||
| } | |||
| } | |||
| closedir(dir); | |||
| #endif | |||
| @@ -1429,3 +1399,27 @@ ESPEAK_API espeak_VOICE *espeak_GetCurrentVoice(void) | |||
| } | |||
| #pragma GCC visibility pop | |||
| static int AddToVoicesList(const char *fname, int len_path_voices, int is_language_file) { | |||
| int ftype = GetFileLength(fname); | |||
| if (ftype == -EISDIR) { | |||
| // a sub-directory | |||
| GetVoices(fname, len_path_voices, is_language_file); | |||
| } else if (ftype > 0) { | |||
| // a regular file, add it to the voices list | |||
| FILE *f_voice; | |||
| if ((f_voice = fopen(fname, "r")) == NULL) | |||
| return 1; | |||
| // pass voice file name within the voices directory | |||
| espeak_VOICE *voice_data; | |||
| voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, is_language_file); | |||
| fclose(f_voice); | |||
| if (voice_data != NULL) | |||
| voices_list[n_voices_list++] = voice_data; | |||
| return 0; | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -449,7 +449,6 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control) | |||
| int hmax; | |||
| int hmax_samplerate; // highest harmonic allowed for the samplerate | |||
| int x; | |||
| int ix; | |||
| int h1; | |||
| // initialise as much of *out as we will need | |||
| @@ -516,6 +515,7 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control) | |||
| x = htab[h] >> 15; | |||
| htab[h] = (x * x) >> 8; | |||
| int ix; | |||
| if ((ix = (f >> 19)) < N_TONE_ADJUST) | |||
| htab[h] = (htab[h] * wvoice->tone_adjust[ix]) >> 13; // index tone_adjust with Hz/8 | |||
| } | |||
| @@ -666,12 +666,12 @@ static int ApplyBreath(void) | |||
| int value = 0; | |||
| int noise; | |||
| int ix; | |||
| int amp; | |||
| // use two random numbers, for alternate formants | |||
| noise = (rand() & 0x3fff) - 0x2000; | |||
| for (ix = 1; ix < N_PEAKS; ix++) { | |||
| int amp; | |||
| if ((amp = wvoice->breath[ix]) != 0) { | |||
| amp *= (peaks[ix].height >> 14); | |||
| value += (int)resonator(&rbreath[ix], noise) * amp; | |||
| @@ -910,7 +910,6 @@ static int Wavegen(int length, int modulation, bool resume, frame_t *fr1, frame_ | |||
| static int PlaySilence(int length, bool resume) | |||
| { | |||
| static int n_samples; | |||
| int value = 0; | |||
| nsamples = 0; | |||
| samplecount = 0; | |||
| @@ -922,6 +921,7 @@ static int PlaySilence(int length, bool resume) | |||
| if (resume == false) | |||
| n_samples = length; | |||
| int value = 0; | |||
| while (n_samples-- > 0) { | |||
| value = (echo_buf[echo_tail++] * echo_amp) >> 8; | |||
| @@ -1111,12 +1111,12 @@ static void SetAmplitude(int length, unsigned char *amp_env, int value) | |||
| void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range) | |||
| { | |||
| int x; | |||
| int base; | |||
| int range; | |||
| int pitch_value; | |||
| if (pitch1 > pitch2) { | |||
| int x; | |||
| x = pitch1; // swap values | |||
| pitch1 = pitch2; | |||
| pitch2 = x; | |||
| @@ -1171,7 +1171,6 @@ static void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t * | |||
| int length2; | |||
| int length4; | |||
| int qix; | |||
| int cmd; | |||
| static const int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256 | |||
| static const int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256 | |||
| @@ -1194,7 +1193,7 @@ static void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t * | |||
| if (qix >= N_WCMDQ) qix = 0; | |||
| if (qix == wcmdq_tail) break; | |||
| cmd = wcmdq[qix][0]; | |||
| int cmd = wcmdq[qix][0]; | |||
| if (cmd == WCMD_SPECT) { | |||
| end_wave = 0; // next wave generation is from another spectrum | |||
| break; | |||