diff --git a/dictsource/de_list b/dictsource/de_list
index 3f4caa2f..f20a80e8 100644
--- a/dictsource/de_list
+++ b/dictsource/de_list
@@ -93,6 +93,12 @@ _tld t'Ild@
v faU
x Iks
+// Alphabets
+_ar aR'AbIS
+_cyr ky:R'IlIS
+_he hEbr'E:IS
+
+
// Numbers
//========
_0 'nUl
diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes
index 9d6813ba..96d541b0 100644
--- a/dictsource/dict_phonemes
+++ b/dictsource/dict_phonemes
@@ -67,7 +67,7 @@ R3 s S t T tS v w
x z Z
-Dictionary hu_dict 2012-07-25
+Dictionary hu_dict 2013-02-25
a A a: e E e: i i:
o o: u u: Y y y: Y:
@@ -79,7 +79,7 @@ S s2 t t2 tS ts v w
z Z
-Dictionary de_dict 2012-11-26
+Dictionary de_dict 2013-02-25
3 @ @- a A A: aI aU
A~ E E2 E: e: EI i I
@@ -103,20 +103,21 @@ p Q r R s s; t T
ts v x z
-Dictionary en_dict 2013-02-20
+Dictionary en_dict 2013-02-27
0 0# 3 3: @ @- @2 @5
@L a a# A: A@ aa aI aI3
-aI@ aU aU@ A~ E e: e@ eI
-i I I# I2 i: i@ i@3 IR
-O O: o: O@ o@ OI oU O~
-U u: U@ V VR
+aI@ aU aU@ A~ e E e: e@
+eI i I I# I2 i: i@ i@3
+IR o O O: o: O@ o@ OI
+oU O~ u U u: U@ V VR
-: ; ? b C d D d#
-dZ f g h j k l l#
-m n N n^ p Q r r-
-s S t T t2 tS v w
-x z Z z#
+* : ; ? b C d D
+d# dZ f g h j k l
+l# l/ m n N n^ p Q
+q Q" r R r- R2 s S
+t T t2 tS v w x z
+Z z#
Dictionary eo_dict 2013-01-24
@@ -329,7 +330,7 @@ k l m n p R s S
t tS v w x
-Dictionary nl_dict 2011-11-22
+Dictionary nl_dict 2013-02-26
8 @ @- a A a: A~ e
E e# E2 e: EI eU i I
@@ -377,7 +378,7 @@ S s; S; t t; tS ts tS;
ts; v w x z Z Z;
-Dictionary pt_dict 2013-02-20
+Dictionary pt_dict 2013-02-25
& &/ &U~ &~ @ @- a A
aI aU e E eI EI eU EU
diff --git a/dictsource/en_list b/dictsource/en_list
index 37fa1abb..27531271 100644
--- a/dictsource/en_list
+++ b/dictsource/en_list
@@ -225,8 +225,9 @@ _₠ jU@roU
♭ flat
¬ n0t_|saIn
√ skw,e@r'u:t
-∞ Inf'InI2tI2
+∞ Inf'InI2ti
≠ n0t'i:kw@LtU
+∫ IntIgr@L
№ nju:m@roU
। dVnda#
● bl,aks'3:k@L
@@ -249,6 +250,140 @@ _₠ jU@roU
ʧ tSES
ʤ dZEZ
+// Language names
+_el gr'i:k
+_cyr sI2r'IlIk
+_hy A@m'i:ni@n
+_he h'i:bru:
+_ar 'ar@bIk
+_dv t'A:na#
+_hi h'Indi
+_bn bEng'A:li
+_gur g'U@mUki
+_gu gu:dZ3r'A:ti
+_or 0r'i@
+_ta t'amI2l
+_kn k'A:na#d@
+_ml maleI'A:l@m
+_si sI2nh'A:l@
+_th t'aI
+_lo l'aU
+_ti tI2b'Et@n
+_my mj'A:nmA@
+_ka dZ'O@dZ@n
+_ko k3r'i@n
+_eth i:TI'0pIk
+
+
+// Cyrillic letters
+а a
+б bE
+в vE
+г gE
+д dE
+е jE
+ё jo
+ж ZE
+з zE
+и I
+й ,Ik@-*'atkOji
+к ka
+л El/1
+м Em
+н En
+о o
+п pE
+р Er
+с Es
+т tE
+у u
+ф Ef
+х xa
+ц tsE
+ч tSE
+ш Sa
+щ StSa
+ъ jEr
+ы _^_RU
+ь jer
+э E
+ю ju
+я ja
+
+// Arabic letters
+
+ء h'amza
+آ 'Elifm,adda#
+أ 'Elifh,amza
+ا 'Elif
+ب bE?
+ة t'E?maR2b'uta#
+ت tE?
+ث TE?
+ج ZIm
+ح hE?
+خ xE?
+د dEl/1
+ذ DEl/1
+ر R2A:?
+ز zEjn
+س si:n
+ش Si:n
+ص sO:d@-
+ض dO:d@-
+ط thA:?
+ظ DA:?
+ع ?ajn
+غ Q"ajn
+ف fE?
+ق qO:f
+ك kEf
+ل lEm
+م mi:m
+ن nu|:n
+ه hE?
+و wO:w
+ي jE?
+
+َ a
+ِ i
+ُ u
+ّ S'ada#
+ْ suk'un
+
+
+
+
+// Hebrew letters
+א 'alef_
+ב bet_
+ג 'gimel_
+ד 'dalet_
+ה he_
+ו vav_
+ז z'ajin_
+ח xet_
+ט tet_
+י jod_
+ך kaf_
+כ kaf_
+ל l'amed_
+ם mem_
+מ mem_
+ן nun_
+נ nun_
+ס s'amex_
+ע ?'ajin_
+ף pe_
+פ pe_
+ץ ts'adi_
+צ ts'adi_
+ק kuf_
+ר ReS_
+ש Sin_
+ת tav_
+
+
// phonetic modifiers
ː lENT@nd_
U+2b0 aspI2reItI2d_ // supr-h
@@ -389,6 +524,7 @@ id $abbrev
ie aIi:_! $pause $only
i.e aIi:_! $pause
imo $abbrev
+inlb $abbrev
irc $abbrev
irs $abbrev
itx $abbrev
@@ -443,6 +579,7 @@ utc $abbrev
uv $abbrev
VI $abbrev
wwii dVb@Lju:dVb@Lju:t'u:
+xl $abbrev // not roman 40
xxx $abbrev // not roman 30
xy $abbrev
yd $abbrev
@@ -814,12 +951,14 @@ brie bri:
bridal braId@L
brigade $2
brigadier brIga#d'i@3
+brioche bri:'oUS
broccoli br0k@li
brochure broUS3
?3 brochure broU'SU@r
brooch broUtS
budgerigar bVdZ@rIgA@
buffet bVfeI
+?3 bulimia bUl'Imi@
bunion bVnI2@n
bureaucracy bjU@'0kr@si
bursar b3:s3
@@ -875,6 +1014,7 @@ carburetor kA@b@r'Et3
?3 carburetor kA@b@reIt3
career k@r'i@3
caress k@rEs
+carousel kar@s'El
carpel kA@p@l
cascade $alt3
cashier kaS'i@3
@@ -1056,8 +1196,7 @@ convent k0nv@nt
converse $1 $only
converse $verb
convert $1 $noun
-convict $1 $onlys
-convict $verb
+convict $2 $verb
convolute k0nv@l'u:t
coop ku:p
cooper ku:p3
@@ -1483,7 +1622,6 @@ haha hA:h'A:
halleluiah halI2'lu:j@
hallelujah halI2'lu:j@
halloween $3
-hallucinate $alt3
halogen hal@dZ@n
hanged haNd
harem hA:r'i:m
@@ -1641,6 +1779,7 @@ itinerary aIt'In@r@rI
ja jA:
jagged dZagI#d
jaguar dZagwA@
+jalapeno hA:l@p'eIn;oU
japan dZ@pan
jasmine dZazmIn
jedi dZEdaI
@@ -1651,6 +1790,7 @@ jukebox dZu:kb0ks
july dZu:l'aI
kaput $alt3
+karaoke karI'oUki
karate k@rA:ti
kebab k@bab
?3 kebab k@bA:b
@@ -1936,6 +2076,7 @@ nosedive noUzdaIv
nosir noUs3:
not noUt // for noted, notable, etc
nots n0ts
+(nôtre dame) noUtr@'dA:m
nott n0t
nothing nVTIN
notwithstanding $3
@@ -2027,6 +2168,7 @@ oxymoron $3
padre pA:dreI
paella paI'El@
palling palIN
+palsy pO:lzi
papa pa#p'A:
?3 papa pA:p@
papal peIp@L
@@ -2116,7 +2258,7 @@ pizzeria pi:ts@r'i@
plaguing pleIgIN
playtest pleItEst
plaza plA:z@
-plebeian pl@b'i@n
+plebeian pl@b'i:@n
plethora plET3r@
plicate $2
plumber plVm3
@@ -2128,6 +2270,7 @@ poll poUl
polyamide p0lI'eImaId
polythene $1
portend po@t'End
+?!3 portrait po@treIt
poseidon p@saId@n
posse p0si
postage poUstI2dZ
@@ -2370,19 +2513,18 @@ salad sal@d
salami $alt3
saline seIlaIn
?3 saline seIli:n
+salmon sam@n
?3 salon $alt3
saloon $alt3
san ,san $only
sardine $2
-satan seIt@n
-satanist seIt@nIst
+satanic $alt3
saucepan sO:sp@n
saudi saUdi
saute sO:teI
?3 savant sa#vA:nt
says sEz
scaly skeIlI
-salmon sam@n
scalpel skalp@L
scared ske@d
scaring ske@rIN
@@ -2458,6 +2600,8 @@ sierra si:'e@r@
signage saInI2dZ
signal sIgn@l // signaled
signer saIn3
+signoff s,aIn'0f
+signon s,aIn'0n
signup saInVp
sikh si:k
silo saIloU
@@ -2932,7 +3076,6 @@ Belgrade $2
Belize bEl'i:z
Bengal b,Eng'O:l
Benin bEnIn
-Berlin b3:l'In
Bhutan bu:t'an
Bideford bIdIf@d
Bogota b0g@t'A:
@@ -2993,6 +3136,7 @@ Geneva dZ@ni:v@
Gdansk g@-dansk
Gibraltar $2
Gomera goUm'e@r@
+Gurmukhi gU@mUki
Harare ha#rA:ri
Hanoi han'OI
Havana ha#van@
@@ -3073,6 +3217,7 @@ Moroccan m@r0k@n
Montana m0nt'an@
Monte m0nt2i
Munich mju:nIk
+Myanmar mjA:nmA@
Nairobi naIr'oUbi
Naples neIp@Lz
Nauru naUru:
@@ -3136,6 +3281,7 @@ Sumatran su:m'A:tr@n
Suriname sU@rIn'am
Taipei t,aIp'eI
Taiwan taI'wA:n
+Taiwanese taIw@n'i:z
Tawakoni ta#wA:k@ni
Tblisi t@-bli:si
Tehran te@r'A:n
@@ -3348,7 +3494,7 @@ Jacob dZeIk@b
Jacques Zak
Jamie dZeImi
Jared dZar@d
-Jarred dZar@d
+Jarrad dZar@d
Jesus dZi:z@s
Jonah dZoUn@
José hoUs'eI
@@ -3496,6 +3642,7 @@ Tricia trIS@
Vanessa $alt3
Wallace w0lI#s
Wally w0li
+?3 William wIlj@m
Yves i:v
Yvonne $2
Zoe zoUi
@@ -3510,6 +3657,7 @@ Boswell b0zwEl
Buchanan bju:k'an@n
Cabrillo ka#bri:oU
Campbell kamb@l
+Capone ka#poUn
Carnegie kA@n@gi
Cohen koU@n
Cthulhu k@-Tu:l#u:
@@ -3529,6 +3677,7 @@ Gibson gIbs@n
Guinness gInIs
Hades heIdi:z
Hamilton ham@Lt@n
+Hoosier hu:Z3
Jacobi dZa#koUbi
Kendell kEnd@L
Kyocera kaI|@s'i@r@
@@ -3555,7 +3704,9 @@ Rivera rI2ve@r@
Rizzoli rI2zoUli
Rodrigues r0dr'i:gEz
Sanchez santSEz
+Shakur Sa#kU@
Tzu tsu:
+Versace v3sA:tSi
Wii wi::
Yaesu jeIsu:
Yamaha jam@hA:
diff --git a/dictsource/en_rules b/dictsource/en_rules
index 3aaa5016..97f6c7ab 100644
--- a/dictsource/en_rules
+++ b/dictsource/en_rules
@@ -53,7 +53,7 @@
-) a (- a#
_) a (- 'eI
_) a (-half a#
- X) a ($w_alt3+++ a#
+ X) a ($w_alt3++++ a#
sw) a (B 0
a (Be# eI
w) a (Be# eI
@@ -155,6 +155,7 @@
@) a (tious 'eI
n) a (tur eI
n) a (tura a
+ &) a (ture_ @
sign) a (ture I
_) a (ve a
_) a (viat eI
@@ -499,6 +500,7 @@
aise (_ 'eIz
_c) ais (l aS // 'caislin'
@l) ais (_ eI
+ portr) ai (t I#
.group al
_) al (@ a#l
@@ -532,6 +534,7 @@
_) al (i al
_) al (ig a#l
X) al (in eIl
+ st) al (in A:l
_) ali (Be a#laI
&) ali (sC_ @lI
&) al (isCic @l
@@ -620,6 +623,7 @@
f) all (ib al
_C) all (ow al
h) all (C O:l
+ h) all (uc a#l
sm) all O:l
st) all O:l
t) all O:l
@@ -686,7 +690,7 @@
und) am (en @m
_) am (en a#m
ame (nab a#mi:
- _l) ame (nt %amE
+ _l) am (ent a#m
amm (end a#m
amoeb a#mi:b
f) amil amIl
@@ -748,6 +752,7 @@
&) an (ty_ @n
&) an (t_ @n
&) an (t_$w_alt an
+?3 &) an (t_$w_alt A:n
?8 &) an (t_ a#n
_f) an (at a#n
pl) an (t_ an
@@ -900,7 +905,7 @@
_p) ara (de @reI
&t) ar (_ 3
st) ar (_ A@
- guit) ar (_ A@
+ guit) ar 'A@
_t) ar (_ A@
&) ar (dis 3
&) ar (diz 3
@@ -1084,6 +1089,7 @@
w) ast (e# eIst
.group at
+ _s) ata (n eIt@
_g) ator eIt3
&) ate (_$w_alt2 @t
pal) ate (_ @t
@@ -1101,7 +1107,7 @@
par) ates (_ eIt|s
@) ated (++_ eItId
_s) ate (ll at@
- @) ati (_ 'A:tI
+ @) ati (_ 'A:ti
at (im_ 'eIt
@) ating (++_ eItIN
&) at (ive @t
@@ -1126,7 +1132,7 @@
@) ath (An_ @T
athed (_ eIDd
athei eITI2I
- &) athy =@TI2
+ &) athy (_ =@TI2
@) ath (is =@T
_) at (lan a#t
at (omi a#t
@@ -1231,7 +1237,7 @@
.group b
b b
- _) bh b
+ _) bh (@ b
_) b (L01Y b // allow _bl _br
_) bj (A bj
_) brz (e brz
@@ -1289,6 +1295,7 @@
benevo b@nEv@
_) be (o beI
be (qu bI2
+ _) berlin %b3:lIn
_) ber (s b3
be (see bI2
be (sie bI2
@@ -1594,7 +1601,7 @@
co (ntrol+ k@
conva (l k0nv@
_) co (nvenA k@
- _) co (nvi k@
+ _) co (nvi k0#
_) co (nvoy k0
_) co (nw k0
_) copy k0pI
@@ -2200,6 +2207,7 @@
h) emorrh Em@r
sph) em @m
sph) em (e 'i:m
+ _s) ema (nti @ma
&) em (y_ @m
yst) em @m
yst) em (i Em
@@ -2378,6 +2386,7 @@
erred (_ '3:d
er (_ 3:
er (B_ 3:
+ _c) ere (br 3ri:
&) ere (_ 3
ere (_ 3:
&) er (s_ 3
@@ -2987,7 +2996,7 @@
&) ia (n i@
@) ia (nic I'a
@) ia (nit I'a
- @) ia (na i:'a
+ @) ia (na_ i:'a
ia (ng_ ja
_f) ia (nc I'0
_f) iance I'0nseI
@@ -3467,6 +3476,7 @@
an) ism (_S3d Iz@m
@iB) ism (_S3d Iz@m
@) ism (_S3de Iz@m
+ et) ism (_S3 Iz@m
is (o_ aIz
is (or_ aIz
iss (a_ 'Is
@@ -3575,6 +3585,7 @@
_) ja (mai dZa#
_) jere (C dZEr@
_) jes (ui dZEz
+ _) jiha (d dZI2hA:
_) joa (n@ dZoU'a
n) j (a_ j
j (ü j
@@ -4706,7 +4717,7 @@
per (fec p3
_) per (iC@@ p,Er
_) perini pErIn'i:
- per (iph p3r
+ _) per (iph p3r
_) per (isc pEr
_) per (ish pEr
perme (a p3:mI
@@ -4946,7 +4957,7 @@
_) re (i@P2 r,i:
_) rei (c raI
_) rei (l raI
- _) rei (s raI
+ _) reis raIz
_) re (iss r%i:
_) rele (g rElI2
rele (nt rI2lE
@@ -5845,6 +5856,7 @@
_) zs (Y z
_) z (wY z
+ n) z (_ ts
@) zales (_ z'A:l@s
zei zaI
zes (_ zI2z
@@ -6051,6 +6063,7 @@
// ñ nj
ñ _^_ES
+ _) ʻ (A ? // arabic
'
! _:Ekskl@meIS@n_:
diff --git a/dictsource/hu_list b/dictsource/hu_list
index fedebc09..fe8aa7ab 100755
--- a/dictsource/hu_list
+++ b/dictsource/hu_list
@@ -5421,6 +5421,12 @@ _ˇ lEfEle:n^i:l
_¡ AlSo:indEks
+// Alphabets
+_ar 'AR2Ab
+_cry ts'iR2ill
+_he h'e:bER2
+
+
// Main Exceptions List
//=====================
diff --git a/dictsource/nl_list b/dictsource/nl_list
index 72858e88..8842911f 100644
--- a/dictsource/nl_list
+++ b/dictsource/nl_list
@@ -703,6 +703,27 @@ zwanger $alt
Vlaander $alt
+// -s is not a suffix
+as $alt
+bres $alt
+chaos $alt $1
+es $alt
+fles $alt
+fris $alt
+glas $alt
+mes $alt
+moeras $alt
+was $alt // gewas
+
+// -s, just remove 's' from the plural
+charges $alt2
+curves $alt2
+droogtes $alt2
+groeves $alt2
+hoeves $alt2
+reserves $alt2
+marges $alt2
+marge mArZ@
// words where -age is [a:Q@] not French ['a:Z@]
drage $alt
@@ -1370,9 +1391,6 @@ meppel $alt
moesel muz@l
vondel $alt
-// -s is not plural
-chaos xa:Os
-
// all words on _aard are treated as suffix in the rules.
diff --git a/dictsource/nl_rules b/dictsource/nl_rules
index bd3d594d..c15ddde1 100644
--- a/dictsource/nl_rules
+++ b/dictsource/nl_rules
@@ -30,7 +30,7 @@
m) ach (in %a:S
_) af (C@P2 'Af
_) affich %AfiS
- age (_N 'a:Z@
+ age (_ 'a:Z@
ages (_S1 s
age (_$w_alt a:Q@
aille (_ 'Aj@
@@ -45,6 +45,7 @@
@) ant (e_ 'Ant
@) ant (en_ 'Ant
@) ant (er_ 'Ant
+ @) ares (_ a:r'Es
aris (_ 'a:rIs
arissen (_ 'a:rIs@n
a (tor_ 'a:
@@ -243,8 +244,10 @@
@) ent (st_ 'Ent
@) ent (ste_ 'Ent
ag) ent 'Ent
- @j) es (_ @s
+ @j) es (_S1 s
+ @z) es (_S1 s
@) es (_S2qd 'Es // double the previous vowel
+ @) es (_$w_alt2S1 s // just remove 's'
KAC) es (_S2e @s
@) essen (_S5qd 'Es@n
@) eres (_S4qd @r'Es
@@ -400,6 +403,9 @@
_) in (C@P2 'In
// _) in (gP2 'In
io (nage iO
+ io (de_ i'o:
+ iodes (_ i'o:d@s
+ is (_ Is
@) isch (_ =is
@) ische (_ =is@
@) isme (_ 'Ism@
@@ -449,6 +455,7 @@ _) inn (@P2 'I // ?? inneren
management ma:nIdZm@nt
_) mee (@P3 m'e:
menu (_ m@ny
+ _) mi (cro mi
_) mi (s@ m%I
_) mis (anC miz
_) mis (commP3 m'Is
@@ -526,6 +533,7 @@ _) inn (@P2 'I // ?? inneren
_) openings (P8 'o:p@nINs
_) op (era 'o:p
_) op (tion Op
+ os (_ Os
ou (che_ u
ouch (en_ uS
d) ou (blu u
@@ -620,6 +628,7 @@ _) inn (@P2 'I // ?? inneren
sj S
@) sje (_ sj@
@) s (_S1 s
+ @) s (_$w_alt =s
sc (oop sk
sc (opi sk
@@ -702,6 +711,7 @@ _) inn (@P2 'I // ?? inneren
uw (_ yU
_) uit (@P3 'Wyt
+ us (_ 8s
u (sie_ 'y
@) ute (_ 'yt
uu (r_ 'y
diff --git a/dictsource/pt_list b/dictsource/pt_list
index d2a6ccfc..3f55eae9 100755
--- a/dictsource/pt_list
+++ b/dictsource/pt_list
@@ -41,6 +41,11 @@ _stk b'ax&
_tld tS'iU
?1 _tld til
+// alphabets
+_ar 'a*aby
+_cyr si*'ilikU
+_he eb*'aIkU
+
// character names
@@ -372,38 +377,38 @@ do $u $nounf
da $u $nounf
dos $u $nounf
das $u $nounf
-dum $u
-duma $u
-duns $u
-dumas $u
+dum $u $nounf
+duma $u $nounf
+duns $u $nounf
+dumas $u $nounf
em $u // in,on,at
no nu $u $nounf
na $u $nounf
-num $u
-numa $u
-nuns $u
-numas $u
+num $u $nounf
+numa $u $nounf
+nuns $u $nounf
+numas $u $nounf
por $u $nounf // by,for,through
pelo $u $nounf
?2 pela $u $nounf p'el&
-ao $u
+ao $u $nounf
à ,a:
à $atend $atstart $accent
-aos $u
-às ,a:s
+aos $u $nounf
+às ,a:s $nounf
para $u // for,to
pro $u $nounf
-pra $u
-pros $u
-pras $u
-prò $u
-prà $u
-pròs $u
-pràs $u
+pra $u $nounf
+pros $u $nounf
+pras $u $nounf
+prò $u $nounf
+prà $u $nounf
+pròs $u $nounf
+pràs $u $nounf
com $u // with
?2 sem // without
@@ -660,6 +665,7 @@ atrozes $alt
austera $alt
austero $alt
autora $alt2
+avesso $alt2
axé aSE
baqueta $alt2
beco $alt2
@@ -696,6 +702,8 @@ cateto $alt2
catorze $alt2
cebola $alt2
cefaleia $alt
+cerca $alt
+cerca $alt2 $noun
cerco $alt $verb
cesta $alt2
cesto $alt2
diff --git a/dictsource/pt_rules b/dictsource/pt_rules
index 7a1a327f..5a5a3600 100755
--- a/dictsource/pt_rules
+++ b/dictsource/pt_rules
@@ -361,6 +361,7 @@ _estend) e (L06_ e
_vend) e (L06_ e
respond) e (L06_ e // cor-
_aborrec) e (L07_ e
+_rejuvenec) e (L07_ e
_adoec) e (L07_ e
_amanhec) e (L07_ e
_anoitec) e (L07_ e
@@ -398,6 +399,7 @@ entend) e (L07_ e
padec) e (L07_ e // com-
parec) e (L07_ e // a- rea- com- desa-
preend) e (L07_ e // sur- com-
+_perec) e (L07_ e
respond) e (L07_ e // cor-
torc) e (L07_ e // con-
venc) e (L07_ e // con-
@@ -430,6 +432,7 @@ respond) e (L07_ e // cor-
_alb) e (rguL02_ E
_enx) e (rguL02_ E
_bez) e (rrL03_ e
+ _rejuven) e (çL03_ e
_inv) e (rtL03_ e
_f) e (rvL03_ e
_p) e (scL03_ E
diff --git a/phsource/compile_report b/phsource/compile_report
index 33fbd4ff..69fdc75a 100644
--- a/phsource/compile_report
+++ b/phsource/compile_report
@@ -1,5 +1,5 @@
-86 phoneme tables
+87 phoneme tables
new total
base 109 109
consonants 10 118
@@ -53,6 +53,7 @@ consonants 10 118
no 28 134
is 42 141
vi 53 147
+ vi-hue 8 147
zhy 41 138
zh 64 155
sw 9 110
@@ -235,11 +236,15 @@ dzh/xdz_pzd [J] base
envelope/i_risefall [11] zh
envelope/i_risefall2 [+2] rw
envelope/p_214 [5] vi
+ [5] vi-hue
[214] zh
envelope/p_512 [6] vi
+ [4] vi-hue
+ [6] vi-hue
[+] pa
envelope/p_fall [2] vi
[7] vi
+ [2] vi-hue
[4] zhy
[7] zhy
[21] zh
@@ -250,17 +255,23 @@ envelope/p_fall [2] vi
[+] rw
envelope/p_fallrise [4] vi
envelope/p_level [1] vi
+ [1] vi-hue
+ [7] vi-hue
[1] zhy
[3] zhy
[6] zhy
[55] zh
envelope/p_rise [3] vi
+ [3] vi-hue
[2] zhy
[5] zhy
[44] zh
[35] zh
envelope/vi_5amp [5] vi
+ [5] vi-hue
envelope/vi_6amp [6] vi
+ [2] vi-hue
+ [6] vi-hue
g2/xg [gh] hi
g/g [g] base
[g-] en
@@ -421,7 +432,7 @@ l/l_ [l] base
[l/] fr
l/l_@ [l/3] base
[l/] fr
-l/l@ [h6s] base
+l/l@ [h6r] base
[l#] base
[l] fr
[l/2] fr
@@ -455,7 +466,7 @@ l/L2_oL [l/2] base
l/L2_uL [l/2] base
l/l_3 [l/] de
l/l_4 [ll] sq
-l/la [h6s] base
+l/la [h6r] base
[l#] base
[l] fr
[l/2] fr
@@ -463,7 +474,7 @@ l/la [h6s] base
[K] tn
l/l_a [l/3] base
[l/] fr
-l/le [h6s] base
+l/le [h6r] base
[l#] base
[l] fr
[l/2] fr
@@ -475,7 +486,7 @@ l/L_eL_af [&] af
[&:] af
l/l_front [L] sq
l/l_front_ [l/4] sq
-l/li [h6s] base
+l/li [h6r] base
[l#] base
[l] fr
[l/2] fr
@@ -489,7 +500,7 @@ ll/ll [L] base
ll/_ll [L] base
l/l_long [l] base
[l] fr
-l/lo [h6s] base
+l/lo [h6r] base
[l#] base
[l/2] fr
[K] nso
@@ -500,7 +511,7 @@ l^/l_rfx [l.] base
[l;] lt
[l] ru
[l^] ru
-l/lu [h6s] base
+l/lu [h6r] base
[l#] base
[l] fr
[l/2] fr
@@ -1356,6 +1367,7 @@ vnasal/aa_n4 [A~] de
[A~] fr
[A~] ht
vnasal/a#_n [&~] pt
+vnasal/a#_n2 [&~] pt
vnasal/a#u_n [&U~] pt
[&U~] pt-pt
[o#] vi
@@ -1391,7 +1403,6 @@ vnasal/u_n [U~] hi
vnasal/V_n [V~] hi
vnasal/W_n [E~] fr
[W~] fr
- [&~] pt
[E~] ht
voc/bh [B] base
voc/dh [D] base
diff --git a/phsource/ph_english_us b/phsource/ph_english_us
index 5b2b64cc..93d2454e 100644
--- a/phsource/ph_english_us
+++ b/phsource/ph_english_us
@@ -354,20 +354,17 @@ phoneme t
vls alv stop
voicingswitch d
lengthmod 2
-
-// IF prevPhW(isVowel) OR prevPhW(n) THEN
- IF prevPhW(isVowel) THEN // test, don't reduce [t] after [n]
- IF nextPhW(isVowel) AND nextPh(isUnstressed) THEN
- IF next2Ph(n) AND next2Ph(notWordStart) THEN
- ELSE
- ChangePhoneme(t#)
- ENDIF
- ENDIF
- ENDIF
-
Vowelin f1=0 f2=1700 -300 300 f3=-100 80
Vowelout f1=0 f2=1700 -300 250 f3=-100 80 rms=20
+ IF nextPhW(isVowel) AND nextPh(isUnstressed) AND NOT next2PhW(n) THEN
+ IF prevPhW(isVowel) THEN
+ ChangePhoneme(t#)
+ ELIF prevPhW(n) THEN
+ WAV(ustop/t, 60)
+ ENDIF
+ ENDIF
+
IF nextPh(isPause2) THEN
WAV(ustop/t_)
ELIF nextPh(r) OR nextPh(R) OR nextPh(R2) THEN
diff --git a/phsource/ph_pt_brazil b/phsource/ph_pt_brazil
index e7f233db..c39d76e3 100644
--- a/phsource/ph_pt_brazil
+++ b/phsource/ph_pt_brazil
@@ -40,7 +40,7 @@ phoneme &~
ipa ɐU+0303
length 180
IF thisPh(isFinalVowel) THEN
- FMT(vnasal/W_n)
+ FMT(vnasal/a#_n2)
ELSE
FMT(vnasal/a#_n)
ENDIF
diff --git a/phsource/phonemes b/phsource/phonemes
index 2c050525..5f0f61e2 100644
--- a/phsource/phonemes
+++ b/phsource/phonemes
@@ -1814,6 +1814,9 @@ include ph_icelandic
phonemetable vi base
include ph_vietnam
+phonemetable vi-hue vi
+include ph_vietnam_hue
+
phonemetable zhy base
include ph_zh_yue
diff --git a/phsource/vowel/&_2 b/phsource/vowel/&_2
index a6d61039..6c62b459 100644
Binary files a/phsource/vowel/&_2 and b/phsource/vowel/&_2 differ
diff --git a/phsource/vowel/vowelchart.png b/phsource/vowel/vowelchart.png
index f81d4859..180761a3 100644
Binary files a/phsource/vowel/vowelchart.png and b/phsource/vowel/vowelchart.png differ
diff --git a/src/compiledata.cpp b/src/compiledata.cpp
index 4e83fa7a..762f6e58 100644
--- a/src/compiledata.cpp
+++ b/src/compiledata.cpp
@@ -1390,6 +1390,24 @@ static int NextItem(int type)
+static int NextItemMax(int max)
+{//==============================
+// Get a number, but restrict value to max
+ int value;
+ char msg[80];
+
+ value = NextItem(tNUMBER);
+ if(value > max)
+ {
+ sprintf(msg, "Value %d is greater than maximum %d", value, max);
+ error(msg, NULL);
+ value = max;
+ }
+ return(value);
+}
+
+
+
static int NextItemBrackets(int type, int control)
{//===============================================
// Expect a parameter inside parantheses
@@ -2794,17 +2812,17 @@ int CompilePhoneme(int compile_phoneme)
break;
case i_PAUSE_BEFORE:
- value = NextItem(tNUMBER);
+ value = NextItemMax(255);
*prog_out++ = (i_PAUSE_BEFORE << 8) + value;
break;
case i_PAUSE_AFTER:
- value = NextItem(tNUMBER);
+ value = NextItemMax(255);
*prog_out++ = (i_PAUSE_AFTER << 8) + value;
break;
case i_SET_LENGTH:
- value = NextItem(tNUMBER);
+ value = NextItemMax(511);
if(after_if == 0)
{
phoneme_out->std_length = value/2;
diff --git a/src/dictionary.cpp b/src/dictionary.cpp
index 880eda41..4ed621f6 100644
--- a/src/dictionary.cpp
+++ b/src/dictionary.cpp
@@ -2489,6 +2489,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
int ix;
unsigned int digit_count=0;
char *p;
+ ALPHABET *alphabet;
int dict_flags0=0;
MatchRecord match1;
MatchRecord match2;
@@ -2685,6 +2686,13 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c
match1.points = 1;
p += (wc_bytes-1);
}
+
+ if(((alphabet = AlphabetFromChar(letter)) != NULL) && (alphabet->language != 0) && (alphabet->offset != tr->letter_bits_offset))
+ {
+ // switch to the nominated language for this alphabet
+ sprintf(phonemes,"%c%s",phonSWITCH, WordToString2(alphabet->language));
+ return(0);
+ }
}
}
diff --git a/src/numbers.cpp b/src/numbers.cpp
index de3e5e17..838fc145 100644
--- a/src/numbers.cpp
+++ b/src/numbers.cpp
@@ -591,15 +591,19 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
int letter;
int len;
int ix;
- int save_option_phonemes;
char *p2;
char *pbuf;
+ ALPHABET *alphabet;
+ int language;
+ int phontab_1;
char capital[20];
char ph_buf[80];
char ph_buf2[80];
+ char ph_alphabet[80];
char hexbuf[6];
ph_buf[0] = 0;
+ ph_alphabet[0] = 0;
capital[0] = 0;
n_bytes = utf8_in(&letter,word);
@@ -627,6 +631,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
return(0);
}
+#ifdef deleted
if((ph_buf[0] == 0) && (tr->translator_name != L('e','n')))
{
// speak as English, check whether there is a translation for this character
@@ -643,6 +648,67 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
return(0);
}
}
+#endif
+
+ alphabet = AlphabetFromChar(letter);
+ if(alphabet != current_alphabet)
+ {
+ current_alphabet = alphabet;
+ if((alphabet != NULL) && !(alphabet->flags & AL_DONT_NAME))
+ {
+ if(Lookup(translator, alphabet->name, ph_alphabet) == 0) // the original language for the current voice
+ {
+ // Can't find the local name for this alphabet, use the English name
+ phontab_1 = tr->phoneme_tab_ix;
+ ph_alphabet[2] = SetTranslator2("en"); // overwrites previous contents of translator2
+ if(Lookup(translator2, alphabet->name, &ph_alphabet[3]) != 0)
+ {
+ ph_alphabet[0] = phonPAUSE;
+ ph_alphabet[1] = phonSWITCH;
+ len = strlen(&ph_alphabet[3]) + 3;
+ ph_alphabet[len] = phonSWITCH; // switch back
+ ph_alphabet[len+1] = phontab_1;
+ ph_alphabet[len+2] = 0;
+ }
+ }
+ }
+ }
+
+
+// caution: SetWordStress() etc don't expect phonSWITCH + phoneme table number
+ if(ph_buf[0] == 0)
+ {
+ if((alphabet != NULL) && (alphabet->language != 0) && !(alphabet->flags & AL_NOT_LETTERS))
+ language = alphabet->language;
+ else
+ language = L('e','n');
+
+ if(language != tr->translator_name)
+ {
+ // speak in the language for this alphabet (or English)
+ ph_buf[2] = SetTranslator2(WordToString2(language));
+ LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1);
+
+ if(ph_buf[3] == phonSWITCH)
+ {
+ // another level of language change
+ ph_buf[2] = SetTranslator2(&ph_buf[4]);
+ LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1);
+ }
+
+ SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table
+
+ if(ph_buf[3] != 0)
+ {
+ ph_buf[0] = phonPAUSE;
+ ph_buf[1] = phonSWITCH;
+ len = strlen(&ph_buf[3]) + 3;
+ ph_buf[len] = phonSWITCH; // switch back
+ ph_buf[len+1] = tr->phoneme_tab_ix;
+ ph_buf[len+2] = 0;
+ }
+ }
+ }
if(ph_buf[0] == 0)
{
@@ -695,10 +761,11 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control)
}
len = strlen(phonemes);
+
if(tr->langopts.accents & 2)
- sprintf(ph_buf2,"%c%s%s",0xff,ph_buf,capital);
+ sprintf(ph_buf2,"%c%s%s%s",0xff,ph_alphabet,ph_buf,capital);
else
- sprintf(ph_buf2,"%c%s%s",0xff,capital,ph_buf); // the 0xff marker will be removed or replaced in SetSpellingStress()
+ sprintf(ph_buf2,"%c%s%s%s",0xff,ph_alphabet,capital,ph_buf); // the 0xff marker will be removed or replaced in SetSpellingStress()
if((len + strlen(ph_buf2)) < N_WORD_PHONEMES)
{
strcpy(&phonemes[len],ph_buf2);
@@ -714,23 +781,25 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
int ix;
unsigned int c;
int n_stress=0;
+ int prev = 0;
int count;
unsigned char buf[N_WORD_PHONEMES];
for(ix=0; (c = phonemes[ix]) != 0; ix++)
{
- if(c == phonSTRESS_P)
+ if((c == phonSTRESS_P) && (prev != phonSWITCH))
{
n_stress++;
}
- buf[ix] = c;
+ buf[ix] = prev = c;
}
buf[ix] = 0;
count = 0;
+ prev = 0;
for(ix=0; (c = buf[ix]) != 0; ix++)
{
- if((c == phonSTRESS_P) && (n_chars > 1))
+ if((c == phonSTRESS_P) && (n_chars > 1) && (prev != phonSWITCH))
{
count++;
@@ -761,10 +830,8 @@ void SetSpellingStress(Translator *tr, char *phonemes, int control, int n_chars)
c = phonPAUSE_NOLINK; // pause following a primary stress
else
c = phonPAUSE_VSHORT;
-// else
-// continue; // remove marker
}
- *phonemes++ = c;
+ *phonemes++ = prev = c;
}
if(control >= 2)
*phonemes++ = phonPAUSE_NOLINK;
diff --git a/src/readclause.cpp b/src/readclause.cpp
index af2b294b..c6bc34e2 100644
--- a/src/readclause.cpp
+++ b/src/readclause.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2005 to 2011 by Jonathan Duddington *
+ * Copyright (C) 2005 to 2013 by Jonathan Duddington *
* email: jonsd@users.sourceforge.net *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -58,7 +58,7 @@ static const char *ungot_word = NULL;
static int end_of_input;
static int ignore_text=0; // set during ... to ignore text which has been replaced by an alias
-static int audio_text=0; // set during
+static int audio_text=0; // set during
static int clear_skipping_text = 0; // next clause should clear the skipping_text flag
int count_characters = 0;
static int sayas_mode;
@@ -110,7 +110,7 @@ static const unsigned short punct_chars[] = {',','.','?','!',':',';',
0xff1a, // fullwidth colon
0xff1b, // fullwidth semicolon
0xff1f, // fullwidth question mark
-
+
0};
@@ -448,7 +448,7 @@ static int GetC_get(void)
end_of_input = 1;
return(0);
}
-
+
if(!end_of_input)
{
if(option_multibyte == espeakCHARS_16BIT)
@@ -563,8 +563,8 @@ static void UngetC(int c)
}
-static const char *WordToString2(unsigned int word)
-{//================================================
+const char *WordToString2(unsigned int word)
+{//============================================
// Convert a language mnemonic word into a string
int ix;
static char buf[5];
@@ -961,7 +961,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output
if(attributes & CLAUSE_BIT_SENTENCE)
return(attributes);
-
+
return(short_pause);
} // end of AnnouncePunctuation
@@ -1078,7 +1078,7 @@ static const char *VoiceFromStack()
}
p += (strlen(p) + 1);
}
-
+
if(voice_name_specified == 0)
voice_name[0] = 0; // forget a previous voice name if a language is specified
}
@@ -1248,7 +1248,7 @@ static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name)
static int attrcmp(const wchar_t *string1, const char *string2)
{//============================================================
int ix;
-
+
if(string1 == NULL)
return(1);
@@ -1334,7 +1334,7 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
}
if(*pw == '-')
{
- pw++;
+ pw++;
sign = -1;
}
value = (double)wcstod(pw,&tail);
@@ -1485,10 +1485,10 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type)
age = GetSsmlAttribute(pw,"age");
gender = GetSsmlAttribute(pw,"gender");
}
-
+
if((tag_type != SSML_VOICE) && (lang==NULL))
return(0); // or
without language spec, nothing to do - + ssml_sp = &ssml_stack[n_ssml_stack++]; attrcopy_utf8(ssml_sp->language,lang,sizeof(ssml_sp->language)); @@ -1592,7 +1592,7 @@ static int ReplaceKeyName(char *outbuf, int index, int &outix) {"underscore ", 0xe05f}, {"double-quote ", '"'}, {NULL, 0}}; - + int ix; int letter; char *p; @@ -1624,7 +1624,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb int voice_change_flag; wchar_t *px; wchar_t *attr1; - wchar_t *attr2; + wchar_t *attr2; wchar_t *attr3; int terminator; char *uri; @@ -1688,7 +1688,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb tag_name[ix] = 0; px = &xml_buf[ix]; // the tag's attributes - + if(tag_name[0] == '/') { // closing tag @@ -2268,7 +2268,7 @@ f_input = f_in; // for GetC etc } xml_buf[n_xml_buf] = 0; c2 = ' '; - + self_closing = 0; if(xml_buf[n_xml_buf-1] == '/') { @@ -2276,9 +2276,9 @@ f_input = f_in; // for GetC etc xml_buf[n_xml_buf-1] = ' '; self_closing = 1; } - + terminator = ProcessSsmlTag(xml_buf,buf,ix,n_buf,self_closing); - + if(terminator != 0) { if(end_clause_after_tag) @@ -2286,7 +2286,7 @@ f_input = f_in; // for GetC etc buf[ix] = ' '; buf[ix++] = 0; - + if(terminator & CLAUSE_BIT_VOICE) { strcpy(voice_change, current_voice_id); @@ -2397,7 +2397,7 @@ f_input = f_in; // for GetC etc if(iswspace(c1)) { char *p_word; - + if(tr->translator_name == 0x6a626f) { // language jbo : lojban @@ -2514,7 +2514,7 @@ if(option_ssml) parag=1; // Because of an xml tag, we are waiting for the // next non-blank character to decide whether to end the clause // i.e. is dot followed by an upper-case letter? - + if(!iswspace(c1)) { if(!IsAlpha(c1) || !iswlower(c1)) @@ -2548,7 +2548,7 @@ if(option_ssml) parag=1; if((punct = lookupwchar(punct_chars,c1)) != 0) { punct_data = punct_attributes[punct]; - + if(punct_data & PUNCT_IN_WORD) { // Armenian punctuation inside a word @@ -2579,7 +2579,7 @@ if(option_ssml) parag=1; announced_punctuation = c1; } } - + if((punct_data & PUNCT_SAY_NAME) && (announced_punctuation == 0)) { // used for elipsis (and 3 dots) if a pronunciation for elipsis is given in *_list @@ -2626,7 +2626,7 @@ if(option_ssml) parag=1; if(c1 == '.') { - if((tr->langopts.numbers & NUM_ORDINAL_DOT) && + if((tr->langopts.numbers & NUM_ORDINAL_DOT) && (iswdigit(cprev) || (IsRomanU(cprev) && (IsRomanU(cprev2) || iswspace(cprev2))))) // lang=hu { // dot after a number indicates an ordinal number @@ -2643,7 +2643,7 @@ if(option_ssml) parag=1; else if(c_next == '\'') { - is_end_clause = 0; // eg. u.s.a.'s + is_end_clause = 0; // eg. u.s.a.'s } if(iswlower(c_next)) { diff --git a/src/synthdata.cpp b/src/synthdata.cpp index 245291b6..eed59bf4 100644 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,7 +35,7 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.46.37 20.Feb.13"; +const char *version_string = "1.46.38 27.Feb.13"; const int version_phdata = 0x014636; int option_device_number = -1; diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp index 4ff39120..db1766b8 100644 --- a/src/tr_languages.cpp +++ b/src/tr_languages.cpp @@ -48,6 +48,7 @@ #define OFFSET_GREEK 0x380 #define OFFSET_CYRILLIC 0x420 #define OFFSET_ARMENIAN 0x530 +#define OFFSET_HEBREW 0x590 #define OFFSET_ARABIC 0x600 #define OFFSET_THAANA 0x780 // Divehi/Maldives #define OFFSET_DEVANAGARI 0x900 @@ -60,12 +61,61 @@ #define OFFSET_KANNADA 0xc80 #define OFFSET_MALAYALAM 0xd00 #define OFFSET_SINHALA 0x0d80 +#define OFFSET_THAI 0x0e00 +#define OFFSET_LAO 0x0e80 #define OFFSET_TIBET 0x0f00 -#define OFFSET_GEORGIAN 0x1080 +#define OFFSET_MYANMAR 0x1000 +#define OFFSET_GEORGIAN 0x10a0 #define OFFSET_KOREAN 0x1100 #define OFFSET_ETHIOPIC 0x1200 +ALPHABET alphabets [] = { + {"_el", OFFSET_GREEK, 0x380, 0x3ff, L('e','l'), AL_DONT_NAME | AL_NOT_LETTERS}, + {"_cyr", OFFSET_CYRILLIC, 0x400, 0x52f, 0, 0}, + {"_hy", OFFSET_ARMENIAN, 0x530, 0x58f, L('h','y'), 0}, + {"_he", OFFSET_HEBREW, 0x590, 0x5ff, 0, 0}, + {"_ar", OFFSET_ARABIC, 0x600, 0x6ff, 0, 0}, + {"_dv", OFFSET_THAANA, 0x780, 0x7bf, 0, 0}, + {"_hi", OFFSET_DEVANAGARI, 0x900, 0x97f,L('h','i'), 0}, + {"_bn", OFFSET_BENGALI, 0x0980, 0x9ff, 0, 0}, + {"_gur", OFFSET_GURMUKHI, 0xa00, 0xa7f, 0, 0}, + {"_gu", OFFSET_GUJARATI, 0xa80, 0xaff, 0, 0}, + {"_or", OFFSET_ORIYA, 0xb00, 0xb7f, 0, 0}, + {"_ta", OFFSET_TAMIL, 0xb80, 0xbff, L('t','a'), 0}, + {"_te", OFFSET_TELUGU, 0xc00, 0xc7f, 0, 0}, + {"_kn", OFFSET_KANNADA, 0xc80, 0xcff, L('k','n'), 0}, + {"_ml", OFFSET_MALAYALAM,0xd00, 0xd7f, L('m','l'), 0}, + {"_si", OFFSET_SINHALA, 0xd80, 0xdff, 0, 0}, + {"_th", OFFSET_THAI, 0xe00, 0xe7f, 0, 0}, + {"_lo", OFFSET_LAO, 0xe80, 0xeff, 0, 0}, + {"_ti", OFFSET_TIBET, 0xf00, 0xfff, 0, 0}, + {"_my", OFFSET_MYANMAR, 0x1000,0x109f, 0, 0}, + {"_ka", OFFSET_GEORGIAN, 0x10a0,0x10ff, L('k','a'), 0}, + {"_ko", OFFSET_KOREAN, 0x1100,0x11ff, 0, 0}, + {"_eth", OFFSET_ETHIOPIC, 0x1200,0x139f, 0, 0}, + {NULL, 0, 0, 0, 0, 0} +}; + + +ALPHABET *AlphabetFromChar(int c) +{//=============================== + // Find the alphabet from a character. + ALPHABET *alphabet = alphabets; + + while(alphabet->name != NULL) + { + if((c >= alphabet->range_min) && (c <= alphabet->range_max)) + { + return(alphabet); + } + alphabet++; + } + return(NULL); +} + + + static void Translator_Russian(Translator *tr); @@ -93,7 +143,7 @@ static void SetLetterBits(Translator *tr, int group, const char *string) {//===================================================================== int bits; unsigned char c; - + bits = (1L << group); while((c = *string++) != 0) tr->letter_bits[c] |= bits; @@ -242,7 +292,7 @@ static const char transpose_map_latin[] = { // common letter pairs, encode these as a single byte // 2 bytes, using the transposed character codes -static const short pairs_ru[] = { +static const short pairs_ru[] = { 0x010c, // ла 21052 0x23 0x010e, // на 18400 0x0113, // та 14254 @@ -279,7 +329,7 @@ static const short pairs_ru[] = { -static const unsigned int replace_cyrillic_latin[] = +static const unsigned int replace_cyrillic_latin[] = {0x430,'a', 0x431,'b', 0x446,'c', @@ -413,7 +463,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.param[LOPT_DIERESES] = 1; tr->langopts.param[LOPT_PREFIXES] = 1; SetLetterVowel(tr,'y'); // add 'y' to vowels - + tr->langopts.numbers = NUM_SWAP_TENS | NUM_HUNDRED_AND | NUM_SINGLE_AND | NUM_ROMAN | NUM_1900; tr->langopts.accents = 1; } @@ -496,7 +546,7 @@ Translator *SelectTranslator(const char *name) // tr->langopts.intonation_group = 4; // 'diminished' is an unstressed final syllable - tr->langopts.stress_flags = 0x6 | 0x10; + tr->langopts.stress_flags = 0x6 | 0x10; tr->langopts.unstressed_wd1 = 0; tr->langopts.unstressed_wd2 = 2; tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels @@ -532,7 +582,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.param[LOPT_PREFIXES] = 1; tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x100; // devoice at end of word tr->langopts.param[LOPT_LONG_VOWEL_THRESHOLD] = 175/2; - + tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_ALLOW_SPACE | NUM_ORDINAL_DOT | NUM_ROMAN; // tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_ALLOW_SPACE | NUM_ORDINAL_DOT | NUM_ROMAN; SetLetterVowel(tr,'y'); @@ -549,7 +599,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.stress_rule = STRESSPOSN_1L; tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable SetLetterBitsRange(tr,LETTERGP_B,0x26,0x30); // vowel signs, and virama - tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000 + tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000 tr->langopts.numbers = 1; } break; @@ -578,7 +628,7 @@ Translator *SelectTranslator(const char *name) // character codes offset by 0x380 static const char el_vowels[] = {0x10,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x35,0x37,0x39,0x3f,0x45,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0}; static const char el_fvowels[] = {0x2d,0x2e,0x2f,0x35,0x37,0x39,0x45,0x4d,0}; // ε η ι υ έ ή ί ύ - static const char el_voiceless[]= {0x38,0x3a,0x3e,0x40,0x42,0x43,0x44,0x46,0x47,0}; // θ κ ξ π ς σ τ φ χ + static const char el_voiceless[]= {0x38,0x3a,0x3e,0x40,0x42,0x43,0x44,0x46,0x47,0}; // θ κ ξ π ς σ τ φ χ static const char el_consonants[]={0x32,0x33,0x34,0x36,0x38,0x3a,0x3b,0x3c,0x3d,0x3e,0x40,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0}; static const wchar_t el_char_apostrophe[] = {0x3c3,0}; // σ @@ -602,7 +652,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.unstressed_wd2 = 2; tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels - tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA; + tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA; tr->langopts.numbers2 = 0x2 | NUM2_MULTIPLE_ORDINAL; // variant form of numbers before thousands if(name2 == L_grc) @@ -618,7 +668,7 @@ Translator *SelectTranslator(const char *name) static const short stress_lengths_eo[8] = {150, 150, 230, 180, 0, 0, 300, 320}; static const unsigned char stress_amps_eo[] = {16,14, 20,20, 20,22, 22,21 }; static const wchar_t eo_char_apostrophe[2] = {'l',0}; - + SetupTranslator(tr,stress_lengths_eo,stress_amps_eo); tr->charset_a0 = charsets[3]; // ISO-8859-3 @@ -627,7 +677,7 @@ Translator *SelectTranslator(const char *name) // tr->langopts.word_gap = 1; tr->langopts.vowel_pause = 2; tr->langopts.stress_rule = STRESSPOSN_2R; - tr->langopts.stress_flags = 0x6 | 0x10; + tr->langopts.stress_flags = 0x6 | 0x10; // tr->langopts.unstressed_wd1 = 3; tr->langopts.unstressed_wd2 = 2; @@ -651,13 +701,13 @@ Translator *SelectTranslator(const char *name) // stress last syllable if it doesn't end in vowel or "s" or "n" // 'diminished' is an unstressed final syllable - tr->langopts.stress_flags = 0x200 | 0x6 | 0x10; + tr->langopts.stress_flags = 0x200 | 0x6 | 0x10; tr->langopts.unstressed_wd1 = 0; tr->langopts.unstressed_wd2 = 2; tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_ROMAN | NUM_ROMAN_AFTER; - tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL; + tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL; if(name2 == L('c','a')) { @@ -667,7 +717,7 @@ Translator *SelectTranslator(const char *name) else if(name2 == L('a','n')) { - tr->langopts.stress_flags = 0x200 | 0x6 | 0x10; + tr->langopts.stress_flags = 0x200 | 0x6 | 0x10; } else if(name2 == L_pap) @@ -805,7 +855,7 @@ Translator *SelectTranslator(const char *name) tr->charset_a0 = charsets[2]; // ISO-8859-2 tr->langopts.stress_rule = STRESSPOSN_1L; - tr->langopts.stress_flags = 0x10; + tr->langopts.stress_flags = 0x10; tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3; tr->langopts.max_initial_consonants = 5; tr->langopts.spelling_stress = 1; @@ -884,7 +934,7 @@ SetLengthMods(tr,3); // all equal SetupTranslator(tr,stress_lengths_id,stress_amps_id); tr->langopts.stress_rule = STRESSPOSN_2R; tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_ROMAN; - tr->langopts.stress_flags = 0x6 | 0x10; + tr->langopts.stress_flags = 0x6 | 0x10; tr->langopts.accents = 2; // "capital" after letter name } break; @@ -919,7 +969,7 @@ SetLengthMods(tr,3); // all equal tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable tr->langopts.stress_rule = STRESSPOSN_2R; - tr->langopts.stress_flags = 0x10 | 0x20000; + tr->langopts.stress_flags = 0x10 | 0x20000; tr->langopts.vowel_pause = 1; tr->langopts.unstressed_wd1 = 2; tr->langopts.unstressed_wd2 = 2; @@ -974,7 +1024,7 @@ SetLengthMods(tr,3); // all equal { static const unsigned char stress_amps_tr[8] = {18,16, 20,21, 20,21, 21,20 }; static const short stress_lengths_tr[8] = {190,180, 230,230, 0,0, 250,250}; - + tr->letter_bits_offset = OFFSET_CYRILLIC; memset(tr->letter_bits,0,sizeof(tr->letter_bits)); SetLetterBits(tr,LETTERGP_A,(char *)ru_vowels); @@ -1173,9 +1223,9 @@ SetLengthMods(tr,3); // all equal tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable - tr->langopts.stress_flags = 0x6 | 0x10 | 0x2000 | 0x20000; + tr->langopts.stress_flags = 0x6 | 0x10 | 0x2000 | 0x20000; tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_DFRACTION_2 | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_ROMAN; - tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL | NUM2_NO_TEEN_ORDINALS; + tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL | NUM2_NO_TEEN_ORDINALS; SetLetterVowel(tr,'y'); ResetLetterBits(tr,0x2); SetLetterBits(tr,1,"bcdfgjkmnpqstvxz"); // B hard consonants, excluding h,l,r,w,y @@ -1223,7 +1273,7 @@ SetLengthMods(tr,3); // all equal tr->charset_a0 = charsets[2]; // ISO-8859-2 tr->langopts.stress_rule = STRESSPOSN_1L; - tr->langopts.stress_flags = 0x16; + tr->langopts.stress_flags = 0x16; tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3; tr->langopts.max_initial_consonants = 5; tr->langopts.spelling_stress = 1; @@ -1259,11 +1309,11 @@ SetLengthMods(tr,3); // all equal memset(tr->letter_bits,0,sizeof(tr->letter_bits)); SetLetterBitsRange(tr,LETTERGP_A,0x05,0x16); // vowel letters SetLetterBitsRange(tr,LETTERGP_A,0x4a,0x73); // + vowel signs, and virama - + SetLetterBitsRange(tr,LETTERGP_B,0x4a,0x73); // vowel signs, and virama - + SetLetterBitsRange(tr,LETTERGP_C,0x1a,0x46); // the main consonant range - + tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words tr->langopts.suffix_add_e = tr->letter_bits_offset + 0x4a; //virama tr->langopts.numbers = NUM_OMIT_1_THOUSAND | NUM_SINGLE_STRESS_L | NUM_DFRACTION_7; @@ -1292,7 +1342,7 @@ SetLengthMods(tr,3); // all equal SetupTranslator(tr,stress_lengths_sq,stress_amps_sq); tr->langopts.stress_rule = STRESSPOSN_2R; - tr->langopts.stress_flags = 0x16 + 0x100; + tr->langopts.stress_flags = 0x16 + 0x100; SetLetterVowel(tr,'y'); tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_DFRACTION_4; tr->langopts.accents = 2; // "capital" after letter name @@ -1324,7 +1374,7 @@ SetLengthMods(tr,3); // all equal tr->langopts.vowel_pause = 1; tr->langopts.stress_rule = STRESSPOSN_2R; - tr->langopts.stress_flags = 0x6 | 0x10; + tr->langopts.stress_flags = 0x6 | 0x10; tr->langopts.numbers = NUM_AND_UNITS | NUM_HUNDRED_AND | NUM_SINGLE_AND | NUM_OMIT_1_HUNDRED; tr->langopts.break_numbers = 0x49249268; // for languages which have numbers for 100,000 and 1,000,000 @@ -1343,7 +1393,7 @@ SetLengthMods(tr,3); // all equal tr->langopts.stress_rule = STRESSPOSN_1L; tr->langopts.stress_flags = 0x10004; // use 'diminished' for unstressed final syllable tr->langopts.spelling_stress = 1; - tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000 + tr->langopts.break_numbers = 0x14a8; // 1000, 100,000 10,000,000 if(name2 == L('t','a')) { @@ -1604,7 +1654,7 @@ PH('V','#'),PH('I','3'),PH('I','2'),PH('E','3')}; /*2*/ {'o', '8', '8', 'o', '8', '8'}, // O /*3*/ {'i', 'I', 'i', 'a', 'I', 'a'}, // I Uses 3,4,5 columns. /*4*/ {'i', PH('I','#'), 'i', 'i', PH('I','#'), 'i'}, // I# - /*5*/ {'E', PH('E','#'), 'E', 'e', PH('E','#'), 'e'}, // E# + /*5*/ {'E', PH('E','#'), 'E', 'e', PH('E','#'), 'e'}, // E# /*6*/ {'E', PH('E','2'), 'E', 'e', PH('E','2'), 'e'}, // E2 Uses 3,4,5 columns. /*7*/ {PH('j','a'), 'V', PH('j','a'), 'A', 'V', 'A'}, // V# /*8*/ {PH('j','a'), 'I', PH('j','a'), 'e', 'I', 'e'}, // I3 Uses 3,4,5 columns. diff --git a/src/translate.cpp b/src/translate.cpp index a363ad6e..233a1c40 100644 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -77,6 +77,7 @@ static int prev_clause_pause=0; static int max_clause_pause = 0; static int any_stressed_words; int pre_pause; +ALPHABET *current_alphabet; // these were previously in translator class @@ -874,6 +875,7 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt unpron_phonemes[0] = 0; prefix_phonemes[0] = 0; end_phonemes[0] = 0; + current_alphabet = NULL; if(tr->data_dictlist == NULL) { @@ -902,6 +904,12 @@ int TranslateWord(Translator *tr, char *word_start, int next_pause, WORD_TAB *wt spell_word = 0; + if((word_length == 1) && (wflags & FLAG_TRANSLATOR2)) + { + // retranslating a 1-character word using a different language, say its name + spell_word = 1; + } + if(option_sayas == SAYAS_KEY) { if(word_length == 1) @@ -1061,6 +1069,8 @@ if((wmark > 0) && (wmark < 8)) return(FLAG_SPELLWORD); // a mixture of languages, retranslate as individual letters, separated by spaces return(0); } + strcpy(word_phonemes, phonemes); + return(0); // ?? } else if(found == 0) @@ -1098,7 +1108,7 @@ if((wmark > 0) && (wmark < 8)) if(strcmp(&unpron_phonemes[1],"en")==0) return(FLAG_SPELLWORD); // _^_en must have been set in TranslateLetter(), not *_rules return(0); - } + } #ifdef deleted p = &wordx[word_length-3]; // this looks wrong. Doesn't consider multi-byte chars. @@ -1158,6 +1168,8 @@ if(end_type & SUFX_UNPRON) { return(0); } + strcpy(word_phonemes, phonemes); + return(0); } } @@ -1713,6 +1725,7 @@ int SetTranslator2(const char *new_language) new_phoneme_tab = -1; translator2_language[0] = 0; } + translator2->phoneme_tab_ix = new_phoneme_tab; } } return(new_phoneme_tab); @@ -1953,12 +1966,14 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa if(switch_phonemes >= 0) { // re-translate the word using the new translator + wtab[0].flags |= FLAG_TRANSLATOR2; flags = TranslateWord(translator2, word, next_pause, wtab); // strcpy((char *)p,translator2->word_phonemes); if(p[0] == phonSWITCH) { // the second translator doesn't want to process this word - switch_phonemes = -1; +// switch_phonemes = -1; +return(FLAG_SPELLWORD); } } if(switch_phonemes < 0) @@ -2050,8 +2065,16 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa if(switch_phonemes >= 0) { // this word uses a different phoneme table - SetPlist2(&ph_list2[n_ph_list2],phonSWITCH); - ph_list2[n_ph_list2++].tone_ph = switch_phonemes; // temporary phoneme table number + if(ph_list2[n_ph_list2-1].phcode == phonSWITCH) + { + //previous phoneme is also a phonSWITCH, just change its phoneme table number + n_ph_list2--; + } + else + { + SetPlist2(&ph_list2[n_ph_list2],phonSWITCH); + } + ph_list2[n_ph_list2++].tone_ph = switch_phonemes; // temporary phoneme table number } // remove initial pause from a word if it follows a hyphen @@ -2078,7 +2101,9 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa ph_list2[n_ph_list2].phcode = ph_code; ph_list2[n_ph_list2].sourceix = 0; ph_list2[n_ph_list2].synthflags = embedded_flag; - ph_list2[n_ph_list2++].tone_ph = *p++; + ph_list2[n_ph_list2++].tone_ph = *p; + SelectPhonemeTable(*p); + p++; } else if(ph->type == phSTRESS) diff --git a/src/translate.h b/src/translate.h index f39e2534..9248d09e 100644 --- a/src/translate.h +++ b/src/translate.h @@ -111,6 +111,7 @@ #define FLAG_INDIVIDUAL_DIGITS 0x80000 // speak number as individual digits #define FLAG_DELETE_WORD 0x100000 // don't speak this word, it has been spoken as part of the previous word #define FLAG_CHAR_REPLACED 0x200000 // characters have been replaced by .replace in the *_rules +#define FLAG_TRANSLATOR2 0x400000 // retranslating using a different language #define FLAG_SUFFIX_VOWEL 0x08000000 // remember an initial vowel from the suffix #define FLAG_NO_TRACE 0x10000000 // passed to TranslateRules() to suppress dictionary lookup printout @@ -258,6 +259,21 @@ extern PARAM_STACK param_stack[]; extern const int param_defaults[N_SPEECH_PARAM]; +typedef struct { + const char *name; + int offset; + unsigned short range_min, range_max; + int language; + int flags; +} ALPHABET; + +extern ALPHABET alphabets[]; +extern ALPHABET *current_alphabet; +// alphabet flags +#define AL_DONT_NAME 0x01 // don't speak the alphabet name +#define AL_NOT_LETTERS 0x02 // don't use the language for speaking letters +#define AL_NOT_WORDS 0x04 // don't use the language to speak words + #define N_LOPTS 21 #define LOPT_DIERESES 1 @@ -664,6 +680,8 @@ int IsAlpha(unsigned int c); int isspace2(unsigned int c); int towlower2(unsigned int c); void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa); +const char *WordToString2(unsigned int word); +ALPHABET *AlphabetFromChar(int c); Translator *SelectTranslator(const char *name); int SetTranslator2(const char *name);