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 7b372399..17ea16c0 100644
Binary files a/phsource/voc/v and b/phsource/voc/v differ
diff --git a/src/compiledata.cpp b/src/compiledata.cpp
index 06f70904..fbf7ff28 100755
--- a/src/compiledata.cpp
+++ b/src/compiledata.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: *
* . *
***************************************************************************/
@@ -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;