[1.41.15]

Fixes to: announce punctuation ( --punct option)


git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@227 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
jonsd
2009-10-12 16:38:17 +00:00
parent 749c336768
commit 1ef2aa6091
27 changed files with 365 additions and 130 deletions
+1 -4
View File
@@ -223,8 +223,6 @@ static int compile_line(char *linebuf, char *dict_line, int *hash)
unsigned char bad_phoneme[4];
static char nullstring[] = {0};
WORD_TAB winfo;
comment = NULL;
text_not_phonemes = 0;
phonetic = word = nullstring;
@@ -437,12 +435,11 @@ step=1; // TEST
if(word[0] == '_')
{
// This is a special word, used by eSpeak. Translate this into phonemes now
memset(&winfo,0,sizeof(winfo));
strcat(phonetic, " "); // need a space to indicate word-boundary
// PROBLEM vowel reductions are not applied to the translated phonemes
// condition rules are not applied
TranslateWord(translator,phonetic,0,&winfo);
TranslateWord(translator,phonetic,0,NULL);
text_not_phonemes = 0;
strncpy0(encoded_ph, word_phonemes, N_WORD_BYTES-4);
+6 -3
View File
@@ -247,6 +247,12 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
sprintf(fname,"%s%c%s_dict",path_home,PATHSEP,name);
size = GetFileLength(fname);
if(tr->data_dictlist != NULL)
{
Free(tr->data_dictlist);
tr->data_dictlist = NULL;
}
f = fopen(fname,"rb");
if((f == NULL) || (size <= 0))
{
@@ -257,9 +263,6 @@ int LoadDictionary(Translator *tr, const char *name, int no_error)
return(1);
}
if(tr->data_dictlist != NULL)
Free(tr->data_dictlist);
tr->data_dictlist = Alloc(size);
fread(tr->data_dictlist,size,1,f);
fclose(f);
+4 -11
View File
@@ -317,7 +317,6 @@ void Lexicon_It(int pass)
char phonemes[80];
char phonemes2[80];
char buf_out[120];
WORD_TAB winfo;
static const char *vowels1 = "aeiou";
static const char *vowels2 = "aeou";
@@ -438,8 +437,7 @@ void Lexicon_It(int pass)
}
}
// translate
memset(&winfo,0,sizeof(winfo));
TranslateWord(translator,&word1[1],0,&winfo);
TranslateWord(translator,&word1[1],0, NULL);
DecodePhonemes(word_phonemes,phonemes);
stress_posn1 = 0;
@@ -462,8 +460,7 @@ void Lexicon_It(int pass)
vowel_ix++;
}
memset(&winfo,0,sizeof(winfo));
TranslateWord(translator,&word2[1],0,&winfo);
TranslateWord(translator,&word2[1],0, NULL);
DecodePhonemes(word_phonemes,phonemes2);
vowel_ix = 1;
@@ -619,7 +616,6 @@ void Lexicon_De()
char pronounce2[80];
char phonemes[80];
char phonemes2[80];
WORD_TAB winfo;
static const char *vowels = "aeiouyAEIOUY29@";
@@ -728,8 +724,7 @@ void Lexicon_De()
}
// translate
memset(&winfo,0,sizeof(winfo));
TranslateWord(translator,&word2[1],0,&winfo);
TranslateWord(translator,&word2[1],0, NULL);
DecodePhonemes2(word_phonemes,phonemes); // also need to change some phoneme names
@@ -794,7 +789,6 @@ void Lexicon_Ru()
int wlen;
int len;
int check_root;
WORD_TAB winfo;
char word[80];
char word2[80];
@@ -933,8 +927,7 @@ p_unicode = unicode;
}
// translate
memset(&winfo,0,sizeof(winfo));
TranslateWord(translator, &word2[1],0,&winfo);
TranslateWord(translator, &word2[1],0, NULL);
DecodePhonemes(word_phonemes,phonemes);
// find the stress position in the translation
+13 -18
View File
@@ -1314,7 +1314,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
char ph_buf2[50];
char suffix[20];
char *wordptr;
unsigned int dictflags[2];
unsigned int dictflags;
static const char str_pause[2] = {phonPAUSE_NOLINK,0};
@@ -1331,14 +1331,12 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
// but not if the next word starts with an upper-case letter
ordinal = 2;
word[ix] = ' ';
if(tr->translator_name == L('h','u'))
{
// lang=hu don't treat dot as ordinal indicator if the next word is a month name ($alt)
dictflags[0] = 0;
wordptr = &word[ix+2];
LookupDictList(tr, &wordptr, ph_buf, dictflags, 0, NULL);
if(dictflags[0] & FLAG_ALT_TRANS) // TEST
dictflags = TranslateWord(tr, &word[ix+2], 0, NULL);
if(dictflags & FLAG_ALT_TRANS)
ordinal = 0;
}
}
@@ -1514,23 +1512,20 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
}
break;
case NUM_DFRACTION_1: // italian, say "hundredths" is leading zero
case NUM_DFRACTION_1: // italian, say "hundredths" if leading zero
case NUM_DFRACTION_5: // hungarian, always say "tenths" etc.
if(decimal_count <= 4)
LookupNum3(tr, atoi(&word[n_digits]), ph_buf, 0,0,0);
if((word[n_digits]=='0') || (decimal_mode == NUM_DFRACTION_5))
{
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);
if(Lookup(tr, string, buf1) == 0)
break; // revert to speaking single digits
// decimal part has leading zeros, so add a "hundredths" or "thousandths" suffix
sprintf(string,"_0Z%d",decimal_count);
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;
strcat(ph_buf,buf1);
}
strcat(ph_out,ph_buf);
n_digits += decimal_count;
break;
case NUM_DFRACTION_3:
+106 -55
View File
@@ -816,8 +816,8 @@ static int LoadSoundFile2(const char *fname)
static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bufix)
{//=================================================================================
static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output, int *bufix, int end_clause)
{//==========================================================================================================
// announce punctuation names
// c1: the punctuation character
// c2: the following character
@@ -826,12 +826,19 @@ static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bu
const char *punctname;
int found = 0;
int soundicon;
char *p;
int c2;
int len;
int bufix1;
char buf[200];
char buf2[80];
c2 = *c2_ptr;
buf[0] = 0;
if((soundicon = LookupSoundicon(c1)) >= 0)
{
// add an embedded command to play the soundicon
sprintf(&buf[bufix],"\001%dI ",soundicon);
sprintf(buf,"\001%dI ",soundicon);
UngetC(c2);
found = 1;
}
@@ -839,7 +846,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bu
if((punctname = LookupCharName(tr, c1)) != NULL)
{
found = 1;
if(bufix==0)
if((*bufix==0) || (end_clause==0))
{
punct_count=1;
while(c2 == c1)
@@ -847,26 +854,32 @@ static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bu
punct_count++;
c2 = GetC();
}
UngetC(c2);
*c2_ptr = c2;
if(end_clause)
{
UngetC(c2);
}
p = &buf[bufix];
if(punct_count==1)
{
sprintf(p,"%s %s %s",tone_punct_on,punctname,tone_punct_off);
sprintf(buf,"%s %s %s",tone_punct_on,punctname,tone_punct_off);
}
else
if(punct_count < 4)
{
sprintf(p,"\001+10S%s",tone_punct_on);
sprintf(buf,"\001+10S%s",tone_punct_on);
while(punct_count-- > 0)
sprintf(buf,"%s %s",buf,punctname);
sprintf(p,"%s %s\001-10S",buf,tone_punct_off);
{
sprintf(buf2," %s",punctname);
strcat(buf, buf2);
}
sprintf(buf2," %s\001-10S",tone_punct_off);
strcat(buf, buf2);
}
else
{
sprintf(p,"%s %s %d %s %s",
sprintf(buf,"%s %s %d %s %s",
tone_punct_on,punctname,punct_count,punctname,tone_punct_off);
return(CLAUSE_COMMA);
}
}
else
@@ -879,17 +892,25 @@ static int AnnouncePunctuation(Translator *tr, int c1, int c2, char *buf, int bu
ssml_ignore_l_angle = c1; // this was &lt; which was converted to <, don't pick it up again as <
}
ungot_char2 = c1;
buf[bufix] = ' ';
buf[bufix+1] = 0;
buf[0] = ' ';
buf[1] = 0;
}
}
if(found == 0)
return(-1);
bufix1 = *bufix;
len = strlen(buf);
strcpy(&output[*bufix],buf);
*bufix += len;
if(end_clause==0)
return(-1);
if(c1 == '-')
return(CLAUSE_NONE); // no pause
if(bufix > 0)
if(bufix1 > 0)
return(CLAUSE_SHORTCOMMA);
if((strchr_w(punct_close,c1) != NULL) && !iswalnum(c2))
return(CLAUSE_SHORTFALL+4);
@@ -1919,8 +1940,8 @@ int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix
int any_alnum = 0;
int self_closing;
int punct_data;
int is_punctuation;
int save_c2;
int is_end_clause;
int announced_punctuation;
int stressed_word = 0;
const char *p;
wchar_t xml_buf[N_XML_BUF+1];
@@ -2304,35 +2325,48 @@ if(option_ssml) parag=1;
linelength = 0;
}
if(option_punctuation && (phoneme_mode==0) && (sayas_mode==0) && iswpunct(c1))
{
// option is set to explicitly speak punctuation characters
// if a list of allowed punctuation has been set up, check whether the character is in it
if((option_punctuation == 1) || (wcschr(option_punctlist,c1) != NULL))
{
if((terminator = AnnouncePunctuation(tr, c1, c2, buf, ix)) >= 0)
return(terminator);
}
}
announced_punctuation = 0;
if((phoneme_mode==0) && (sayas_mode==0) && ((punct = lookupwchar(punct_chars,c1)) != 0))
if((phoneme_mode==0) && (sayas_mode==0))
{
punct_data = punct_attributes[punct];
is_end_clause = 0;
if(punct_data & PUNCT_IN_WORD)
if((punct = lookupwchar(punct_chars,c1)) != 0)
{
// Armenian punctuation inside a word
stressed_word = 1;
*tone_type = punct_data >> 12 & 0xf; // override the end-of-sentence type
continue;
punct_data = punct_attributes[punct];
if(punct_data & PUNCT_IN_WORD)
{
// Armenian punctuation inside a word
stressed_word = 1;
*tone_type = punct_data >> 12 & 0xf; // override the end-of-sentence type
continue;
}
if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || (c2=='-') || Eof()))
{
// note: (c2='?') is for when a smart-quote has been replaced by '?'
is_end_clause = 1;
}
}
if((iswspace(c2) || (punct_data & 0x8000) || IsBracket(c2) || (c2=='?') || (c2=='-') || Eof()))
if(option_punctuation && iswpunct(c1))
{
// note: (c2='?') is for when a smart-quote has been replaced by '?'
is_punctuation = 1;
// option is set to explicitly speak punctuation characters
// if a list of allowed punctuation has been set up, check whether the character is in it
if((option_punctuation == 1) || (wcschr(option_punctlist,c1) != NULL))
{
if((terminator = AnnouncePunctuation(tr, c1, &c2, buf, &ix, is_end_clause)) >= 0)
return(terminator);
announced_punctuation = c1;
}
}
if(is_end_clause)
{
int c_next;
if((c1 == '.') && (cprev == '.'))
{
c1 = 0x2026;
@@ -2340,47 +2374,43 @@ if(option_ssml) parag=1;
}
nl_count = 0;
save_c2 = c2;
c_next = c2;
if(iswspace(c2))
if(iswspace(c_next))
{
while(!Eof() && iswspace(c2))
while(!Eof() && iswspace(c_next))
{
if(c2 == '\n')
if(c_next == '\n')
nl_count++;
c2 = GetC(); // skip past space(s)
}
if(!Eof())
{
UngetC(c2);
c_next = GetC(); // skip past space(s)
}
}
if((nl_count==0) && (c1 == '.'))
{
// if(iswdigit(cprev) && (tr->langopts.numbers & NUM_ORDINAL_DOT) && islower(c2))
if(iswdigit(cprev) && (tr->langopts.numbers & NUM_ORDINAL_DOT))
{
// dot after a number indicates an ordinal number
is_punctuation = 0;
if(islower(c_next) || (c_next == '<'))
is_end_clause = 0; // only if followed by lower-case, (or if there is a XML tag)
}
else
if(iswlower(c2))
if(iswlower(c_next))
{
// next word has no capital letter, this dot is probably from an abbreviation
c1 = ' ';
is_punctuation = 0;
is_end_clause = 0;
}
if(any_alnum==0)
{
c1 = ' '; // no letters or digits yet, so probably not a sentence terminator
is_punctuation = 0;
is_end_clause = 0;
}
}
c2 = save_c2;
if(is_punctuation)
if(is_end_clause)
{
UngetC(c_next);
buf[ix] = ' ';
buf[ix+1] = 0;
@@ -2393,12 +2423,33 @@ if(option_ssml) parag=1;
}
return(punct_data); // only recognise punctuation if followed by a blank or bracket/quote
}
else
{
if(!Eof())
{
if(iswspace(c2))
UngetC(c_next);
}
}
}
}
if(speech_parameters[espeakSILENCE]==1)
continue;
if(c1 == announced_punctuation)
{
// const unsigned short keep_punctuation[] = {
// '\'', '-', 0x92, 0xb4, 0x2019, 0x2032, 0 };
// This character has already been announced, so delete it so that it isn't spoken a second time.
// Unless it's a hyphen or apostrophe (which is used by TranslateClause() )
if(!IsBracket(c1))
{
c1 = ' ';
}
}
j = ix+1;
ix += utf8_out(c1,&buf[ix]); // buf[ix++] = c1;
if(!iswspace(c1) && !IsBracket(c1))
+1 -1
View File
@@ -35,7 +35,7 @@
#include "translate.h"
#include "wave.h"
const char *version_string = "1.41.13 10.Oct.09";
const char *version_string = "1.41.15 12.Oct.09";
const int version_phdata = 0x014100;
int option_device_number = -1;
+1 -1
View File
@@ -535,7 +535,7 @@ static short vcolouring[N_VCOLOUR][5] = {
// fprintf(stderr,"FMT%d %3s %3d-%3d f1=%d f2=%4d %4d %4d f3=%4d %3d\n",
// which,WordToString(other_ph->mnemonic),len,rms,f1,f2,f2_min,f2_max,f3_adj,f3_amp);
if(other_ph->mnemonic == '?')
if((other_ph != NULL) && (other_ph->mnemonic == '?'))
flags |= 8;
if(which == 1)
+7
View File
@@ -464,6 +464,13 @@ Translator *SelectTranslator(const char *name)
break;
case L('f','a'): // Farsi
{
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
}
break;
case L('f','i'): // Finnish
{
static const unsigned char stress_amps_fi[8] = {18,16, 22,22, 20,22, 22,22 };
+19 -2
View File
@@ -601,8 +601,9 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
int spell_word;
int stress_bits;
int emphasize_allcaps = 0;
int wflags = wtab->flags;
int wmark = wtab->wmark;
int wflags;
int wmark;
WORD_TAB wtab_null[8];
// translate these to get pronunciations of plural 's' suffix (different forms depending on
// the preceding letter
@@ -610,6 +611,14 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
static char word_iz[4] = {0,'i','z',0};
static char word_ss[4] = {0,'s','s',0};
if(wtab == NULL)
{
memset(wtab_null, 0, sizeof(wtab_null));
wtab = wtab_null;
}
wflags = wtab->flags;
wmark = wtab->wmark;
dictionary_flags[0] = 0;
dictionary_flags[1] = 0;
dictionary_flags2[0] = 0;
@@ -620,6 +629,13 @@ int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab)
end_phonemes[0] = 0;
ph_limit = &phonemes[N_WORD_PHONEMES];
if(tr->data_dictlist == NULL)
{
// dictionary is not loaded
word_phonemes[0] = 0;
return(0);
}
// count the length of the word
if(*word1 == ' ') word1++; // possibly a dot was replaced by space: $dot
wordx = word1;
@@ -1053,6 +1069,7 @@ strcpy(phonemes2,phonemes);
AppendPhonemes(tr,phonemes, N_WORD_PHONEMES, end_phonemes);
end_phonemes[0] = 0;
}
memcpy(wordx,word_copy,strlen(word_copy));
}
wordx[-1] = c_temp;
}
+1 -1
View File
@@ -98,10 +98,10 @@
#define FLAG_DONT_SWITCH_TRANSLATOR 0x1000
#define FLAG_SUFFIX_REMOVED 0x2000
#define FLAG_HYPHEN_AFTER 0x4000
#define FLAG_ORDINAL 0x8000 // passed to TranslateNumber() to indicate an ordinal number
#define FLAG_NO_TRACE 0x10000 // passed to TranslateRules() to suppress dictionary lookup printout
#define FLAG_NO_PREFIX 0x20000
#define FLAG_ORDINAL 0x40000 // passed to TranslateNumber() to indicate an ordinal number
// prefix/suffix flags (bits 8 to 14, bits 16 to 22) don't use 0x8000, 0x800000
#define SUFX_E 0x0100 // e may have been added