From 1a28202d0048096ceb7d3c911a4c033488c66703 Mon Sep 17 00:00:00 2001 From: jonsd Date: Wed, 4 Jul 2007 22:59:40 +0000 Subject: [PATCH] [1.27.04] tr_languages: replace_char substitution can do 2->1 and 1->2 characters. espeakedit: set and save path for master phonemes file. espeakedit: added delete_phoneme and import_phoneme actions in phoneme files. espeakedit: improve data in log_espeakedit, include phoneme names. espeakedit: only write to log_espeakedit for speak from text window, not when playing vowel files. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@59 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/dict_phonemes | 22 +++++----- dictsource/en_rules | 5 ++- dictsource/hu_list | 7 ++++ dictsource/hu_rules | 3 +- dictsource/ru_list | 6 +-- dictsource/ru_rules | 7 ++-- phsource/compile_report | 48 +++++++++++----------- phsource/ph_macedonian | 1 + phsource/ph_russian | 10 ++--- phsource/voc/v | Bin 5805 -> 5805 bytes src/compiledata.cpp | 75 +++++++++++++++++++++++++++++----- src/espeakedit.cpp | 14 ++++++- src/main.h | 1 + src/menus.cpp | 5 ++- src/numbers.cpp | 27 ++++++++----- src/options.cpp | 5 ++- src/options.h | 3 +- src/phoneme.h | 3 +- src/phonemelist.cpp | 9 ++++- src/speak_lib.h | 2 +- src/synthdata.cpp | 4 +- src/synthesize.cpp | 2 +- src/synthesize.h | 1 + src/tr_languages.cpp | 68 ++++++++++++++++--------------- src/tr_languages.h | 2 +- src/translate.cpp | 84 +++++++++++++++++++++++++-------------- src/translate.h | 9 +++-- src/transldlg.cpp | 5 ++- src/wavegen.cpp | 60 +++++++++++++++++++++------- 29 files changed, 328 insertions(+), 160 deletions(-) create mode 100644 phsource/ph_macedonian diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index f9e0f116..e0cb0512 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -11,8 +11,8 @@ Yy - : ; b c d dZ f g h j k l m n N -p r r- s S t tS v -w x2 z Z +p r r- s S t tS ts +v w x2 z Z Dictionary cs_dict @@ -110,7 +110,7 @@ yi Yy yY * : b d f g h j k l m n N p r s -S s2 t v Z +S s2 t ts v Z Dictionary fr_dict @@ -122,7 +122,7 @@ y Y : ; b c d dZ f g h j k l L m n N n^ p R s S t t2 tS -v w z Z z2 +ts v w z Z z2 Dictionary hi_dict @@ -142,9 +142,8 @@ t.h th v w x z Dictionary hr_dict & @ @- @2 a A a: aI -aU E e e: E~ i I i: -l- o o: oU r- u U u: -y +aU E e e: i I i: l- +o o: oU r- u U u: y * b d dZ dZ; f g h j k l l^ m n N n^ @@ -183,7 +182,7 @@ y Y: yU * : ; b C d f g h j k l m n N n^ p Q r s S s; t tS -v v2 w x z +ts v v2 w x z Dictionary no_dict @@ -322,7 +321,7 @@ y y# Yy f g h j J k l l# m m# n N n# N# n^ n^# p Q r R r# R2 s S -t T tl# v x z +t T tl# ts v x z Dictionary la_dict @@ -339,9 +338,8 @@ r R s t w z Dictionary sr_dict & @ @- @2 a A a: aI -aU E e e: E~ i I i: -l- o o: oU r- u U u: -y +aU E e e: i I i: l- +o o: oU r- u U u: y * b d dZ dZ; f g h j k l l^ m n N n^ diff --git a/dictsource/en_rules b/dictsource/en_rules index 3dd8c862..bf5d8763 100644 --- a/dictsource/en_rules +++ b/dictsource/en_rules @@ -14,7 +14,7 @@ // * GNU General Public License for more details. * // * * // * You should have received a copy of the GNU General Public License * -// * along with this program; if not, write see: * +// * along with this program; if not, see: * // * . * // ***************************************************************************/ @@ -32,6 +32,7 @@ .group a _) a (_ a2 _) a (- 'eI + _) a (-half a2 _) a (_D ,eI _) a's (_ eIz D_) a (_ eI @@ -61,6 +62,8 @@ &b) a (_ =@ grandC) a (_ A: aa A: + aa (a a: + aa) aa a: aar 'A@ a (Bo_ 'A: _C) a (ble eI diff --git a/dictsource/hu_list b/dictsource/hu_list index 965f8794..1445a3da 100644 --- a/dictsource/hu_list +++ b/dictsource/hu_list @@ -233,6 +233,13 @@ ellen $u //against volna $u // would részén $u //on ... part of +nélkül $u // without +folytán $u // because of +úgy $u // like that +így $u // like this +egyaránt $u // alike +minden $u // all +részben $u // partly // word pairs diff --git a/dictsource/hu_rules b/dictsource/hu_rules index f81b6261..dfa3e3e1 100644 --- a/dictsource/hu_rules +++ b/dictsource/hu_rules @@ -4,9 +4,10 @@ .group a a A - _) a (_ %A + !_n) ato a:to: // NATO + .group á á a: diff --git a/dictsource/ru_list b/dictsource/ru_list index 0d5a7429..b3e52987 100644 --- a/dictsource/ru_list +++ b/dictsource/ru_list @@ -51,13 +51,13 @@ _6C S,E#s;t;s'ot _7C s;,Ims'ot _8C vOs;Ims'ot _9C dev;Vn'ostO -_1M1 t'ys;Its;V // no '1' before thousand +_1MA1 t'ys;Its;V // no '1' before thousand _0MA1 t'ys;Its;i _0M1 t'ys;Vts; -_1M2 m;,IlI;'on +_1MA2 m;,IlI;'on _0MA2 m;,IlI;'ona _0M2 m;,IlI;'onof -_1M3 m;,IlI;'art +_1MA3 m;,IlI;'art _0MA3 m;,IlI;'arda _0M3 m;,IlI;'artof _dpt _:'i_: // start of decimal fraction diff --git a/dictsource/ru_rules b/dictsource/ru_rules index 8dc3141a..1e020c23 100755 --- a/dictsource/ru_rules +++ b/dictsource/ru_rules @@ -365,10 +365,9 @@ .group р _) р (_ E* - р (_ r; - р (Y r; - р (B r; - р @-* + р (Y R; + р (B R; + р R .group с _) с (_ Es diff --git a/phsource/compile_report b/phsource/compile_report index 27f68993..0d8e3f92 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,23 +1,23 @@ 38 phoneme tables new total - base 96 96 + base 97 97 base2 23 114 - en 53 144 - en_n 29 144 - en_us 37 144 - en_sc 39 146 - en_rp 34 144 - en_wm 30 144 - af 38 128 - cy 29 122 - de 32 123 - eo 13 108 - fi 40 127 - fr 33 118 - fr_ca 11 118 - hi 49 131 + en 54 145 + en_n 29 145 + en_us 37 145 + en_sc 39 147 + en_rp 34 145 + en_wm 30 145 + af 38 129 + cy 29 123 + de 31 123 + eo 12 108 + fi 40 128 + fr 33 119 + fr_ca 11 119 + hi 49 132 hu 22 112 - nl 26 117 + nl 26 118 pl 15 107 sk 29 125 cs 5 125 @@ -26,18 +26,18 @@ sr 2 129 ru 36 124 it 17 117 - la 21 114 + la 21 115 es 6 114 pt 28 131 pt_pt 20 131 ro 36 138 el 8 114 - sv 25 118 - no 28 122 - is 32 121 - vi 41 133 - zhy 32 124 - sw 14 105 + sv 25 119 + no 28 123 + is 32 122 + vi 41 134 + zhy 32 125 + sw 14 106 3 b/b base hi ro 2 b/b_ base hi @@ -260,7 +260,7 @@ 2 ustop/t_hi hi 4 ustop/t_pzd pl ru 7 ustop/tr base en hi ru - 8 ustop/ts base2 de eo hu pl ru ro zhy + 7 ustop/ts base base2 hu pl ru ro zhy 2 ustop/tsh base zhy 2 ustop/tsh_ base zhy 3 ustop/t_short hi sk el diff --git a/phsource/ph_macedonian b/phsource/ph_macedonian new file mode 100644 index 00000000..e96097bc --- /dev/null +++ b/phsource/ph_macedonian @@ -0,0 +1 @@ +// Initially empty diff --git a/phsource/ph_russian b/phsource/ph_russian index 016df3da..79c2c962 100755 --- a/phsource/ph_russian +++ b/phsource/ph_russian @@ -124,7 +124,7 @@ endphoneme phoneme i vowel starttype (i) endtype (i) - length 130 + length 100 formants vwl_ru/i endphoneme @@ -136,7 +136,7 @@ endphoneme phoneme y vowel starttype (i) endtype (i) - length 130 + length 100 formants vwl_ru/i# endphoneme @@ -184,7 +184,7 @@ endphoneme phoneme A vowel starttype (a) endtype (a) - length 150 + length 100 formants vwl_ru/a endphoneme @@ -202,7 +202,7 @@ endphoneme phoneme u vowel starttype (u) endtype (u) - length 150 + length 80 formants vwl_ru/u endphoneme @@ -227,7 +227,7 @@ endphoneme phoneme e vowel starttype (e) endtype (e) - length 190 + length 100 formants vwl_ru/ee endphoneme diff --git a/phsource/voc/v b/phsource/voc/v index 7b3723998727990ab513c28bea7e8c0d99867f00..17ea16c0cbaf95d9c0f6a6e256684b87bc3dd639 100644 GIT binary patch delta 39 xcmV+?0NDSnEv+rE?*jphv+x7M1C#Fq7PH9*t^)zMvv>=^1C#v{A+uT!QwLc%5DNeR delta 44 zcmV+{0Mq}iEv+rE?*o&w2Ntsh1g--Ew9)Oewg. * ***************************************************************************/ @@ -65,7 +65,8 @@ #define tSWITCHVOICING 21 #define tVOWELIN 22 #define tVOWELOUT 23 -#define tAPPENDPH 24 +#define tAPPENDPH 24 // always insert another phoneme (linkout) after this one +#define tIMPORTPH 25 #define tPHONEMENUMBER 29 #define tPHONEMETABLE 30 @@ -123,6 +124,7 @@ private: void AddSpectList(int *list, int control); void AddEnvelope(int *list); void VowelTransition(int which, unsigned int *trans); + void ImportPhoneme(void); FILE *f_in; @@ -190,6 +192,7 @@ static keywtab_t keywords[] = { {"fricative", 0x1000000+phFRICATIVE}, {"vstop", 0x1000000+phVSTOP}, {"vfricative",0x1000000+phVFRICATIVE}, + {"delete_phoneme", 0x1000000+phDELETED}, // type of consonant {"stop", 0x1000000+phSTOP}, @@ -226,6 +229,7 @@ static keywtab_t keywords[] = { {"vowelin",22}, {"vowelout",23}, {"appendph",24}, + {"import_phoneme",25}, // flags {"wavef", 0x2000000+phWAVE}, @@ -1229,6 +1233,49 @@ void Compile::VowelTransition(int which, unsigned int *trans) } // end of VowelTransition +void Compile::ImportPhoneme(void) +{//============================== + int ix; + unsigned int mnem; + unsigned int ph_mnem; + unsigned int ph_code; + PHONEME_TAB_LIST *phtab = NULL; + + NextItem(tSTRING); + mnem = StringToWord(item_string); + + NextItem(tSTRING); + for(ix=0; ixphoneme_tab_ptr[ix].mnemonic) + { + ph_mnem = ph->mnemonic; + ph_code = ph->code; + memcpy(ph,&phtab->phoneme_tab_ptr[ix],sizeof(PHONEME_TAB)); + ph->mnemonic = ph_mnem; + ph->code = ph_code; + break; + } + } + if(ix == 256) + { + Error("Import phoneme not found",WordToString(mnem)); + } +} int Compile::CPhoneme() {//==================== @@ -1382,6 +1429,10 @@ int Compile::CPhoneme() VowelTransition(2,vowel_out); break; + case tIMPORTPH: + ImportPhoneme(); + break; + default: Error("Syntax error",item_string); break; @@ -1430,6 +1481,11 @@ int Compile::CPhoneme() ph->std_length |= 0x8000; // 'locally declared' indicator + if(ph->type == phDELETED) + { + ph->mnemonic = 0x01; // will not be recognised + } + return(phindex); } // end of Compile::CPhoneme @@ -2030,22 +2086,23 @@ memset(markers_used,0,sizeof(markers_used)); f_errors = stderr; strncpy0(current_fname,source,sizeof(current_fname)); - sprintf(fname,"%s%s",path_source,source); + + strncpy0(fname,path_phfile.mb_str(wxConvLocal),sizeof(fname)); f_in = fopen_log(f_errors,fname,"rb"); if(f_in == NULL) { if(gui_flag) { - wxString dir = wxDirSelector(_T("Directory for 'phonemes' file"),path_phsource); - if(!dir.IsEmpty()) + wxString phfile = wxFileSelector(_T("Master phonemes file"),path_phsource, + _T(""),_T(""),_T("*"),wxOPEN); + + if(!phfile.IsEmpty()) { - path_phsource = dir; - strncpy0(path_source,path_phsource.mb_str(wxConvLocal),sizeof(path_source)-1); - strcat(path_source,"/"); + path_phfile = phfile; } } - sprintf(fname,"%s%s",path_source,source); + strncpy0(fname,path_phfile.mb_str(wxConvLocal),sizeof(fname)); f_in = fopen_log(f_errors,fname,"rb"); if(f_in == NULL) { diff --git a/src/espeakedit.cpp b/src/espeakedit.cpp index 0e1c35c7..bb42ae88 100755 --- a/src/espeakedit.cpp +++ b/src/espeakedit.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -180,6 +180,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame) EVT_MENU(MENU_SPECTRUM2, MyFrame::OnNewWindow) EVT_MENU(MENU_PROSODY, MyFrame::OnProsody) EVT_MENU(MENU_PARAMS, MyFrame::OnOptions) + EVT_MENU(MENU_PATH0, MyFrame::OnOptions) EVT_MENU(MENU_PATH1, MyFrame::OnOptions) EVT_MENU(MENU_PATH2, MyFrame::OnOptions) EVT_MENU(MENU_PATH3, MyFrame::OnOptions) @@ -366,6 +367,15 @@ void OnOptions2(int event_id) } break; + case MENU_PATH0: + string = wxFileSelector(_T("Master phonemes file"),wxFileName(path_phfile).GetPath(), + _T(""),_T(""),_T("*"),wxOPEN); + if(!string.IsEmpty()) + { + path_phfile = string; + } + break; + case MENU_PATH1: string = wxDirSelector(_T("Phoneme source directory"),path_phsource); if(!string.IsEmpty()) @@ -393,7 +403,7 @@ void OnOptions2(int event_id) case MENU_PATH4: string = wxFileSelector(_T("Voice file to modify formant peaks"),wxFileName(path_speech).GetPath(), - _T(""),_T("WAV"),_T("*"),wxSAVE); + _T(""),_T(""),_T("*"),wxOPEN); if(!string.IsEmpty()) { path_modifiervoice = string; diff --git a/src/main.h b/src/main.h index 438745af..08d188e0 100755 --- a/src/main.h +++ b/src/main.h @@ -123,6 +123,7 @@ enum { MENU_OPTIONS, MENU_PARAMS, MENU_PATHS, + MENU_PATH0, MENU_PATH1, MENU_PATH2, MENU_PATH3, diff --git a/src/menus.cpp b/src/menus.cpp index d040fa65..0f34c34c 100755 --- a/src/menus.cpp +++ b/src/menus.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -89,10 +89,11 @@ wxMenuBar *MakeMenu(int type) // OPTIONS MENU paths_menu = new wxMenu; + paths_menu->Append(MENU_PATH0, _("Master phonemes file")); paths_menu->Append(MENU_PATH1, _("Phoneme data source")); paths_menu->Append(MENU_PATH2, _("Dictionary data source")); paths_menu->Append(MENU_PATH3, _("Synthesized sound WAV file")); - speak_menu->AppendSeparator(); + paths_menu->AppendSeparator(); paths_menu->Append(MENU_PATH4, _("Voice file to modify formant peaks")); option_menu = new wxMenu; diff --git a/src/numbers.cpp b/src/numbers.cpp index 062fcf58..0e841c0e 100644 --- a/src/numbers.cpp +++ b/src/numbers.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -434,13 +434,22 @@ static char *M_Variant(int value) {//============================== // returns M, or perhaps MA for some cases - // for Polish language - two forms of plural! - if ((translator->langopts.numbers & 0x80000) && - ((value % 10)>=2) && - ((value % 10)<=4) && - ((value % 100)>20 || (value % 100)<10)) + if(((value % 100)>20) || ((value % 100)<10)) // but not teens, 10 to 19 { - return("MA"); + if ((translator->langopts.numbers2 & 0x40) && + ((value % 10)>=2) && + ((value % 10)<=4)) + { + // for Polish language - two forms of plural! + return("0MA"); + } + + if((translator->langopts.numbers2 & 0x80) && + ((value % 10)==1)) + { + return("1MA"); + } + } return("M"); } @@ -465,7 +474,7 @@ int Translator::LookupThousands(int value, int thousandplex, char *ph_out) Lookup("_0of",ph_of); } - sprintf(string,"_0%s%d",M_Variant(value),thousandplex); + sprintf(string,"_%s%d",M_Variant(value),thousandplex); if(Lookup(string,ph_thousands) == 0) { @@ -610,7 +619,7 @@ int Translator::TranslateNumber_1(char *word, char *ph_out, unsigned int *flags, else if((thousandplex > 1) && prev_thousands && (prev_value > 0)) { - sprintf(string,"_0%s%d",M_Variant(value),thousandplex+1); + sprintf(string,"_%s%d",M_Variant(value),thousandplex+1); if(Lookup(string,buf1)==0) { // speak this thousandplex if there was no word for the previous thousandplex diff --git a/src/options.cpp b/src/options.cpp index a4525ca2..e238864e 100755 --- a/src/options.cpp +++ b/src/options.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -45,6 +45,7 @@ wxString path_spectload2; wxString path_pitches; wxString path_wave; wxString path_speech; +wxString path_phfile; wxString path_phsource; wxString path_dictsource; wxString path_speaktext; @@ -164,6 +165,7 @@ void ConfigInit() pConfig->Read(_T("/voicename"),&string,wxEmptyString); strcpy(voice_name,string.mb_str(wxConvLocal)); pConfig->Read(_T("/phsource"),&path_phsource,basedir+_T("/phsource")); + pConfig->Read(_T("/phfile"),&path_phfile,path_phsource+_T("/phonemes")); pConfig->Read(_T("/dictsource"),&path_dictsource,basedir+_T("/dictsource")); pConfig->Read(_T("/speaktext"),&path_speaktext,wxEmptyString); pConfig->Read(_T("/modifiervoice"),&path_modifiervoice,basedir); @@ -189,6 +191,7 @@ void ConfigSave(int exit) pConfig->Write(_T("/speechpath"),path_speech); pConfig->Write(_T("/voicename"),wxString(voice_name,wxConvLocal)); pConfig->Write(_T("/phsource"),path_phsource); + pConfig->Write(_T("/phfile"),path_phfile); pConfig->Write(_T("/dictsource"),path_dictsource); pConfig->Write(_T("/speaktext"),path_speaktext); pConfig->Write(_T("/speed"),option_speed); diff --git a/src/options.h b/src/options.h index 77c8611c..e0b950e6 100755 --- a/src/options.h +++ b/src/options.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -34,6 +34,7 @@ extern void ConfigSetPaths(); extern wxString path_spectload; extern wxString path_spectload2; extern wxString path_pitches; +extern wxString path_phfile; extern wxString path_phsource; extern wxString path_dictsource; extern wxString path_modifiervoice; diff --git a/src/phoneme.h b/src/phoneme.h index 01c83a69..94807ae7 100755 --- a/src/phoneme.h +++ b/src/phoneme.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -30,6 +30,7 @@ #define phVFRICATIVE 7 #define phNASAL 8 #define phVIRTUAL 9 +#define phDELETED 14 #define phINVALID 15 diff --git a/src/phonemelist.cpp b/src/phonemelist.cpp index 467981b7..76e2b4b3 100755 --- a/src/phonemelist.cpp +++ b/src/phonemelist.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -400,9 +400,16 @@ void Translator::MakePhonemeList(int post_pause, int start_sentence) if(alternative > 1) { + PHONEME_TAB *ph2; + ph2 = ph; ph = phoneme_tab[alternative]; + if(ph->type == phVOWEL) + { plist2->synthflags |= SFLAG_SYLLABLE; + if(ph2->type != phVOWEL) + plist2->stress = 0; // change from non-vowel to vowel, make sure it's unstressed + } else plist2->synthflags &= ~SFLAG_SYLLABLE; } diff --git a/src/speak_lib.h b/src/speak_lib.h index 3e52e67e..84dd056f 100644 --- a/src/speak_lib.h +++ b/src/speak_lib.h @@ -15,7 +15,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ diff --git a/src/synthdata.cpp b/src/synthdata.cpp index 6861ab29..87775b9e 100755 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -35,7 +35,7 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.27.03 03.Jul.07"; +const char *version_string = "1.27.04 04.Jul.07"; const int version_phdata = 0x012701; int option_device_number = -1; diff --git a/src/synthesize.cpp b/src/synthesize.cpp index bbad2776..7048ec1d 100755 --- a/src/synthesize.cpp +++ b/src/synthesize.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ diff --git a/src/synthesize.h b/src/synthesize.h index 6c91af59..80ebef7f 100755 --- a/src/synthesize.h +++ b/src/synthesize.h @@ -236,6 +236,7 @@ extern unsigned char *out_end; extern int event_list_ix; extern espeak_EVENT *event_list; extern t_espeak_callback* synth_callback; +extern int option_log_frames; #define N_SOUNDICON_TAB 100 extern int n_soundicon_tab; diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp index 6ab8e818..e76d1be2 100644 --- a/src/tr_languages.cpp +++ b/src/tr_languages.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -44,6 +44,22 @@ #define OFFSET_CYRILLIC 0x420 #define OFFSET_DEVANAGARI 0x900 + +static const unsigned int replace_cyrillic[] = + {0x430,0x431,0x446,0x45b,0x447,0x45f,0x455,0x434,0x452, + 0x435,0x444,0x433,0x445,0x438,0x458,0x43a,0x459, + 0x43b,0x43c,0x45a,0x43d,0x43e,0x43f,0x440,0x441, + 0x448,0x442,0x443,0x432,0x437,0x436, + 0x453,0x45c,0}; // ѓ ѕ ќ + +static const unsigned int replace_cyrillic_latin[] = + {'a','b','c',0x107,0x10d,'d'+(0x17e<<16),'d'+('z'<<16),'d',0x111, + 'e','f','g','h','i','j','k','l'+('j'<<16), + 'l','m','n'+('j'<<16),'n','o','p','r','s', + 0x161,'t','u','v','z',0x17e, + 0x111,0x107,0}; + + void SetupTranslator(Translator *tr, int *lengths, int *amps) {//========================================================== if(lengths != NULL) @@ -243,7 +259,7 @@ Translator *SelectTranslator(const char *name) case L('h','i'): { static const char dev_consonants2[] = {0x02,0x03,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f}; - static const wchar_t replace_chars_hi[11] = {0x966,0x967,0x968,0x969,0x96a,0x96b,0x96c,0x96d,0x96e,0x96f,0}; // digits 0-9 + static const unsigned int replace_chars_hi[11] = {0x966,0x967,0x968,0x969,0x96a,0x96b,0x96c,0x96d,0x96e,0x96f,0}; // digits 0-9 static const unsigned int replacement_chars_hi[11] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0}; static int stress_lengths_hi[8] = {190, 190, 210, 210, 0, 0, 230, 250}; static int stress_amps_hi[8] = {17,14, 20,19, 20,24, 24,22 }; @@ -273,20 +289,6 @@ Translator *SelectTranslator(const char *name) case L('h','r'): // Croatian case L('s','r'): // Serbian { - static const wchar_t replace_chars_hr[] = - {0x430,0x431,0x446,0x45b,0x447,0x434,0x452,0x45f, - 0x435,0x444,0x433,0x445,0x438,0x458,0x43a,0x43b, - 0x459,0x43c,0x43d,0x45a,0x43e,0x43f,0x440,0x441, - 0x448,0x442,0x443,0x432,0x437,0x436, - 0x453,0x455,0x45c,0}; // ѓ ѕ ќ - - static const unsigned int replacement_chars_hr[] = - {'a','b','c',0x107,0x10d,'d',0x111,'d'+(0x17e<<16), - 'e','f','g','h','i','j','k','l', - 'l'+('j'<<16),'m','n','n'+('j'<<16),'o','p','r','s', - 0x161,'t','u','v','z',0x17e, - 0x111,'d'+('z'<<16),0x107,0}; - static int stress_amps_hr[8] = {16,16, 20,20, 20,24, 24,22 }; static int stress_lengths_hr[8] = {180,160, 200,200, 0,0, 220,230}; @@ -300,10 +302,10 @@ Translator *SelectTranslator(const char *name) tr->langopts.max_initial_consonants = 5; tr->langopts.spelling_stress = 1; - tr->langopts.numbers = 0x1c0d + 0x84000; - tr->langopts.numbers2 = 0xa; // variant numbers before thousands,milliards - tr->langopts.replace_chars = replace_chars_hr; - tr->langopts.replacement_chars = replacement_chars_hr; + tr->langopts.numbers = 0x1c0d + 0x4000; + tr->langopts.numbers2 = 0x4a; // variant numbers before thousands,milliards + tr->langopts.replace_chars = replace_cyrillic; + tr->langopts.replacement_chars = replace_cyrillic_latin; SetLetterVowel(tr,'y'); SetLetterVowel(tr,'r'); @@ -316,7 +318,7 @@ Translator *SelectTranslator(const char *name) static int stress_amps_hu[8] = {17,17, 19,19, 20,24, 24,22 }; static int stress_lengths_hu[8] = {185,190, 190,190, 0,0, 210,220}; // static int stress_lengths_hu[8] = {180,180, 200,190, 0,0, 210,225}; - static const wchar_t replace_chars_hu[] = {0xd4,0xf4,0xdb,0xfb,0}; + static const unsigned int replace_chars_hu[] = {0xd4,0xf4,0xdb,0xfb,0}; static const unsigned int replacement_chars_hu[] = {0x150,0x151,0x170,0x171,0}; // allow o,u-circumflex for o,u-double-acute tr = new Translator(); @@ -411,8 +413,11 @@ Translator *SelectTranslator(const char *name) tr->letter_groups[0] = vowels_cyrillic; tr->langopts.stress_rule = 4; // antipenultimate - tr->langopts.numbers = 0x0c29 + 0x84000; - tr->langopts.numbers2 = 0xa; // variant numbers before thousands,milliards + tr->langopts.numbers = 0x0c29 + 0x4000; + tr->langopts.numbers2 = 0x8a; // variant numbers before thousands,milliards + + tr->langopts.replace_chars = replace_cyrillic_latin; + tr->langopts.replacement_chars = replace_cyrillic; } break; @@ -460,7 +465,8 @@ Translator *SelectTranslator(const char *name) tr->langopts.stress_flags = 0x6; // mark unstressed final syllables as diminished tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x8; tr->langopts.max_initial_consonants = 7; // for example: wchrzczony :) - tr->langopts.numbers=0x81809 + 0x4000; + tr->langopts.numbers=0x1809 + 0x4000; + tr->langopts.numbers2=0x40; tr->langopts.param[LOPT_COMBINE_WORDS] = 2 + 0x100; // combine 'nie' (marked with $alt2) with some 1-syllable words (marked with $alt) SetLetterVowel(tr,'y'); } @@ -487,7 +493,7 @@ Translator *SelectTranslator(const char *name) { static int stress_lengths_ro[8] = {170, 170, 180, 180, 0, 0, 240, 260}; static int stress_amps_ro[8] = {15,13, 18,18, 20,22, 22,22 }; - static const wchar_t replace_chars_ro[5] = {0x218,0x219,0x21a,0x21b,0}; + static const unsigned int replace_chars_ro[5] = {0x218,0x219,0x21a,0x21b,0}; static const unsigned int replacement_chars_ro[5] = {0x15e,0x15f,0x162,0x163,0}; // replace s-comma, t-comma by s-cedilla, t-cedilla tr = new Translator(); @@ -526,8 +532,8 @@ Translator *SelectTranslator(const char *name) tr->langopts.spelling_stress = 1; tr->langopts.param[LOPT_COMBINE_WORDS] = 4; // combine some prepositions with the following word - // tr->langopts.numbers = 0x1c0d + 0x84000; - tr->langopts.numbers = 0x1c01 + 0x84000; + tr->langopts.numbers = 0x1c01 + 0x4000; + tr->langopts.numbers2 = 0x40; tr->langopts.thousands_sep = 0; //no thousands separator tr->langopts.decimal_sep = ','; @@ -706,8 +712,8 @@ Translator_Russian::Translator_Russian() : Translator() langopts.stress_rule = 5; langopts.stress_flags = 0x0020; // waas 0x1010 - langopts.numbers = 0x80409; - langopts.numbers2 = 0x2; // variant numbers before thousands + langopts.numbers = 0x0409; + langopts.numbers2 = 0xc2; // variant numbers before thousands langopts.phoneme_change = 1; langopts.testing = 2; @@ -941,8 +947,8 @@ Translator_Afrikaans::Translator_Afrikaans() : Translator() } -int Translator_Afrikaans::TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert) -{//============================================================================================= +int Translator_Afrikaans::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert) +{//=============================================================================================================== // look for 'n and replace by a special character (unicode: schwa) if(!iswalpha(prev_in)) diff --git a/src/tr_languages.h b/src/tr_languages.h index 73c33543..8b421b3b 100644 --- a/src/tr_languages.h +++ b/src/tr_languages.h @@ -51,7 +51,7 @@ class Translator_Afrikaans: public Translator public: Translator_Afrikaans(); private: - int TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert); + int TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert); }; // end of class Translator_Afrikaans diff --git a/src/translate.cpp b/src/translate.cpp index 5b67928f..42b03ea8 100755 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -1544,48 +1544,71 @@ static int EmbeddedCommand(unsigned int &source_index) -int Translator::TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert) -{//=================================================================================== +int Translator::TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert) +{//===================================================================================================== // To allow language specific examination and replacement of characters - const wchar_t *p; + int ix; + unsigned int word; unsigned int new_c, c2; int upper_case = 0; + static int ignore_next = 0; + if(ignore_next) + { + ignore_next = 0; + return(8); + } if(c == 0) return(0); - if(langopts.replace_chars != NULL) + if(langopts.replace_chars == NULL) + return(c); + + // there is a list of character codes to be substituted with alternative codes + + if(iswupper(c)) { - // there is a list of character codes to be substituted with alternative codes + c = towlower(c); + upper_case = 1; + } - if((p = wcschr(langopts.replace_chars,c)) == NULL) + new_c = 0; + for(ix=0; (word = langopts.replace_chars[ix]) != 0; ix++) + { + if(c == (word & 0xffff)) { - // Try converting to lower case - if((p = wcschr(langopts.replace_chars,towlower(c))) != NULL) - upper_case =1; - } - - if(p != NULL) - { - new_c = langopts.replacement_chars[p - langopts.replace_chars]; - if(new_c & 0xffe00000) + if((word >> 16) == 0) { - // there is a second character to be inserted - // don't convert the case of the second character unless the next letter is also upper case - c2 = new_c >> 16; - if(upper_case && iswupper(next_in)) - c2 = towupper(c2); - *insert = c2; - new_c &= 0xffff; + new_c = langopts.replacement_chars[ix]; + break; + } + if((word >> 16) == tolower(next_in)) + { + new_c = langopts.replacement_chars[ix]; + ignore_next = 1; + break; } -#ifndef PLATFORM_RISCOS - if(upper_case) - new_c = towupper(new_c); -#endif - return(new_c); } } - return(c); + + if(new_c == 0) + return(c); // no substitution + + if(new_c & 0xffe00000) + { + // there is a second character to be inserted + // don't convert the case of the second character unless the next letter is also upper case + c2 = new_c >> 16; + if(upper_case && iswupper(next_in)) + c2 = towupper(c2); + *insert = c2; + new_c &= 0xffff; + } +#ifndef PLATFORM_RISCOS + if(upper_case) + new_c = towupper(new_c); +#endif + return(new_c); } @@ -1823,6 +1846,9 @@ if((c == '/') && (langopts.testing & 2) && isdigit(next_in) && IsAlpha(prev_out) } c = TranslateChar(&source[source_index], prev_in,c, next_in, &char_inserted); // optional language specific function + if(c == 8) + continue; // ignore this character + if(char_inserted) next_in = char_inserted; diff --git a/src/translate.h b/src/translate.h index b84584c3..c0c867da 100755 --- a/src/translate.h +++ b/src/translate.h @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -290,11 +290,12 @@ 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 // bit18=special word for 100,000s LANG=sw - // bit19=(LANG=pl) two forms of plural, M or MA int numbers; // bits 1-4 use variant form of numbers before thousands,millions,etc. + // bit6=(LANG=pl) two forms of plural, M or MA + // bit7=(LANG-ru) use MB for 1 thousand, million, etc int numbers2; int thousands_sep; @@ -307,7 +308,7 @@ typedef struct { char tone_numbers; char ideographs; // treat as separate words int testing; // testing options: bit 1= specify stressed syllable in the form: "outdoor/2" - const wchar_t *replace_chars; // characters to be substitutes + const unsigned int *replace_chars; // characters to be substitutes const unsigned int *replacement_chars; // substitutes for replace_chars } LANGUAGE_OPTIONS; @@ -404,7 +405,7 @@ protected: virtual int Unpronouncable(char *word); virtual void SetWordStress(char *output, unsigned int dictionary_flags, int tonic, int prev_stress); virtual int RemoveEnding(char *word, int end_type, char *word_copy); - virtual int TranslateChar(char *ptr, int prev_in, int c, int next_in, int *insert); + virtual int TranslateChar(char *ptr, int prev_in, unsigned int c, unsigned int next_in, int *insert); virtual int TranslateNumber(char *word1, char *ph_out, unsigned int *flags, int wflags); virtual int ChangePhonemes(PHONEME_LIST2 *phlist, int n_ph, int index, PHONEME_TAB *ph, CHANGEPH *ch); diff --git a/src/transldlg.cpp b/src/transldlg.cpp index e53a8498..c49f901c 100755 --- a/src/transldlg.cpp +++ b/src/transldlg.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -348,7 +348,10 @@ void TranslDlg::OnCommand(wxCommandEvent& event) { myframe->OnProsody(event); } + option_phoneme_events = 1; + option_log_frames = 1; MakeWave2(ph_list,n_ph_list); + option_log_frames = 0; break; } } // end of TranslDlg::OnCommand diff --git a/src/wavegen.cpp b/src/wavegen.cpp index 69522817..6e1c4282 100755 --- a/src/wavegen.cpp +++ b/src/wavegen.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write see: * + * along with this program; if not, see: * * . * ***************************************************************************/ @@ -59,6 +59,7 @@ static voice_t *wvoice; FILE *f_log = NULL; int option_waveout = 0; int option_harmonic1 = 11; // 10 +int option_log_frames = 0; static int flutter_amp = 64; static int general_amplitude = 60; @@ -1529,12 +1530,15 @@ void SetPitch(int length, unsigned char *env, int pitch1, int pitch2) int pitch_value; #ifdef LOG_FRAMES -f_log=fopen("log-espeakedit","a"); -if(f_log != NULL) +if(option_log_frames) { -fprintf(f_log," %3d %3d\n",pitch1,pitch2); -fclose(f_log); -f_log=NULL; + f_log=fopen("log-espeakedit","a"); + if(f_log != NULL) + { + fprintf(f_log," pitch %3d %3d %3dmS\n",pitch1,pitch2,(length*1000)/samplerate); + fclose(f_log); + f_log=NULL; + } } #endif if((pitch_env = env)==NULL) @@ -1592,14 +1596,18 @@ void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2) static int glottal_reduce_tab2[4] = {0x90, 0xa0, 0xb0, 0xc0}; // vowel after [?], amp * 1/256 #ifdef LOG_FRAMES -f_log=fopen("log-espeakedit","a"); -if(f_log != NULL) +if(option_log_frames) { -fprintf(f_log,"%3dmS %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d %4d/%3d\n",length*1000/samplerate, - fr1->ffreq[0],fr1->fheight[0],fr1->ffreq[1],fr1->fheight[1], fr1->ffreq[2],fr1->fheight[2], fr1->ffreq[3],fr1->fheight[3], - fr2->ffreq[0],fr2->fheight[0],fr2->ffreq[1],fr2->fheight[1], fr2->ffreq[2],fr2->fheight[2], fr2->ffreq[3],fr2->fheight[3] ); -fclose(f_log); -f_log=NULL; + f_log=fopen("log-espeakedit","a"); + if(f_log != NULL) + { + fprintf(f_log,"%3dmS %3d %3d %4d %4d (%3d %3d %3d %3d) to %3d %3d %4d %4d (%3d %3d %3d %3d)\n",length*1000/samplerate, + fr1->ffreq[0],fr1->ffreq[1],fr1->ffreq[2],fr1->ffreq[3], fr1->fheight[0],fr1->fheight[1],fr1->fheight[2],fr1->fheight[3], + fr2->ffreq[0],fr2->ffreq[1],fr2->ffreq[2],fr2->ffreq[3], fr2->fheight[0],fr2->fheight[1],fr2->fheight[2],fr2->fheight[3] ); + + fclose(f_log); + f_log=NULL; + } } #endif @@ -1676,6 +1684,28 @@ f_log=NULL; } // end of SetSynth +#ifdef LOG_FRAMES +static void LogMarker(int type, int value) +{//======================================= + if(option_log_frames == 0) + return; + + if((type == espeakEVENT_PHONEME) || (type == espeakEVENT_SENTENCE)) + { + f_log=fopen("log-espeakedit","a"); + if(f_log) + { + if(type == espeakEVENT_PHONEME) + fprintf(f_log,"Phoneme [%s]\n",WordToString(value)); + else + fprintf(f_log,"\n"); + fclose(f_log); + f_log = NULL; + } + } +} +#endif + static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2) {//==================================================================================== if(resume==0) @@ -1849,7 +1879,9 @@ int WavegenFill(int fill_zeros) case WCMD_MARKER: MarkerEvent(q[1],q[2],q[3],out_ptr); - +#ifdef LOG_FRAMES + LogMarker(q[1],q[3]); +#endif if(q[1] == 1) { current_source_index = q[2] & 0xffffff;