From a6a5246a54afd8718e97b20e4288e58ffbe883e6 Mon Sep 17 00:00:00 2001 From: jonsd Date: Tue, 11 Sep 2007 09:58:39 +0000 Subject: [PATCH] [1.29.04] Allow up to 10 parts in multiple-word entries in *_list files. lang=hr: Recognize Roman numbers only when all-capitals. lang=en: Change to word-final [I] (phoneme [i]). git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@84 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/en_rules | 35 ++++--- dictsource/hr_list | 4 +- phsource/vowel/ii_4 | Bin 955 -> 958 bytes phsource/vowel/ii_en | Bin 959 -> 959 bytes platforms/windows/make_espeak.iss | 4 +- platforms/windows/windows_sapi/ttsengobj.cpp | 105 ++++++++++++++++++- src/compiledict.cpp | 17 ++- src/dictionary.cpp | 7 +- src/numbers.cpp | 3 - src/synthdata.cpp | 17 +-- src/tr_languages.cpp | 2 +- src/translate.cpp | 22 ++-- src/translate.h | 9 +- 13 files changed, 172 insertions(+), 53 deletions(-) diff --git a/dictsource/en_rules b/dictsource/en_rules index 1b61e3a5..ba05f1b7 100644 --- a/dictsource/en_rules +++ b/dictsource/en_rules @@ -5092,23 +5092,24 @@ .group // non-ascii characters with specified pronunciations - é eI - _) é I2 - ä E - ë E - ï i: - ö 3: -?5 ö VR - ü u: - ç s - ß s - _) ß (_ b'i:t@_ - č tS - š S - ş S - ž Z - þ T - ð D + é eI + _) é I2 + ê E: + ä E + ë E + ï i: + ö 3: +?5 ö VR + ü u: + ç s + ß s + _) ß (_ b'i:t@_ + č tS + š S + ş S + ž Z + þ T + ð D \\ bakstroUk diff --git a/dictsource/hr_list b/dictsource/hr_list index 6a706cda..188b2fc6 100644 --- a/dictsource/hr_list +++ b/dictsource/hr_list @@ -169,10 +169,10 @@ _1M4 b'ilijUn ?2 _0M4 b'ilijOna ?2 _1M4 b'ilijOn _dpt _:z'a*Ez_ - +_roman @-*'imsko // not Roman numerals -vi ti +// vi vi // not needed if only all-capitals are spoken as Roman numbers // Abbreviations diff --git a/phsource/vowel/ii_4 b/phsource/vowel/ii_4 index 8ab977db1369ebfcab2f049510729b6602477f7b..4e8a216003edce0699faa70be9526af62df00414 100644 GIT binary patch delta 78 zcmdnZzK>lXIKb68B-k~Og@J(~Gc(>~BX0zw<`y6a1RPkeF90(b{1})R;(^R}{|_)Q Ya5pe*mrP0 zV1$Uj;pE_fu@!hTpyL1k-{5<|1`|(^e8D{VBBRX2&G%SlFgnOgjMkdGpYdBzJlM1Y t3=QlJOdL!QTYd<_Y+1oBzzH)!gbQXe0|UYq1_m4c9Z0sUU;^5*0|2>|HS7QY diff --git a/platforms/windows/make_espeak.iss b/platforms/windows/make_espeak.iss index b9d3bac7..5e8c76b5 100755 --- a/platforms/windows/make_espeak.iss +++ b/platforms/windows/make_espeak.iss @@ -2,7 +2,7 @@ [Setup] AppName=eSpeak -AppVerName=eSpeak version 1.29.02 +AppVerName=eSpeak version 1.29.03 DefaultDirName={pf}\eSpeak DefaultGroupName=eSpeak @@ -159,7 +159,7 @@ begin case lang1 of 'af': value := $436; - 'bs': value := $141a; + 'bs': value := $41a; // should be $141a but Jaws crashes on startup 'cs': value := $405; 'cy': value := $452; 'de': value := $407; diff --git a/platforms/windows/windows_sapi/ttsengobj.cpp b/platforms/windows/windows_sapi/ttsengobj.cpp index 988b6c6f..e468f08c 100755 --- a/platforms/windows/windows_sapi/ttsengobj.cpp +++ b/platforms/windows/windows_sapi/ttsengobj.cpp @@ -298,10 +298,100 @@ STDMETHODIMP CTTSEngObj::SetObjectToken(ISpObjectToken * pToken) //=== ISpTTSEngine Implementation ============================================ // +#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer + +static char *phoneme_names_en[] = { + NULL,NULL,NULL," ",NULL,NULL,NULL,NULL,"'",",", + "A:","a","V","0","aU","@","aI", + "b","tS","d","D","E","3:","eI", + "f","g","h","I","i:","dZ","k", + "l","m","n","N","oU","OI","p", + "r","s","S","t","T","U","u:", + "v","w","j","z","Z", + NULL + }; + + + +int CTTSEngObj::WritePhonemes(SPPHONEID *phons, wchar_t *pW) +{//========================================================= + int ph; + int ix=2; + int skip=0; + int maxph = 49; + char *p; + int j; + int lang; + char **phoneme_names; + char phbuf[200]; + espeak_VOICE *voice; + + voice = espeak_GetCurrentVoice(); + lang = (voice->languages[1] << 8) + (voice->languages[2]); + + phoneme_names = phoneme_names_en; + maxph = 0; + + if(lang == L('e','n')) + { + phoneme_names = phoneme_names_en; + maxph = 49; + } + + if(maxph == 0) + return(0); + + strcpy(phbuf,"[["); + while(((ph = *phons++) != 0) && (ix < (sizeof(phbuf) - 3))) + { + if(skip) + { + skip = 0; + continue; + } + if(ph > maxph) + continue; + + p = phoneme_names[phons[0]]; // look at the phoneme after this one + if(p != NULL) + { + if(p[0] == '\'') + { + phbuf[ix++] = '\''; // primary stress, put before the vowel, not after + skip=1; + } + if(p[0] == ',') + { + phbuf[ix++] = ','; // secondary stress + skip=1; + } + } + + p = phoneme_names[ph]; // look at this phoneme + + if(p != NULL) + { + strcpy(&phbuf[ix],p); + ix += strlen(p); + } + } + strcpy(&phbuf[ix],"]]"); + ix += 2; + + if(pW != NULL) + { + for(j=0; j<=ix; j++) + { + pW[j] = phbuf[j]; + } + } + return(strlen(phbuf)); +} + int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_start, ISpTTSEngineSite* pOutputSite, int *n_text) -{//============================================================================================================================= +{//============================================================================================================================ int action; int control; @@ -338,6 +428,7 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st CheckActions(pOutputSite); sayas = 0; + state = &pTextFragList->State; switch(action) { @@ -366,7 +457,6 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st } // first set the volume, rate, pitch - state = &pTextFragList->State; volume = (state->Volume * master_volume)/100; speed = ConvertRate(state->RateAdj); pitch = ConvertPitch(state->PitchAdj.MiddleAdj); @@ -467,6 +557,14 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st } } break; + + case SPVA_Pronounce: + total += WritePhonemes(state->pPhoneIds, pW); + if(pW != NULL) + { + pW += total; + } + break; } @@ -478,6 +576,7 @@ int CTTSEngObj::ProcessFragList(const SPVTEXTFRAG* pTextFragList, wchar_t *pW_st *pW = 0; } *n_text = frag_count; + return(total); } // end of ProcessFragList @@ -600,7 +699,7 @@ STDMETHODIMP CTTSEngObj::Speak( DWORD dwSpeakFlags, if(size > 0) { - espeak_Synth(TextBuf,0,0,POS_CHARACTER,0,espeakCHARS_WCHAR | espeakKEEP_NAMEDATA,NULL,NULL); + espeak_Synth(TextBuf,0,0,POS_CHARACTER,0,espeakCHARS_WCHAR | espeakKEEP_NAMEDATA | espeakPHONEMES,NULL,NULL); } } return hr; diff --git a/src/compiledict.cpp b/src/compiledict.cpp index c34e2a35..95e21173 100755 --- a/src/compiledict.cpp +++ b/src/compiledict.cpp @@ -384,12 +384,19 @@ int compile_line(char *linebuf, char *dict_line, int *hash) } length += n_flag_codes; - if((multiple_string != NULL) && (multiple_words > 0) && (multiple_words <= 4)) + if((multiple_string != NULL) && (multiple_words > 0)) { - dict_line[length++] = 40 + multiple_words; - ix = multiple_string_end - multiple_string; - memcpy(&dict_line[length],multiple_string,ix); - length += ix; + if(multiple_words > 10) + { + fprintf(f_log,"%5d: Two many parts in a multi-word entry: %d\n",linenum,multiple_words); + } + else + { + dict_line[length++] = 40 + multiple_words; + ix = multiple_string_end - multiple_string; + memcpy(&dict_line[length],multiple_string,ix); + length += ix; + } } dict_line[0] = length; diff --git a/src/dictionary.cpp b/src/dictionary.cpp index 056a3205..60bf6947 100755 --- a/src/dictionary.cpp +++ b/src/dictionary.cpp @@ -36,7 +36,7 @@ #include "translate.h" - +int dictionary_skipwords; char dictionary_name[40]; extern MNEM_TAB mnem_flags[]; @@ -2716,12 +2716,13 @@ int Translator::LookupDict2(char *word, char *word2, char *phonetic, unsigned in else if(flag > 40) { - // flags 41,42,or 43 match more than one word + // flags 41 to 50 match more than one word // This comes after the other flags n_chars = next - p; if(memcmp(word2,p,n_chars)==0) { - dictionary_flags |= ((flag-40) << 5); // set (bits 5-7) to 1,2,or 3 + dictionary_flags |= FLAG_SKIPWORDS; + dictionary_skipwords = (flag - 40); p = next; word_end = word2 + n_chars; } diff --git a/src/numbers.cpp b/src/numbers.cpp index eadb1b43..08647774 100644 --- a/src/numbers.cpp +++ b/src/numbers.cpp @@ -214,9 +214,6 @@ int Translator::TranslateRoman(char *word, char *ph_out) static char *roman_numbers = "ixcmvld"; static int roman_values[] = {1,10,100,1000,5,50,500}; - if((langopts.numbers & NUM_ROMAN) == 0) - return(0); - acc = 0; prev = 0; subtract = 0x7fff; diff --git a/src/synthdata.cpp b/src/synthdata.cpp index bac101ad..15e0fe0d 100755 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,7 +35,7 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.29.02 10.Sep.07"; +const char *version_string = "1.29.04 11.Sep.07"; const int version_phdata = 0x012901; int option_device_number = -1; @@ -204,7 +204,7 @@ static unsigned int LookupSound2(int index, unsigned int other_phcode, int contr {//================================================================================ // control=1 get formant transition data only - int code; + unsigned int code; unsigned int value, value2; while((value = phoneme_index[index++]) != 0) @@ -223,12 +223,17 @@ static unsigned int LookupSound2(int index, unsigned int other_phcode, int contr } break; case 1: - if(control==0) - seq_len_adjust = value2 >> 8; + if(control==0) + { + seq_len_adjust = value2 >> 8; + } break; case 2: - if(control==0) - seq_len_adjust = -(value2 >> 8); + if(control==0) + { + seq_len_adjust = value2 >> 8; + seq_len_adjust = -seq_len_adjust; + } break; case 3: if(control==0) diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp index ee0d9abf..7aa0e1df 100644 --- a/src/tr_languages.cpp +++ b/src/tr_languages.cpp @@ -304,7 +304,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.max_initial_consonants = 5; tr->langopts.spelling_stress = 1; - tr->langopts.numbers = 0x1c0d + 0x4000 + NUM_ROMAN; + tr->langopts.numbers = 0x1c0d + 0x4000 + NUM_ROMAN_UC; tr->langopts.numbers2 = 0x4a; // variant numbers before thousands,milliards tr->langopts.replace_chars = replace_cyrillic; tr->langopts.replacement_chars = replace_cyrillic_latin; diff --git a/src/translate.cpp b/src/translate.cpp index 0b38270f..e9f7f959 100755 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -671,8 +671,12 @@ if((wmark > 0) && (wmark < 8)) if(!found & ((word_flags & FLAG_UPPERS) != FLAG_FIRST_UPPER)) { // either all upper or all lower case - if((found = TranslateRoman(word,phonemes)) != 0) - dictionary_flags |= FLAG_ABBREV; // don't spell capital Roman numbers as individual letters + + if((langopts.numbers & NUM_ROMAN) || ((langopts.numbers & NUM_ROMAN_UC) && (word_flags & FLAG_ALL_UPPER))) + { + if((found = TranslateRoman(word,phonemes)) != 0) + dictionary_flags |= FLAG_ABBREV; // don't spell capital Roman numbers as individual letters + } } if((wflags & FLAG_ALL_UPPER) && (clause_upper_count <= clause_lower_count) && @@ -1233,7 +1237,8 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne } else { - flags |= FLAG_SKIPWORDS_1; + flags |= FLAG_SKIPWORDS; + dictionary_skipwords = 1; } } } @@ -1562,7 +1567,7 @@ int Translator::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned i int ix; unsigned int word; - unsigned int new_c, c2; + unsigned int new_c, c2, c_lower; int upper_case = 0; static int ignore_next = 0; @@ -1578,16 +1583,16 @@ int Translator::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned i // there is a list of character codes to be substituted with alternative codes - if(iswupper(c)) + if(iswupper(c_lower = c)) { - c = towlower(c); + c_lower = towlower(c); upper_case = 1; } new_c = 0; for(ix=0; (word = langopts.replace_chars[ix]) != 0; ix++) { - if(c == (word & 0xffff)) + if(c_lower == (word & 0xffff)) { if((word >> 16) == 0) { @@ -2217,7 +2222,8 @@ if((c == '/') && (langopts.testing & 2) && isdigit(next_in) && IsAlpha(prev_out) else { dict_flags = TranslateWord2(word, &words[ix], words[ix].pre_pause, words[ix+1].pre_pause); - ix += ((dict_flags >> 5) & 7); // dictionary indicates skip next word(s) + if(dict_flags & FLAG_SKIPWORDS) + ix += dictionary_skipwords; // dictionary indicates skip next word(s) if((dict_flags & FLAG_DOT) && (ix == word_count-1) && (terminator == CLAUSE_PERIOD)) { diff --git a/src/translate.h b/src/translate.h index 96b1461e..d6b7e6e8 100755 --- a/src/translate.h +++ b/src/translate.h @@ -34,8 +34,7 @@ /* flags from word dictionary */ // bits 0-3 stressed syllable, 7=unstressed -#define FLAG_SKIPWORDS 0xe0 /* bits 5,6,7 number of words to skip */ -#define FLAG_SKIPWORDS_1 0x20 +#define FLAG_SKIPWORDS 0x80 #define FLAG_PREPAUSE 0x100 #define FLAG_ONLY 0x200 #define BITNUM_FLAG_ONLY 9 // bit 9 is set @@ -277,7 +276,8 @@ typedef struct { unsigned char *length_mods; unsigned char *length_mods0; -#define NUM_ROMAN 0x20000 +#define NUM_ROMAN 0x20000 +#define NUM_ROMAN_UC 0x40000 // bits0-1=which numbers routine to use. // bit2= thousands separator must be space // bit3= , decimal separator, not . @@ -293,6 +293,7 @@ typedef struct { // bits13-15 post-decimal-digits 0=single digits, 1=(LANG=it) 2=(LANG=pl) 3=(LANG=ro) // bit16=dot after number indicates ordinal // bit17=recognize roman numbers + // bit18=Roman numbers only if upper case int numbers; @@ -501,6 +502,8 @@ extern char ctrl_embedded; // to allow an alternative CTRL for embedded comma extern char *p_textinput; extern wchar_t *p_wchar_input; extern int ungot_char; +extern int dictionary_skipwords; + extern int (* uri_callback)(int, const char *, const char *); extern int (* phoneme_callback)(const char *); extern void SetLengthMods(Translator *tr, int value);