diff --git a/src/libespeak-ng/dictionary.c b/src/libespeak-ng/dictionary.c index 6b549bb9..255ed4db 100644 --- a/src/libespeak-ng/dictionary.c +++ b/src/libespeak-ng/dictionary.c @@ -761,95 +761,6 @@ int IsVowel(Translator *tr, int letter) return IsLetter(tr, letter, LETTERGP_VOWEL2); } -static int Unpronouncable2(Translator *tr, char *word) -{ - int c; - int end_flags; - char ph_buf[N_WORD_PHONEMES]; - - ph_buf[0] = 0; - c = word[-1]; - word[-1] = ' '; // ensure there is a space before the "word" - end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL); - word[-1] = c; - if ((end_flags == 0) || (end_flags & SUFX_UNPRON)) - return 1; - return 0; -} - -int Unpronouncable(Translator *tr, char *word, int posn) -{ - /* Determines whether a word in 'unpronouncable', i.e. whether it should - be spoken as individual letters. - - This function may be language specific. This is a generic version. - */ - - int c; - int c1 = 0; - int vowel_posn = 9; - int index; - int count; - ALPHABET *alphabet; - - utf8_in(&c, word); - if ((tr->letter_bits_offset > 0) && (c < 0x241)) { - // Latin characters for a language with a non-latin alphabet - return 0; // so we can re-translate the word as English - } - - if (((alphabet = AlphabetFromChar(c)) != NULL) && (alphabet->offset != tr->letter_bits_offset)) { - // Character is not in our alphabet - return 0; - } - - if (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 1) - return 0; - - if (((c = *word) == ' ') || (c == 0) || (c == '\'')) - return 0; - - index = 0; - count = 0; - for (;;) { - index += utf8_in(&c, &word[index]); - if ((c == 0) || (c == ' ')) - break; - - if ((c == '\'') && ((count > 1) || (posn > 0))) - break; // "tv'" but not "l'" - - if (count == 0) - c1 = c; - - if ((c == '\'') && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 3)) { - // don't count apostrophe - } else - count++; - - if (IsVowel(tr, c)) { - vowel_posn = count; // position of the first vowel - break; - } - - if ((c != '\'') && !iswalpha(c)) - return 0; - } - - if ((vowel_posn > 2) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) { - // Lookup unpronounable rules in *_rules - return Unpronouncable2(tr, word); - } - - if (c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE]) - vowel_posn--; // disregard this as the initial letter when counting - - if (vowel_posn > (tr->langopts.max_initial_consonants+1)) - return 1; // no vowel, or no vowel in first few letters - - return 0; -} - int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int *vowel_count, int *stressed_syllable, int control) { // control = 1, set stress to 1 for forced unstressed vowels diff --git a/src/libespeak-ng/dictionary.h b/src/libespeak-ng/dictionary.h index 75b8b286..e09492e1 100644 --- a/src/libespeak-ng/dictionary.h +++ b/src/libespeak-ng/dictionary.h @@ -41,7 +41,6 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int const char *GetTranslatedPhonemeString(int phoneme_mode); int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *vowel_stress, int *vowel_count, int *stressed_syllable, int control); int IsVowel(Translator *tr, int letter); -int Unpronouncable(Translator *tr, char *word, int posn); void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int tonic, int control); void AppendPhonemes(Translator *tr, char *string, int size, const char *ph); int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, unsigned int *dict_flags); diff --git a/src/libespeak-ng/translateword.c b/src/libespeak-ng/translateword.c index d9c1535d..9a820766 100644 --- a/src/libespeak-ng/translateword.c +++ b/src/libespeak-ng/translateword.c @@ -51,6 +51,8 @@ static int CheckDottedAbbrev(char *word1); static int NonAsciiNumber(int letter); static char *SpeakIndividualLetters(Translator *tr, char *word, char *phonemes, int spell_word, ALPHABET *current_alphabet, char word_phonemes[]); static int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALPHABET *current_alphabet); +static int Unpronouncable(Translator *tr, char *word, int posn); +static int Unpronouncable2(Translator *tr, char *word); int TranslateWord3(Translator *tr, char *word_start, WORD_TAB *wtab, char *word_out, bool *any_stressed_words, ALPHABET *current_alphabet, char word_phonemes[], size_t size_word_phonemes) { @@ -1079,3 +1081,92 @@ static int NonAsciiNumber(int letter) } return -1; } + +static int Unpronouncable(Translator *tr, char *word, int posn) +{ + /* Determines whether a word in 'unpronouncable', i.e. whether it should + be spoken as individual letters. + + This function may be language specific. This is a generic version. + */ + + int c; + int c1 = 0; + int vowel_posn = 9; + int index; + int count; + ALPHABET *alphabet; + + utf8_in(&c, word); + if ((tr->letter_bits_offset > 0) && (c < 0x241)) { + // Latin characters for a language with a non-latin alphabet + return 0; // so we can re-translate the word as English + } + + if (((alphabet = AlphabetFromChar(c)) != NULL) && (alphabet->offset != tr->letter_bits_offset)) { + // Character is not in our alphabet + return 0; + } + + if (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 1) + return 0; + + if (((c = *word) == ' ') || (c == 0) || (c == '\'')) + return 0; + + index = 0; + count = 0; + for (;;) { + index += utf8_in(&c, &word[index]); + if ((c == 0) || (c == ' ')) + break; + + if ((c == '\'') && ((count > 1) || (posn > 0))) + break; // "tv'" but not "l'" + + if (count == 0) + c1 = c; + + if ((c == '\'') && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 3)) { + // don't count apostrophe + } else + count++; + + if (IsVowel(tr, c)) { + vowel_posn = count; // position of the first vowel + break; + } + + if ((c != '\'') && !iswalpha(c)) + return 0; + } + + if ((vowel_posn > 2) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) { + // Lookup unpronounable rules in *_rules + return Unpronouncable2(tr, word); + } + + if (c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE]) + vowel_posn--; // disregard this as the initial letter when counting + + if (vowel_posn > (tr->langopts.max_initial_consonants+1)) + return 1; // no vowel, or no vowel in first few letters + + return 0; +} + +static int Unpronouncable2(Translator *tr, char *word) +{ + int c; + int end_flags; + char ph_buf[N_WORD_PHONEMES]; + + ph_buf[0] = 0; + c = word[-1]; + word[-1] = ' '; // ensure there is a space before the "word" + end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL); + word[-1] = c; + if ((end_flags == 0) || (end_flags & SUFX_UNPRON)) + return 1; + return 0; +} \ No newline at end of file