mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-11 16:39:15 +00:00
Merge branch 'upstream' into development
Conflicts: dictsource/dict_phonemes phsource/compile_report phsource/ph_irish
This commit is contained in:
+15
-12
@@ -310,7 +310,7 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
|
||||
p++; // skip over the zero which terminates the list for this hash value
|
||||
}
|
||||
|
||||
if((tr->dict_min_size > 0) && (size < tr->dict_min_size))
|
||||
if((tr->dict_min_size > 0) && (size < (unsigned int)tr->dict_min_size))
|
||||
{
|
||||
fprintf(stderr, "Full dictionary is not installed for '%s'\n", name);
|
||||
}
|
||||
@@ -1040,7 +1040,7 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char *
|
||||
{
|
||||
if(vowel_stress[ix] == 4)
|
||||
{
|
||||
if(tr->langopts.stress_flags & 0x20000)
|
||||
if(tr->langopts.stress_flags & S_PRIORITY_STRESS)
|
||||
vowel_stress[ix] = 1;
|
||||
else
|
||||
vowel_stress[ix] = 3;
|
||||
@@ -1208,12 +1208,6 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
|
||||
max_stress = GetVowelStress(tr, phonetic, vowel_stress, vowel_count, stressed_syllable, 1);
|
||||
if((max_stress < 0) && dictionary_flags)
|
||||
{
|
||||
if((tr->langopts.stress_flags & 1) && (vowel_count == 2))
|
||||
{
|
||||
// lang=fr: don't stress monosyllables except at end-of-clause
|
||||
vowel_stress[1] = 0;
|
||||
dictionary_flags[0] |= FLAG_STRESS_END2;
|
||||
}
|
||||
max_stress = 0;
|
||||
}
|
||||
|
||||
@@ -2652,6 +2646,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
if((match1.points == 0) && ((option_sayas & 0x10) == 0))
|
||||
{
|
||||
n = utf8_in(&letter,p-1)-1;
|
||||
|
||||
if(tr->letter_bits_offset > 0)
|
||||
{
|
||||
// not a Latin alphabet, switch to the default Latin alphabet language
|
||||
@@ -2720,11 +2715,19 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
p += (wc_bytes-1);
|
||||
}
|
||||
|
||||
if(((alphabet = AlphabetFromChar(letter)) != NULL) && (alphabet->flags & AL_WORDS) && (alphabet->offset != tr->letter_bits_offset))
|
||||
if(((alphabet = AlphabetFromChar(letter)) != NULL) && (alphabet->offset != tr->letter_bits_offset))
|
||||
{
|
||||
// switch to the nominated language for this alphabet
|
||||
sprintf(phonemes,"%c%s",phonSWITCH, WordToString2(alphabet->language));
|
||||
return(0);
|
||||
if(tr->langopts.alt_alphabet == alphabet->offset)
|
||||
{
|
||||
sprintf(phonemes,"%c%s",phonSWITCH, tr->langopts.alt_alphabet_lang);
|
||||
return(0);
|
||||
}
|
||||
if(alphabet->flags & AL_WORDS)
|
||||
{
|
||||
// switch to the nominated language for this alphabet
|
||||
sprintf(phonemes,"%c%s",phonSWITCH, WordToString2(alphabet->language));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+39
-20
@@ -596,6 +596,8 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
ALPHABET *alphabet;
|
||||
int language;
|
||||
int phontab_1;
|
||||
int alphabet_name_switch;
|
||||
char *ph_alphabet_end;
|
||||
char capital[20];
|
||||
char ph_buf[80];
|
||||
char ph_buf2[80];
|
||||
@@ -631,6 +633,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
return(0);
|
||||
}
|
||||
|
||||
alphabet_name_switch = 0;
|
||||
alphabet = AlphabetFromChar(letter);
|
||||
if(alphabet != current_alphabet)
|
||||
{
|
||||
@@ -638,38 +641,49 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
current_alphabet = alphabet;
|
||||
if((alphabet != NULL) && !(alphabet->flags & AL_DONT_NAME) && (alphabet->offset != translator->letter_bits_offset))
|
||||
{
|
||||
phontab_1 = tr->phoneme_tab_ix;
|
||||
ph_buf2[0] = 0;
|
||||
if(Lookup(translator, alphabet->name, ph_alphabet) == 0) // the original language for the current voice
|
||||
if((alphabet->flags & AL_DONT_NAME) || (alphabet->offset == translator->langopts.alt_alphabet))
|
||||
{
|
||||
// Can't find the local name for this alphabet, use the English name
|
||||
ph_alphabet[2] = SetTranslator2("en"); // overwrites previous contents of translator2
|
||||
Lookup(translator2, alphabet->name, ph_buf2);
|
||||
// don't say the alphabet name
|
||||
}
|
||||
else
|
||||
if(translator != tr)
|
||||
{
|
||||
phontab_1 = tr->phoneme_tab_ix;
|
||||
strcpy(ph_buf2, ph_alphabet);
|
||||
ph_alphabet[2] = translator->phoneme_tab_ix;
|
||||
}
|
||||
ph_buf2[0] = 0;
|
||||
if(Lookup(translator, alphabet->name, ph_alphabet) == 0) // the original language for the current voice
|
||||
{
|
||||
// Can't find the local name for this alphabet, use the English name
|
||||
ph_alphabet[2] = SetTranslator2("en"); // overwrites previous contents of translator2
|
||||
Lookup(translator2, alphabet->name, ph_buf2);
|
||||
}
|
||||
else
|
||||
if(translator != tr)
|
||||
{
|
||||
phontab_1 = tr->phoneme_tab_ix;
|
||||
strcpy(ph_buf2, ph_alphabet);
|
||||
ph_alphabet[2] = translator->phoneme_tab_ix;
|
||||
}
|
||||
|
||||
if(ph_buf2[0] != 0)
|
||||
{
|
||||
// we used a different language for the alphabet name (now in ph_buf2)
|
||||
ph_alphabet[0] = phonPAUSE;
|
||||
ph_alphabet[1] = phonSWITCH;
|
||||
strcpy(&ph_alphabet[3], ph_buf2);
|
||||
len = strlen(ph_buf2) + 3;
|
||||
ph_alphabet[len] = phonSWITCH;
|
||||
ph_alphabet[len+1] = phontab_1;
|
||||
ph_alphabet[len+2] = 0;
|
||||
if(ph_buf2[0] != 0)
|
||||
{
|
||||
// we used a different language for the alphabet name (now in ph_buf2)
|
||||
ph_alphabet[0] = phonPAUSE;
|
||||
ph_alphabet[1] = phonSWITCH;
|
||||
strcpy(&ph_alphabet[3], ph_buf2);
|
||||
len = strlen(ph_buf2) + 3;
|
||||
ph_alphabet[len] = phonSWITCH;
|
||||
ph_alphabet[len+1] = phontab_1;
|
||||
ph_alphabet[len+2] = 0;
|
||||
|
||||
ph_alphabet_end = &ph_alphabet[len];
|
||||
alphabet_name_switch = ph_alphabet[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number
|
||||
|
||||
if(ph_buf[0] == 0)
|
||||
{
|
||||
if((alphabet != NULL) && (alphabet->language != 0) && !(alphabet->flags & AL_NOT_LETTERS))
|
||||
@@ -702,6 +716,11 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
|
||||
ph_buf[len+2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((ph_buf[2] == alphabet_name_switch) && (capital[0] == 0))
|
||||
{
|
||||
ph_alphabet_end[0]= 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(ph_buf[0] == 0)
|
||||
|
||||
+1
-1
@@ -428,7 +428,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
{
|
||||
// in a sequence of unstressed syllables, reduce alternate syllables to 'diminished'
|
||||
// stress. But not for the last phoneme of a stressed word
|
||||
if((tr->langopts.stress_flags & 0x2) || ((word_stress > 3) && ((plist3+1)->sourceix!=0)))
|
||||
if((tr->langopts.stress_flags & S_NO_DIM) || ((word_stress > 3) && ((plist3+1)->sourceix!=0)))
|
||||
{
|
||||
// An unstressed final vowel of a stressed word
|
||||
unstress_count=1; // try again for next syllable
|
||||
|
||||
+1
-1
@@ -892,7 +892,7 @@ if(stress <= 1)
|
||||
{
|
||||
// this is the last syllable in the clause, lengthen it - more for short vowels
|
||||
len = (p->ph->std_length * 2);
|
||||
if(tr->langopts.stress_flags & 0x40000)
|
||||
if(tr->langopts.stress_flags & S_EO_CLAUSE1)
|
||||
len=200; // don't lengthen short vowels more than long vowels at end-of-clause
|
||||
length_mod = length_mod * (256 + (280 - len)/3)/256;
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.46.43 07.Mar.13";
|
||||
const char *version_string = "1.46.44 08.Mar.13";
|
||||
const int version_phdata = 0x014640;
|
||||
|
||||
int option_device_number = -1;
|
||||
|
||||
+29
-25
@@ -478,7 +478,7 @@ Translator *SelectTranslator(const char *name)
|
||||
SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
|
||||
tr->letter_bits_offset = OFFSET_ETHIOPIC;
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2 | S_FINAL_DIM; // don't use secondary stress
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
tr->langopts.numbers = NUM_OMIT_1_HUNDRED;
|
||||
@@ -550,7 +550,7 @@ Translator *SelectTranslator(const char *name)
|
||||
// tr->langopts.intonation_group = 4;
|
||||
|
||||
// 'diminished' is an unstressed final syllable
|
||||
tr->langopts.stress_flags = 0x6 | 0x10;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
|
||||
tr->langopts.unstressed_wd1 = 0;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels
|
||||
@@ -651,7 +651,7 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY; // mark unstressed final syllables as diminished
|
||||
tr->langopts.unstressed_wd1 = 0;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels
|
||||
@@ -681,7 +681,7 @@ Translator *SelectTranslator(const char *name)
|
||||
// tr->langopts.word_gap = 1;
|
||||
tr->langopts.vowel_pause = 2;
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x6 | 0x10;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
|
||||
// tr->langopts.unstressed_wd1 = 3;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
|
||||
@@ -989,7 +989,7 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x10 | 0x20000;
|
||||
tr->langopts.stress_flags = 0x10 | S_PRIORITY_STRESS;
|
||||
tr->langopts.vowel_pause = 1;
|
||||
tr->langopts.unstressed_wd1 = 2;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
@@ -1023,8 +1023,9 @@ SetLengthMods(tr,3); // all equal
|
||||
case L('k','a'): // Georgian
|
||||
{
|
||||
// character codes offset by 0x1080
|
||||
static const char ka_vowels[] = {0x50,0x54,0x58,0x5d,0x63,0x75,0x77,0};
|
||||
static const char ka_consonants[] = {0x51,0x52,0x53,0x55,0x56,0x57,0x59,0x5a,0x5b,0x5c,0x5e,0x5f,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x76,0};
|
||||
static const char ka_vowels[] = {0x30,0x34,0x38,0x3d,0x43,0x55,0x57,0};
|
||||
static const char ka_consonants[] = {0x31,0x32,0x33,0x35,0x36,0x37,0x39,0x3a,0x3b,0x3c,0x3e,0x3f,
|
||||
0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x56,0};
|
||||
SetupTranslator(tr,stress_lengths_ta,stress_amps_ta);
|
||||
memset(tr->letter_bits,0,sizeof(tr->letter_bits));
|
||||
SetLetterBits(tr,LETTERGP_A,ka_vowels);
|
||||
@@ -1037,6 +1038,9 @@ SetLengthMods(tr,3); // all equal
|
||||
// tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
tr->langopts.max_initial_consonants = 7;
|
||||
tr->langopts.numbers = NUM_VIGESIMAL | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED |NUM_OMIT_1_THOUSAND | NUM_DFRACTION_5 | NUM_ROMAN;
|
||||
|
||||
tr->langopts.alt_alphabet = OFFSET_CYRILLIC;
|
||||
tr->langopts.alt_alphabet_lang = "ru";
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1111,7 +1115,7 @@ SetLengthMods(tr,3); // all equal
|
||||
{
|
||||
tr->charset_a0 = charsets[4]; // ISO-8859-4, includes a,e,i,o,u-macron
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x20;
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2;
|
||||
tr->langopts.unstressed_wd1 = 0;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
tr->langopts.param[LOPT_DIERESES] = 1;
|
||||
@@ -1124,7 +1128,7 @@ SetLengthMods(tr,3); // all equal
|
||||
{
|
||||
tr->charset_a0 = charsets[4]; // ISO-8859-4
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x20;
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2;
|
||||
tr->langopts.unstressed_wd1 = 0;
|
||||
tr->langopts.unstressed_wd2 = 2;
|
||||
tr->langopts.param[LOPT_DIERESES] = 1;
|
||||
@@ -1211,7 +1215,7 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
SetupTranslator(tr,stress_lengths_om,stress_amps_om);
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x16 + 0x80000;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | 0x80000;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1224,7 +1228,7 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
tr->charset_a0 = charsets[2]; // ISO-8859-2
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY; // mark unstressed final syllables as diminished
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x9;
|
||||
tr->langopts.max_initial_consonants = 7; // for example: wchrzczony :)
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_2;
|
||||
@@ -1243,7 +1247,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
|
||||
tr->langopts.stress_flags = 0x6 | 0x10 | 0x2000 | 0x20000;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_INITIAL_2 | S_PRIORITY_STRESS;
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_DFRACTION_2 | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_ROMAN;
|
||||
tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL | NUM2_NO_TEEN_ORDINALS;
|
||||
SetLetterVowel(tr,'y');
|
||||
@@ -1261,7 +1265,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetupTranslator(tr,stress_lengths_ro,stress_amps_ro);
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x100 + 0x6;
|
||||
tr->langopts.stress_flags = S_FINAL_STRESS_C + S_FINAL_DIM_ONLY;
|
||||
|
||||
tr->charset_a0 = charsets[2]; // ISO-8859-2
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_3 | NUM_AND_UNITS | NUM_ROMAN;
|
||||
@@ -1276,7 +1280,7 @@ SetLengthMods(tr,3); // all equal
|
||||
case L('r','w'): // Kiryarwanda
|
||||
{
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x16;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
tr->langopts.numbers = NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_DFRACTION_2 | NUM_AND_HUNDRED;
|
||||
@@ -1293,7 +1297,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->charset_a0 = charsets[2]; // ISO-8859-2
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = 0x16;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3;
|
||||
tr->langopts.max_initial_consonants = 5;
|
||||
tr->langopts.spelling_stress = 1;
|
||||
@@ -1322,7 +1326,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM | S_NO_AUTO_DIM | S_FINAL_NO_2;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
|
||||
tr->langopts.spelling_stress = 1;
|
||||
|
||||
tr->letter_bits_offset = OFFSET_SINHALA;
|
||||
@@ -1345,7 +1349,7 @@ SetLengthMods(tr,3); // all equal
|
||||
case L('s','l'): // Slovenian
|
||||
tr->charset_a0 = charsets[2]; // ISO-8859-2
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R; // Temporary
|
||||
tr->langopts.stress_flags = 0x20;
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2;
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x103;
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 0x76; // [v] don't count this character at start of word
|
||||
tr->letter_bits['r'] |= 0x80; // add 'r' to letter group 7, vowels for Unpronouncable test
|
||||
@@ -1362,7 +1366,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetupTranslator(tr,stress_lengths_sq,stress_amps_sq);
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x16 + 0x100;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2 | S_FINAL_STRESS_C;
|
||||
SetLetterVowel(tr,'y');
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_DFRACTION_4;
|
||||
tr->langopts.accents = 2; // "capital" after letter name
|
||||
@@ -1394,7 +1398,7 @@ SetLengthMods(tr,3); // all equal
|
||||
|
||||
tr->langopts.vowel_pause = 1;
|
||||
tr->langopts.stress_rule = STRESSPOSN_2R;
|
||||
tr->langopts.stress_flags = 0x6 | 0x10;
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY | S_FINAL_NO_2;
|
||||
|
||||
tr->langopts.numbers = NUM_AND_UNITS | NUM_HUNDRED_AND | NUM_SINGLE_AND | NUM_OMIT_1_HUNDRED;
|
||||
tr->langopts.break_numbers = 0x49249268; // for languages which have numbers for 100,000 and 1,000,000
|
||||
@@ -1411,7 +1415,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1L;
|
||||
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
|
||||
tr->langopts.stress_flags = S_FINAL_DIM_ONLY; // use 'diminished' for unstressed final syllable
|
||||
tr->langopts.spelling_stress = 1;
|
||||
tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000
|
||||
|
||||
@@ -1457,7 +1461,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetupTranslator(tr,stress_lengths_th,stress_amps_th);
|
||||
|
||||
tr->langopts.stress_rule = 0; // stress on final syllable of a "word"
|
||||
tr->langopts.stress_flags = 2; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.stress_flags = S_NO_DIM; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
// tr->langopts.tone_numbers = 1; // a number after letters indicates a tone number (eg. pinyin or jyutping)
|
||||
@@ -1476,7 +1480,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->charset_a0 = charsets[9]; // ISO-8859-9 - Latin5
|
||||
|
||||
tr->langopts.stress_rule = 7; // stress on the last syllable, before any explicitly unstressed syllable
|
||||
tr->langopts.stress_flags = 0x20; //no automatic secondary stress
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2; //no automatic secondary stress
|
||||
tr->langopts.param[LOPT_SUFFIX] = 1;
|
||||
|
||||
if(name2 == L('a','z'))
|
||||
@@ -1496,7 +1500,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetCyrillicLetters(tr);
|
||||
SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
|
||||
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
|
||||
tr->langopts.stress_flags = 0x20; //no automatic secondary stress
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2; //no automatic secondary stress
|
||||
tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_DFRACTION_4;
|
||||
}
|
||||
break;
|
||||
@@ -1561,7 +1565,7 @@ SetLengthMods(tr,3); // all equal
|
||||
SetupTranslator(tr,stress_lengths_zh,stress_amps_zh);
|
||||
|
||||
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable of a "word"
|
||||
tr->langopts.stress_flags = 2; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.stress_flags = S_NO_DIM; // don't automatically set diminished stress (may be set in the intonation module)
|
||||
tr->langopts.vowel_pause = 0;
|
||||
tr->langopts.tone_language = 1; // Tone language, use CalcPitches_Tone() rather than CalcPitches()
|
||||
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
|
||||
@@ -1618,7 +1622,7 @@ static void Translator_Russian(Translator *tr)
|
||||
tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 1;
|
||||
tr->langopts.param[LOPT_REDUCE] = 2;
|
||||
tr->langopts.stress_rule = 5;
|
||||
tr->langopts.stress_flags = 0x0020; // waas 0x1010
|
||||
tr->langopts.stress_flags = S_NO_AUTO_2;
|
||||
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_OMIT_1_HUNDRED;
|
||||
tr->langopts.numbers2 = 0x2 + NUM2_THOUSANDS_VAR1; // variant numbers before thousands
|
||||
|
||||
+61
-12
@@ -2074,17 +2074,29 @@ return(FLAG_SPELLWORD);
|
||||
|
||||
if(switch_phonemes >= 0)
|
||||
{
|
||||
// this word uses a different phoneme table
|
||||
if(ph_list2[n_ph_list2-1].phcode == phonSWITCH)
|
||||
{
|
||||
//previous phoneme is also a phonSWITCH, just change its phoneme table number
|
||||
n_ph_list2--;
|
||||
}
|
||||
if((p[0] == phonPAUSE) && (p[1] == phonSWITCH))
|
||||
{
|
||||
// the new word starts with a phoneme table switch, so there's no need to switch before it.
|
||||
if(ph_list2[n_ph_list2-1].phcode == phonSWITCH)
|
||||
{
|
||||
//previous phoneme is also a phonSWITCH, delete it
|
||||
n_ph_list2--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPlist2(&ph_list2[n_ph_list2],phonSWITCH);
|
||||
// this word uses a different phoneme table
|
||||
if(ph_list2[n_ph_list2-1].phcode == phonSWITCH)
|
||||
{
|
||||
//previous phoneme is also a phonSWITCH, just change its phoneme table number
|
||||
n_ph_list2--;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPlist2(&ph_list2[n_ph_list2],phonSWITCH);
|
||||
}
|
||||
ph_list2[n_ph_list2++].tone_ph = switch_phonemes; // temporary phoneme table number
|
||||
}
|
||||
ph_list2[n_ph_list2++].tone_ph = switch_phonemes; // temporary phoneme table number
|
||||
}
|
||||
|
||||
// remove initial pause from a word if it follows a hyphen
|
||||
@@ -2484,6 +2496,34 @@ static int TranslateChar(Translator *tr, char *ptr, int prev_in, unsigned int c,
|
||||
}
|
||||
|
||||
|
||||
static const char *UCase_ga[] = {"bp","bhf","dt","gc","hA","mb","ng","ts","tA","nA",NULL};
|
||||
|
||||
int UpperCaseInWord(Translator *tr, char *word, int c)
|
||||
{//=====================================================
|
||||
int ix;
|
||||
int len;
|
||||
const char *p;
|
||||
|
||||
if(tr->translator_name == L('g','a'))
|
||||
{
|
||||
// Irish
|
||||
for(ix=0; ; ix++)
|
||||
{
|
||||
if((p = UCase_ga[ix]) == NULL)
|
||||
break;
|
||||
|
||||
len = strlen(p);
|
||||
if((word[-len]==' ') && (memcmp(&word[-len+1], p, len-1) == 0))
|
||||
{
|
||||
if((c == p[len-1]) || ((p[len-1]=='A') && IsVowel(tr, c)))
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone_out, char **voice_change)
|
||||
{//==========================================================================================================
|
||||
int ix;
|
||||
@@ -2910,10 +2950,19 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
{
|
||||
if(iswlower(prev_in))
|
||||
{
|
||||
c = ' '; // lower case followed by upper case, treat as new word
|
||||
space_inserted = 1;
|
||||
prev_in_save = c;
|
||||
// next_word_flags |= FLAG_NOSPACE; // problem: prevents FLAG_HAS_DOT being set
|
||||
// lower case followed by upper case in a word
|
||||
if(UpperCaseInWord(tr, &sbuf[ix], c) == 1)
|
||||
{
|
||||
// convert to lower case and continue
|
||||
c = towlower(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ' '; // lower case followed by upper case, treat as new word
|
||||
space_inserted = 1;
|
||||
prev_in_save = c;
|
||||
// next_word_flags |= FLAG_NOSPACE; // problem: prevents FLAG_HAS_DOT being set
|
||||
}
|
||||
}
|
||||
else
|
||||
if((c != ' ') && iswupper(prev_in) && iswlower(next_in))
|
||||
|
||||
+34
-13
@@ -372,35 +372,53 @@ typedef struct {
|
||||
|
||||
#define S_NO_DIM 0x02
|
||||
#define S_FINAL_DIM 0x04
|
||||
#define S_FINAL_NO_2 0x10
|
||||
#define S_NO_AUTO_2 0x20
|
||||
#define S_2_TO_HEAVY 0x40
|
||||
#define S_FIRST_PRIMARY 0x80
|
||||
#define S_2_SYL_2 0x1000
|
||||
#define S_INITIAL_2 0x2000
|
||||
#define S_NO_AUTO_DIM 0x10000
|
||||
#define S_HYPEN_UNSTRESS 0x100000
|
||||
#define S_NO_EOC_LENGTHEN 0x200000
|
||||
// bit0=don't stress monosyllables, except at end of clause
|
||||
#define S_FINAL_DIM_ONLY 0x06
|
||||
// bit1=don't set diminished stress,
|
||||
// bit2=mark unstressed final syllables as diminished
|
||||
|
||||
// bit3=set consecutive unstressed syllables in unstressed words to diminished, but not in stressed words
|
||||
|
||||
#define S_FINAL_NO_2 0x10
|
||||
// bit4=don't allow secondary stress on last syllable
|
||||
|
||||
#define S_NO_AUTO_2 0x20
|
||||
// bit5-don't use automatic secondary stress
|
||||
|
||||
#define S_2_TO_HEAVY 0x40
|
||||
// bit6=light syllable followed by heavy, move secondary stress to the heavy syllable. LANG=Finnish
|
||||
|
||||
#define S_FIRST_PRIMARY 0x80
|
||||
// bit7=if more than one primary stress, make the subsequent primaries to secondary stress
|
||||
|
||||
#define S_FINAL_STRESS_C 0x100
|
||||
// bit8=stress last syllable if it doesn't end in a vowel
|
||||
|
||||
#define S_FINAL_SPANISH 0x200
|
||||
// bit9=stress last syllable if it doesn't end in vowel or "s" or "n" LANG=Spanish
|
||||
|
||||
#define S_2_SYL_2 0x1000
|
||||
// bit12= In a 2-syllable word, if one has primary stress then give the other secondary stress
|
||||
|
||||
#define S_INITIAL_2 0x2000
|
||||
// bit13= If there is only one syllable before the primary stress, give it a secondary stress
|
||||
// bit15= Give stress to the first unstressed syllable
|
||||
// bit16= Don't diminish consecutive syllables within a word.
|
||||
|
||||
#define S_PRIORITY_STRESS 0x20000
|
||||
// bit17= "priority" stress reduces other primary stress to "unstressed" not "secondary"
|
||||
|
||||
#define S_EO_CLAUSE1 0x40000
|
||||
// bit18= don't lengthen short vowels more than long vowels at end-of-clause
|
||||
// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
|
||||
|
||||
|
||||
#define S_HYPEN_UNSTRESS 0x100000
|
||||
// bit20= hyphenated words, 2nd part is unstressed
|
||||
|
||||
#define S_NO_EOC_LENGTHEN 0x200000
|
||||
// bit21= don't lengthen vowels at end-of-clause
|
||||
|
||||
// bit15= Give stress to the first unstressed syllable
|
||||
// bit19=stress on final syllable if it has a long vowel, but previous syllable has a short vowel
|
||||
|
||||
|
||||
int stress_flags;
|
||||
int unstressed_wd1; // stress for $u word of 1 syllable
|
||||
int unstressed_wd2; // stress for $u word of >1 syllable
|
||||
@@ -518,6 +536,8 @@ typedef struct {
|
||||
int listx; // compile *_listx after *list
|
||||
const unsigned int *replace_chars; // characters to be substitutes
|
||||
const char *ascii_language; // switch to this language for Latin characters
|
||||
int alt_alphabet; // offset for another language to recognize
|
||||
const char *alt_alphabet_lang; // language for the alt_alphabet
|
||||
int max_lengthmod;
|
||||
int lengthen_tonic; // lengthen the tonic syllable
|
||||
int suffix_add_e; // replace a suffix (which has the SUFX_E flag) with this character
|
||||
@@ -680,6 +700,7 @@ void InitText(int flags);
|
||||
void InitText2(void);
|
||||
int IsDigit(unsigned int c);
|
||||
int IsAlpha(unsigned int c);
|
||||
int IsVowel(Translator *tr, int c);
|
||||
int isspace2(unsigned int c);
|
||||
int towlower2(unsigned int c);
|
||||
void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa);
|
||||
|
||||
+43
-26
@@ -61,7 +61,7 @@ int formant_rate[9]; // values adjusted for actual sample rate
|
||||
|
||||
|
||||
#define DEFAULT_LANGUAGE_PRIORITY 5
|
||||
#define N_VOICES_LIST 200
|
||||
#define N_VOICES_LIST 250
|
||||
static int n_voices_list = 0;
|
||||
static espeak_VOICE *voices_list[N_VOICES_LIST];
|
||||
static int len_path_voices;
|
||||
@@ -578,10 +578,8 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
static const char *voices_europe =
|
||||
"bg bs ca cs cy da el es et fi fr-be hr hu is it lt lv mk nl no pl pt-pt ro ru sk sq sr sv ";
|
||||
|
||||
strcpy(voicename,vname);
|
||||
if(voicename[0]==0)
|
||||
strcpy(voicename,"default");
|
||||
|
||||
strncpy0(voicename, vname, sizeof(voicename));
|
||||
if(control & 0x10)
|
||||
{
|
||||
strcpy(buf,vname);
|
||||
@@ -590,6 +588,9 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(voicename[0]==0)
|
||||
strcpy(voicename,"default");
|
||||
|
||||
sprintf(path_voices,"%s%cvoices%c",path_home,PATHSEP,PATHSEP);
|
||||
sprintf(buf,"%s%s",path_voices,voicename); // first, look in the main voices directory
|
||||
|
||||
@@ -1634,30 +1635,35 @@ static void GetVoices(const char *path)
|
||||
return;
|
||||
|
||||
do {
|
||||
sprintf(fname,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
|
||||
if(n_voices_list >= (N_VOICES_LIST-2))
|
||||
break; // voices list is full
|
||||
|
||||
ftype = GetFileLength(fname);
|
||||
|
||||
if((ftype == -2) && (FindFileData.cFileName[0] != '.'))
|
||||
if(FindFileData.cFileName[0] != '.')
|
||||
{
|
||||
// a sub-sirectory
|
||||
GetVoices(fname);
|
||||
}
|
||||
else
|
||||
if(ftype > 0)
|
||||
{
|
||||
// a regular line, add it to the voices list
|
||||
if((f_voice = fopen(fname,"r")) == NULL)
|
||||
continue;
|
||||
sprintf(fname,"%s%c%s",path,PATHSEP,FindFileData.cFileName);
|
||||
ftype = GetFileLength(fname);
|
||||
|
||||
// pass voice file name within the voices directory
|
||||
voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, FindFileData.cFileName);
|
||||
fclose(f_voice);
|
||||
if(ftype == -2)
|
||||
{
|
||||
// a sub-sirectory
|
||||
GetVoices(fname);
|
||||
}
|
||||
else
|
||||
if(ftype > 0)
|
||||
{
|
||||
// a regular line, add it to the voices list
|
||||
if((f_voice = fopen(fname,"r")) == NULL)
|
||||
continue;
|
||||
|
||||
if(voice_data != NULL)
|
||||
{
|
||||
voices_list[n_voices_list++] = voice_data;
|
||||
}
|
||||
// pass voice file name within the voices directory
|
||||
voice_data = ReadVoiceFile(f_voice, fname+len_path_voices, FindFileData.cFileName);
|
||||
fclose(f_voice);
|
||||
|
||||
if(voice_data != NULL)
|
||||
{
|
||||
voices_list[n_voices_list++] = voice_data;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(FindNextFileA(hFind, &FindFileData) != 0);
|
||||
FindClose(hFind);
|
||||
@@ -1674,11 +1680,14 @@ static void GetVoices(const char *path)
|
||||
if(n_voices_list >= (N_VOICES_LIST-2))
|
||||
break; // voices list is full
|
||||
|
||||
if(ent->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
sprintf(fname,"%s%c%s",path,PATHSEP,ent->d_name);
|
||||
|
||||
ftype = GetFileLength(fname);
|
||||
|
||||
if((ftype == -2) && (ent->d_name[0] != '.'))
|
||||
if(ftype == -2)
|
||||
{
|
||||
// a sub-sirectory
|
||||
GetVoices(fname);
|
||||
@@ -1710,15 +1719,23 @@ static void GetVoices(const char *path)
|
||||
espeak_ERROR SetVoiceByName(const char *name)
|
||||
{//=========================================
|
||||
espeak_VOICE *v;
|
||||
int ix;
|
||||
espeak_VOICE voice_selector;
|
||||
char *variant_name;
|
||||
static char buf[60];
|
||||
|
||||
strncpy0(buf,name,sizeof(buf));
|
||||
|
||||
variant_name = ExtractVoiceVariantName(buf, 0, 1);
|
||||
|
||||
for(ix=0; ;ix++)
|
||||
{
|
||||
// convert voice name to lower case (ascii)
|
||||
if((buf[ix] = tolower(buf[ix])) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&voice_selector,0,sizeof(voice_selector));
|
||||
// voice_selector.name = buf;
|
||||
voice_selector.name = (char *)name; // include variant name in voice stack ??
|
||||
|
||||
// first check for a voice with this filename
|
||||
|
||||
Reference in New Issue
Block a user