mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-05 14:47:26 +00:00
[1.43.02 release]
Language improvements include Danish rules.
Fixed phoneme [n^] for Klatt synthesizer, was producing noise burst.
espeakedit: Display error details after Compile Dictionary.
espeakedit: Fix: After speaking a word which changes language, Compile
Dictionary may compile the wrong dictionary.
Don't consider multiple spaces as thousands separator (eg. 2 000 )
Lang=Hungarian, don't allow dot as thousands separator.
Lang-Hungarian, Fix suffixes -a, -e, -az, -ez, -azt, -ezt after numbers.
git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@239 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+1
-1
@@ -3156,7 +3156,7 @@ fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references
|
||||
report.Printf(_T("Compiled phonemes: %d errors."),error_count);
|
||||
if(error_count > 0)
|
||||
{
|
||||
report += _T(" See file: 'error_log'.");
|
||||
report += _T(" See file: 'phsource/error_log'.");
|
||||
wxLogError(report);
|
||||
}
|
||||
wxLogStatus(report + report_dict);
|
||||
|
||||
@@ -1007,6 +1007,11 @@ static char *compile_rule(char *input)
|
||||
copy_rule_string(buf,state);
|
||||
state = 3;
|
||||
p = buf;
|
||||
if(input[ix+1] == ' ')
|
||||
{
|
||||
fprintf(f_log,"%5d: Syntax error. Space after (\n",linenum);
|
||||
error_count++;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n': // end of line
|
||||
|
||||
@@ -590,7 +590,36 @@ void MyFrame::OnTools(wxCommandEvent& event)
|
||||
wxLogStatus(_T("Compiled '")+wxString(dictionary_name,wxConvLocal)+_T("', %d errors"),err);
|
||||
|
||||
if(log != NULL)
|
||||
{
|
||||
fclose(log);
|
||||
|
||||
if(err > 0)
|
||||
{
|
||||
// display the error messages
|
||||
int len;
|
||||
FILE *f;
|
||||
char *msg;
|
||||
wxString msg_string;
|
||||
|
||||
len = GetFileLength(fname_log);
|
||||
if(len > 0)
|
||||
{
|
||||
if(len > 2000)
|
||||
len = 2000; // restrict length to pppppevent crash in wxLogMessage()
|
||||
msg = (char *)malloc(len+1);
|
||||
if(msg != NULL)
|
||||
{
|
||||
f = fopen(fname_log,"r");
|
||||
fread(msg,len,1,f);
|
||||
fclose(f);
|
||||
msg[len] = 0;
|
||||
msg_string = wxString(msg,wxConvUTF8);
|
||||
wxLogMessage(msg_string);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_FORMAT_DICTIONARY:
|
||||
|
||||
+49
-36
@@ -758,26 +758,26 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
|
||||
static char ph_ordinal2[12];
|
||||
|
||||
|
||||
static int CheckDotOrdinal(Translator *tr, char *word, WORD_TAB *wtab, int roman)
|
||||
{//==============================================================================
|
||||
static int CheckDotOrdinal(Translator *tr, char *word, char *word_end, WORD_TAB *wtab, int roman)
|
||||
{//==============================================================================================
|
||||
|
||||
int ordinal = 0;
|
||||
int c2;
|
||||
int nextflags;
|
||||
|
||||
if((tr->langopts.numbers & NUM_ORDINAL_DOT) && ((word[0] == '.') || (wtab[0].flags & FLAG_HAS_DOT)) && !(wtab[1].flags & FLAG_NOSPACE))
|
||||
if((tr->langopts.numbers & NUM_ORDINAL_DOT) && ((word_end[0] == '.') || (wtab[0].flags & FLAG_HAS_DOT)) && !(wtab[1].flags & FLAG_NOSPACE))
|
||||
{
|
||||
if(roman || !(wtab[1].flags & FLAG_FIRST_UPPER))
|
||||
{
|
||||
utf8_in(&c2, &word[2]);
|
||||
if((word[1] != 0) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || IsAlpha(c2)))
|
||||
utf8_in(&c2, &word_end[2]);
|
||||
if((word_end[1] != 0) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || IsAlpha(c2)))
|
||||
{
|
||||
// ordinal number is indicated by dot after the number
|
||||
// but not if the next word starts with an upper-case letter
|
||||
// (c2 == 0) is for cases such as, "2.,"
|
||||
ordinal = 2;
|
||||
if(word[0] == '.')
|
||||
word[0] = ' ';
|
||||
if(word_end[0] == '.')
|
||||
word_end[0] = ' ';
|
||||
|
||||
if((roman==0) && (tr->translator_name == L('h','u')))
|
||||
{
|
||||
@@ -785,7 +785,7 @@ static int CheckDotOrdinal(Translator *tr, char *word, WORD_TAB *wtab, int roman
|
||||
nextflags = 0;
|
||||
if(IsAlpha(c2))
|
||||
{
|
||||
nextflags = TranslateWord(tr, &word[2], 0, NULL);
|
||||
nextflags = TranslateWord(tr, &word_end[2], 0, NULL);
|
||||
}
|
||||
|
||||
if((tr->prev_dict_flags & FLAG_ALT_TRANS) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || iswdigit(c2)))
|
||||
@@ -793,8 +793,15 @@ if((tr->prev_dict_flags & FLAG_ALT_TRANS) && ((c2 == 0) || (wtab[0].flags & FLAG
|
||||
|
||||
if(nextflags & FLAG_ALT_TRANS)
|
||||
ordinal = 0;
|
||||
if((tr->prev_dict_flags & (FLAG_ALT_TRANS | FLAG_ALT3_TRANS)) && (nextflags & FLAG_ALT3_TRANS))
|
||||
ordinal = 0x22;
|
||||
|
||||
if(nextflags & FLAG_ALT3_TRANS)
|
||||
{
|
||||
if(word[-2] == '-')
|
||||
ordinal = 0; // eg. december 2-5. között
|
||||
|
||||
if(tr->prev_dict_flags & (FLAG_ALT_TRANS | FLAG_ALT3_TRANS))
|
||||
ordinal = 0x22;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -816,6 +823,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
|
||||
int subtract;
|
||||
int repeat = 0;
|
||||
int n_digits = 0;
|
||||
char *word_start;
|
||||
unsigned int flags[2];
|
||||
char ph_roman[30];
|
||||
char number_chars[N_WORD_BYTES];
|
||||
@@ -833,6 +841,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
|
||||
if((tr->langopts.numbers & NUM_ROMAN_CAPITALS) && !(wtab[0].flags & FLAG_ALL_UPPER))
|
||||
return(0);
|
||||
|
||||
word_start = word;
|
||||
while((c = *word++) != ' ')
|
||||
{
|
||||
if((p2 = strchr(roman_numbers,c)) == NULL)
|
||||
@@ -886,7 +895,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
|
||||
|
||||
sprintf(number_chars," %d ",acc);
|
||||
|
||||
if(CheckDotOrdinal(tr, word, wtab, 1))
|
||||
if(CheckDotOrdinal(tr, word_start, word, wtab, 1))
|
||||
wtab[0].flags |= FLAG_ORDINAL;
|
||||
|
||||
if(tr->langopts.numbers & NUM_ROMAN_ORDINAL)
|
||||
@@ -947,31 +956,34 @@ static int LookupThousands(Translator *tr, int value, int thousandplex, int thou
|
||||
ph_of[0] = 0;
|
||||
|
||||
// first look for a match with the exact value of thousands
|
||||
if(thousands_exact & 1)
|
||||
if(value > 0)
|
||||
{
|
||||
if(thousands_exact & 2)
|
||||
if(thousands_exact & 1)
|
||||
{
|
||||
// ordinal number
|
||||
sprintf(string,"_%dM%do",value,thousandplex);
|
||||
if(thousands_exact & 2)
|
||||
{
|
||||
// ordinal number
|
||||
sprintf(string,"_%dM%do",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
if(!found_value & (number_control & 1))
|
||||
{
|
||||
// look for the 'e' variant
|
||||
sprintf(string,"_%dM%de",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
if(!found_value)
|
||||
{
|
||||
// is there a different pronunciation if there are no hundreds,tens,or units ? (LANG=ta)
|
||||
sprintf(string,"_%dM%dx",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
}
|
||||
if(found_value == 0)
|
||||
{
|
||||
sprintf(string,"_%dM%d",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
if(!found_value & (number_control & 1))
|
||||
{
|
||||
// look for the 'e' variant
|
||||
sprintf(string,"_%dM%de",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
if(!found_value)
|
||||
{
|
||||
// is there a different pronunciation if there are no hundreds,tens,or units ? (LANG=ta)
|
||||
sprintf(string,"_%dM%dx",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
}
|
||||
if(found_value == 0)
|
||||
{
|
||||
sprintf(string,"_%dM%d",value,thousandplex);
|
||||
found_value = Lookup(tr, string, ph_thousands);
|
||||
}
|
||||
|
||||
if(found_value == 0)
|
||||
@@ -1504,7 +1516,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
if((tr->langopts.thousands_sep == ' ') || (tr->langopts.numbers & NUM_ALLOW_SPACE))
|
||||
{
|
||||
// thousands groups can be separated by spaces
|
||||
if((n_digits == 3) && isdigit(word[-2]))
|
||||
if((n_digits == 3) && !(wtab->flags & FLAG_MULTIPLE_SPACES) && isdigit(word[-2]))
|
||||
{
|
||||
prev_thousands = 1;
|
||||
}
|
||||
@@ -1520,7 +1532,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
if(prev_thousands || (word[0] != '0'))
|
||||
{
|
||||
// don't check for ordinal if the number has a leading zero
|
||||
ordinal = CheckDotOrdinal(tr, &word[ix], wtab, 0);
|
||||
ordinal = CheckDotOrdinal(tr, word, &word[ix], wtab, 0);
|
||||
}
|
||||
|
||||
if((word[ix] == '.') && !isdigit(word[ix+1]) && !isdigit(word[ix+2]) && !(wtab[1].flags & FLAG_NOSPACE))
|
||||
@@ -1627,8 +1639,9 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
|
||||
|
||||
if(tr->translator_name == L('h','u'))
|
||||
{
|
||||
// variant form of numbers when followed by hyphen and a suffix starting with 'a' or 'e'
|
||||
if((wtab[thousandplex].flags & FLAG_HYPHEN_AFTER) && (thousands_exact==1) && ((word[suffix_ix] == 'a') || (word[suffix_ix] == 'e')))
|
||||
// variant form of numbers when followed by hyphen and a suffix starting with 'a' or 'e' (buit not a, e, az, ez, azt, ezt
|
||||
if((wtab[thousandplex].flags & FLAG_HYPHEN_AFTER) && (thousands_exact==1)
|
||||
&& ((word[suffix_ix] == 'a') || (word[suffix_ix] == 'e')) && ((c = word[suffix_ix+1]) != ' ') && (c != 'z'))
|
||||
{
|
||||
number_control |= 1; // use _1e variant of number
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#include "wave.h"
|
||||
|
||||
unsigned char *outbuf=NULL;
|
||||
extern FILE *f_logespeak;
|
||||
extern espeak_VOICE voice_selected;
|
||||
|
||||
espeak_EVENT *event_list=NULL;
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.43.03 24.Feb.10";
|
||||
const int version_phdata = 0x014220;
|
||||
const char *version_string = "1.43.02 08.Mar.10";
|
||||
const int version_phdata = 0x014300;
|
||||
|
||||
int option_device_number = -1;
|
||||
FILE *f_logespeak = NULL;
|
||||
|
||||
@@ -598,7 +598,9 @@ Translator *SelectTranslator(const char *name)
|
||||
tr->langopts.param[LOPT_ANNOUNCE_PUNCT] = 2; // don't break clause before announcing . ? !
|
||||
tr->langopts.param[LOPT_MIN_LONG_VOWEL] = 65;
|
||||
|
||||
tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_DFRACTION_5 | NUM_ROMAN | NUM_ROMAN_ORDINAL | NUM_ROMAN_CAPITALS | NUM_ORDINAL_DOT | NUM_OMIT_1_HUNDRED;
|
||||
tr->langopts.numbers = NUM_DFRACTION_5 | NUM_ALLOW_SPACE | NUM_ROMAN | NUM_ROMAN_ORDINAL | NUM_ROMAN_CAPITALS | NUM_ORDINAL_DOT | NUM_OMIT_1_HUNDRED;
|
||||
tr->langopts.thousands_sep = ' '; // don't allow dot as thousands separator
|
||||
tr->langopts.decimal_sep = ',';
|
||||
tr->langopts.min_roman = 1;
|
||||
SetLetterVowel(tr,'y');
|
||||
tr->langopts.spelling_stress = 1;
|
||||
|
||||
@@ -1361,6 +1361,18 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
int word_flags;
|
||||
int word_copy_len;
|
||||
char word_copy[N_WORD_BYTES+1];
|
||||
char old_dictionary_name[40];
|
||||
|
||||
if((f_logespeak != NULL) && (logging_type & 8))
|
||||
{
|
||||
fprintf(f_logespeak,"WORD: flg=%.5x len=%d '",wtab->flags,wtab->length);
|
||||
for(ix=0; ix<40; ix++)
|
||||
{
|
||||
if(word[ix]==0) break;
|
||||
fputc(word[ix], f_logespeak);
|
||||
}
|
||||
fprintf(f_logespeak,"'\n");
|
||||
}
|
||||
|
||||
len = wtab->length;
|
||||
if(len > 31) len = 31;
|
||||
@@ -1550,6 +1562,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
if(new_language[0]==0)
|
||||
new_language = "en";
|
||||
|
||||
strcpy(old_dictionary_name, dictionary_name);
|
||||
switch_phonemes = SetTranslator2(new_language);
|
||||
|
||||
if(switch_phonemes >= 0)
|
||||
@@ -1784,6 +1797,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa
|
||||
if(switch_phonemes >= 0)
|
||||
{
|
||||
// this word uses a different phoneme table, now switch back
|
||||
strcpy(dictionary_name, old_dictionary_name);
|
||||
SelectPhonemeTable(voice->phoneme_tab_ix);
|
||||
SetPlist2(&ph_list2[n_ph_list2],phonSWITCH);
|
||||
ph_list2[n_ph_list2++].tone_ph = voice->phoneme_tab_ix; // original phoneme table number
|
||||
@@ -2076,6 +2090,14 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t
|
||||
charix[ix] = 0;
|
||||
terminator = ReadClause(tr, f_text, source, charix, &charix_top, N_TR_SOURCE, &tone2);
|
||||
|
||||
if((f_logespeak != NULL) && (logging_type & 4))
|
||||
{
|
||||
fprintf(f_logespeak,"CLAUSE %x:\n",terminator);
|
||||
for(p=source; *p != 0; p++)
|
||||
fputc(*p, f_logespeak);
|
||||
fprintf(f_logespeak,"ENDCLAUSE\n");
|
||||
}
|
||||
|
||||
charix[charix_top+1] = 0;
|
||||
charix[charix_top+2] = 0x7fff;
|
||||
charix[charix_top+3] = 0;
|
||||
|
||||
@@ -642,3 +642,5 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_
|
||||
void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata);
|
||||
|
||||
extern FILE *f_trans; // for logging
|
||||
extern FILE *f_logespeak;
|
||||
extern int logging_type; // from config file
|
||||
|
||||
Reference in New Issue
Block a user