mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-12 00:46:50 +00:00
[1.42.03 release]
Allow .txt release for *_rules and *_list files. Rules lookup, consider multi-byte characters when calculating matchign points. Fix bug in Roman Number translation. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@232 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+18
-3
@@ -2085,6 +2085,7 @@ wxString CompileAllDictionaries()
|
||||
wxString filename;
|
||||
wxFileName fname;
|
||||
wxString dictstr;
|
||||
wxString filetype;
|
||||
wxString report = _T("");
|
||||
int err;
|
||||
int errors = 0;
|
||||
@@ -2135,18 +2136,32 @@ wxString CompileAllDictionaries()
|
||||
fprintf(f_phused,"Phonemes which are used in the *_rules and *_list files\n");
|
||||
}
|
||||
|
||||
bool cont = dir.GetFirst(&filename, _T("*_rules"), wxDIR_FILES);
|
||||
bool cont = dir.GetFirst(&filename, _T("*_rules*"), wxDIR_FILES);
|
||||
while ( cont )
|
||||
{
|
||||
fname = wxFileName(filename);
|
||||
filetype = fname.GetName().AfterLast('_');
|
||||
if((filetype != _T("rules")) && (filetype != _T("rules.txt")))
|
||||
{
|
||||
cont = dir.GetNext(&filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
dictstr = fname.GetName().BeforeLast('_');
|
||||
strcpy(dictname,dictstr.mb_str(wxConvLocal));
|
||||
|
||||
dict_count++;
|
||||
strcpy(voicename,dictname);
|
||||
|
||||
// read the *_rules file to see if a phoneme table is specified though a voice name
|
||||
sprintf(path,"%s%s_rules",path_dsource,dictname);
|
||||
if((f_in = fopen(path,"r")) != NULL)
|
||||
sprintf(path,"%s%s_rules.txt",path_dsource,dictname);
|
||||
if((f_in = fopen(path,"r")) == NULL)
|
||||
{
|
||||
sprintf(path,"%s%s_rules",path_dsource,dictname);
|
||||
f_in = fopen(path,"r");
|
||||
}
|
||||
|
||||
if(f_in != NULL)
|
||||
{
|
||||
unsigned int ix;
|
||||
unsigned int c;
|
||||
|
||||
+20
-8
@@ -690,9 +690,14 @@ static int compile_dictlist_file(const char *path, const char* filename)
|
||||
|
||||
text_mode = 0;
|
||||
|
||||
sprintf(fname,"%s%s",path,filename);
|
||||
// try with and without '.txt' extension
|
||||
sprintf(fname,"%s%s.txt",path,filename);
|
||||
if((f_in = fopen(fname,"r")) == NULL)
|
||||
return(-1);
|
||||
{
|
||||
sprintf(fname,"%s%s",path,filename);
|
||||
if((f_in = fopen(fname,"r")) == NULL)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
fprintf(f_log,"Compiling: '%s'\n",fname);
|
||||
|
||||
@@ -860,6 +865,9 @@ static void copy_rule_string(char *string, int &state)
|
||||
case 'X':
|
||||
c = RULE_NOVOWELS;
|
||||
break;
|
||||
case 'J':
|
||||
c = RULE_SKIPCHARS;
|
||||
break;
|
||||
case 'L':
|
||||
// expect two digits
|
||||
c = *p++ - '0';
|
||||
@@ -1659,14 +1667,18 @@ int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, cha
|
||||
if(f_log == NULL)
|
||||
f_log = stderr;
|
||||
|
||||
// try with and without '.txt' extension
|
||||
sprintf(path,"%s%s_",dsource,dict_name);
|
||||
sprintf(fname_in,"%srules",path);
|
||||
f_in = fopen_log(fname_in,"r");
|
||||
if(f_in == NULL)
|
||||
sprintf(fname_in,"%srules.txt",path);
|
||||
if((f_in = fopen(fname_in,"r")) == NULL)
|
||||
{
|
||||
if(fname_err)
|
||||
strcpy(fname_err,fname_in);
|
||||
return(-1);
|
||||
sprintf(fname_in,"%srules",path);
|
||||
if((f_in = fopen_log(fname_in,"r")) == NULL)
|
||||
{
|
||||
if(fname_err)
|
||||
strcpy(fname_err,fname_in);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(fname_out,"%s%c%s_dict",path_home,PATHSEP,dict_name);
|
||||
|
||||
+35
-6
@@ -1648,7 +1648,7 @@ static char *DecodeRule(const char *group_chars, int group_length, char *rule)
|
||||
static char output[60];
|
||||
|
||||
static char symbols[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',
|
||||
'@','&','%','+','#','S','D','Z','A','L',' ',' ',' ',' ',' ','N','K','V',' ','T','X','?','W'};
|
||||
'@','&','%','+','#','S','D','Z','A','L','!',' ','?','?','J','N','K','V','?','T','X','?','W'};
|
||||
|
||||
static char symbols_lg[] = {'A','B','C','H','F','G','Y'};
|
||||
|
||||
@@ -1998,7 +1998,8 @@ static void MatchRule(Translator *tr, char *word[], int group_length, char *rule
|
||||
|
||||
if((letter == rb) || ((letter==(unsigned char)REPLACED_E) && (rb=='e')))
|
||||
{
|
||||
add_points = 21;
|
||||
if((letter & 0xc0) != 0x80)
|
||||
add_points = 21; // don't add point for non-initial UTF-8 bytes
|
||||
consumed++;
|
||||
}
|
||||
else
|
||||
@@ -2148,6 +2149,27 @@ static void MatchRule(Translator *tr, char *word[], int group_length, char *rule
|
||||
}
|
||||
break;
|
||||
|
||||
case RULE_SKIPCHARS:
|
||||
{
|
||||
// Used for lang=Tamil, used to match on the next word after an unknown word ending
|
||||
// only look until the end of the word (including the end-of-word marker)
|
||||
// Jx means 'skip characters until x', where 'x' may be '_' for 'end of word'
|
||||
char *p = post_ptr + letter_xbytes;
|
||||
char *p2 = p;
|
||||
int rule_w; // skip characters until this
|
||||
utf8_in(&rule_w,rule);
|
||||
while((letter_w != rule_w) && (letter_w != RULE_SPACE))
|
||||
{
|
||||
p2 = p;
|
||||
p += utf8_in(&letter_w,p);
|
||||
}
|
||||
if(letter_w == rule_w)
|
||||
{
|
||||
post_ptr = p2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RULE_INC_SCORE:
|
||||
add_points = 20; // force an increase in points
|
||||
break;
|
||||
@@ -2180,10 +2202,11 @@ static void MatchRule(Translator *tr, char *word[], int group_length, char *rule
|
||||
default:
|
||||
if(letter == rb)
|
||||
{
|
||||
if(letter == RULE_SPACE)
|
||||
add_points = (21-distance_right);
|
||||
else
|
||||
if((letter & 0xc0) != 0x80)
|
||||
{
|
||||
// not for non-initial UTF-8 bytes
|
||||
add_points = (21-distance_right);
|
||||
}
|
||||
}
|
||||
else
|
||||
failed = 1;
|
||||
@@ -2348,7 +2371,13 @@ static void MatchRule(Translator *tr, char *word[], int group_length, char *rule
|
||||
if(letter == RULE_SPACE)
|
||||
add_points = 4;
|
||||
else
|
||||
add_points = (21-distance_left);
|
||||
{
|
||||
if((letter & 0xc0) != 0x80)
|
||||
{
|
||||
// not for non-initial UTF-8 bytes
|
||||
add_points = (21-distance_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
failed = 1;
|
||||
|
||||
+10
-5
@@ -1344,14 +1344,19 @@ void FormatDictionary(const char *dictname)
|
||||
const int tab2 = 18;
|
||||
const int tab3 = 28;
|
||||
|
||||
sprintf(fname_in,"%s/%s_rules",path_dsource,dictname);
|
||||
sprintf(fname_out,"%s_formatted",fname_in);
|
||||
|
||||
// try with and without '.txt' extension
|
||||
sprintf(fname_in,"%s/%s_rules.txt",path_dsource,dictname);
|
||||
if((f_in = fopen(fname_in,"r")) == NULL)
|
||||
{
|
||||
wxLogError(_T("Can't open rules file: ") + wxString(fname_in,wxConvLocal));
|
||||
return;
|
||||
sprintf(fname_in,"%s/%s_rules",path_dsource,dictname);
|
||||
if((f_in = fopen(fname_in,"r")) == NULL)
|
||||
{
|
||||
wxLogError(_T("Can't open rules file: ") + wxString(fname_in,wxConvLocal));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(fname_out,"%s/%s_rules_formatted",path_dsource,dictname);
|
||||
if((f_out = fopen(fname_out,"w")) == NULL)
|
||||
{
|
||||
wxLogError(_T("Can't write to file: ") + wxString(fname_out,wxConvLocal));
|
||||
|
||||
@@ -813,6 +813,8 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
|
||||
prev = 0;
|
||||
subtract = 0x7fff;
|
||||
ph_out[0] = 0;
|
||||
flags[0] = 0;
|
||||
flags[1] = 0;
|
||||
|
||||
if((tr->langopts.numbers & NUM_ROMAN_CAPITALS) && !(wtab[0].flags & FLAG_ALL_UPPER))
|
||||
return(0);
|
||||
|
||||
+9
-5
@@ -92,6 +92,9 @@ static const unsigned short punct_chars[] = {',','.','?','!',':',';',
|
||||
0x055e, // Armenian question
|
||||
0x055b, // Armenian emphasis mark
|
||||
|
||||
0x0b1b, // Arabic ;
|
||||
0x061f, // Arabic ?
|
||||
|
||||
0x1362, // Ethiopic period
|
||||
0x1363,
|
||||
0x1364,
|
||||
@@ -131,6 +134,9 @@ static const unsigned int punct_attributes [] = { 0,
|
||||
CLAUSE_QUESTION + PUNCT_IN_WORD, // Armenian question
|
||||
CLAUSE_PERIOD + PUNCT_IN_WORD, // Armenian emphasis mark
|
||||
|
||||
CLAUSE_SEMICOLON, // Arabic ;
|
||||
CLAUSE_QUESTION, // Arabic question mark
|
||||
|
||||
CLAUSE_PERIOD, // Ethiopic period
|
||||
CLAUSE_COMMA, // Ethiopic comma
|
||||
CLAUSE_SEMICOLON, // Ethiopic semicolon
|
||||
@@ -570,6 +576,7 @@ static const char *LookupSpecial(Translator *tr, const char *string, char* text_
|
||||
char phonemes2[55];
|
||||
char *string1 = (char *)string;
|
||||
|
||||
flags[0] = flags[1] = 0;
|
||||
if(LookupDictList(tr,&string1,phonemes,flags,0,NULL))
|
||||
{
|
||||
SetWordStress(tr, phonemes, flags, -1, 0);
|
||||
@@ -2406,14 +2413,11 @@ if(option_ssml) parag=1;
|
||||
// Because of an xml tag, we are waiting for the
|
||||
// next non-blank character to decide whether to end the clause
|
||||
// i.e. is dot followed by an upper-case letter?
|
||||
if(c1 == '\n')
|
||||
{
|
||||
// end_clause_after_tag &= ~CLAUSE_DOT;
|
||||
}
|
||||
|
||||
if(!iswspace(c1))
|
||||
{
|
||||
if(iswdigit(c1) || (IsAlpha(c1) && !iswlower(c1)))
|
||||
if(!IsAlpha(c1) || !iswlower(c1))
|
||||
// if(iswdigit(c1) || (IsAlpha(c1) && !iswlower(c1)))
|
||||
{
|
||||
UngetC(c2);
|
||||
ungot_char2 = c1;
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.42.02 30.Nov.09";
|
||||
const char *version_string = "1.42.03 08.Dec.09";
|
||||
const int version_phdata = 0x014200;
|
||||
|
||||
int option_device_number = -1;
|
||||
|
||||
@@ -279,7 +279,6 @@ Translator *SelectTranslator(const char *name)
|
||||
break;
|
||||
|
||||
case L('a','r'): // Arabic
|
||||
case L('u','r'): // Urdu
|
||||
tr->letter_bits_offset = OFFSET_ARABIC;
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
break;
|
||||
@@ -538,7 +537,7 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->langopts.stress_rule = 6; // stress on last heaviest syllable, excluding final syllable
|
||||
tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable
|
||||
tr->langopts.numbers = NUM_SWAP_TENS;
|
||||
tr->langopts.break_numbers = 0x24924aa8; // for languages which have numbers for 100,000 and 100,00,000, eg Hindi
|
||||
tr->langopts.break_numbers = 0x14aa8; // for languages which have numbers for 100,000 and 100,00,000, eg Hindi
|
||||
tr->letter_bits_offset = OFFSET_DEVANAGARI;
|
||||
|
||||
if(name2 == L('p','a'))
|
||||
@@ -1034,6 +1033,13 @@ SetLengthMods(tr,3); // all equal
|
||||
}
|
||||
break;
|
||||
|
||||
case L('u','r'): // Urdu
|
||||
tr->letter_bits_offset = OFFSET_ARABIC;
|
||||
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
|
||||
tr->langopts.numbers = NUM_SWAP_TENS;
|
||||
tr->langopts.break_numbers = 0x52a8; // for languages which have numbers for 100,000 and 100,00,000, eg Hindi
|
||||
break;
|
||||
|
||||
case L('v','i'): // Vietnamese
|
||||
{
|
||||
static const short stress_lengths_vi[8] = {150, 150, 180, 180, 210, 230, 230, 240};
|
||||
|
||||
+8
-7
@@ -135,18 +135,19 @@
|
||||
#define RULE_LINENUM 8 // next 2 bytes give a line number, for debugging purposes
|
||||
|
||||
#define RULE_SPACE 32 // ascii space
|
||||
#define RULE_SYLLABLE 9
|
||||
#define RULE_STRESSED 10
|
||||
#define RULE_DOUBLE 11
|
||||
#define RULE_INC_SCORE 12
|
||||
#define RULE_DEL_FWD 13
|
||||
#define RULE_ENDING 14
|
||||
#define RULE_SYLLABLE 9 // @
|
||||
#define RULE_STRESSED 10 // &
|
||||
#define RULE_DOUBLE 11 // %
|
||||
#define RULE_INC_SCORE 12 // +
|
||||
#define RULE_DEL_FWD 13 // #
|
||||
#define RULE_ENDING 14 // S
|
||||
#define RULE_DIGIT 15 // D digit
|
||||
#define RULE_NONALPHA 16 // Z non-alpha
|
||||
#define RULE_LETTERGP 17 // A B C H F G Y letter group number
|
||||
#define RULE_LETTERGP2 18 // L + letter group number
|
||||
#define RULE_CAPITAL 19 // word starts with a capital letter
|
||||
#define RULE_CAPITAL 19 // ! word starts with a capital letter
|
||||
#define RULE_REPLACEMENTS 20 // section for character replacements
|
||||
#define RULE_SKIPCHARS 23 // J
|
||||
#define RULE_NO_SUFFIX 24 // N
|
||||
#define RULE_NOTVOWEL 25 // K
|
||||
#define RULE_IFVERB 26 // V
|
||||
|
||||
Reference in New Issue
Block a user