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-fd96e6ae7743master
@@ -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^ |
@@ -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: * | |||
// * <http://www.gnu.org/licenses/>. * | |||
// ***************************************************************************/ | |||
@@ -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 |
@@ -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 |
@@ -4,9 +4,10 @@ | |||
.group a | |||
a A | |||
_) a (_ %A | |||
!_n) ato a:to: // NATO | |||
.group á | |||
á a: | |||
@@ -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 |
@@ -365,10 +365,9 @@ | |||
.group р | |||
_) р (_ E* | |||
р (_ r; | |||
р (Y r; | |||
р (B r; | |||
р @-* | |||
р (Y R; | |||
р (B R; | |||
р R | |||
.group с | |||
_) с (_ Es |
@@ -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 |
@@ -0,0 +1 @@ | |||
// Initially empty |
@@ -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 | |||
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; ix<n_phoneme_tabs; ix++) | |||
{ | |||
if(strcmp(phoneme_tab_list2[ix].name,item_string) == 0) | |||
{ | |||
phtab = &phoneme_tab_list2[ix]; | |||
break; | |||
} | |||
} | |||
if(phtab == NULL) | |||
{ | |||
Error("Unknown phoneme table",item_string); | |||
return; // phoneme table not found | |||
} | |||
for(ix=1; ix<256; ix++) | |||
{ | |||
if(mnem == phtab->phoneme_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) | |||
{ |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; |
@@ -123,6 +123,7 @@ enum { | |||
MENU_OPTIONS, | |||
MENU_PARAMS, | |||
MENU_PATHS, | |||
MENU_PATH0, | |||
MENU_PATH1, | |||
MENU_PATH2, | |||
MENU_PATH3, |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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 |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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); |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -30,6 +30,7 @@ | |||
#define phVFRICATIVE 7 | |||
#define phNASAL 8 | |||
#define phVIRTUAL 9 | |||
#define phDELETED 14 | |||
#define phINVALID 15 | |||
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; | |||
} |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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)) |
@@ -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 | |||
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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) | |||
{ | |||
// there is a list of character codes to be substituted with alternative codes | |||
if(langopts.replace_chars == NULL) | |||
return(c); | |||
if((p = wcschr(langopts.replace_chars,c)) == NULL) | |||
{ | |||
// Try converting to lower case | |||
if((p = wcschr(langopts.replace_chars,towlower(c))) != NULL) | |||
upper_case =1; | |||
} | |||
// there is a list of character codes to be substituted with alternative codes | |||
if(p != NULL) | |||
if(iswupper(c)) | |||
{ | |||
c = towlower(c); | |||
upper_case = 1; | |||
} | |||
new_c = 0; | |||
for(ix=0; (word = langopts.replace_chars[ix]) != 0; ix++) | |||
{ | |||
if(c == (word & 0xffff)) | |||
{ | |||
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; | |||
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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); | |||
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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 |
@@ -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: * | |||
* <http://www.gnu.org/licenses/>. * | |||
***************************************************************************/ | |||
@@ -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; |