Lang=pt: fix ordinal numbers 11-19. Lang=en-us: minor vowel changes. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@291 d46cf337-b52f-0410-862d-fd96e6ae7743master
Z Z; | Z Z; | ||||
Dictionary ko_dict 2012-09-14 | |||||
Dictionary ko_dict 2012-09-15 | |||||
@ a e E i o u u- | @ a e E i o u u- | ||||
$textmode | |||||
// eSpeak Korean rules. Changed pronunciation, as numbers were not announced. | |||||
// Number forms: | |||||
_0 ᅧᆼ | |||||
_1 ᅵᆯ | |||||
_2 ᅵ | |||||
_3 삼 | |||||
_4 사 | |||||
_5 ᅩ | |||||
_6 ᅲᆨ | |||||
_7 칠 | |||||
_8 팔 | |||||
_9 구 | |||||
_1X 십 | |||||
_2X ᅵ십 | |||||
_3X 삼십 | |||||
_4X 사십 | |||||
_5X ᅩ십 | |||||
_6X ᅲᆨ십 | |||||
_7X 칠십 | |||||
_8X 팔십 | |||||
_9X 구십 | |||||
_0C 백 | |||||
_0M1 천 | |||||
_1M1 천 | |||||
$phonememode | |||||
_0M2 m'an // 10^4 | |||||
_1M2 m'an | |||||
_0M3 tSh-@n||m'an // 10^7 | |||||
_1M3 tSh-@n||m'an | |||||
_0M4 '@q // 10^8 | |||||
_1M4 '@q | |||||
_0M5 tSh-@n||'@q // 10^11 | |||||
_1M5 tSh-@n||'@q | |||||
_0M6 tS;'o // 10^12 | |||||
_1M6 tS;'o | |||||
_0M7 tSh-@n||tS;'o | |||||
_1M7 tSh-@n||tS;'o | |||||
_0M8 gj'@nN | |||||
_1M8 gj'@nN | |||||
$textmode | |||||
// Number forms: | |||||
_0 j'@N_! | |||||
_1 'iR_! | |||||
_2 'i_! | |||||
_3 s'am_! | |||||
_4 s'a_! | |||||
_5 'o_! | |||||
_6 j'uq_! | |||||
_7 tS'h'iR_! | |||||
_8 ph'aR_! | |||||
_9 g'u_! | |||||
_1X s'ip_! | |||||
_2X 'i_!||s'ip_! | |||||
_3X s'am_!||s'ip_! | |||||
_4X s'a_!||s'ip_! | |||||
_5X 'o_!||s'ip_! | |||||
_6X j'uq_!||s'ip_! | |||||
_7X tS'h'iR_!s'ip_! | |||||
_8X ph'aR_!||s'ip_! | |||||
_9X g'u_!||s'ip_! | |||||
_0C p'Eq_! | |||||
// Larger numbers | |||||
_0M0 tS'h-@n // 10^3 | |||||
_1M0 tS'h-@n | |||||
_0M1 m'an // 10^4 | |||||
_1M1 m'an | |||||
_0M2 '@q // 10^8 | |||||
_1M2 '@q | |||||
_0M3 tS;'o // 10^12 | |||||
_1M3 tS;'o | |||||
_0M4 gj'@N | |||||
_1M4 gj'@N | |||||
// Character names: | // Character names: | ||||
ㄱ ㄱㅣㅇㅕㄱ | |||||
ㄲ ㅆㅏㅇㄱㅣㅇㅕㄱ | |||||
ㄴ ㄴㅣㅇㅡㄴ | |||||
ㄷ ㄷㅣㄱㅡㄷ | |||||
ㄸ ㅆㅏㅇㄷㅣㄱㅡㄷ | |||||
ㄹ ㄹㅣㅇㅡㄹ | |||||
ㅁ ㅁㅣㅇㅡㅁ | |||||
ㅂ ㅂㅣㅇㅡㅂ | |||||
ㅃ ㅆㅏㅇㅂㅣㅇㅡㅂ | |||||
ㅅ ㅅㅣㅇㅗㅅ | |||||
ㅆ ㅆㅏㅇㅅㅣㅇㅗㅅ | |||||
ㅇ ㅇㅣㅇㅡㅇ | |||||
ㅈ ㅈㅣㅇㅡㅈ | |||||
ㅉ ㅆㅏㅇㅈㅣㅇㅡㅈ | |||||
ㅊ ㅊㅣㅇㅡㅊ | |||||
ㅋ ㅋㅣㅇㅡㅋ | |||||
ㅌ ㅌㅣㅇㅡㅌ | |||||
ㅍ ㅍㅣㅇㅡㅍ | |||||
ㅎ ㅎㅣㅇㅡㅎ | |||||
ᄀ gij'@q | |||||
ᄁ 's-aNq,ij@q | |||||
ᄂ ni;'u-n | |||||
ᄃ diq'u-d- | |||||
ᄄ 's-aNd,iqu-d- | |||||
ᄅ *i;'u-rr | |||||
ᄆ mi;'u-m | |||||
ᄇ pi;'u-p | |||||
ᄈ 's-aNb,i;u-p | |||||
ᄉ si;'ot- | |||||
ᄊ 's-aNs,i;ot- | |||||
ᄋ i;'u-N | |||||
ᄌ tS;i;'u-t | |||||
ᄍ 's-aNdZ;,i;u-t | |||||
ᄎ tSh-'i;u-t | |||||
ᄏ khi;'u-k | |||||
ᄐ thi;'u-t- | |||||
ᄑ phi;'u-p | |||||
ᄒ hi;'u-t- | |||||
// end of character names. | |||||
$textmode | |||||
// Misc: | // Misc: | ||||
// 사ᅵ시ᅩᆺ | // 사ᅵ시ᅩᆺ | ||||
고랫재 고랟째 | 고랫재 고랟째 |
// eSpeak Korean rules | |||||
// This file is UTF8 encoded | // This file is UTF8 encoded | ||||
// char names (mostly to catch "ng" sound): | |||||
.group ᄋ | |||||
ᄋ i;'u-N | |||||
.replace | .replace | ||||
// Note: These specific range of "normalized" unicode characters of Korean are | // Note: These specific range of "normalized" unicode characters of Korean are | ||||
// h-finals: ㅎ ㄶㅀ | // h-finals: ㅎ ㄶㅀ | ||||
.L03 ᇂ ᆭ ᆶ | .L03 ᇂ ᆭ ᆶ | ||||
// Char names: | |||||
// Initials | // Initials | ||||
// Order: ㄱㄲㅋ ㄷㄸㅌ ㅂㅃㅍ ㅅㅆㅈㅉㅊ ㄴㅁ ㄹ ㅎ | // Order: ㄱㄲㅋ ㄷㄸㅌ ㅂㅃㅍ ㅅㅆㅈㅉㅊ ㄴㅁ ㄹ ㅎ | ||||
ᆷ m | ᆷ m | ||||
.group ᆼ // ㅇ | .group ᆼ // ㅇ | ||||
ᆼ nN | |||||
ᆼ N | |||||
.group ᇂ // ㅎ | .group ᇂ // ㅎ | ||||
ᇂ t- | ᇂ t- |
_7o s'EtSim | _7o s'EtSim | ||||
_8o oIt'av | _8o oIt'av | ||||
_9o n'on | _9o n'on | ||||
_10o d'Esim | |||||
_1Xo d'Esim | |||||
_2Xo viZ'Ezim | _2Xo viZ'Ezim | ||||
_3Xo tRiZ'Ezim | _3Xo tRiZ'Ezim | ||||
_4Xo kwad*aZ'Ezim | _4Xo kwad*aZ'Ezim |
<table> | <table> | ||||
<tbody valign=top> | <tbody valign=top> | ||||
<tr> | <tr> | ||||
<td width=25><code>[p]</code><td width=80> | |||||
<td width=25><code>[b]</code><td width=80> | |||||
<td width=25><code>[p]</code><td width=150> | |||||
<td width=25><code>[b]</code><td width=150> | |||||
<tr> | <tr> | ||||
<td><code>[t]</code><td> | <td><code>[t]</code><td> | ||||
<td><code>[d]</code><td> | <td><code>[d]</code><td> | ||||
<table> | <table> | ||||
<tbody valign=top> | <tbody valign=top> | ||||
<tr><td width=25><code>[@]</code> | <tr><td width=25><code>[@]</code> | ||||
<td width=60>alph<b>a</b><td width=80>schwa | |||||
<td width=60>alph<b>a</b><td width=400>schwa | |||||
<tr><td><code>[3]</code> | <tr><td><code>[3]</code> | ||||
<td>bett<b>er</b><td>rhotic schwa. In British English this is the same as <code>[@]</code>, but it includes 'r' colouring in American and other rhotic accents. In these cases a separate <code>[r]</code> should not be included unless it is followed immediately by another vowel. | <td>bett<b>er</b><td>rhotic schwa. In British English this is the same as <code>[@]</code>, but it includes 'r' colouring in American and other rhotic accents. In these cases a separate <code>[r]</code> should not be included unless it is followed immediately by another vowel. | ||||
<tr><td><code>[a]</code><td>tr<b>a</b>p | <tr><td><code>[a]</code><td>tr<b>a</b>p | ||||
<tr><td><code>[aa]</code><td>b<b>a</b>th<td>This is <code>[a]</code> in some accents, <code>[A:]</code> in others. | <tr><td><code>[aa]</code><td>b<b>a</b>th<td>This is <code>[a]</code> in some accents, <code>[A:]</code> in others. | ||||
<tr><td><code>[a2]</code><td><b>a</b>bout<td>This may be <code>[@]</code> or may be a more open schwa. | |||||
<tr><td><code>[a#]</code><td><b>a</b>bout<td>This may be <code>[@]</code> or may be a more open schwa. | |||||
<tr><td><code>[A:]</code><td>p<b>al</b>m | <tr><td><code>[A:]</code><td>p<b>al</b>m | ||||
<tr><td><code>[A@]</code><td>st<b>ar</b>t | <tr><td><code>[A@]</code><td>st<b>ar</b>t | ||||
<tr><td><p> | <tr><td><p> | ||||
</tbody> | </tbody> | ||||
</table> | </table> | ||||
<p> | |||||
<code> [:] </code> can be used to lengthen a vowel, eg <code> [e:]</code> | |||||
</body> | </body> | ||||
</html> | </html> |
[l/] fr | [l/] fr | ||||
l/l_@ [l/3] base | l/l_@ [l/3] base | ||||
[l/] fr | [l/] fr | ||||
l/l@ [h1ø] base | |||||
l/l@ [hÖ{] base | |||||
[l#] base | [l#] base | ||||
[l] fr | [l] fr | ||||
[l/2] fr | [l/2] fr | ||||
l/L2_uL [l/2] base | l/L2_uL [l/2] base | ||||
l/l_3 [l/] de | l/l_3 [l/] de | ||||
l/l_4 [ll] sq | l/l_4 [ll] sq | ||||
l/la [h1ø] base | |||||
l/la [hÖ{] base | |||||
[l#] base | [l#] base | ||||
[l] fr | [l] fr | ||||
[l/2] fr | [l/2] fr | ||||
[K] tn | [K] tn | ||||
l/l_a [l/3] base | l/l_a [l/3] base | ||||
[l/] fr | [l/] fr | ||||
l/le [h1ø] base | |||||
l/le [hÖ{] base | |||||
[l#] base | [l#] base | ||||
[l] fr | [l] fr | ||||
[l/2] fr | [l/2] fr | ||||
[&:] af | [&:] af | ||||
l/l_front [L] sq | l/l_front [L] sq | ||||
l/l_front_ [l/4] sq | l/l_front_ [l/4] sq | ||||
l/li [h1ø] base | |||||
l/li [hÖ{] base | |||||
[l#] base | [l#] base | ||||
[l] fr | [l] fr | ||||
[l/2] fr | [l/2] fr | ||||
ll/_ll [L] base | ll/_ll [L] base | ||||
l/l_long [l] base | l/l_long [l] base | ||||
[l] fr | [l] fr | ||||
l/lo [h1ø] base | |||||
l/lo [hÖ{] base | |||||
[l#] base | [l#] base | ||||
[l/2] fr | [l/2] fr | ||||
[K] nso | [K] nso | ||||
[l;] lt | [l;] lt | ||||
[l] ru | [l] ru | ||||
[l^] ru | [l^] ru | ||||
l/lu [h1ø] base | |||||
l/lu [hÖ{] base | |||||
[l#] base | [l#] base | ||||
[l] fr | [l] fr | ||||
[l/2] fr | [l/2] fr | ||||
[U@] en-n | [U@] en-n | ||||
[U@] en-wm | [U@] en-wm | ||||
[u@] vi | [u@] vi | ||||
vdiph2/uw [u:] en-us | |||||
vdiph2/uw_2 [u:] en | vdiph2/uw_2 [u:] en | ||||
vdiph2/uw_3 [yU] ro | vdiph2/uw_3 [yU] ro | ||||
vdiph2/uw_4 [u:] en-n | vdiph2/uw_4 [u:] en-n | ||||
vdiph2/uw_6 [u#] kk | |||||
vdiph2/uw_6 [u:] en-us | |||||
[u#] kk | |||||
vdiph2/y@ [y@] zh | vdiph2/y@ [y@] zh | ||||
vdiph2/y#@ [Y@] af | vdiph2/y#@ [Y@] af | ||||
vdiph2/ye [yE] sq | vdiph2/ye [yE] sq |
phoneme u: | phoneme u: | ||||
vowel starttype #u endtype #u | vowel starttype #u endtype #u | ||||
length 190 | length 190 | ||||
FMT(vdiph2/uw) | |||||
FMT(vdiph2/uw_6) | |||||
endphoneme | endphoneme | ||||
} // end f LookupThousands | } // end f LookupThousands | ||||
static int LookupNum2(Translator *tr, int value, int control, char *ph_out) | |||||
{//======================================================================== | |||||
static int LookupNum2(Translator *tr, int value, const int control, char *ph_out) | |||||
{//============================================================================= | |||||
// Lookup a 2 digit number | // Lookup a 2 digit number | ||||
// control bit 0: ordinal number | // control bit 0: ordinal number | ||||
// control bit 1: final tens and units (not number of thousands) (use special form of '1', LANG=de "eins") | // control bit 1: final tens and units (not number of thousands) (use special form of '1', LANG=de "eins") | ||||
int ix; | int ix; | ||||
int units; | int units; | ||||
int tens; | int tens; | ||||
int is_ordinal; | |||||
int used_and=0; | int used_and=0; | ||||
int found_ordinal = 0; | int found_ordinal = 0; | ||||
int next_phtype; | int next_phtype; | ||||
ord_type = 'q'; | ord_type = 'q'; | ||||
} | } | ||||
is_ordinal = control & 1; | |||||
if((control & 2) && (n_digit_lookup == 2)) | if((control & 2) && (n_digit_lookup == 2)) | ||||
{ | { | ||||
// pronunciation of the final 2 digits has already been found | // pronunciation of the final 2 digits has already been found | ||||
// is there a special pronunciation for this 2-digit number | // is there a special pronunciation for this 2-digit number | ||||
if(control & 8) | if(control & 8) | ||||
{ | { | ||||
// is there a feminine form? | |||||
sprintf(string,"_%df",value); | sprintf(string,"_%df",value); | ||||
found = Lookup(tr, string, ph_digits); | found = Lookup(tr, string, ph_digits); | ||||
} | } | ||||
else | else | ||||
if(control & 1) | |||||
if(is_ordinal) | |||||
{ | { | ||||
strcpy(ph_ordinal, ph_ordinal2); | strcpy(ph_ordinal, ph_ordinal2); | ||||
if(!found) | if(!found) | ||||
{ | { | ||||
sprintf(string,"_%d",value); | |||||
found = Lookup(tr, string, ph_digits); | |||||
if((is_ordinal) && (tr->langopts.numbers2 & NUM2_NO_TEEN_ORDINALS)) | |||||
{ | |||||
// don't use numbers 10-99 to make ordinals, always use _1Xo etc (lang=pt) | |||||
} | |||||
else | |||||
{ | |||||
sprintf(string,"_%d",value); | |||||
found = Lookup(tr, string, ph_digits); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
if((control & 1) && | |||||
if((is_ordinal) && | |||||
((units == 0) || (tr->langopts.numbers & NUM_SWAP_TENS) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL))) | ((units == 0) || (tr->langopts.numbers & NUM_SWAP_TENS) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL))) | ||||
{ | { | ||||
sprintf(string,"_%dX%c", tens, ord_type); | sprintf(string,"_%dX%c", tens, ord_type); | ||||
sprintf(string,"_%df",units); | sprintf(string,"_%df",units); | ||||
found = Lookup(tr, string, ph_digits); | found = Lookup(tr, string, ph_digits); | ||||
} | } | ||||
if((control & 1) && ((tr->langopts.numbers & NUM_SWAP_TENS) == 0)) | |||||
if((is_ordinal) && ((tr->langopts.numbers & NUM_SWAP_TENS) == 0)) | |||||
{ | { | ||||
// ordinal | // ordinal | ||||
sprintf(string,"_%d%c",units,ord_type); | sprintf(string,"_%d%c",units,ord_type); | ||||
} | } | ||||
} | } | ||||
if((control & 1) && (found_ordinal == 0) && (ph_ordinal[0] == 0)) | |||||
if((is_ordinal) && (found_ordinal == 0) && (ph_ordinal[0] == 0)) | |||||
{ | { | ||||
if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & NUM_SWAP_TENS))) | if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & NUM_SWAP_TENS))) | ||||
Lookup(tr, "_ord20", ph_ordinal); | Lookup(tr, "_ord20", ph_ordinal); | ||||
{ | { | ||||
Lookup(tr, "_0and", ph_and); | Lookup(tr, "_0and", ph_and); | ||||
if((control & 1) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) | |||||
if((is_ordinal) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) | |||||
ph_and[0] = 0; | ph_and[0] = 0; | ||||
if(tr->langopts.numbers & NUM_SWAP_TENS) | if(tr->langopts.numbers & NUM_SWAP_TENS) | ||||
int ix; | int ix; | ||||
int exact; | int exact; | ||||
int ordinal; | int ordinal; | ||||
int tplex; | |||||
int say_zero_hundred=0; | int say_zero_hundred=0; | ||||
char string[12]; // for looking up entries in **_list | char string[12]; // for looking up entries in **_list | ||||
char buf1[100]; | char buf1[100]; | ||||
if ((value % 1000) == 0) | if ((value % 1000) == 0) | ||||
exact = 1; | exact = 1; | ||||
if(LookupThousands(tr, hundreds / 10, thousandplex+1, exact | ordinal, ph_10T) == 0) | |||||
tplex = thousandplex+1; | |||||
if(tr->langopts.numbers2 & NUM2_MYRIADS) | |||||
{ | |||||
tplex = 0; | |||||
} | |||||
if(LookupThousands(tr, hundreds / 10, tplex, exact | ordinal, ph_10T) == 0) | |||||
{ | { | ||||
x = 0; | x = 0; | ||||
if(tr->langopts.numbers2 & (1 << (thousandplex+1))) | |||||
if(tr->langopts.numbers2 & (1 << tplex)) | |||||
x = 8; // use variant (feminine) for before thousands and millions | x = 8; // use variant (feminine) for before thousands and millions | ||||
LookupNum2(tr, hundreds/10, x, ph_digits); | LookupNum2(tr, hundreds/10, x, ph_digits); | ||||
} | } | ||||
} // end of LookupNum3 | } // end of LookupNum3 | ||||
bool CheckThousandsGroup(char *word, int group_len) | |||||
{//================================================ | |||||
// Is this a group of 3 digits which looks like a thousands group? | |||||
int ix; | |||||
if(isdigit(word[group_len]) || isdigit(-1)) | |||||
return(false); | |||||
for(ix=0; ix < group_len; ix++) | |||||
{ | |||||
if(!isdigit(word[ix])) | |||||
return(false); | |||||
} | |||||
return(true); | |||||
} | |||||
static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, WORD_TAB *wtab, int control) | static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, WORD_TAB *wtab, int control) | ||||
{//===================================================================================================================== | {//===================================================================================================================== | ||||
// Number translation with various options | // Number translation with various options | ||||
int decimal_mode; | int decimal_mode; | ||||
int suffix_ix; | int suffix_ix; | ||||
int skipwords = 0; | int skipwords = 0; | ||||
int group_len; | |||||
char *p; | char *p; | ||||
char string[32]; // for looking up entries in **_list | char string[32]; // for looking up entries in **_list | ||||
char buf1[100]; | char buf1[100]; | ||||
n_digits = ix; | n_digits = ix; | ||||
value = this_value = atoi(word); | value = this_value = atoi(word); | ||||
group_len = 3; | |||||
if(tr->langopts.numbers2 & NUM2_MYRIADS) | |||||
group_len = 4; | |||||
// is there a previous thousands part (as a previous "word") ? | // is there a previous thousands part (as a previous "word") ? | ||||
if((n_digits == 3) && (word[-2] == tr->langopts.thousands_sep) && isdigit(word[-3])) | |||||
if((n_digits == group_len) && (word[-2] == tr->langopts.thousands_sep) && isdigit(word[-3])) | |||||
{ | { | ||||
prev_thousands = 1; | prev_thousands = 1; | ||||
} | } | ||||
// a "thousand"/"million" suffix to this one | // a "thousand"/"million" suffix to this one | ||||
digix = n_digits + thousands_inc; | digix = n_digits + thousands_inc; | ||||
while(((wtab[thousandplex+1].flags & FLAG_MULTIPLE_SPACES) == 0) && | |||||
isdigit(word[digix]) && isdigit(word[digix+1]) && isdigit(word[digix+2]) && !isdigit(word[digix+3]) && !isdigit(word[digix-1])) | |||||
while(((wtab[thousandplex+1].flags & FLAG_MULTIPLE_SPACES) == 0) && CheckThousandsGroup(&word[digix], group_len)) | |||||
{ | { | ||||
if((word[digix] != '0') || (word[digix+1] != '0') || (word[digix+2] != '0')) | |||||
thousands_exact = 0; | |||||
for(ix=0; ix<group_len; ix++) | |||||
{ | |||||
if(word[digix+ix] != '0') | |||||
{ | |||||
thousands_exact = 0; | |||||
break; | |||||
} | |||||
} | |||||
thousandplex++; | thousandplex++; | ||||
digix += 3; | |||||
digix += group_len; | |||||
if((word[digix] == tr->langopts.thousands_sep) || ((tr->langopts.numbers & NUM_ALLOW_SPACE) && (word[digix] == ' '))) | if((word[digix] == tr->langopts.thousands_sep) || ((tr->langopts.numbers & NUM_ALLOW_SPACE) && (word[digix] == ' '))) | ||||
{ | { | ||||
suffix_ix = digix+2; | suffix_ix = digix+2; | ||||
{ | { | ||||
if(thousands_inc > 0) | if(thousands_inc > 0) | ||||
{ | { | ||||
if((thousandplex > 0) && (value < 1000)) | |||||
if(thousandplex > 0) | |||||
// if((thousandplex > 0) && (value < 1000)) | |||||
{ | { | ||||
if((suppress_null == 0) && (LookupThousands(tr,value,thousandplex, thousands_exact, ph_append))) | if((suppress_null == 0) && (LookupThousands(tr,value,thousandplex, thousands_exact, ph_append))) | ||||
{ | { |
} // end of SwitchVowelType | } // end of SwitchVowelType | ||||
static int NumInstnWords(USHORT *prog) | |||||
{//=================================== | |||||
int NumInstnWords(USHORT *prog) | |||||
{//============================ | |||||
int instn; | int instn; | ||||
int instn2; | int instn2; | ||||
int instn_type; | int instn_type; | ||||
int n; | int n; | ||||
static const char n_words[16] = {1,1,0,0,1,1,1,1,1,2,4,0,0,0,0,0}; | |||||
int type2; | |||||
static const char n_words[16] = {0,1,0,0,1,1,0,1,1,2,4,0,0,0,0,0}; | |||||
instn = *prog; | instn = *prog; | ||||
instn_type = instn >> 12; | instn_type = instn >> 12; | ||||
if((n = n_words[instn_type]) > 0) | if((n = n_words[instn_type]) > 0) | ||||
return(n); | return(n); | ||||
if(instn_type < 4) | |||||
switch(instn_type) | |||||
{ | { | ||||
case 0: | |||||
if(((instn & 0xf00) >> 8) == i_IPA_NAME) | |||||
{ | |||||
n = ((instn & 0xff) + 1) / 2; | |||||
return(n+1); | |||||
} | |||||
return(1);; | |||||
case 6: | |||||
type2 = (instn & 0xf00) >> 9; | |||||
if((type2 == 5) || (type2 == 6)) | |||||
return(12); // switch on vowel type | |||||
return(1); | |||||
case 2: | |||||
case 3: | |||||
// a condition, check for a 2-word instruction | // a condition, check for a 2-word instruction | ||||
if(((n = instn & 0x0f00) == 0x600) || (n == 0x0d00)) | if(((n = instn & 0x0f00) == 0x600) || (n == 0x0d00)) | ||||
return(2); | return(2); | ||||
return(1); | return(1); | ||||
} | |||||
// instn_type 11 to 15, 2 words | |||||
instn2 = prog[2]; | |||||
if((instn2 >> 12) == 0xf) | |||||
{ | |||||
// This instruction is followed by addWav(), 2 more words | |||||
return(4); | |||||
} | |||||
if(instn2 == i_CONTINUE) | |||||
{ | |||||
return(3); | |||||
default: | |||||
// instn_type 11 to 15, 2 words | |||||
instn2 = prog[2]; | |||||
if((instn2 >> 12) == 0xf) | |||||
{ | |||||
// This instruction is followed by addWav(), 2 more words | |||||
return(4); | |||||
} | |||||
if(instn2 == i_CONTINUE) | |||||
{ | |||||
return(3); | |||||
} | |||||
return(2); | |||||
} | } | ||||
return(2); | |||||
} // end of NumInstnWords | } // end of NumInstnWords | ||||
int PauseLength(int pause, int control); | int PauseLength(int pause, int control); | ||||
int LookupPhonemeTable(const char *name); | int LookupPhonemeTable(const char *name); | ||||
unsigned char *GetEnvelope(int index); | unsigned char *GetEnvelope(int index); | ||||
int NumInstnWords(USHORT *prog); | |||||
void InitBreath(void); | void InitBreath(void); | ||||
tr->langopts.stress_rule = 8; // ?? 1st syllable if it is heavy, else 2nd syllable | tr->langopts.stress_rule = 8; // ?? 1st syllable if it is heavy, else 2nd syllable | ||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words | tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words | ||||
tr->langopts.numbers = NUM_OMIT_1_HUNDRED; | tr->langopts.numbers = NUM_OMIT_1_HUNDRED; | ||||
tr->langopts.break_numbers = 0x9999998; | |||||
tr->langopts.numbers2 = NUM2_MYRIADS; | |||||
tr->langopts.break_numbers = 0x1111110; | |||||
tr->langopts.max_digits = 20; | tr->langopts.max_digits = 20; | ||||
} | } | ||||
break; | break; | ||||
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable | tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable | ||||
tr->langopts.stress_flags = 0x6 | 0x10 | 0x2000 | 0x20000; | tr->langopts.stress_flags = 0x6 | 0x10 | 0x2000 | 0x20000; | ||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_DFRACTION_2 | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_ROMAN; | tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_DFRACTION_2 | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_ROMAN; | ||||
tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL; | |||||
tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL | NUM2_NO_TEEN_ORDINALS; | |||||
SetLetterVowel(tr,'y'); | SetLetterVowel(tr,'y'); | ||||
ResetLetterBits(tr,0x2); | ResetLetterBits(tr,0x2); | ||||
SetLetterBits(tr,1,"bcdfgjkmnpqstvxz"); // B hard consonants, excluding h,l,r,w,y | SetLetterBits(tr,1,"bcdfgjkmnpqstvxz"); // B hard consonants, excluding h,l,r,w,y |
int numbers; | int numbers; | ||||
#define NUM2_MULTIPLE_ORDINAL 0x1000 | #define NUM2_MULTIPLE_ORDINAL 0x1000 | ||||
#define NUM2_ENGLISH_NUMERALS 0x2000 | |||||
#define NUM2_NO_TEEN_ORDINALS 0x2000 | |||||
#define NUM2_MYRIADS 0x4000 | |||||
#define NUM2_ENGLISH_NUMERALS 0x8000 | |||||
#define NUM2_THOUSANDS_VAR1 0x40 | #define NUM2_THOUSANDS_VAR1 0x40 | ||||
#define NUM2_THOUSANDS_VAR2 0x80 | #define NUM2_THOUSANDS_VAR2 0x80 | ||||
#define NUM2_THOUSANDS_VAR3 0xc0 | #define NUM2_THOUSANDS_VAR3 0xc0 | ||||
// bits 6-8 use different forms of thousand, million, etc (M MA MB) | // bits 6-8 use different forms of thousand, million, etc (M MA MB) | ||||
// bit9=(LANG=rw) say "thousand" and "million" before its number, not after | // bit9=(LANG=rw) say "thousand" and "million" before its number, not after | ||||
// bit12=(LANG=el,es) use ordinal form of hundreds and tens as well as units | // bit12=(LANG=el,es) use ordinal form of hundreds and tens as well as units | ||||
// bit13=(LANG=ne) speak (non-replaced) English numerals in English | |||||
// bit13=(LANG=pt) don't use 11-19 numbers to make ordinals | |||||
// bit14=(LANG=ko) use myriads (groups of 4 digits) not thousands (groups of 3) | |||||
// bit15=(LANG=ne) speak (non-replaced) English numerals in English | |||||
int numbers2; | int numbers2; | ||||
#define BREAK_THOUSANDS 0x49249248 | #define BREAK_THOUSANDS 0x49249248 |
prog_end = prog_start + length; | prog_end = prog_start + length; | ||||
n_vowelfmt_addr = 0; | n_vowelfmt_addr = 0; | ||||
for(prog = &phoneme_index[prog_start]; prog < &phoneme_index[prog_end]; prog++) | |||||
for(prog = &phoneme_index[prog_start]; prog < &phoneme_index[prog_end]; prog += NumInstnWords(prog)) | |||||
{ | { | ||||
instn = *prog; | instn = *prog; | ||||
switch(instn >> 12) | |||||
if((instn >> 12) == 11) | |||||
{ | { | ||||
case 2: | |||||
case 3: | |||||
// conditions | |||||
while((instn & 0xe000) == 0x2000) | |||||
{ | |||||
instn = *(++prog); | |||||
} | |||||
prog--; | |||||
break; | |||||
case 10: // Vowelin, Vowelout | |||||
prog += 3; | |||||
break; | |||||
case 9: | |||||
case 12: // WAV | |||||
case 13: // VowelStart | |||||
case 14: // VowelEnd | |||||
case 15: // addWav | |||||
prog++; | |||||
break; | |||||
case 11: // FMT | |||||
// FMT instruction | |||||
if(n_vowelfmt_addr < N_VOWELFMT_ADDR) | if(n_vowelfmt_addr < N_VOWELFMT_ADDR) | ||||
{ | { | ||||
vowelfmt_addr[n_vowelfmt_addr++] = ((instn & 0xf) << 18) + (prog[1] << 2); | vowelfmt_addr[n_vowelfmt_addr++] = ((instn & 0xf) << 18) + (prog[1] << 2); | ||||
} | } | ||||
prog++; | |||||
break; | |||||
} | } | ||||
} | } | ||||
} // end of FindVowelFmt | } // end of FindVowelFmt |