mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-14 17:47:19 +00:00
[1.40.07]
*_list files. Ad feature for ordinal numbers (for some languages). *_list files. Allow hyphenated word groups to start with a number. *_list files. Allow "words" of symbols to contain brackets (move check for bracket characters to after the *_list lookup). --punct option. Fix some unnecessary pauses when speaking punctuation names. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@215 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+2
-6
@@ -876,12 +876,8 @@ int Compile::LoadWavefile(FILE *f, const char *fname)
|
||||
max = -sample;
|
||||
|
||||
}
|
||||
if(max > 1)
|
||||
{
|
||||
scale_factor = (max / 127) + 1;
|
||||
}
|
||||
else
|
||||
scale_factor = 0;
|
||||
|
||||
scale_factor = (max / 127) + 1;
|
||||
|
||||
//fprintf(f_errors," sample len=%d max=%4x shift=%d\n",length,max,scale_factor);
|
||||
|
||||
|
||||
+21
-2
@@ -203,6 +203,7 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
|
||||
int flag_offset;
|
||||
int length;
|
||||
int multiple_words = 0;
|
||||
int multiple_numeric_hyphen = 0;
|
||||
char *multiple_string = NULL;
|
||||
char *multiple_string_end = NULL;
|
||||
|
||||
@@ -343,7 +344,14 @@ step=1; // TEST
|
||||
case 1:
|
||||
if((c == '-') && (word[0] != '_'))
|
||||
{
|
||||
flag_codes[n_flag_codes++] = BITNUM_FLAG_HYPHENATED;
|
||||
if(isdigit(word[0]))
|
||||
{
|
||||
multiple_numeric_hyphen = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flag_codes[n_flag_codes++] = BITNUM_FLAG_HYPHENATED;
|
||||
}
|
||||
c = ' ';
|
||||
}
|
||||
if(isspace2(c))
|
||||
@@ -530,8 +538,14 @@ step=1; // TEST
|
||||
}
|
||||
else
|
||||
{
|
||||
dict_line[length++] = 80 + multiple_words;
|
||||
dict_line[length++] = 80 + multiple_words + multiple_numeric_hyphen; // if numeric, count a hyphen as an extra word
|
||||
ix = multiple_string_end - multiple_string;
|
||||
if(multiple_numeric_hyphen)
|
||||
{
|
||||
// the first part is numeric, so keep the hyphen to match on
|
||||
dict_line[length++] = '-';
|
||||
dict_line[length++] = ' ';
|
||||
}
|
||||
memcpy(&dict_line[length],multiple_string,ix);
|
||||
length += ix;
|
||||
}
|
||||
@@ -1303,6 +1317,11 @@ static int compile_lettergroup(char *input, FILE *f_out)
|
||||
fputc(RULE_GROUP_START,f_out);
|
||||
fputc(RULE_LETTERGP2,f_out);
|
||||
fputc(group + 'A', f_out);
|
||||
if(letterGroupsDefined[group] != 0)
|
||||
{
|
||||
fprintf(f_log,"%5d: lettergroup L%.2d is already defined\n",linenum,group);
|
||||
error_count++;
|
||||
}
|
||||
letterGroupsDefined[group] = 1;
|
||||
|
||||
n_items = 0;
|
||||
|
||||
+9
-1
@@ -542,7 +542,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out)
|
||||
|
||||
if(plist->synthflags & SFLAG_SYLLABLE)
|
||||
{
|
||||
if((stress = plist->tone) > 1)
|
||||
if((stress = plist->stresslevel) > 1)
|
||||
{
|
||||
if(stress > 5) stress = 5;
|
||||
phon_out[phon_out_ix++] = stress_chars[stress];
|
||||
@@ -2550,6 +2550,14 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// is it a bracket ?
|
||||
if(IsBracket(letter))
|
||||
{
|
||||
if(pre_pause < 4)
|
||||
pre_pause = 4;
|
||||
}
|
||||
|
||||
// no match, try removing the accent and re-translating the word
|
||||
if((letter >= 0xc0) && (letter <= 0x241) && ((ix = remove_accent[letter-0xc0]) != 0))
|
||||
{
|
||||
|
||||
+1
-1
@@ -466,7 +466,7 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 0x104: // --voices
|
||||
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,NULL,0);
|
||||
espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,data_path,0);
|
||||
DisplayVoices(stdout,optarg);
|
||||
exit(0);
|
||||
|
||||
|
||||
@@ -1163,7 +1163,6 @@ void Test2()
|
||||
|
||||
|
||||
const char* text1 = "Hello world. Testing.";
|
||||
extern void TestCompile2(void);
|
||||
|
||||
void TestTest(int control)
|
||||
{//=======================
|
||||
@@ -1178,7 +1177,6 @@ void TestTest(int control)
|
||||
//CharsetToUnicode("ISO-8859-4");
|
||||
//CharsetToUnicode("ISCII");
|
||||
|
||||
//TestCompile2();
|
||||
return;
|
||||
|
||||
if(control==2)
|
||||
|
||||
+11
-11
@@ -734,12 +734,12 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
p = &phoneme_list[0];
|
||||
for(ix=0; ix<n_phoneme_list; ix++, p++)
|
||||
{
|
||||
if((p->type == phVOWEL) && (p->tone >= 4))
|
||||
if((p->type == phVOWEL) && (p->stresslevel >= 4))
|
||||
{
|
||||
if(count_stressed == 0)
|
||||
final_stressed = ix;
|
||||
|
||||
if(p->tone >= 4)
|
||||
if(p->stresslevel >= 4)
|
||||
{
|
||||
final_stressed = ix;
|
||||
count_stressed++;
|
||||
@@ -747,7 +747,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
}
|
||||
}
|
||||
|
||||
phoneme_list[final_stressed].tone = 7;
|
||||
phoneme_list[final_stressed].stresslevel = 7;
|
||||
|
||||
// language specific, changes to tones
|
||||
if(tr->translator_name == L('v','i'))
|
||||
@@ -813,7 +813,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
if((tph->mnemonic == 0x3535 ) || (tph->mnemonic == 0x3135))
|
||||
{
|
||||
// change sentence final tone 1 or 4 to stress 6, not 7
|
||||
phoneme_list[final_stressed].tone = 6;
|
||||
phoneme_list[final_stressed].stresslevel = 6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,7 +840,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
p->tone_ph = PhonemeCode2('4','4');
|
||||
|
||||
// tone 5 is unstressed (shorter)
|
||||
p->tone = 1; // diminished stress
|
||||
p->stresslevel = 1; // diminished stress
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ static void CalcPitches_Tone(Translator *tr, int clause_tone)
|
||||
{
|
||||
tone_ph = p->tone_ph;
|
||||
|
||||
if(p->tone != 1) // TEST, consider all syllables as stressed
|
||||
if(p->stresslevel != 1) // TEST, consider all syllables as stressed
|
||||
{
|
||||
if(ix == final_stressed)
|
||||
{
|
||||
@@ -924,9 +924,9 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
syllable_tab[n_st].flags = 0;
|
||||
syllable_tab[n_st].env = PITCHfall;
|
||||
syllable_tab[n_st].nextph_type = phoneme_list[ix+1].type;
|
||||
syllable_tab[n_st++].stress = p->tone; // stress level
|
||||
syllable_tab[n_st++].stress = p->stresslevel;
|
||||
|
||||
if(p->tone >= 4)
|
||||
if(p->stresslevel >= 4)
|
||||
n_primary++;
|
||||
}
|
||||
else
|
||||
@@ -1051,7 +1051,7 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
for(ix=ph_start; ix < ph_end; ix++)
|
||||
{
|
||||
p = &phoneme_list[ix];
|
||||
p->tone = syllable_tab[st_ix].stress;
|
||||
p->stresslevel = syllable_tab[st_ix].stress;
|
||||
|
||||
if(p->synthflags & SFLAG_SYLLABLE)
|
||||
{
|
||||
@@ -1071,7 +1071,7 @@ void CalcPitches(Translator *tr, int clause_type)
|
||||
p->env = PITCHrise;
|
||||
}
|
||||
else
|
||||
if(p->tone > 5)
|
||||
if(p->stresslevel > 5)
|
||||
p->env = syl->env;
|
||||
|
||||
if(p->pitch1 > p->pitch2)
|
||||
@@ -1092,7 +1092,7 @@ if(p->tone_ph)
|
||||
|
||||
if(syl->flags & SYL_EMPHASIS)
|
||||
{
|
||||
p->tone |= 8; // emphasized
|
||||
p->stresslevel |= 8; // emphasized
|
||||
}
|
||||
|
||||
st_ix++;
|
||||
|
||||
+143
-62
@@ -893,39 +893,54 @@ static int LookupThousands(Translator *tr, int value, int thousandplex, char *ph
|
||||
static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
{//========================================================================
|
||||
// Lookup a 2 digit number
|
||||
// control bit 0: use special form of '1'
|
||||
// control bit 0: tens and units (use special form of '1')
|
||||
// control bit 1: ordinal number
|
||||
// control bit 2: use feminine form of '2'
|
||||
// control bit 3: speak zero tens
|
||||
|
||||
int found;
|
||||
int ix;
|
||||
int units;
|
||||
int used_and=0;
|
||||
int found_ordinal = 0;
|
||||
int next_phtype;
|
||||
char string[12]; // for looking up entries in de_list
|
||||
char string[12]; // for looking up entries in *_list
|
||||
char ph_tens[50];
|
||||
char ph_digits[50];
|
||||
char ph_and[12];
|
||||
char ph_ordinal[12];
|
||||
|
||||
if((value == 1) && (control & 1))
|
||||
{
|
||||
if(Lookup(tr, "_1a", ph_out) != 0)
|
||||
return(0);
|
||||
}
|
||||
// is there a special pronunciation for this 2-digit number
|
||||
found = 0;
|
||||
|
||||
if(control & 4)
|
||||
{
|
||||
sprintf(string,"_%df",value);
|
||||
found = Lookup(tr, string, ph_digits);
|
||||
}
|
||||
if(control & 2)
|
||||
{
|
||||
sprintf(string,"_%do",value);
|
||||
if((found = Lookup(tr, string, ph_digits)) != 0)
|
||||
{
|
||||
found_ordinal = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(found == 0)
|
||||
{
|
||||
if((value == 1) && (control & 1))
|
||||
{
|
||||
if(Lookup(tr, "_1a", ph_out) != 0)
|
||||
return(0);
|
||||
}
|
||||
sprintf(string,"_%d",value);
|
||||
found = Lookup(tr, string, ph_digits);
|
||||
}
|
||||
|
||||
// no, speak as tens+units
|
||||
if((control & 2) && (value < 10))
|
||||
|
||||
if((control & 8) && (value < 10))
|
||||
{
|
||||
// speak leading zero
|
||||
Lookup(tr, "_0", ph_tens);
|
||||
@@ -934,49 +949,70 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
{
|
||||
if(found)
|
||||
{
|
||||
strcpy(ph_out,ph_digits);
|
||||
return(0);
|
||||
ph_tens[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
units = (value % 10);
|
||||
|
||||
if((value % 10) == 0)
|
||||
{
|
||||
sprintf(string,"_%d0",value / 10);
|
||||
found = Lookup(tr, string, ph_tens);
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
sprintf(string,"_%dX",value / 10);
|
||||
Lookup(tr, string, ph_tens);
|
||||
}
|
||||
if((control & 2) && ((units == 0) || (tr->langopts.numbers & 0x10)))
|
||||
{
|
||||
sprintf(string,"_%dXo",value / 10);
|
||||
if(Lookup(tr, string, ph_tens) != 0)
|
||||
{
|
||||
found_ordinal = 1;
|
||||
}
|
||||
}
|
||||
if(found_ordinal == 0)
|
||||
{
|
||||
sprintf(string,"_%dX",value / 10);
|
||||
Lookup(tr, string, ph_tens);
|
||||
}
|
||||
|
||||
if((value % 10) == 0)
|
||||
{
|
||||
strcpy(ph_out,ph_tens);
|
||||
return(0);
|
||||
}
|
||||
|
||||
found = 0;
|
||||
units = (value % 10);
|
||||
if(control & 4)
|
||||
{
|
||||
// is there a variant form of this number?
|
||||
sprintf(string,"_%df",units);
|
||||
found = Lookup(tr, string, ph_digits);
|
||||
}
|
||||
if(found == 0)
|
||||
{
|
||||
sprintf(string,"_%d",units);
|
||||
Lookup(tr, string, ph_digits);
|
||||
ph_digits[0] = 0;
|
||||
if(units > 0)
|
||||
{
|
||||
found = 0;
|
||||
if(control & 4)
|
||||
{
|
||||
// is there a variant form of this number?
|
||||
sprintf(string,"_%df",units);
|
||||
found = Lookup(tr, string, ph_digits);
|
||||
}
|
||||
if((control & 2) && ((tr->langopts.numbers & 0x10) == 0))
|
||||
{
|
||||
// ordinal
|
||||
sprintf(string,"_%do",units);
|
||||
if((found = Lookup(tr, string, ph_digits)) != 0)
|
||||
{
|
||||
found_ordinal = 1;
|
||||
}
|
||||
}
|
||||
if(found == 0)
|
||||
{
|
||||
sprintf(string,"_%d",units);
|
||||
Lookup(tr, string, ph_digits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(tr->langopts.numbers & 0x30)
|
||||
ph_ordinal[0] = 0;
|
||||
if((control & 2) && (found_ordinal == 0))
|
||||
{
|
||||
if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & 0x10)))
|
||||
Lookup(tr, "_ord20", ph_ordinal);
|
||||
if(ph_ordinal[0] == 0)
|
||||
Lookup(tr, "_ord", ph_ordinal);
|
||||
}
|
||||
|
||||
if((tr->langopts.numbers & 0x30) && (ph_tens[0] != 0) && (ph_digits[0] != 0))
|
||||
{
|
||||
Lookup(tr, "_0and", ph_and);
|
||||
if(tr->langopts.numbers & 0x10)
|
||||
sprintf(ph_out,"%s%s%s",ph_digits,ph_and,ph_tens);
|
||||
sprintf(ph_out,"%s%s%s%s",ph_digits, ph_and, ph_tens, ph_ordinal);
|
||||
else
|
||||
sprintf(ph_out,"%s%s%s",ph_tens,ph_and,ph_digits);
|
||||
sprintf(ph_out,"%s%s%s%s",ph_tens, ph_and, ph_digits, ph_ordinal);
|
||||
used_and = 1;
|
||||
}
|
||||
else
|
||||
@@ -993,7 +1029,7 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
ph_tens[ix] = 0;
|
||||
}
|
||||
}
|
||||
sprintf(ph_out,"%s%s",ph_tens,ph_digits);
|
||||
sprintf(ph_out,"%s%s%s",ph_tens, ph_digits, ph_ordinal);
|
||||
}
|
||||
|
||||
if(tr->langopts.numbers & 0x100)
|
||||
@@ -1015,9 +1051,11 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
|
||||
} // end of LookupNum2
|
||||
|
||||
|
||||
static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null, int thousandplex, int prev_thousands)
|
||||
{//====================================================================================================================
|
||||
static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null, int thousandplex, int control)
|
||||
{//=============================================================================================================
|
||||
// Translate a 3 digit number
|
||||
// control bit 0, previous thousands
|
||||
// bit 1, ordinal number
|
||||
int found;
|
||||
int hundreds;
|
||||
int x;
|
||||
@@ -1039,7 +1077,16 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
ph_thousands[0] = 0;
|
||||
ph_thousand_and[0] = 0;
|
||||
|
||||
Lookup(tr, "_0C", ph_100);
|
||||
found = 0;
|
||||
if((control & 2) && ((value % 100) == 0))
|
||||
{
|
||||
// ordinal number, with no tens or units
|
||||
found = Lookup(tr, "_0Co", ph_100);
|
||||
}
|
||||
if(found == 0)
|
||||
{
|
||||
Lookup(tr, "_0C", ph_100);
|
||||
}
|
||||
|
||||
if(((tr->langopts.numbers & 0x0800) != 0) && (hundreds == 19))
|
||||
{
|
||||
@@ -1073,7 +1120,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
ph_digits[0] = 0;
|
||||
if(hundreds > 0)
|
||||
{
|
||||
if((tr->langopts.numbers & 0x100000) && (prev_thousands || (ph_thousands[0] != 0)))
|
||||
if((tr->langopts.numbers & 0x100000) && ((control & 1) || (ph_thousands[0] != 0)))
|
||||
{
|
||||
Lookup(tr, "_0and", ph_thousand_and);
|
||||
}
|
||||
@@ -1111,7 +1158,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
ph_hundred_and[0] = 0;
|
||||
if((tr->langopts.numbers & 0x40) && ((value % 100) != 0))
|
||||
{
|
||||
if((value > 100) || (prev_thousands && (thousandplex==0)))
|
||||
if((value > 100) || ((control & 1) && (thousandplex==0)))
|
||||
{
|
||||
Lookup(tr, "_0and", ph_hundred_and);
|
||||
}
|
||||
@@ -1121,16 +1168,15 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
buf2[0] = 0;
|
||||
value = value % 100;
|
||||
|
||||
if(value == 0)
|
||||
{
|
||||
if(suppress_null == 0)
|
||||
Lookup(tr, "_0", buf2);
|
||||
}
|
||||
else
|
||||
if((value != 0) || (suppress_null == 0))
|
||||
{
|
||||
x = 0;
|
||||
if(thousandplex==0)
|
||||
{
|
||||
x = 1; // allow "eins" for 1 rather than "ein"
|
||||
if(control & 2)
|
||||
x = 3; // ordinal number
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tr->langopts.numbers2 & (1 << thousandplex))
|
||||
@@ -1150,6 +1196,9 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
|
||||
} // end of LookupNum3
|
||||
|
||||
|
||||
static const char *ordinalstr_en[] = {"th","st","nd","rd",NULL,};
|
||||
static const char *ordinalstr_af[] = {"de","ste",NULL,};
|
||||
static const char **ordinal_strings[] = {NULL, ordinalstr_en, ordinalstr_af};
|
||||
|
||||
static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, int wflags)
|
||||
{//====================================================================================================
|
||||
@@ -1166,10 +1215,15 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
int thousandplex = 0;
|
||||
int thousands_inc = 0;
|
||||
int prev_thousands = 0;
|
||||
int ordinal = 0;
|
||||
int this_value;
|
||||
static int prev_value;
|
||||
int decimal_count;
|
||||
int max_decimal_count;
|
||||
int decimal_mode;
|
||||
int len;
|
||||
const char *p;
|
||||
const char **pp;
|
||||
char string[12]; // for looking up entries in de_list
|
||||
char buf1[100];
|
||||
char ph_append[50];
|
||||
@@ -1182,6 +1236,30 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
n_digits = ix;
|
||||
value = this_value = atoi(word);
|
||||
|
||||
if((tr->langopts.numbers & 0x10000) && (word[ix] == '.'))
|
||||
{
|
||||
// ordinal number
|
||||
ordinal = 2;
|
||||
word[ix] = ' ';
|
||||
}
|
||||
else
|
||||
if(tr->langopts.ordinals)
|
||||
{
|
||||
// ordinal numbers are recognized by letters after the number
|
||||
ix++;
|
||||
pp = ordinal_strings[tr->langopts.ordinals];
|
||||
while((p = *pp++) != NULL)
|
||||
{
|
||||
len = strlen(p);
|
||||
if((word[ix+len] == ' ') && (memcmp(&word[ix], p, len) == 0))
|
||||
{
|
||||
ordinal = 2;
|
||||
memset(&word[ix], ' ', len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ph_append[0] = 0;
|
||||
ph_buf2[0] = 0;
|
||||
|
||||
@@ -1200,7 +1278,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
}
|
||||
}
|
||||
|
||||
if((word[0] == '0') && (prev_thousands == 0) && (word[1] != tr->langopts.decimal_sep))
|
||||
if((word[0] == '0') && (prev_thousands == 0) && (word[1] != ' ') && (word[1] != tr->langopts.decimal_sep))
|
||||
{
|
||||
if((n_digits == 2) && (word[3] == ':') && isdigit(word[5]) && isspace(word[7]))
|
||||
{
|
||||
@@ -1278,7 +1356,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
Lookup(tr, "_.", ph_append);
|
||||
}
|
||||
|
||||
LookupNum3(tr, value, ph_buf, suppress_null, thousandplex, prev_thousands);
|
||||
LookupNum3(tr, value, ph_buf, suppress_null, thousandplex, prev_thousands | ordinal);
|
||||
if((thousandplex > 0) && (tr->langopts.numbers2 & 0x200))
|
||||
sprintf(ph_out,"%s%s%s",ph_append,ph_buf2,ph_buf); // say "thousands" before its number
|
||||
else
|
||||
@@ -1296,7 +1374,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
if(decimal_count > 1)
|
||||
{
|
||||
max_decimal_count = 2;
|
||||
switch(tr->langopts.numbers & 0xe000)
|
||||
switch(decimal_mode = (tr->langopts.numbers & 0xe000))
|
||||
{
|
||||
case 0x8000:
|
||||
max_decimal_count = 5;
|
||||
@@ -1318,18 +1396,21 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
break;
|
||||
|
||||
case 0x2000:
|
||||
case 0xa000:
|
||||
// Italian decimal fractions
|
||||
if((decimal_count < 4) || ((decimal_count==4) && (word[n_digits] != '0')))
|
||||
if(decimal_count <= 4)
|
||||
{
|
||||
LookupNum3(tr, atoi(&word[n_digits]), buf1, 0,0,0);
|
||||
strcat(ph_out,buf1);
|
||||
if(word[n_digits]=='0')
|
||||
LookupNum3(tr, atoi(&word[n_digits]), ph_buf, 0,0,0);
|
||||
if((word[n_digits]=='0') || (decimal_mode == 0xa000))
|
||||
{
|
||||
// decimal part has leading zeros, so add a "hundredths" or "thousandths" suffix
|
||||
sprintf(string,"_0Z%d",decimal_count);
|
||||
Lookup(tr, string, buf1);
|
||||
strcat(ph_out,buf1);
|
||||
if(Lookup(tr, string, buf1) == 0)
|
||||
break; // revert to speaking single digits
|
||||
|
||||
strcat(ph_buf,buf1);
|
||||
}
|
||||
strcat(ph_out,ph_buf);
|
||||
n_digits += decimal_count;
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -628,7 +628,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence)
|
||||
phlist[ix].type = ph->type;
|
||||
phlist[ix].env = PITCHfall; // default, can be changed in the "intonation" module
|
||||
phlist[ix].synthflags = plist2->synthflags | switched_language;
|
||||
phlist[ix].tone = plist2->stress & 0xf;
|
||||
phlist[ix].stresslevel = plist2->stress & 0xf;
|
||||
phlist[ix].tone_ph = plist2->tone_number;
|
||||
phlist[ix].sourceix = 0;
|
||||
|
||||
|
||||
@@ -136,11 +136,11 @@ void ProsodyDisplay::SelectPh(int index)
|
||||
if((p == NULL) || (p->ph == NULL)) return;
|
||||
|
||||
emphasized = "";
|
||||
if(p->tone & 8)
|
||||
if(p->stresslevel & 8)
|
||||
emphasized = "*";
|
||||
|
||||
sprintf(buf,"Stress %s%d Amp %2d LenMod %2d Pitch %3d %3d [env=%d] Flags %.2x ",
|
||||
emphasized,p->tone&0x7,p->amp,p->length,p->pitch1,p->pitch2,p->env,p->ph->phflags);
|
||||
emphasized,p->stresslevel&0x7,p->amp,p->length,p->pitch1,p->pitch2,p->env,p->ph->phflags);
|
||||
wxLogStatus(wxString(buf,wxConvLocal));
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -862,8 +862,10 @@ static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bu
|
||||
|
||||
if(c1 == '-')
|
||||
return(CLAUSE_NONE); // no pause
|
||||
if(bufix > 0)
|
||||
return(CLAUSE_SHORTCOMMA);
|
||||
if((strchr_w(punct_close,c1) != NULL) && !iswalnum(c2))
|
||||
return(CLAUSE_COLON);
|
||||
return(CLAUSE_SHORTFALL+4);
|
||||
if(iswspace(c2) && strchr_w(punct_stop,c1)!=NULL)
|
||||
return(punct_attributes[lookupwchar(punct_chars,c1)]);
|
||||
|
||||
@@ -2029,7 +2031,7 @@ f_input = f_in; // for GetC etc
|
||||
}
|
||||
}
|
||||
else
|
||||
if((c1 == '<') && (ssml_ignore_l_angle != '<'))
|
||||
if((c1 == '<') && (ssml_ignore_l_angle != '<') && ((c2 == '/') || iswalpha(c2)))
|
||||
{
|
||||
// SSML Tag
|
||||
n_xml_buf = 0;
|
||||
@@ -2300,10 +2302,10 @@ if(option_ssml) parag=1;
|
||||
|
||||
if((nl_count==0) && (c1 == '.'))
|
||||
{
|
||||
if(iswdigit(cprev) && (tr->langopts.numbers & 0x10000))
|
||||
if(iswdigit(cprev) && (tr->langopts.numbers & 0x10000) && islower(c2))
|
||||
{
|
||||
// dot after a number indicates an ordinal number
|
||||
c2 = ' ';
|
||||
c2 = '.';
|
||||
continue;
|
||||
}
|
||||
if(iswlower(c2))
|
||||
|
||||
+2
-2
@@ -298,8 +298,8 @@ void CalcLengths(Translator *tr)
|
||||
{
|
||||
prev = &phoneme_list[ix-1];
|
||||
p = &phoneme_list[ix];
|
||||
stress = p->tone & 0x7;
|
||||
emphasized = p->tone & 0x8;
|
||||
stress = p->stresslevel & 0x7;
|
||||
emphasized = p->stresslevel & 0x8;
|
||||
|
||||
next = &phoneme_list[ix+1];
|
||||
|
||||
|
||||
@@ -676,6 +676,7 @@ int main (int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 0x104: // --voices
|
||||
init_path(argv[0],data_path);
|
||||
DisplayVoices(stdout,optarg2);
|
||||
exit(0);
|
||||
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.40 22.Dec.08";
|
||||
const char *version_string = "1.40.07 13.Jan.09";
|
||||
const int version_phdata = 0x014000;
|
||||
|
||||
int option_device_number = -1;
|
||||
@@ -46,7 +46,7 @@ int current_phoneme_table;
|
||||
PHONEME_TAB *phoneme_tab[N_PHONEME_TAB];
|
||||
unsigned char phoneme_tab_flags[N_PHONEME_TAB]; // bit 0: not inherited
|
||||
|
||||
unsigned int *phoneme_index=NULL;
|
||||
static unsigned int *phoneme_index=NULL;
|
||||
char *spects_data=NULL;
|
||||
unsigned char *wavefile_data=NULL;
|
||||
static unsigned char *phoneme_tab_data = NULL;
|
||||
|
||||
+1
-1
@@ -1394,7 +1394,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
|
||||
|
||||
case phVOWEL:
|
||||
ph = p->ph;
|
||||
stress = p->tone & 0xf;
|
||||
stress = p->stresslevel & 0xf;
|
||||
|
||||
// vowel transition from the preceding phoneme
|
||||
vowel_transition0 = vowel_transition[0];
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
PHONEME_TAB *ph;
|
||||
unsigned char env; // pitch envelope number
|
||||
unsigned char tone;
|
||||
unsigned char stresslevel;
|
||||
unsigned char type;
|
||||
unsigned char prepause;
|
||||
unsigned char amp;
|
||||
|
||||
@@ -263,6 +263,7 @@ Translator *SelectTranslator(const char *name)
|
||||
SetLetterVowel(tr,'y'); // add 'y' to vowels
|
||||
|
||||
tr->langopts.numbers = 0x8d1 + NUM_ROMAN;
|
||||
tr->langopts.ordinals = 2;
|
||||
tr->langopts.accents = 1;
|
||||
}
|
||||
break;
|
||||
@@ -344,6 +345,7 @@ Translator *SelectTranslator(const char *name)
|
||||
|
||||
tr->langopts.stress_rule = 0;
|
||||
tr->langopts.numbers = 0x841 + NUM_ROMAN;
|
||||
tr->langopts.ordinals = 1;
|
||||
tr->langopts.param[LOPT_COMBINE_WORDS] = 2; // allow "mc" to cmbine with the following word
|
||||
}
|
||||
break;
|
||||
@@ -554,7 +556,7 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->langopts.param[LOPT_IT_DOUBLING] = 1;
|
||||
tr->langopts.param[LOPT_COMBINE_WORDS] = 99; // combine some prepositions with the following word
|
||||
|
||||
tr->langopts.numbers = 0x1009 + NUM_ROMAN;
|
||||
tr->langopts.numbers = 0x1009 + 0xa000 + NUM_ROMAN + 0x10000;
|
||||
SetLetterVowel(tr,'y');
|
||||
tr->langopts.spelling_stress = 1;
|
||||
SetLengthMods(tr,3); // all equal
|
||||
@@ -1038,6 +1040,7 @@ SetLengthMods(tr,3); // all equal
|
||||
break;
|
||||
|
||||
default:
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+19
-5
@@ -74,6 +74,7 @@ static int word_emphasis = 0; // set if emphasis level 3 or 4
|
||||
|
||||
static int prev_clause_pause=0;
|
||||
static int max_clause_pause = 0;
|
||||
int pre_pause;
|
||||
|
||||
|
||||
// these were previously in translator class
|
||||
@@ -641,6 +642,7 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
|
||||
found = LookupDictList(tr, &word1, phonemes, dictionary_flags, FLAG_ALLOW_TEXTMODE, wtab); // the original word
|
||||
if(dictionary_flags[0] & FLAG_TEXTMODE)
|
||||
{
|
||||
first_char = word1[0];
|
||||
stress_bits = dictionary_flags[0] & 0x7f;
|
||||
found = LookupDictList(tr, &word1, phonemes, dictionary_flags2, 0, wtab); // the text replacement
|
||||
if(dictionary_flags2[0]!=0)
|
||||
@@ -1172,7 +1174,7 @@ strcpy(phonemes2,phonemes);
|
||||
if(dictionary_flags[1] & FLAG_NOUNF)
|
||||
{
|
||||
/* not expecting a verb next */
|
||||
tr->expect_noun = 3;
|
||||
tr->expect_noun = 2;
|
||||
tr->expect_verb = 0;
|
||||
tr->expect_verb_s = 0;
|
||||
tr->expect_past = 0;
|
||||
@@ -1942,7 +1944,6 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int next_in;
|
||||
int char_inserted=0;
|
||||
int clause_pause;
|
||||
int pre_pause=0;
|
||||
int pre_pause_add=0;
|
||||
int word_mark = 0;
|
||||
int all_upper_case=FLAG_ALL_UPPER;
|
||||
@@ -1972,13 +1973,13 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
int tone;
|
||||
int tone2;
|
||||
|
||||
|
||||
p_textinput = (char *)vp_input;
|
||||
p_wchar_input = (wchar_t *)vp_input;
|
||||
|
||||
embedded_ix = 0;
|
||||
embedded_read = 0;
|
||||
option_phoneme_input &= ~2; // clear bit 1 (temporary indication)
|
||||
pre_pause = 0;
|
||||
|
||||
if((clause_start_char = count_characters) < 0)
|
||||
clause_start_char = 0;
|
||||
@@ -2409,12 +2410,15 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifdef deleted
|
||||
// Brackets are now recognised in TranslateRules()
|
||||
if(IsBracket(c))
|
||||
{
|
||||
pre_pause_add = 4;
|
||||
c = ' ';
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(lookupwchar(breaks,c) != 0)
|
||||
{
|
||||
c = ' '; // various characters to treat as space
|
||||
@@ -2636,10 +2640,13 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
}
|
||||
}
|
||||
pn[0] = ' ';
|
||||
pn[1] = 0;
|
||||
word = pw;
|
||||
|
||||
// include the next few characters, in case there are an ordinal indicator
|
||||
pn[0] = ' ';
|
||||
memcpy(pn+1, pw, 5);
|
||||
pn[5] = 0;
|
||||
|
||||
for(pw = &number_buf[1]; pw < pn;)
|
||||
{
|
||||
TranslateWord2(tr, pw, &words[ix], words[ix].pre_pause,0 );
|
||||
@@ -2650,8 +2657,15 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
|
||||
}
|
||||
else
|
||||
{
|
||||
pre_pause = 0;
|
||||
dict_flags = TranslateWord2(tr, word, &words[ix], words[ix].pre_pause, words[ix+1].pre_pause);
|
||||
|
||||
if(pre_pause > words[ix+1].pre_pause)
|
||||
{
|
||||
words[ix+1].pre_pause = pre_pause;
|
||||
pre_pause = 0;
|
||||
}
|
||||
|
||||
if(dict_flags & FLAG_SPELLWORD)
|
||||
{
|
||||
// redo the word, speaking single letters
|
||||
|
||||
+4
-1
@@ -175,7 +175,8 @@
|
||||
#define CLAUSE_VOICE 0 + 0x24000
|
||||
#define CLAUSE_PERIOD 35 + 0x80000
|
||||
#define CLAUSE_COMMA 20 + 0x41000
|
||||
#define CLAUSE_SHORTCOMMA 5 + 0x41000
|
||||
#define CLAUSE_SHORTCOMMA 4 + 0x41000
|
||||
#define CLAUSE_SHORTFALL 4 + 0x40000
|
||||
#define CLAUSE_QUESTION 35 + 0x82000
|
||||
#define CLAUSE_EXCLAMATION 40 + 0x83000
|
||||
#define CLAUSE_COLON 30 + 0x40000
|
||||
@@ -363,6 +364,7 @@ typedef struct {
|
||||
int max_roman;
|
||||
int thousands_sep;
|
||||
int decimal_sep;
|
||||
int ordinals;
|
||||
|
||||
// bit 0, accent name before the letter name, bit 1 "capital" after letter name
|
||||
int accents;
|
||||
@@ -496,6 +498,7 @@ extern int end_character_position;
|
||||
extern int clause_start_char;
|
||||
extern int clause_start_word;
|
||||
extern char *namedata;
|
||||
extern int pre_pause;
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user