From 4423576af2547eedffaca75df0d8e88d77817df7 Mon Sep 17 00:00:00 2001 From: jonsd Date: Mon, 2 Aug 2010 09:09:25 +0000 Subject: [PATCH] [1.43.63] Phoneme definitions. Add "equivalents" table to translate phonemes from a foreign language (eg. English) into the equivalant phonemes of this language. This is used when *_rules and *_list files indicate that a word uses pronunciation rules from a different language. Unpronouncable words can be recognised by rules in *_rule files. This feature is now used for en, de, es. Lang=ta, hi. Letter-names for combining vowel characters are distinguished from stand-alone vowel characters by a preceding beep. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@251 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/ca_list | 1 - dictsource/da_list | 9 +- dictsource/da_rules | 66 +++- dictsource/de_list | 84 ++--- dictsource/de_rules | 104 +++++-- dictsource/dict_phonemes | 83 ++--- dictsource/en_list | 8 +- dictsource/en_rules | 148 +++++++-- dictsource/es_list | 19 +- dictsource/es_rules | 47 ++- dictsource/fr_list | 172 +++++------ dictsource/fr_rules | 337 +++++++++++---------- dictsource/hi_list | 23 ++ dictsource/hu_list | 70 ++++- dictsource/hu_rules | 58 +++- dictsource/nl_list | 1 - dictsource/pap_list | 1 - dictsource/ta_list | 17 +- dictsource/ta_rules | 14 +- dictsource/tr_list | 1 - dictsource/tr_rules | 3 +- phsource/compile_report | 66 ++-- phsource/intonation | 3 +- phsource/ph_afrikaans | 7 +- phsource/ph_catalan | 1 + phsource/ph_croatian | 9 +- phsource/ph_english | 6 +- phsource/ph_french | 152 ++++++++-- phsource/ph_german | 80 ++++- phsource/ph_hindi | 7 + phsource/ph_slovak | 4 +- phsource/ph_swedish | 2 + phsource/ph_tamil | 8 + phsource/ph_turkish | 5 +- phsource/phonemes | 6 + phsource/vdiph2/vowelchart.png | Bin 52296 -> 52429 bytes phsource/vowel/& | Bin 6753 -> 6753 bytes platforms/big_endian/espeak-phoneme-data.c | 16 +- src/compiledata.cpp | 198 ++++++++++-- src/compiledict.cpp | 19 +- src/dictionary.cpp | 203 +++++-------- src/espeakedit.cpp | 2 + src/extras.cpp | 72 +++++ src/main.h | 1 + src/menus.cpp | 1 + src/numbers.cpp | 19 +- src/phoneme.h | 3 +- src/prosodydisplay.cpp | 2 +- src/readclause.cpp | 14 +- src/synth_mbrola.cpp | 2 +- src/synthdata.cpp | 25 +- src/synthesize.cpp | 6 +- src/synthesize.h | 1 + src/tr_languages.cpp | 27 +- src/translate.cpp | 116 ++++++- src/translate.h | 15 +- src/voices.cpp | 1 + src/vowelchart.cpp | 4 +- 58 files changed, 1641 insertions(+), 728 deletions(-) diff --git a/dictsource/ca_list b/dictsource/ca_list index 97052b3b..0e1cfb17 100755 --- a/dictsource/ca_list +++ b/dictsource/ca_list @@ -109,7 +109,6 @@ _5C sins'Ents _7C s,ets'Ents _9C n,Ous'Ents _0M1 m'il -_1M1 m'il // no '1' before thousand _0M2 mil^'on@s _dpt _koma //_roman Rom'a diff --git a/dictsource/da_list b/dictsource/da_list index eae75c2b..b13db194 100755 --- a/dictsource/da_list +++ b/dictsource/da_list @@ -1,7 +1,7 @@ -tv $abbrev - // PB = Peter Bjarkov - pbj1234@hotmail.com +iv $abbrev + // This file is UTF8 encoded // Spelling-to-phoneme words for Danish @@ -130,6 +130,8 @@ _0M4 bilij'o:n3 _0and 3 _dpt _k,Vm&: +_roman d%En + // PB a number followed by dot // ordinals are followed by a dot in Danish @@ -6156,7 +6158,7 @@ proceder $alt producere $alt profaner $alt professionaliser $alt -profeter $alt +profetere $alt profilere $alt profiter $alt prognosticer $alt @@ -8563,6 +8565,7 @@ ovation $alt ovulation $alt oxidation $alt participation $alt +pavillon $alt passion $alt pension $alt perception $alt diff --git a/dictsource/da_rules b/dictsource/da_rules index 8f17a268..53287628 100755 --- a/dictsource/da_rules +++ b/dictsource/da_rules @@ -81,10 +81,11 @@ // PB general rule: [a] after k before m k) a (m a // PB kam, kamp c) a (mp & // PB camping -// PB kamm => [a] - k) a (mm a // PB kammerat +// PB amm => [a] + a (mm a // PB kammerat, amme // PB kame => [&] k) a (me & // PB kamel, kamera + // PB general rule: [&] after d d) a (+ & // PB dame, dag d) a (g@ a // PB dagbog @@ -160,6 +161,7 @@ l) a (gt+ A // PB lagt l) ag (_ &j // lag f) ag (s au // PB fagsnak + l) ag (C au // PB flagstang, lagkage // PB general rule: [A] before vn after consonant C) a (vn A // favn, savn // PB general rule: [a] after kl before consonant @@ -486,6 +488,7 @@ amsterd) a (m 'a // PB sp) ag (num Au // PB r) ag (e+ Au // PB drage, rage C) age (+ &:j@ // PB tage, bage, kage + g) age (+ &:S@ // PB fl) ager (mus AuV // PB C) ager (_+ &:jV // PB tager, bager, kager l) agd (e &:j // PB lagde @@ -625,6 +628,7 @@ _trienn) ale '&:l@ offi) ce (r se // PB sprogofficer ce (rt s'E // PB koncert c (i s +frederi) c (ia =ks // PB c (k ch (+ S // PB check, chokolade mi) ch (a k S @@ -803,7 +807,7 @@ stikor) d // PB exception - silent d in 'stikord' dodge dVdZ // PB city daiquiri d&k@ri // PB drink _) duke dZu:k // PB Duke - name - _) drive dRAjv // PB drive-in + _) drive (- dRAjv // PB drive-in .group é // added by PB é 'e // idé, entré @@ -815,6 +819,8 @@ stikor) d // PB exception - silent d in 'stikord' &b) e (@ E, // PB hv'alrosbest,and // PB general rules l) e e + val) e (ncia 'E // PB + al) er V // PB maler perl) e @ // PB _dil) e (mma 'E // PB ll) e (de // PB silent e - billede @@ -851,6 +857,7 @@ stikor) d // PB exception - silent d in 'stikord' rn) e (d+ e // PB derned an) e (r @ // PB anerkende L09) e (de E // nede, nederlag + mus) e (um 'E // PB stressed mån) e (d @ // PB L09) e (t e // metal L09) e (l E // mellem @@ -1062,6 +1069,7 @@ _sakram) e (nte 'e _st) eg (_ e // steg - verb, problem with noun = "roast" best) eg (_ 'e // PB besteg best) eg (et_ 'e // PB besteget + st) eg (å @g // PB præstegård n) egl ajl // PB negl r) egel Ejl // PB regel r) egl Ejl // PB regler @@ -1176,6 +1184,7 @@ muskat) el ''El // PB intellektu) el el // // PB bestandd) el el // PB halvd) el el // PB + evang) el el // PB evangelie d) el (t+ el // PB tildelt lob) el (ia 'el // PB d) el (A+ el // PB dele, omdele @@ -1186,6 +1195,7 @@ _offici) el (+ 'el // PB officiel mod) el el // PB fotomodel _mod) el 'el // PB modelbureau u) el (+ 'el // aktuel, seksuel, visuel + u) el (t+ 'el // aktuelt, seksuelt, visuelt gennemsku) el (ig =el ur) el (_+ '&#l // konjunkturel and) el el // andel @@ -1303,7 +1313,7 @@ _præsid) en (t 'en // præsidentfrue &b) en (+ en // PB koben, nøgleben _åb) en (+ @n // PB åben våb) en (+ @n // PB våben - C) en (sC @n // PB TEST - verdensmagt +// C) en (sC @n // PB TEST - verdensmagt tj) en (st En // PB fortjenstmedalje m) en (s+ En // PB menstruation g) en (st en // PB genstand @@ -1500,7 +1510,9 @@ L06L06) er V // PB klipper _) er (_ &r // PB er L09) er (ne_ V // PB kameraerne juvel) er (en 'er // PB juveleren - juvel) er (er 'er // PB juvelerer + juvel) erer ''eV // PB juvelerer + _man) erer 'eV // PB + man) erer eV // PB _l) er (_++ er // PB ler v) er (r_ er // PB levere th) er_ V // Luther @@ -1537,7 +1549,7 @@ L06L06) er V // PB klipper år) ede (_+ 3D@ // PB sårede odr) ede (_+ 3D@ // PB fodrede obr) ede (_ 3D@ // PB erobrede - tr) ede (_+ 3D@ // PB splintrede + tr) ede (_+ 3D-@ // PB splintrede hundr) ed (+ @:D // PB hundred rn) ed (e eD // PB dernede &k) ede (+ eD@ // PB dødkede @@ -1568,6 +1580,7 @@ _tromp) et 'et // PB stressed _klarin) et 'et // PB _servi) et 'et // PB servi) et et // PB + _prof) et 'et // PB stressed klarin) et et // PB _plan) et 'et // PB meg) et (+ et // PB not a suffix @@ -1708,7 +1721,9 @@ _vinaigr) ette '&t@ al) geriet Sj3r'i@d // PB Algeriet al) gerier Sj'iV // PB Algeriet al) gerisk Sj'i:rsg + g (iro S // PB guinea gin'e& // PB + gui (nnes ge // PB ødi) g (t_ // nødigt i) g (i g g (entl j // PB egentlig @@ -1721,6 +1736,7 @@ _vinaigr) ette '&t@ ble) g (ansigt j // PB blegansigt ble) g (fi j L08e) g j // PB steg, spegepølse + g (å++ g // PB præstegård L08e) g (t g // PB stegt æ) g (e j æl) g (e j // PB sælge vælge @@ -1825,7 +1841,8 @@ _vinaigr) ette '&t@ geneve Sen'E:v // PB genève Sen'E:v // PB _) gudskelov (_ gusg@lVu // PB - georgia dZV:dZj& + georgia dZV:dZj& // PB + gibraltar SibRalt'A // PB .group ge @@ -1890,6 +1907,7 @@ _korte) ge =Se _l) ig (_ordentligt ek // PB _l) ig (_godt ek // PB _l) ig (_roligt ek // PB + pav) ill (o ilj // PB pavillon færd) ig i // PB silent g hurt) ig i // PB silent g ig (hed i // PB vittighed @@ -1977,6 +1995,7 @@ intell) ige (n ig'e // PB intelligent sk) i (dt i // PB skidt sk) i (mm e // PB skimmel mask) i (n 'i // PB stressed - maskinskrive + par) i (s 'i // PB h) i (d i // PB hidtil b) i (lled e / PB billede kr) i (dt i // PB skridt, kridt @@ -2247,6 +2266,7 @@ _terap) i 'i v) i (sne e // PB l) i (e j r) i (gt e // PB rigtigt + r) i (c e // PB Fredericia l) ig (g+ e // PB ligge - only one g s) i (e j // t) i (e j @@ -2365,6 +2385,7 @@ _sport) iv 'iw spe) k (takl // silent k - spektakler &) k k // after stressed vowel _) kate (_ kEjt // PB name + karaoke k&r&'ouki // PB // &) kk g .group l // PB l changed to l/3 in ph_danish @@ -2607,6 +2628,8 @@ subtrahe) nd nd .group ng ng (_ N // general rule - ting, ring A) ng (e N // general rule - mange, penge + i) ngeni (ø nSin // PB ingeniør + eva) ng (el ng // PB evangelie allo) ng (e NS // PB _ri) ng (o ng // PB Ringo - name hæ) ng N // PB hængning @@ -2722,6 +2745,7 @@ mening) oko (k ok'V // PB meningokokker hypok) o (nder 'V // PB d) o (b V // PB dobbelt d) o (nn V // PB donna + b) o (ls V // PB bolsje h) o (ll V // PB Holland _horis) o (n 'V // PB horisont o (nt V // PB dont @@ -3019,6 +3043,8 @@ dødvægtt) on Vn kol) on Vn kol) onn 'Vn // kolonne - only one n, stressed kompagn) on VN +_pavill) on 'VN +pavill) on VN orl) on Vn _maked) on 'on // PB makedoner perl) on Vn @@ -3126,7 +3152,7 @@ _success) or =V _f) or (a_ 'V // PB fora (plur. of 'forum') _f) or (an_ 'V // PB foran _f) or (ankørende 'V // PB forankørende - _f) or (annævnt'V // PB forannævnt + _f) or (annævnt 'V // PB forannævnt _f) or (ansat 'V // PB foransat _f) or (anstille 'V // PB foranstillet _f) or (anstående 'V // PB foranstående @@ -3472,6 +3498,7 @@ strabad) s s // PB not a suffix ky) s s // PB not a suffix anderlede) s s // PB not a suffix interferen) s s // PB not a suffix +residen) s s // PB tilpa) s s s (p s @@ -3505,6 +3532,7 @@ franci) sc (o sk // PB Francisco sydney sidni // PB shakespeare SEiksbi:r // PB squash sgwVS // PB + shor (t SV // PB shorts _) stone sdoun // PB namde - Stone er_) sig (_til saj // PB avoid [si] - glæder sig [saj] til et_) sig (_til saj // PB avoid [si] - glædet sig [saj] til @@ -3741,6 +3769,7 @@ meningi) ti (s =ti // PB final -tur in da_list - stressed u &t) ur ($p_alt 'ur // struktur + _komf) ur 'ur // PB // PB final -ut in da_list - stressed u &) ut ($p_alt 'ut // rekrut @@ -3991,7 +4020,8 @@ _molek) y (le 'y // PB stressed f) yrre (t Y:V // PB fyrretræ n) y (t Y // PB nyt n) y (tt W // PB nytte, benytte - n) y (k W: // PB nyk + n) y (k_ W // PB nyk + n) y (ker W // PB nykker kn) y (tt W: // PB tilknytte kn) y (t y // PB knyt k) y (s W // PB kys @@ -4052,12 +4082,13 @@ _molek) y (le 'y // PB stressed tr) æ (n &# // PB trænge tr) æ (ne E // PB træne dr) æ (n E // PB dræne -// kr) æ (f &# // PB kræfter -// kr) æ (m &# // PB skræmme, kræmmer + kr) æ (f &# // PB kræfter + kr) æ (m &# // PB skræmme, kræmmer // r) æ (n &# // PB changed from [Aj] - rænke // r) æ (k &# // PB række // r) æ (t &# // PB åndedræt - r) æ (C &# // PB rædsel + r) æ (d &# // PB rædsel + æ (ld+ E // PB forældre pr) æ (k E // PB præke bl) ære EV // PB blærerøv gr) æ (ken E // Grækenland @@ -4065,9 +4096,13 @@ _molek) y (le 'y // PB stressed br) æ (dd a // PB brædder br) æ (t &# // PB bræt dr) æ (gtig &# // PB nederdrægtig + r) æ (k &# // PB skrækkelig + br) æ (nd &# // PB brænde pr) æ (st & // PB præst tr) æ (t & // PB træt tr) æ (f &# // PB træffe + tr) æ (k &# // PB trække + fr) æ (k &# // PB gr) æ (n & // PB grænse gr) æ (s &# // PB græs gr) æ (d &# // PB græde @@ -4104,6 +4139,7 @@ majest) æ (t 'E // PB stressed æ øjer W#jV // PB bøjer ø (jn W# // PB øjne l) øg 'Vj // løgn, løg + gl) øgg Wg // PB gløgg g) øg (l Vj // PB gøgler l) ø (s W C) ø (j W# // PB søjle, bøjle @@ -4184,8 +4220,10 @@ uimodst) å (elig 'O // PB stressed åre V3 // PB tåre å (lti V // PB måltid + .group ' 's (_S2 s + 'en (_S3 @n 'er (_S3 %V 'erne (_S5 %Vn@ 'ernes (_S6 %Vn@s @@ -4196,7 +4234,3 @@ uimodst) å (elig 'O // PB stressed $ dVlV // PB changed from [dVlar] ñ _^_ES // PB mañana ï i: // PB Thaïs - 'er (_ %V // PB 60'er - 'erne (_ %Vn@ // PB 60'erne - 'ernes (_ %Vn@s // PB 60'ernes - 'en (_S3 %@n // PB EMP'en - doesn't work diff --git a/dictsource/de_list b/dictsource/de_list index b122a888..14ab3011 100644 --- a/dictsource/de_list +++ b/dictsource/de_list @@ -121,7 +121,6 @@ _8X '_axtsIC _9X 'nOYntsIC _0C 'hUnd3t _0M1 'taUz@nt -_1M1 'taUz@nt // no '1' before thousand _0M2 ||mIlI'o:n@n _1M2 _'aIn@||mIlI'o:n _0M3 ||mIlI'ard@n @@ -611,33 +610,34 @@ hm h@m horsam hO3zA:m hostie $alt -illegitim Ile:gi:t'i:m -illiberal Ili:b@r'A:l -illoyal IlOajA:l -immobilie $alt -indem Ind'e:m -inden Ind'e:n -inder Ind3 -indes Ind'Es -indessen Ind'Es@n -injurie $alt -inka INkA: -inkaisch INkA:IS -inkonstant $1 -insbesondere $3 -interess Int@r'Es -intern Int'Ern +illegitim Ile:gi:t'i:m +illiberal Ili:b@r'A:l +illoyal IlOajA:l +immobilie $alt +indem Ind'e:m +inden Ind'e:n +inder Ind3 +indes Ind'Es +indessen Ind'Es@n +injurie $alt +inka INkA: +inkaisch INkA:IS +inkonstant $1 +insbesondere $3 +interess Int@r'Es +intern Int'Ern -januar janu:A:r +januar janu:A:r -kamelie $alt -kanoe kan'u: -kastanie $alt -kid kId -komödie $alt -konservativ $1 -konsul $1 -kurie $alt +kamelie $alt +kanoe kan'u: +kastanie $alt +kid kId +komödie $alt +konservativ $1 +konsul $1 +kurie $alt +kwaß kvas lappalie $alt lilie $alt @@ -709,17 +709,12 @@ telegen te:le:g'e:n the D@ // English theater te:'A:t3 train tre:n +tsunami tsu:n'a:mi: turin $2 umweg $1 unten Unt@n -wasserung vas@rUN // because -ung isn't marked as a suffix -weiterung vaIt@rUN -weither vaIth'Er -weitum vaIt_|'Um -woher vo:h'e:r - verein fEr'aIn vielbesprochen $3 vielleicht $2 @@ -729,18 +724,31 @@ vorherig fo:rh'e:rIg# vorig fo:rIg# //wahrscheinlich $2 -warum vA:r'Um +warum vA:r'Um +wasserung vas@rUN // because -ung isn't marked as a suffix +weiterung vaIt@rUN +weither vaIth'Er +weitum vaIt_|'Um +woher vo:h'e:r -zoom zu:m -zugegen tsu:g'e:g@n -zudem tsu:'de:m + +zloty slOti: +zoom zu:m zugegen tsu:g'e:g@n -zurück $2 -zymbal $1 +zudem tsu:'de:m +zugegen tsu:g'e:g@n +zurück $2 +zymbal $1 // Names +Djakarta dZak'artA: +Djibouti dZib'u:ti: Georg ge:Ork $only George dZO:rdZ +Khmer kme:r +Mc m@-k Neumexiko $2 Neuseeland $2 +Rwanda rU'andA: +Sri sr,i: diff --git a/dictsource/de_rules b/dictsource/de_rules index 328011fd..f769781f 100644 --- a/dictsource/de_rules +++ b/dictsource/de_rules @@ -18,7 +18,8 @@ // * . * // ***************************************************************************/ -.L01 c f h k p q s t // unvoiced, except s+vowel +.L01 l r +.L02 c f h k p q s t // unvoiced, except s+vowel // This file is UTF-8 encoded @@ -145,10 +146,11 @@ .group b _) b (_ be: + _) b (L01A b // allow bl br at start of word b b b) b b (_N p - b (L01 p + b (L02 p b (sA b bt (_N pt @@ -197,6 +199,12 @@ .group c _) c (_ se: + _) c (L01A k // allow cl cr at start of word + _) ch (L01A k + _) ch (a S + _) ch (A C + _) ch (o k + c k c) c @@ -212,7 +220,6 @@ e) chen (_ C@n ü) chen (_ C@n - _) chr kr chs ks (_ ck k @@ -225,8 +232,6 @@ _) ch (if S _) ch (il S chip (_ tSIp // English - _) ch (ol k - _) ch (or k bre) ch (en x chro kro: @@ -236,6 +241,7 @@ pla) c (ie ts coat (_ _^_EN _) code ko:t + _) computer(@P kOmpj'u:t3 _) cow _^_EN crew _^_EN cup _^_EN @@ -243,10 +249,13 @@ .group d _) d (_ de: + _) d (rA d // allow dr at start of word + _) d (schA d + _) d (shA d d d d) d d (_N t - d (L01 t + d (L02 t d (sA d ds (_ ts dt t @@ -440,6 +449,8 @@ _) f (_ Ef f f f) f + _) f (L01A f // allow fl fr at start of word + _) f (jord f _) faks (i f%akz _) farb (C@P4 f'arp @@ -459,12 +470,17 @@ .group g _) g (_ ge: + _) g (L01A g // allow _gl _gr g g g (g g (_N k - g (L01 k + g (L02 k g (sA g gd (_N kt + _) gh (A g + _) g (nA g@- // allow _gn + B) gn (A g@-n + i) gt (_ Ct zei) gt (_ kt gtet (_ kt@t @@ -472,8 +488,6 @@ _) g (eHC g // hC, lC, mC, nC, rC - _) gn (A g@-n - B) gn (A g@-n @) ght (_ _^_EN graph grAf @@ -580,7 +594,7 @@ i (dee %i: i (erin =i: &) ig (+ Ig# // [ig] or [iC] - igh aI + igh (K _^_EN i (i i:_! @@ -679,9 +693,13 @@ formal) ie =I@ _) j (_ jOt j j + .group k _) k (_ kA: k k + _) k (L01A k // allow _kl _kr + _) k (ha k + _) k (nA k // allow _kn k) k // @) keit (_S4 kaIt @@ -753,6 +771,7 @@ formal) ie =I@ _) mit (P3 m'It mitt mIt mitt (eil mItt + _) m (nem m // allow _mnem _) mo (rb m%O _) mono (@ m,o:no: _) motor m%o:to:r @@ -829,6 +848,7 @@ formal) ie =I@ z) oo (m u: &t) or (_ =o:r &) oren (_ 'o:r@n + _) orts (@P4 'Orts oso (_ 'o:zo: st) o (ss o: oy (K OY @@ -838,9 +858,17 @@ formal) ie =I@ .group p _) p (_ pe: p p - p) p - pf pF + p) p + _) p (L01A p // allow _pl _pr + _) pf (A pF + _) pf (L01A pF // allow _pfl _pfr + _) ph (A f // allow _ph + _) ph (L01A f // allow _phl _phr + _) phth (A ft ph f + _) p (neu p // allow _pneu + _) p (sA p // allow _ps + _) p (tol p pake (t p%ake: _) para (@ p,ara @@ -857,6 +885,7 @@ formal) ie =I@ po (et p%o: poesie po:e:z'i: _) poly (@P4 p,o:ly: + _) polygon (@P7 po:ly:g'o:n partei p%artaI _) perfe (k p%ErfE _) polik p'o:li:k @@ -884,7 +913,7 @@ formal) ie =I@ r (r b) r @-* _) r r - _) rh r + _) rh (A r // allow _rh rangier rA:NZ'i:r _) re (d re: @@ -901,15 +930,39 @@ formal) ie =I@ ss s sst (@ sSt + _) s (cA s // allow _sc + _) s (cr s // allow _scr + _) sch (A S + _) sch (L01A S + _) sch (mA S + _) sch (nA S + _) sch (w S + _) sh (A S + _) sh (rA S + _) s (kA s // allow _sk + _) s (kL01A s // allow _skl _skr + _) s (lA s + _) s (mA s + _) s (nA s + _) s (pA S + _) s (phA s + _) s (plA S + _) s (plend s + _) s (prA S + _) s (quA s + _) s (tA S + _) s (trA S + _) s (ve s + _) s (wA s + _) s (zA s + sch S - _) sh S sh (K S sou (nd saU p) s (a s p) s (i s t) s (i s k) s (i s - _) sp Sp _be) sp Sp _ge) sp Sp _ver) sp Sp @@ -925,7 +978,6 @@ formal) ie =I@ &C) ster (_S4 st3 &C) stes (_S4 st@s - _) st St _be) st St _ge) st St _ver) st St @@ -970,9 +1022,15 @@ formal) ie =I@ .group t _) t (_ te: t t - t) t + t) t + _) th (A t // allow _th + _) th (rA t // allow _thr th (K t K) th t + _) t (rA t // allow _tr + _) tsch (A tS + _) t (setse t + _) tw (A tw tz ts &t) te (_ @ @@ -1005,7 +1063,6 @@ formal) ie =I@ _) talent tal'Ent tch tS - _) tsch tS t (chen_ t _) teen _^_EN _) tele (@ t,e:le: @@ -1094,6 +1151,10 @@ formal) ie =I@ v) v v (_N f + _) v (lad v + _) v (lies f + _) v (ri f + _) vie fi: _) vi (CC vI _) vi vi: @@ -1147,6 +1208,9 @@ formal) ie =I@ .group w _) w (_ ve: w v + _) wh (A v + _) w (lad v + _) w (rA v @) wert (_ vErt _) wh _^_EN @@ -1182,7 +1246,9 @@ formal) ie =I@ .group z _) z (_ tsEt z ts - z) z + z) z + _) z (den z + _) z (wA ts // allow _zw _) zentral (@P7 tsEntr'A:l _) zentral (i tsEntral diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index f5b68e54..02a713a4 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -15,7 +15,7 @@ n N n^ p r s S t T tS v w x x2 z Z -Dictionary ca_dict 2010-05-12 +Dictionary ca_dict 2010-07-27 @ a a# aI e E E2 i o O u U @@ -53,7 +53,7 @@ p r s S t T v w x z -Dictionary da_dict 2010-07-03 +Dictionary da_dict 2010-07-29 & &# 0 3 @ @- a A e E i o O u V W @@ -65,7 +65,7 @@ l/2 l/3 m n N p r R s S t T tS v w z -Dictionary hu_dict 2010-07-17 +Dictionary hu_dict 2010-08-02 A a: E e: i i: o o: u u: Y y y: Y: @@ -76,7 +76,7 @@ n^ p r R R2 s S s2 t tS ts v z Z -Dictionary de_dict 2010-07-03 +Dictionary de_dict 2010-07-27 3 3: @ @- a A A: aI aU E E2 E: e: EI i I @@ -100,7 +100,7 @@ n^ p Q r R s s; t T ts v x z z; -Dictionary en_dict 2010-07-13 +Dictionary en_dict 2010-07-30 0 3 3: @ @- @2 @5 @L a a# A: A@ aa aI aI@ aU @@ -110,10 +110,10 @@ O@ o@ OI oU O~ U u: U@ V VR : ; ? b C d D dZ -f g 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 +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 Dictionary eo_dict 2010-05-19 @@ -127,7 +127,7 @@ s S t T tS ts v w x z Z -Dictionary es_dict 2010-07-13 +Dictionary es_dict 2010-07-28 a aI aU e E eI eU i o O oI u @@ -150,16 +150,16 @@ l m n N p r s S s2 t v w Z -Dictionary fr_dict 2010-07-18 +Dictionary fr_dict 2010-07-30 -@ @- a A~ e E E2 E: -E~ i I o O o3 O~ u -u: w W W~ y Y +@ @- a A~ e E E: E~ +i I o O O~ u u: w +W W~ y Y -- : b d dZ f g h -j k l m n N n2 n^ -p p2 r r2 s S t t2 -t3 tS v z Z z2 z3 +: b d dZ f g h j +k l m n N n2 n^ p +p2 r r2 s S t t2 t3 +tS v z Z z2 z3 Dictionary grc_dict 2008-03-03 @@ -185,32 +185,32 @@ N n^ p r R R2 s S t tS ts tS; v x z Z -Dictionary hi_dict 2009-11-24 +Dictionary hi_dict 2010-07-30 @ @- @2 @3 a a: aI aU e E e: E: E~ i I i: l- o O o: O: O~ o~ r- U u: u~ V -- : b bh c ch d d. -dh dh. f g gh h H j -J Jh k kh l l. m n -N n. n^ p ph Q q r -r. s S s. t T t. th -th. v w x z +#X1 #X2 - : b bh c ch +d d. dh dh. f g gh h +H j J Jh k kh l l. +m n N n. n^ p ph Q +q r r. s S s. t T +t. th th. v w x z -Dictionary ta_dict 2010-07-18 +Dictionary ta_dict 2010-07-30 a a: aI aU e E e: i -I i: o o: u U u: U: -V V# +I i: o o: u U u2 u: +U: V V# -: ; b C d d. dZ f -g h H j k l l. m -n N n. n^ p Q r R -s S s. t T t. th tS -v w z z. +#X1 #X2 : ; b C d d. +dZ f g h H j k l +l. m n N n. n^ p Q +r R s S s. t T t. +th tS v w z z. Dictionary hy_dict 2008-12-22 @@ -325,7 +325,7 @@ k l m n p R s S t tS v w x -Dictionary nl_dict 2010-07-18 +Dictionary nl_dict 2010-07-27 8 @ @- A a: A~ E e: EI eU i I O O: o: u @@ -349,7 +349,7 @@ k l m n N p r R s S s; t v w x z -Dictionary pap_dict 2009-05-02 +Dictionary pap_dict 2010-07-27 a a/ aI e E eI i o O u y Y @@ -474,7 +474,7 @@ p R R^ s S t tS ts v w x z Z -Dictionary tr_dict 2010-06-02 +Dictionary tr_dict 2010-07-27 @ a e E i I o O u U W y Y @@ -636,3 +636,14 @@ O~ u w y ; b d f g j k l m n N p r s S t tS v z Z + + +Dictionary az_dict 2010-07-27 + +& @ a e E i o u +W y + +* b c C d dZ f g +h j J k l m n p +Q R s S t tS v w +x z Z diff --git a/dictsource/en_list b/dictsource/en_list index e854ce3a..d6928021 100644 --- a/dictsource/en_list +++ b/dictsource/en_list @@ -1132,7 +1132,6 @@ finite faInaIt fishnet fISnEt fiord fi:O@d fix fIks // for fixer -fjord fIO@d flagellum fla#dZEl@m flamenco fla#mENkoU flexible flEksIb@L @@ -2447,6 +2446,7 @@ Durham dVr@m Egyptian IdZ'IpS@n Eire e@r@ Geneva dZ@ni:v@ +Gdansk g@-dansk Gomera goUm'e@r@ Harare ha#rA:rI Hanoi han'OI @@ -2481,6 +2481,7 @@ Lesotho l@s'u:tu: Liberia laIb'i@ri:@ Lima li:ma# Luxembourg lVks@mb3:g +Lvov l@-v0v ?5 Luxembourg lVks@mbVRg Madagascar mad@g'ask3 Madras m@draas @@ -2536,6 +2537,7 @@ Qatar katA@ Quebec kwI2bEk Raleigh rA:lI Reno ri:noU +Rio ri:oU Sahel sA:h'El Saigon saIg'0n Santiago santI'A:goU @@ -2556,6 +2558,7 @@ Taiwan taI'wan (tel aviv) t,El||a#v'i:v Tenerife tEn3r'i:f Texas tEks@s +Tblisi t@-bli:si Toronto t@r0ntoU Timor ti:mo@ Tokyo toUkIoU @@ -2611,6 +2614,7 @@ Bambi bambi: Barack ba#rA:k Barbara bA@b@r@ Betsy bEtsI +Bjorn bjO@n Boris b0rIs Brien braI@n Candace kandIs @@ -2638,11 +2642,13 @@ Declan dEkla#n Denise d@ni:s Derek dErIk Dinah daIn@ +Dmitri d@mi:tri Dominic d0mI2nIk Donaghy d0n'hi: Doris d0rIs Dorothy dO@r@Ti Dougall du:g@L +Dvina d@vi:n@ Dylan dIl@n Edith i:dIT Elise I2li:z diff --git a/dictsource/en_rules b/dictsource/en_rules index aa4da05b..069a8d21 100644 --- a/dictsource/en_rules +++ b/dictsource/en_rules @@ -28,6 +28,8 @@ // ?7 Scottish // ?8 Use full vowel, not schwa in some word endings + +// Group Y, vowels + y .L01 l r .L02 i y .L03 a i o u // vowel, not 'e' @@ -76,7 +78,6 @@ aar 'A@ w) a (b 0 r) a (ciA eI - _r) a (cis eI w) a (d 0 ow) a (d @ ae i: @@ -230,8 +231,8 @@ &) able (_S4iev @b@L // suffix &c) able (_ @b@L @ct) able (_ =@b@L - &) ability (S7iev @b'IlI2t%I // suffix - &) abilities (S9iev @b'IlI2t%Iz // suffix + &) ability (S7iev @b'IlI2t%i // suffix + &) abilities (S9iev @b'IlI2t%iz // suffix &) ably (_S4iefv @bl%I &c) ably (_S4fv @bl%I @@ -252,7 +253,10 @@ accu (ra akjU accus (A a#kju:z ace (_ eIs + sp) ac (e eIs + _r) ac (e eIs _) ac (e a#s + _r) ac (is eIs acean (_ 'eIS@n pl) ac (at a#k pl) ac (eb @s @@ -277,7 +281,7 @@ achia 'eIS@ f) ac (ilit @s _m) ace (d asI - m) achi (n# @Si: + m) achi (nA# @Si: m) achina (t aSI2neI ach (rom ak ac (id_ as @@ -312,6 +316,7 @@ _b) ac (o eIk y) ach (t 0 &) ac (y_ @s + cr) ac (y_ =@s .group ad _) ad (@ a#d @@ -979,7 +984,7 @@ purch) as (e Is ph) ase (_ eIz r) ase (_ eIz - &) asey (_ @s%I + &) asey (_ @s%i b) as (i eIs b) as (il az as (sist a# @@ -992,7 +997,7 @@ nt) as (t as as (ive 'eIs as (ymp as - &) asy (_ @s%I + &) asy (_ @s%i w) ast (e# eIst .group at @@ -1131,6 +1136,10 @@ .group b b b + _) bh b + _) b (L01Y b // allow _bl _br + _) brz (e brz + b (b m) b (_ _) bally (@ b,alI2 @@ -1233,6 +1242,10 @@ .group c c k + _) c (L01Y k // allow _cl _cr + _) cz (ar ts + _) cz (e tS + cc k ck k c (e s @@ -1272,6 +1285,9 @@ czech tSEk .group ch + _) ch (Y tS + _) ch (L01Y k + ch tS ch (r k chry (sa krI @@ -1469,6 +1485,11 @@ .group d d d + _) d (L01Y d // allow _dl _dr + _) dj (Y dZ + _) d (nie d + _) d (wY d // allow _dw + d (d _) d' (AP2 d @@e) d (_S1 d // suffix @@ -1698,7 +1719,7 @@ econo (m Ik'0n@ econo (mic i:k@n'0 _) eco (s i:koU - &) ecy (_ @s%I + &) ecy (_ @s%i ee i: coff) ee I ee (m 'i: @@ -2028,7 +2049,7 @@ _) encha (n %EntSaa enclav EnkleIv en (core 0n - &) ency (_ @ns%I + &) ency (_ @ns%i ency (cli %EnsI en (dA_ 'En _) en (d En @@ -2432,6 +2453,9 @@ .group f f f + _) f (L01Y f // allow _fl _fr + _) fj (ord fI' + f (f fa (ciA feI fa (miliar f@ @@ -2445,6 +2469,11 @@ .group g g g + _) g (L01Y g + _) gh (Y g + _) g (nY + _) g (wA g + gg g g (e dZ _) gaol dZeIl @@ -2458,10 +2487,8 @@ g (ilC g l) ging dZI2N g (y dZ - _) g (n exa) gg (er dZ ght t - _) gh g gh (_ g C) gh (A g gh (C g @@ -2721,6 +2748,7 @@ .group ie ie I + X) ie i: ie (_ aI ied (_S2i d // suffix ieds (_S3i dz @@ -2741,7 +2769,7 @@ ie (k i: ie (l i: ie (llA I2'E - n) iel (_ I2@L + &n) iel (_ I2@L &r) iel (_ =i:@L ie (n i@ d) iene (_ 'aIi:n @@ -2787,6 +2815,7 @@ ie (ve i: s) ie (ve I ie (z i: + _t) ie aI .group ig am) ig (a_ i:g @@ -2860,19 +2889,19 @@ .group in @) ing (_+S3dve IN @) ings (_S4dve INz - @) ingly (_S5dve INg-lI - @) ingment (_S7dve INg-m@nt + @) ingly (_S5dve INlI + @) ingment (_S7dve INm@nt logu) ing (_S4v IN x) ing (_+S3v IN el) ing (_+S3dv IN @@om) ing (_S3dv IN en) ing (_S3v IN en) ings (_S4v INz - en) ingly (_S5vf INg-lI + en) ingly (_S5vf INgI er) ing (_S3v IN er) ings (_S4v INz - er) ingly (_S5vf INg-lI - er) ingment (_S7v INg-m@nt + er) ingly (_S5vf INlI + er) ingment (_S7v INm@nt Br) ing (_ IN ?7 &) in (_ @n @@ -3160,13 +3189,13 @@ _) it' %It _m) it (o aIt it (o_ 'i:t - _C) ity (_ ItI + _C) ity (_ Iti _ed) it It cred) it It CAt) it (_ 'i:t //apetite v) it (al aIt t) it (l aIt - &) ity (_ =I2t%I + &) ity (_ =I2t%i orb) it It @@) it (an_ =It ?3 &) itary (_ @tEr%I // military @@ -3251,7 +3280,10 @@ .group k k k k (k - _) kn n + _) k (L01Y k + _) k (hY k + _) k (wY k + _) kn (Y n kn (if n kn (iv n kn (it n @@ -3269,6 +3301,10 @@ .group l l l l (l + _) l (hY l + _) ll (Y l + _) l (ju l + l (_ l A') ll l A) ll l @@ -3333,9 +3369,11 @@ ?8 @) lessly (_S6i lEsl%I ?8 @) lessness (_S8i lEsnEs + .group m m m mm m + _) mn (e n h) m (_ @m B) m (_ @m l) m (_ m @@ -3361,7 +3399,6 @@ _) mc (A mak _) mc (-A mak mn (_ m - _) mn n &B) me (_ m%I @) men (_ mEn &) ment (_S4 m@nt @@ -3422,6 +3459,8 @@ .group n n n n) n + _) n (gY+ @-N + &ia) n (_S1 n &ia) ns (_S2 nz @) name (_S4 neIm @@ -4111,7 +4150,7 @@ &dr) ous (_ =@s &l) ous (_ @s &) ous (_ @s - &) ousy (_ @s%I + &) ousy (_ @s%i &m) ous (_ @s &n) ous (_ @s _) out (@P3 %aUt // prefix out @@ -4226,6 +4265,14 @@ .group p p p p (p + _) p (L01Y p // allow _pl _pr + _) pf (Y f + _) ph (Y f + _) ph (L01Y f + _) pn (eu n + _) ps (Y s + _) pt (Y t + ph f phenome (n fI2n0mI phenyl f,i:naIl @@ -4252,12 +4299,10 @@ poly (@@ p,0lI poly (@ p0lI pota (t p@teI - _) ps s pseudo su:doU psych saIk psycho saIkoU psycho (lo saIk'0 - _) pt t ei) pt t ras) p (b _) pur (su p3 @@ -4388,7 +4433,6 @@ pro (log proU .group q - _) q (B kju: q k q (q qu kw @@ -4413,13 +4457,15 @@ .group r r r rr r + _) rh (Y r + _) rw (a r%U + r) r (_ C) r (_N r@ e) r (_ 3 @) r (B @ 3_) rd (_ rEr (_ r3 - _) rh r C) rh r rheu ru: rhi (n raI @@ -4433,7 +4479,6 @@ _) ru (bL01 ru: _) run (a rVn _) run (o rVn - _) rw r%U &ant) ry (_S2 r%I .group re @@ -4541,7 +4586,29 @@ s s s (s s (sh s + + _) s (cY s + _) s (cL01Y s _) sch S + _) sh (Y S + _) sh (L01Y S + _) s (kY s + _) s (kL01Y s + _) s (lY s + _) s (mY s + _) s (nY s + _) s (pY s + _) s (phY s + _) s (pL01Y s + _) s (qu s + _) s (ri s + _) s (tY s + _) s (trY s + _) s (va s + _) s (ve s + _) s (wY s + _) s (zY s + sche (m ski: _) sch (ism sk _) schiz skIts @@ -4721,6 +4788,14 @@ .group t t t t) t + _) th (Y T + _) th (rY T + _) th (wY T + _) t (rY t + _) t (sY t + _) t (wY t + _) tz (ar ts + tch tS _) tele tElI2 r) tga (g gI @@ -4901,6 +4976,7 @@ ?8 &f) ully (_ Vl%I &) u (lous_ =jU b) ul (r Ul + &ic) ul (t @L _) ultra (@ ,Ultra u (lul V @) u (lum =jU @@ -4972,7 +5048,7 @@ g) ui (lC I _g) ui (le aI @) ui (ty 'ju:I - g) ui (dA aI + g) ui (dA# aI g) uide (l aId beg) ui (l aI _g) ui (n I @@ -5098,6 +5174,7 @@ .group v v v v (v + _) v (la v @) va (len veI _) vehem vi@m @@ -5108,6 +5185,9 @@ .group w w w w (w + _) wh (Y w + _) wr (Y r + C) w (_ w@ wh w wr r @@ -5140,14 +5220,14 @@ As) w (ick .group x - _) x (C Eks x ks x) x (A _) xy zaI - _) x z + _) x (Y z xio (n kS@ xious =kS@s xu (a =kSu: + xure (_ kS%U@ .group y y j @@ -5164,6 +5244,8 @@ y (Be# aI @C) y (Be# aI ye (_ aI + y (ear j + %B) y (_NS1d i %B) y (_S1d I _C) y (Ce aI C) y (i I @@ -5201,10 +5283,11 @@ d) yse (n Is@ f) y (_ aI ff) y (_ I - &sk) y (_ =I + &sk) y (_ =i den) y (_ aI bel) y (_ aI &) y (_ %I + &) y (_N %i y (_ aI y (Cic_ 'I y (Cical 'I @@ -5257,6 +5340,11 @@ .group z z z z (z + _) zh (Y Z + _) z (lot z + _) zs (Y z + _) z (wY z + @) zales (_ z'A:lEs zes (_ zI2z zh Z diff --git a/dictsource/es_list b/dictsource/es_list index bc796fb9..11d838a8 100644 --- a/dictsource/es_list +++ b/dictsource/es_list @@ -106,7 +106,6 @@ _5C kinj'EntOs _7C s,eteTj'EntOs _9C n,OBeTj'EntOs _0M1 m'il -_1M1 m'il // no '1' before thousand _0M2 miJ^'ones _1M2 'unmiJ^'On _0M4 _biJ^'onEs @@ -358,23 +357,23 @@ alguna $u b be c Te d de -f Efe +f _|Efe g xe h atSe j xOta k ka -l Ele -m Eme -n Ene -ñ En^e +l _|Ele +m _|Eme +n _|Ene +ñ _|En^e p pe q ku -r E**e -s Ese +r _|E**e +s _|Ese t te -v uBe +v _|uBe w ,uBe||d'OBle -x Ekis +x _|Ekis z TEta _a a diff --git a/dictsource/es_rules b/dictsource/es_rules index a3344f1b..c4f6ce16 100644 --- a/dictsource/es_rules +++ b/dictsource/es_rules @@ -5,11 +5,12 @@ // ?1 Castilian // ?2 Latin America -.L01 j w l r b d g n m p t k c +.L01 l r y .L02 b d g n m // change [s] to [z] before these -.L03 f h j s y z // allow [B] [D] [Q] before these consonants +.L03 f h j s y z r // allow [B] [D] [Q] before these consonants .L04 b v f p // labials, nasals are [m] .L05 g k // velars, nasals are [N] +.L06 j w l r b d g n m p t k c .group a a a @@ -22,7 +23,8 @@ .group b b b - _) b b // phoneme definition may change it to [B] + _) b ($unpr b // phoneme definition may change it to [B] + _) b (L01A b // Only bl, br are allowed at start of word b (A B b (cY B b (L03 B @@ -33,13 +35,17 @@ .group c c k + _) c (L01A k // allow: cl cr at start of word + _) ch (A tS // allow _ch + c (Y T // ce, ci ch tS .group d d d - _) d d // phoneme definition may change it to [D] + _) d ($unpr d // phoneme definition may change it to [D] + _) d (rA d d (A D d (cY D d (L03 D @@ -64,11 +70,15 @@ .group f f f + _) f (L01A f // allow fl fr at start of word .group g g g - _) g g // phoneme definition may change it to [Q] + _) g ($unpr g // phoneme definition may change it to [Q] + _) g (L01A g + _) gh (A g // allow _gh in foreign words + _) gn (A n g (A Q g (cY Q g (L03 Q @@ -95,10 +105,12 @@ .group k k k + _) k (L01A k // allow kl kr at start of word .group l l l + _) ll (A J^ // allowe _ll ll J^ ?2 A) ll (A j: @@ -106,6 +118,8 @@ .group m m m + _) mn (em n + m (K n m (L04 m m (_L04 m @@ -136,11 +150,14 @@ .group p p p + _) p (L01A p // allow pl pr at start of word p (t p: _) ph f ph (K f - _) ps (ico s + _) ps (i s _) ps (eudo s + _) pt (ero t + _) pt (ol t .group q @@ -150,7 +167,6 @@ .group r r R - _) r RR2 r (_ * r (t ** A) r (A ** @@ -165,13 +181,15 @@ .group s s s &) s (_S1 s - _) s (C Es - _) sh S + _) s (C %Es + _) sh (A S + _) sh (L01A S sh (K S .group t t t + _) t (L01A t // all tr at start of word _) th T th (K T @@ -188,15 +206,15 @@ .group v v B - _) v b + _) v (L01A b // allow vl vr at start of word ?1 m) v b ?1 n) v b -?1 v (L01 b +?1 v (L06 b ?1 v (iA b ?1 v (uA b ?2 v v# ?2 _) v v -?2 v (L01 v +?2 v (L06 v ?2 v (j v ?2 v (iA v ?2 v (uA v @@ -204,18 +222,19 @@ .group w w w + _) wh (A w .group x x ks ?1 A) x (A Qs x (_ =Qs - _) x z // ? + _) x ($unpr z // ? .group y y i - _) y J + _) y ($unpr J _m) y J n) y J _l) y J diff --git a/dictsource/fr_list b/dictsource/fr_list index f0b16f26..9550322a 100755 --- a/dictsource/fr_list +++ b/dictsource/fr_list @@ -24,7 +24,7 @@ // 2006-11-18 Gilles Casse // -// Updated 2010-07-16 Michel Such +// Updated 2010-07-25 Michel Such // // * Numbers, a few abbreviations and exceptions. // @@ -83,8 +83,8 @@ z zEd // accent names _lig ligat'yr -_acu aksA~tE2g'y -_ac2 dublaksA~tE2g'y +_acu aksA~tEg'y +_ac2 dublaksA~tEg'y _brv br'Ev _ced sed'ij _cir aksA~sirkO~fl'Eks @@ -104,29 +104,29 @@ _cap maZysk'yl _?A l'Etr _?? sE~b'oll _#9 tabylasiO~ -_#32 E2spas +_#32 Espas -_" gijmE2 +_" gijmE _# djEz _' apostr'Of _( parA~tEz_goS _) parA~tEz_drwat _, virgyl -_- tirE2 +_- tirE _. _|pw%E~ -_/ barOblik +_/ baroblik _: d'Y||pw'E~ _; pwE~||virg'yl _< E~feriWr _= egal _> syperiWr -_? pwE~||dE~tE2rogasj'O~ +_? pwE~||dE~tErogasj'O~ _! pwE~||dEksklamasj'O~ -_[ krOSE2_goS -_\ barOblik_E~vErse -_] krOSE2_drwa +_[ krOSE_goS +_\ bakslaS +_] krOSE_drwa _^ sirkO~flEks __ sulin^e _` aks'A~_gr'av @@ -134,8 +134,8 @@ _{ akOlad_goS _| bar_vErtik'al _} akOlad_drwat ² pyis'A~s||d'Y -_« uvre||gijm'E2 -_» fErme||gijm'E2 +_« uvre||gijm'E +_» fErme||gijm'E _’ apostr'Of _‘ apostr'Of _µ mikr'o @@ -174,7 +174,7 @@ _5 sE~k _6 siz3 _7 sEt _8 _|yit3 -_9 nYf +_9 nWf _10 diz3 _11 _|O~z _12 duz @@ -184,7 +184,7 @@ _15 kE~z _16 sEz _17 disEt _18 dizyit3 -_19 diznYf +_19 diznWf _20 vE~t2 _21 vE~te:W~ _22 vE~tdYz2 @@ -194,7 +194,7 @@ _25 vE~tsE~k _26 vE~tsiz3 _27 vE~tsEt _28 vE~tyit3 -_29 vE~tnYf +_29 vE~tnWf _3X trA~t _31 trA~te:W~ _4X karA~t @@ -251,17 +251,18 @@ cci $abbrev cia $abbrev cio $abbrev cm centimètre $text -collins kOlins +collins _^_en cpu $abbrev ctrl _::kO~trOl -dept depart@mA~ +dept département $text divx diviks ebay _^_en (e bay) ebay $text ebcdic @besedik edf @d,eEf eml @,EmEl -etc E2tsetera +etc Etsetera +fyi fWr||jWr||InfWrm'EjSWn ghz ZigaErts (g hz) ZigaErts hmm hWm @@ -271,14 +272,13 @@ ibm ib,e'Em ide $abbrev ip ipe irc I,Er_|se -jaws dZo3:z kbit kilobit kde $abbrev kg kilogramme $text khz kiloErts km kilomètre $text -(km player) ka,EmplE2j'Wr -(kmplayer) ka,EmplE2j'Wr +(km player) ka,EmplEj'Wr +(kmplayer) ka,EmplEj'Wr kw kilowatt $text m. m@siY mbit megabit @@ -314,12 +314,12 @@ sap $abbrev scsi $abbrev solaris solaris sos $abbrev -s.t.p silt@:pl'E2 -s.v.p silvu:pl'E2 +s.t.p silt@:pl'E +s.v.p silvu:pl'E st s'E~t2 ste s'E~t -stp silt@:pl'E2 -svp silvu:pl'E2 +stp silt@:pl'E +svp silvu:pl'E tva $abbrev uk $abbrev ups ypeEs @@ -331,7 +331,6 @@ u.s y:Es virgin virZin vip v,i||,aj||p'i (web visum) webvisum $text -windows windo3z wma $abbrev xfce iksEfse@ xy $abbrev @@ -421,10 +420,11 @@ lui $u+ $verbf ca sa $u+ $capital $verbf ce $u+ $nounf +ceux $u+ +celle $u+ +celles $u+ ceci $u+ $verbf cela $u+ $verbf -voici $u+ -voilà $u+ cet $u $nounf cette $u $nounf ces sez2 $u $nounf @@ -435,6 +435,8 @@ ces sez2 $u $nounf (celles ci) sEl||si $verbf $u+ (celles là) sEl||la $verbf $u+ plupart $u+ +voici $u+ +voilà $u+ // possessives ma $u $nounf @@ -527,8 +529,8 @@ pourtant $u+ // auxillary verbs (be, have, can, etc) suis $u+ $verb -es E2z2 $u+ -est E2t2 $u+ +es Ez2 $u+ +est Et2 $u+ sommes $u+ $verb êtes $u+ $verb sont $u+ $verb @@ -544,7 +546,7 @@ sois $u+ $verb soit $u+ ai $u+ $verb -(ai je) E2Z $u+ +(ai je) EZ $u+ as as as az2 $u+ $verb (as tu) aty @@ -642,7 +644,6 @@ albinos albinos alleluia alelui'a alterego altErego anis anis -any Eni $u armageddon armagedO~ auvent ovA~ beta beta @@ -653,7 +654,7 @@ blues _^_en blum blum broglie breuil $text browglie breuil $text -buffer bYfYr +buffer bYfWr bus bys bus by $verb cancer kA~sEr @@ -673,11 +674,12 @@ dot dOt enfer A~fEr fahrenheit far@najt faut fot2 $u+ +feldspath fEldspat fier fjer $verb for $u+ francis frA~sis fred frEd -free frI: +free _^_en fuel fjul gangster gA~gstEr gars ga @@ -685,20 +687,20 @@ genesis Zenezis georges ZOrZ gilles Zil gin dZin -gulf gWlf +gulf gOlf gus gys gym Zim +han _|A~ hélas elas $u+ jacques Zak -karaoke karaOke +karaoke karaoke kevin kevin laetitia letisja laser lazEr listbox listbOks louis lwi malus malys -mai mE2 -mailto mEjltu_ +mai mE mapper _^_en mars mars mas mas @@ -712,32 +714,31 @@ mrs _^_en oasis oazis ours urs pataquès patakEs -patchwork patSwWrk -peter pItWr +peter _^_en phallus falys polder pOldEr premier pr@mjer2 program _^_en -(program files) prOgramfajlz -query kueri -queries kueri +query _^_en +queries _^_en quid kwid $u+ -quit kwit -recorder rikOrdWr +quit _^_en +recorder _^_en requiem rekyijEm revolver revOlvEr sas sas -scan skan +scan _^_en scanner skaner2 $verb scanner skanWr $noun scanners skanWr shampoing SA~pwE~ -sir sWr +sir _^_en souris suri stocker stoker2 sus sys sus sy $verb sushi suSi +thierry tjEri to tu $u+ tramway tramwE: tuttiquanti tutikw'anti @@ -745,7 +746,6 @@ vaut $u+ vaux $u+ vénus venys vot vOt -writer raitWr yves iv @@ -777,18 +777,17 @@ zut zyt // et (t is said) -exocet E2gzOsEt +exocet EgzosEt fret fr'Et -budget bydZE2 +budget bydZE hamlet _|amlEt knesset knesEt -lazaret lazarE2 +lazaret lazarE margaret margarEt net nEt offset OfsEt set sEt soviet soviEt -stewart stIwart // urt (t is said) kurt kurt @@ -800,19 +799,14 @@ yogourt _|iogurt short SOrt // art (t said) -steward stiwart stuttgart Stutgart hart art kart kart smart smart // irt -(sweat shirt) swEtSWrt -(sweat shirts) swEtSWrt -(tee shirt) t,IS'Wrt -(tee shirts) t,IS'Wrt -(t shirt) t,IS'Wrt -(t shirts) t,IS'Wrt +(t shirt) _^_en +(t shirts) _^_en // words from other languages @@ -821,34 +815,38 @@ acer asEr and _^_en amazon amaz'On apple _^_en -at at $u+ -(audible manager) od,ibl||manadZ'Wr +at _^_en +(audible manager) _^_en +balabolka balabOlka +be _^_en +better _^_en bin bin bit bit -bluetooth blut'us +bluetooth _^_en computer _^_en (cyber link) _^_en debian debjan +do _^_en edit _^_en -emacs E2maks -emacspeak E2makspI:k +emacs _^_en end _^_en -espeak @spI:k ethernet etErnEt exit egzit -(file zilla) f,ajl||zij'a -from frOm $u+ +(file zilla) _^_en +from _^_en get _^_en -google gug=Wl +google _^_en gnome gnOm gnu $abbrev hamburger _|A~b@rgWr +he _^_en +her _^_en help _^_en hot _^_en -in in $u+ -inside _^_en +in _^_en internet E~tErn'Et -(internet explorer) E~tErn'Et||E2ksplOr'Wr +(internet explorer) E~tErn'Et||EksplOr'Wr +it _^_en klaxon klaksOn let _^_en lite _^_en @@ -856,28 +854,29 @@ login _^_en logon _^_en (mac os x) makoEsiks made _^_en +mail _^_en +mailto _^_en media medja -messenger mE2sEnZWr -my maj $u+ +messenger _^_en nat nat not _^_en null _^_en ok oke $u+ -open op'Wn -(open source) op,Wn||s'urs -outlook autlu:k +open _^_en +outlook _^_en paint _^_en paper _^_en people _^_en -redhat rEdat +redhat _^_en same _^_en sametime _^_en +she _^_en sun _^_en -(text aloud) tEkst||@la=wd +(text aloud) _^_en ubuntu ubuntu up _^_en -win win $u+ yes _^_en +yet _^_en // tions (tjO~ instead of sjO~) @@ -903,6 +902,7 @@ vincent vE~sA~ // Some countries, areas and languages afrikaans afrikans aix Eks +aruba aruba bahamas baamas bangladesh bA~gladES bayeux bajY @@ -915,14 +915,17 @@ burundi burundi calvados calvadoss $text christmas krismas croatie kroasi -esperanto E2sperA~to +esperanto EsperA~to groenland groEnlA~d guatemala gwatemala hindi _|indi honduras _|O~dyras kenya kenja +koweït kowEjt laos laOs +leone leOn lesotho lezOto +libye libi liechtenstein liStWnStajn angeles A~nZelEs malawi malawi @@ -935,15 +938,12 @@ oman oman palaos palaOs samoa samoa swaziland swazilA~d -leone leOn -koweït kowEjt taïwan tajwan -texas tE2ks'as +texas tEks'as tuvalu tuvalu vanuatu vanuatu -venezuela venezy-E2la +venezuela venezyEla (viêt nam) vjEtnam wallis walis futuna futuna zimbabwe zimbabwe - diff --git a/dictsource/fr_rules b/dictsource/fr_rules index 438fb197..d321c939 100755 --- a/dictsource/fr_rules +++ b/dictsource/fr_rules @@ -27,7 +27,7 @@ // http://www.fluxnic.net/cicero // // Rules are now maintained by Michel Such -// Last update: 2010-07-16 Michel Such +// Last update: 2010-07-30 Michel Such // // Letter classes: @@ -45,7 +45,32 @@ .L03 d l m n s t v .L04 c d f g l m n v .L05 g h k l m v w -.L06 l r s + +// Following groups are used to manage mute e inside words. + +// After or before L06, e is not mute +.L06 bl br cl cr ct dr fl fr ft gl gr kl kr pl pr tr vr + +// After L07, e is not mute +.L07 ec éc ed éd lb lc ld lg lm ln lp lt lv rb rc rd rf rg rl rm rn rp rs rt rv + +// All consonants + ch gu qu used as ch g k +.L08 b c d f g h j k l m n p q r s t v w x z ch qu gu + +// E placed after a consonant following L09 is not mute +.L09 l r s + +// When these diphtonges are after a consonant folllowing e, e is not mute +.L10 ia ie io ua ue ui uo +.L11 b p +.L12 é è al ib ie l om on ré + +// Words ending "son" pust sound english if preceded by L13 +.L13 d g k l p er hn + +// For english words ending "side" +.L14 be in up ut + .group a @@ -56,21 +81,18 @@ ain (K E~ // pain Ct) ain (_ E~n2 // certain ami ch) ain (_ E~n2 // prochain arret - ai (_ e // dirai ferai... - _ess) ai (_ E2 // essai - _vr) ai (_ E2 // vrai - ai (b E // faible - ais (_ E2z2 // dirais ferais... - ait (_ E2t2 // dirait ferait... - aient (_ E2t2 // diraient feraient... + ai E + ai (_ e +_bal) ai (_ E +_ess) ai (_ E +_vr) ai (_ E + aie E + ais (_ Ez2 + ait (_ Et2 + aient Et2 f) ai (sA @ // faisons faisan a (ilK a - aie (me E2 // paiement - ai E // aile - ai (L06 E // aile - ai (CAX E // aile - am (b A~ // jambon - am (p A~ // camp + am (L11 A~ // jambon, tampon am (m a // programmation _) am (n am // amnistie am (n a // condamner @@ -106,22 +128,22 @@ aud (_ o // chaud _C) aud (_ od // Maud au (l_ O // Paul - au (re_ o // dinosaure + au (re_ O // dinosaure _) audio (@P5 odio _) auto (@P4 oto _) autom (n otO bb) aye (X ei // abbaye ay (C E // aymé ay Ej // paye - ay (_ E2 // display - Xl) ayer (X E2jWr // player, layer + ay (_ E // display + Xl) ayer (X EjWr // player, layer h) am (_S2 am w) an (_ an a a // bateau // group a: English section - sm) all _^_en // small, smaller - a (wC _^_en + any _^_en + aw (K _^_en .group b @@ -131,12 +153,9 @@ _C) aud (_ od // Maud // group b: English section back _^_en - bbl _^_en - bird _^_en // bird board _^_en // board, keyboard box (_ _^_en // box, inbox, outbox bugg _^_en // debugger - _) by _^_en // by, bye, bypass .group c @@ -239,50 +258,64 @@ _ingré) dien (t_ djA~ // ingrédient _) devic _^_en dle (X _^_en // bundle, handle - .group e // Define use of the final 'e' in french e (_ + +// Manage mute e inside words +@C) e (CeCA @ +@L08) e (CA +@L08) e (CL10C @ +@L08) e (L06 +@L08) e (L06L10C @ +@L06) e (CA @ +@L06) e (L06 @ +@L07) e (CA @ +@L07) e (L06 @ +@L09gu) e (CA @ +@L09gu) e (L06 @ +@L09qu) e (CA @ +@L09qu) e (L06 @ + e (ct+++++ E + e (x+++++ E + _C) e (_ @ // je te -c) e (_ -j) e (_ C) e (- - e (Ce_ E - eau o // bateau - g) ea (s_ a // mangeas - cap) e (la_ e - gh) e (tAX e // spagheti - j) e (a // Jean Jeanne - p) ect (_ E2 // suspect +_) e (CAN e // Evident +_) e (L06A e // Ecran +_eC) e (CA++ E // Evenement + eau (++ o // bateau + e (CC E + cap) e (la_ E + gh) e (tAX E // spagheti + p) ect (_ E // suspect ect (_ Ekt // direct pi) ed (_ e // pied _art) e (++ e // arte, artefact _cl) ef (_ e // clef - _cr) e (at e _) ein (K En // Einstein ein (K E~ // peindre pl) ein (_ E~n2 // plein emploi e (il E // vieille ei E // neige - eoi wa // asseoir - ell El // selle - el (K El // celsius, caramel + e (oi // asseoir + el (l E // belle _f) em (me a // femme i) e (mA // remerciement, d�ploiement - e (ro_ e // Cicero A) e (rA // remerciera tch) e (rX W @) em (me a // patiemment - em (b A~ // décembre + em (L11 A~ // décembre em (mACC A~ // emmancher em (mACAC A~ // emmagasiner - em (ma E2 // emmanuel + em (ma E // emmanuel em (mai A~ // emmailloter l) em (n a // solemnel il) emn Em // dilemne - em (p A~ en (_ A~n2 // en en (hA A~n // enharmonique _C) en (j E~ // benjamin @@ -440,7 +473,7 @@ s_couv) en (t_ // elles couvent _hiv) er (X Er // hiver Cst) er (X Er // hamster _cart) er (X Er // carter - _cutt) er (X Er // cutter + _cutt) er (X Wr // cutter tain) er (X Er // container _ti) er (_ Er ack) er (K Wr @@ -467,6 +500,7 @@ s_couv) en (t_ // elles couvent Am) es (nA e // Dumesnil d) esh (A ez // Deshormeaux + f) eb (vA E // Lefebvre _r) e (ss @ // ressembler _r) e (ssu e // ressusciter @@ -477,13 +511,14 @@ s_couv) en (t_ // elles couvent dg) et (_ Et // Bridget, gadget k) et (_ Et - tick) et (_ E2 + tick) et (_ E m) et (_ Et2 eu Y // eu eu (CX W // neuf eu (CeX W // fleuve eu (Cer_ Y // pleurer + eu (i W // feuille eu (CeX Y // meule eu (reX W // demeure gu) eu (leX W // gueule @@ -494,82 +529,46 @@ gu) eu (ler Y // gueuler _) eut (_ yt2 eut (_ Yt2 - _) extra (uP5 E2kstra - _) extra (CP5 E2kstra + eux (_ Yz2 + _) extra (uP5 Ekstra + _) extra (CP5 Ekstra _) eû y // eût eû Y: // jeûne - ey (_ E2 // dahomey - ey (C E2 // ceylan + ey (_ E // dahomey + ey (C E // ceylan ey Ej // asseye ez (_ ez2 // nez mangez chez g) e (A // mangeons - g) eu Y // vengeur + g) eu W // vengeur g) eu (re y // gageure _d) e (ch @ _r) e (ch @ // recherche e (Cl @ - _l) e (xA E2 - _m) e (xA E2 _l) e (CA @ _l) e (ChA @ _l) e (ClA @ // Leclerc tr) e (CA @ tr) e (ChA @ - e (CC E // infect pelle mettre e (Cr @ _) e (C% e // effet, effectuer e (C_ E - e (t_ E2 e (rC E es (_ z2 - %C) e (xA E2 - - @gu) e (CA - @gu) er (A r - @qu) e (CA - @qu) er (A r - _qu) e (CA @ -@L06gu) e (CA @ -@L06qu) e (CA @ - @C) e (CA - @C) e (li @ - @ch) e (li @ - @C) er (A r - @C) e (rion++ @ - @C) e (riez++ @ - @ch) e (CA - @ch) er (A r - L06ch) e (CA @ - @L06C) e (CA @ - @CL06) e (CA @ - @bC) e (CA @ - @ct) e (CA @ - %C) e (CA++ - %C) er (A++ r - @C) e (xA++ E2 - @c) e (v++ @ - @d) e (v++ @ - - @C) e (CrA - @ch) e (CrA -@L06ch) e (CrA @ - @L06C) e (CrA @ - @L06C) e (rrA E - @CL06) e (CrA @ - %C) e (CrA++ + e (ri_++ e + e (ria_++ e + e (ro_++ e // Cicero e (rr+++ E e @ // menue _) e (CA e - _) e (xC++ E2 - Cr) eam Im + Cr) eam I:m Cr) eamer ImWr Cl) eaner InWr vert) e (rX W @@ -580,26 +579,23 @@ gu) eu (ler Y // gueuler // group e: English section - eac _^_en - C) ead _^_en // read, head - eak _^_en // break, speak - eal _^_en // deal - ear _^_en // ear, search - eas _^_en // please - eave _^_en // leave + ea _^_en + e (CeX _^_en ed (_ _^_en ee _^_en // meeting efore (_ _^_en // before eing (_ _^_en // being, boeing eive _^_en // receive - eld (_ _^_en // field + el (CX _^_en // field + el (sX El _) enter (_ _^_en // enter _) enhan _^_en qu) est (_ _^_en // request qu) este (X_ _^_en // requested, requester - _) even (X _^_en // forever, however - _) ever _^_en // forever, however + _) even (K _^_en + _) ever _^_en oC) ever _^_en // forever, however + ew (++ _^_en _) eye _^_en @@ -636,6 +632,8 @@ gu) eu (ler Y // gueuler .group g g g g (Y Z + ge (a Z + ge (o Z su) gg (Y gZ // suggérer suggestif gg g // agglomérer @@ -683,6 +681,7 @@ _quatrevin) gts (_ z2 // group g: English section _) game (X _^_en girl _^_en // girl + gh (K _^_en gy (_ _^_en @@ -732,7 +731,7 @@ _quatrevin) gts (_ z2 // group h: English section _) half _^_en - here (_ _^_en // here + _) ha (C_ _^_en .group i @@ -751,11 +750,8 @@ _quatrevin) gts (_ z2 or) ien (t iA~ // orient, orienter ot) ien (t_ jA~ // quotient - i (e_ i _) i (ce@ aj // iceberg - _) ill il // illégal - ill (_ il // Bill - _C) ill (y_ il // Billy + _) il (l i // illégal aigu) ill ij // aiguille anqu) ill il // tranquille c) ill (i il @@ -776,17 +772,14 @@ _quatrevin) gts (_ z2 imm imm // immaculé im (_ im // karim im (C E~ // timbre - w) in in // winrar inct (_ E~ // distinct in (h in // inhumain - in (kX iN // link in (n i // innombrable in (C E~ // vingt in (_ E~ // vin - ing (_ iN +// ing (_ iN ing (h ing ing (s iN - ing (to iN _) infra (sP5 E~fra _) inter (@@P5 E~tEr _) interr (A E~tEr @@ -810,13 +803,17 @@ _quatrevin) gts (_ z2 ibuter (X _^_en iev _^_en ife (_ _^_en - igh _^_en + ign (_ _^_en + ill (_ _^_en // Bill + C) ill (y_ _^_en // Billy + ing (_ _^_en +C) irt (_ _^_en iven (_ _^_en ind (X _^_en // find, mind _C) ind (erX _^_en // finder AC) ind (erX _^_en // reminder - ize (X _^_en // realize - _bAl) i (ze i + C) ird (X _^_en // bird + ize (K _^_en // realize ram_f) i (le _^_en .group ï @@ -833,6 +830,7 @@ _quatrevin) gts (_ z2 .group j j Z // adjoint joujoux + je (a Z // Jean _) j' (P2v Z _) jazz dZaz _) j (obK dZ @@ -849,10 +847,11 @@ _quatrevin) gts (_ z2 ke (s_ _^_en // makes, takes ke (rX _^_en // maker ke (nX _^_en // taken +AC) k (X _^_en // bank .group l l l // lit - ll l // aller + ll (A l // aller _) l' (P2 l au) lt // hérault uCi) l (_ // outil, fusil @@ -862,10 +861,15 @@ _quatrevin) gts (_ z2 _) lorsqu' (P7 lorsk // group l: English section + ld (_ _^_en // could less (_ _^_en // noiseless +%C) l (eX _^_en +ff) l (eX l +pp) l (eX l + _) line (X _^_en _) live _^_en @) loud (_ _^_en - ll (X _^_en + AC) l (X _^_en .group m @@ -877,8 +881,9 @@ _quatrevin) gts (_ z2 master (_S6 mastWr // group m: English section - _) mail (_ _^_en // mailer - mov (ieX _^_en // move, movy + m (n_ _^_en // column, autumn + mov (AX _^_en // move, movy + mov (ie_ _^_en // move, movy .group n @@ -894,19 +899,23 @@ _quatrevin) gts (_ z2 _) neuro (@@P5 nYro _) nvda (P4 Envedea +// group n: English section +_) name _^_en +_re) name _^_en + n (eme_ _^_en + n (emes_ _^_en + .group o br) oc (_ o // broc cr) oc (_ o // escroc - ls) on (_ On - Cst) on (_ On - _) os (_ Os + _) os (_++ Os _v) os (gY o s_) os (_ o x_) os (_ o o (t_ o - oe (ll wa // moelleux + oe (llA wa // moelleux oe (i W // oeil _) oe (C Y // oesophage _ph) oe (C e // phoetus @@ -921,8 +930,7 @@ _quatrevin) gts (_ z2 oin (_ wE~ // coin oi wa // poil oê (l wa // poêle - om (b O~ // bombe - om (p O~ // trompe + om (L11 O~ // bombe, pompe n) om (X O~ // nom om (_ Om // www.web.com @@ -937,10 +945,6 @@ _quatrevin) gts (_ z2 _) on (z _|O~ // onze, onzième _c) on (_ O~ // no comment - ps) on (_ On // Epson - gt) on (_ On // Washington - Cst) on (_ On - ps) on (_ On _C) on (_ O~n2 // mon appui, mon histoire, mon havre alc) oo (l O // alcool @@ -969,7 +973,10 @@ _quatrevin) gts (_ z2 o (_ o // zorro allégro gr) oss os // grosse, grossir - C) o (sA o // position +C) o (me_ o // atome, chrome +_C) o (me_ O // Rome tome + o (sA o // position + o (zA o // Mozilla o (CC O // poste, votre o O @@ -979,8 +986,13 @@ _quatrevin) gts (_ z2 oa (s_ oa oa (CerX _^_en oach _^_en - old (er_ _^_en // folder, older + oes _^_en +_) of (X _^_en + o (lder_ _^_en // folder, older +_) o (rder_ _^_en // order C) oing (_ _^_en // going + gt) on (_ _^_en + Cst) on (_ _^_en oo (Ce _^_en // boomer oo (k _^_en // book, cook oo (st _^_en // booster @@ -992,7 +1004,7 @@ _quatrevin) gts (_ z2 _sC) ot _^_en // shot, slot, spot ow (e _^_en // flower, power ow (X _^_en - oy (X _^_en // boy, toy +_C) oy (X _^_en // boy, toy .group ô @@ -1005,11 +1017,11 @@ _quatrevin) gts (_ z2 _) para (pCP4 para _) photo (@P5 foto _) poly (@P4 poli - _) post (KP4 post + _) post (CP4 post _) post (ACCP4 post _) pseudo (@P6 psYdo p (p // appliquer - pays pE2iz2 // pays, paysage + pays pEiz2 // pays, paysage ph f // phrase m) ps (_ // temps champs @@ -1076,7 +1088,6 @@ _quatrevin) gts (_ z2 // group r: English section _) real _^_en - resen _^_en rst (_ _^_en _) rule _^_en @@ -1175,13 +1186,19 @@ _cACpu) s (_ s _tou) s (_leurs_ // group s: English section - CA) sh (_ _^_en // punish + send (_ _^_en sh (_ _^_en sh (Ap _^_en // shop, ship sh (At _^_en // shut, shot +_) side (X+++ _^_en +L14) side (X+++ _^_en _) sky _^_en _) smil _^_en // smile, smiley spy _^_en +_A) s (_ _^_en +L13) son (_ _^_en +L13) ston (_ _^_en + stone (_ _^_en .group t @@ -1194,7 +1211,9 @@ _cACpu) s (_ s VCi) t (_ t2 t (_ peti) t (_ t2 - _) th t // thon + th (L12++ t +or) th (++ t + _) th (erm t ts (_S1 z2 // silent at end of word unless next word starts with a vowel C) t (_ t // compost watt soft script malttact abrupt ki) t (_ t // kit @@ -1284,13 +1303,13 @@ _cACpu) s (_ s _transA) t (_ t // group t: English section - C) th (_ _^_en // month - _) th (eX _^_en // the, then - _) th (aX _^_en // than, that + th (A _^_en // this + th (K _^_en // month _) time _^_en tle (_ _^_en too _^_en ttl _^_en +g) ton (_ _^_en // try, country try (_ _^_en // try, country sCar) t (_ _^_en // smart, start sCar) t (er_ _^_en // starter @@ -1299,34 +1318,30 @@ _transA) t (_ t .group u u y // cruel nuage brut + ue (il W // orgueil ui yi // nuit, fuite uin (K yE~ // juin - _s) u (rfX W + _C) u (rfX W _bl) u (ff W _s) u (rfeX W uy (A yij C) ucci utSi // capuccino - c) ueill Wj // cueillir - c) ueil (_ Wj // recueil _g) ua wa ag) ua (X wa Ctig) ua (_ wa _c) ul (_ y _) ultra (P5 yltra g) u (ay u - g) ueill Wj // orgueilleux haïk) u (X u C) u (bX W // hub, club C) u (gX W // bug, mug _n) u (rse W // nurse - r) u (nX W // run, autorun pr) unt (_ W~ // emprunt um (_ Om // album f) um (_ W~ // parfum - um (b W~ // humble - um (p W~ + um (L11 W~ // humble un (C W~ // emprunt lundi un (n y // tunnel CC) un (_ W~ // brun @@ -1341,10 +1356,14 @@ _transA) t (_ t uz (z W // group u: English section + ual (_ _^_en // usual + uch (_ _^_en // much _b) usi _^_en // business, businessman C) ui (ce _^_en // produice, juice +C) ult (_ _^_en umber (_ _^_en ump (_ _^_en + r) u (nX _^_en // run, autorun unch _^_en under _^_en // under, understand, thunder _C) un (_ _^_en @@ -1353,6 +1372,7 @@ _transA) t (_ t up (_ _^_en // setup urn (X _^_en // burn, turn ust (_ _^_en // just, trust + uzz _^_en // buzz .group ü @@ -1378,19 +1398,19 @@ _transA) t (_ t .group w w w _) w (A _|w - w (ag v // wagon - wa (ve_ wE:j // wave - wa (re_ wE: // hardware software + w (ag++ v // wagon // group w: English section - e) w (K _^_en - _) wan _^_en + _) w (AC _^_en + _) w (ina w + _) w (Ai _^_en + _) w (ACo w + _) we _^_en + wh _^_en // why whisky when wr _^_en // write + war _^_en // war + wav _^_en // wave way _^_en // way, away - _) wir _^_en // wire - winn _^_en // winner - wise _^_en - with _^_en wor _^_en @@ -1432,13 +1452,19 @@ _transA) t (_ t _) yacht _^_en // yacht, yachtman _) yahoo (P5 ja'u - ym (K E~ // tympan - y (nn i - y (nA i + ym (L11 E~ // tympan X) ys (_ is - yx (_ iks - yn E~ // laryngite + yn (K E~ // laryngite + y (nn i + +// group y: English section +_C) y (_ _^_en +C) y (e_ _^_en +%C) y (_ _^_en +//@CAC) y (_ _^_en +nC) y (_ _^_en + yze _^_en .group z @@ -1466,6 +1492,7 @@ _transA) t (_ t $ dOlar ° d@gre _n_) ° // n° + ' (C _^_en diff --git a/dictsource/hi_list b/dictsource/hi_list index d81e028a..36662ce8 100755 --- a/dictsource/hi_list +++ b/dictsource/hi_list @@ -172,6 +172,29 @@ _dpt _d@s@ml'o:_ // ?? what is Hi for "." ? फ़ f@ य़ j@ +// combining vowel signs +ा #X2a: +ि #X1I +ी #X2i: +ु #X1U +ू #X2u: +ृ #X1rI +ॄ #X1rI +ॅ #X1E +ॆ #X1e +े #X2e: +ै #X2E: +?2 ै #X2aI +ॉ #X1O +ॊ #X1o +ो #X2o: +ौ #X2O: +?3 ौ #X2aU +ॢ #X1l- +ॣ #X2l-: +ॐ #X1o~m + + // Punctuation । dVn.d.V diff --git a/dictsource/hu_list b/dictsource/hu_list index 225c2858..5e57274a 100755 --- a/dictsource/hu_list +++ b/dictsource/hu_list @@ -28,7 +28,6 @@ _9X kilEntsvEn _0C sa:z _0M1 EzER2 -_1M1 EzER2 _2M1 ke:tEzER2 _0M2 millio: _1M2 EJmillio: @@ -129,15 +128,15 @@ _#-től e:tY:l $alt2 _#-tól a:to:l $alt2 _#-ig e:ig $alt2 //special date ordinal numbers for example elsejéig, negyedikéig etc. _#-éről e:R2Y:l -_#-áról a:R2o:l $alt2 +_#-áról a:R2o:l -_#-ától a:to:l $alt2 +_#-ától a:to:l _#-ről e:R2Y:l $alt2 _#-ról a:R2o:l $alt2 -_#-ével e:vEl $alt2 -_#-ával a:vAl $alt2 -_#-éig e:ig $alt2 -_#-áig a:ig $alt2 +_#-ével e:vEl +_#-ával a:vAl +_#-éig e:ig +_#-áig a:ig _#-étől e:tY:l $alt2 _#-ét e:t $alt2 _#-át a:t $alt2 @@ -168,8 +167,8 @@ _#-ához a:hoz (1-ig) elsejéig $text $alt2 (1-éről) elsejéről $text $alt2 (1-ről) elsejéről $text $alt2 -(1-ével) elsejével $text $alt2 -(1-éig) elsejéig $text $alt2 +(1-ével) elsejével $text +(1-éig) elsejéig $text (1-étől) elsejétől $text $alt2 (1-ét) elsejét $text $alt2 (1-je) elseje $text $alt2 @@ -188,6 +187,8 @@ _#-ához a:hoz (1-éhez) elsejéhez $text $alt2 (2-i) másodikai $text $alt2 (2-ig) másodikáig $text $alt2 +(2-étől) másodikától $text $alt2 //this is not mistake, don't change! +(2-től) másodikától $text $alt2 //this is not a mistake, don't change! (3-i) hAR2_mAdikAi $alt2 (3-ig) harmadikáig $text $alt2 (6-i) hAtodikAi $alt2 @@ -238,6 +239,7 @@ _#-ához a:hoz (2-őn) kEt:Y:n (2-n) kEt:Y:n (2-m) kEt:Y:m +(2-el) kEt:Y:vEl // entries with a single digit such as (2-i) also apply to 22, 32, etc, unless $only (30-cal) hAR2mints:Al (3-al) ha:R2om:Al @@ -294,6 +296,18 @@ _20e hus (80-al) n^oltsvAn:Al (90-el) kilEntsvEn:El +//Special roman number suffixes and exceptions +(XVI-ig) tizEnhAtodikig //Special roman number suffix exception +(II-el) kEt:Y:vEl +(III-al) ha:R2om:Al +(IV-el) ne:J:El +(5-el) Yt:El //this exception not working, Espeak always spokening YtEl phoneme, but Yt:El phoneme is right +(VI-al) hAt:Al +(VII-el) he:t:El +(VIII-al) n^olts:Al +(IX-el) kilEnts:El +(CD-ellenőrzést) tse:de:El:EnY:R2ze:St //this is not a mistake, default Espeak spokening roman number before the ellenőrzés word + // These words mean that a dot after number, immediately preceding, does not mean an ordinal number január $alt február $alt @@ -346,6 +360,8 @@ tavaszi $alt nyári $alt őszi $alt téli $alt +végén $alt +elején $alt // accent names _lig ligAtu:R2A @@ -403,7 +419,7 @@ BAR bAR2 $allcaps (a . m .) An^n^i||m'int ún u:JnEvEzEt: $hasdot -dr doktoR2 $dot +dr doktoR2 $hasdot mr mistER2 $hasdot //in hungarian we not use, but lot of books contains this word. mrs misis $hasdot //In hungarian we not use, but lot of book contains this word. miss mis: $hasdot @@ -413,7 +429,7 @@ MB mEgAba:jt $allcaps OK ok $allcaps mvgyosz Emve:Je:oEs OTP o:te:pe: $allcaps -id idY:SEb: $hasdot +id idY:SEb: $hasdot $only ill illEtvE $hasdot ifj ifjAb: $hasdot mta $abbrev @@ -1007,6 +1023,36 @@ halt $unstressend ész $unstressend kapta $unstressend kaptak $unstressend +kék $unstressend +kelt $unstressend +kárt $unstressend +gróf $unstressend +grófot $unstressend +lakik $unstressend +laknak $unstressend +laktak $unstressend +kapsz $unstressend +tudta $unstressend +kapnak $unstressend +tért $unstressend +törtek $unstressend +tört $unstressend +vész $unstressend +park $unstressend +tartja $unstressend +válik $unstressend +rajta $unstressend +merült $unstressend +zuhant $unstressend +jöttek $unstressend +leltem $unstressend +múlva $unstressend +várta $unstressend +ház $unstressend +állnak $unstressend +idején $unstressend +néznek $unstressend +érezte $unstressend // word pairs @@ -1045,7 +1091,7 @@ kell $unstressend // should szabad $u+ // can (allowed) -fog $u+ // going to +fog $unstressend // going to fogok $u+ fogsz $u+ fogunk $u+ diff --git a/dictsource/hu_rules b/dictsource/hu_rules index 646428fe..a041be4d 100644 --- a/dictsource/hu_rules +++ b/dictsource/hu_rules @@ -83,6 +83,9 @@ gyümöl) cs (zs tS fil) c (csiz ts szo) c (segély ts _kó) c (csomó ts + árbó) c (csúcs ts + árbo) c (csúcs ts +fegyen) c (csoport ts .group ch anar) ch (i h @@ -208,12 +211,15 @@ menetren) dsz (erű d|s va) d (szeder d twee) d (sapk d fe) dd (hetetlen d -ezre) d (segé d -erő) d (szerű d -csalá) d (szociol d -száza) d (szemle d -zöl) d (szem d - + ezre) d (segé d + erő) d (szerű d + csalá) d (szociol d + száza) d (szemle d + zöl) d (szem d + utó) d (jelöl d + cselé) ds (ég tS: + föl) d (szegély d + stran) d (szezon d .group dz fogó) dz (kod ts @@ -250,9 +256,11 @@ titkoló) dz z ringató) dz z mére) dz (k ts pilóta) dzs (ek dZ -ezre) dz (ene d|z -száza) dz (ene d|z -honvé) dz (ászló d|z + ezre) dz (ene d|z + száza) dz (ene d|z + honvé) dz (ászló d|z +smarag) dz (öld d|z +kapáló) dz z .group e e E @@ -261,7 +269,7 @@ honvé) dz (ászló d|z _) ehhez EhEz _) egyezség EJ:ESSe:g - + _) egyezségg EJ:ESSe:g: .group é é e: @@ -410,6 +418,13 @@ tizene) gy (en J: _e) gy (év J: _e) gy (órá J: _e) gy (se J + je) gy (ezte J + na) gy (sebes J + _í) gys (e J|S + na) gy (siker J +huszone) gy (edik J: + je) gy (ért J +harmince) gy (edik J: .group h h h @@ -461,6 +476,7 @@ tizene) gy (en J: kk k: kk (C k: _) köztársaság k'Ysta:R2SASa:g + _) köztársaságg k'Ysta:R2SASa:g: központ kYspont központt kYspont: központj kYsponc @@ -525,7 +541,7 @@ keresztü) l (j l _) e) lj (ár lj ha) ll (ga l _ta) lj (án lj -_fé) l (jobb l + _fé) l (jobb l @@ -846,6 +862,7 @@ kitöré) ssz (erű Ss nyúva) ssz s: hirdeté) ssz (erve Ss páncélo) ssz Ss + hajtá) ssz (erű Ss .group sz sz s @@ -1030,7 +1047,7 @@ négyze) t (centi t á) tj (öt t|j á) tj (ön t|j á) t (süvít t - bará) tj (ára c: + bará) tj (ár c: //barátjára, barátjáról words need spokening c: phoneme kísérle) t (sorozat t á) t (sült t á) t (süt t @@ -1084,7 +1101,19 @@ fejeze) t (cím t pán) t (szél t boo) t (sorrend t _á) t (jöj t -ú) tsz (oros t|s + ú) tsz (oros t|s +művele) t (sáv t + _ké) t (szob t + ne) t (sátor t + há) tj (ár c: + ker) t (szomszéd t + éle) t (járadék t + _á) t (sodor t + par) t (sáv t + tes) t (játék t + ö) t (jegyű t + ha) t (jegyű t + hé) t (jegyű t .group ts ts (_S2 tS //general rule with word end of ts letters @@ -1171,6 +1200,7 @@ indula) tsz (ó t|s sie) tsz ts: szemé) ts (ég tS: ré) ts (ég tS: + já) tsz (ok ts: .group u u u @@ -1242,7 +1272,7 @@ lefeje) z (ték s gá) z (cső z - ké) z (sz zz + ké) z (sz z há) z (so z diff --git a/dictsource/nl_list b/dictsource/nl_list index bd6458d3..c9b81c51 100644 --- a/dictsource/nl_list +++ b/dictsource/nl_list @@ -108,7 +108,6 @@ _8X t'Axt@x _9X n'e:g@nt@x _0C h'OndErt _0M1 d'WyzEnt -_1M1 d'WyzEnt _0M2 m'iljun _0M3 m'iljArt _0M4 b'iljun diff --git a/dictsource/pap_list b/dictsource/pap_list index 84722927..6a5bedf0 100644 --- a/dictsource/pap_list +++ b/dictsource/pap_list @@ -73,7 +73,6 @@ _8X otS'enta _9X nob'enta _0C sj'en _0M1 m'il -_1M1 m'il _0M2 mi'on _dpt _kOma/ diff --git a/dictsource/ta_list b/dictsource/ta_list index e2c1ad5f..e505473c 100644 --- a/dictsource/ta_list +++ b/dictsource/ta_list @@ -33,6 +33,20 @@ U+bcd ot.RU ஏ je: +// combining vowels, precede by a click so they can be distinguished from stand-alone vowels +ா #X2a:: +ி #X1i +ீ #X2i:: +ு #X1u +ூ #X2u:: +ெ #X1e +ே #X2e:: +ை #X2aI +ொ #X1o +ோ #X2o:: +ௌ #X2aU + + // speak Latin letters as English a e:j @@ -151,9 +165,7 @@ _8C ;en.n.u:t.t.Ri _9C tol.l.a:jirVttU _0M1x a:jirVm -_1M1x a:jirVm _0M1 a:jirVttU -_1M1 a:jirVttU _0M2x lVd.tSVm // 100,000 _1M2x orUlVd.tSVm @@ -234,6 +246,7 @@ tamil தமிழ் $text பலத்தில் $alt பலத்தின் $alt பைக்ல $alt +பாவ்லா $alt (பி . ஏ) bije: diff --git a/dictsource/ta_rules b/dictsource/ta_rules index 72ce5c1a..b7ebba59 100644 --- a/dictsource/ta_rules +++ b/dictsource/ta_rules @@ -242,7 +242,7 @@ அப) க (ீர்த்தி k _பால்) க (ுட k _வளை) க (ுட k -மன்னார்) க (ுடி k +மன்னார்) கு (டி ku2 நற்) க (ுண g _சற்) க (ுண g க (ுமார k @@ -281,6 +281,8 @@ வி) க்ட (ோரியா kt. // victoria வி) க (்ரம k ஆ) க (்ரோஷ k + _கால) க (ட்ட kV + _வலை) க (ாப் k //endsort @@ -388,7 +390,6 @@ ிங்) ட (ன் t.V // -ington _) ட (ாக்க t. // talkies _) டிராக்ட (ர t.ira:gt.V - _) ட (யர t.V _) ட (ைம்_ t. டெலிப (ோன t.elif _) ட (ம்ப்ளர t.V @@ -404,6 +405,9 @@ _) ட (ேப t. _) டாக (்ஸி t.a:k _ல) ட்ட d.d.V# + _) ட (யர் t.V + _) ட (யரில t.V + .group ண ண n.V @@ -684,6 +688,7 @@ _பார்வ) த (ி t ச) த (்ரு t த) த (்ரூப t பா) த (்ரூம t + _கௌ) த (மி tV //endsort @@ -733,6 +738,7 @@ _பார்வ) த (ி t _) ப (கிரங்க bV _) ப (கிஷ்க bV _) ப (கீர bV + _) ப (க்கெட் bV _) பக் (த bVk _) ப (ங்கம bV _) ப (ங்களா bV @@ -790,12 +796,14 @@ _பார்வ) த (ி t _) ப (லூன bV _) ப (வாணி bV _) ப (வானி bV + _) பவுண்ட (ன faUn.t.V _) ப (வ்ய bV _) ப (ஸ bV _) ப (ாகங்க b _) ப (ாகத b _) ப (ாகம b _) ப (ாக்கிய b + _) ப (ாங்க் b _) ப (ாசு b _) ப (ாசுர p _) ப (ாடி_பில்டிங் b @@ -1062,6 +1070,8 @@ _முகத்தின்_) ப (ாவ b மன) ப்பி (ரமை bb துர்) ப்ப (ோதனை bb கம்) ப்யூட (ர pjU:t.V + மென்) ப (ொருள் p + வன்) ப (ொருள் p //endsort // If ப+ appearing in the middle of a word is followed by ட+ diff --git a/dictsource/tr_list b/dictsource/tr_list index 6798b5ed..26bce891 100644 --- a/dictsource/tr_list +++ b/dictsource/tr_list @@ -113,7 +113,6 @@ _9X doksan _0C jyz _2C 'icijyz _0M1 bIn -_1M1 bIn _0M2 miljon _0M3 miljar _dpt _viRg,Yl_| diff --git a/dictsource/tr_rules b/dictsource/tr_rules index aa46a51f..84edcb4d 100644 --- a/dictsource/tr_rules +++ b/dictsource/tr_rules @@ -327,4 +327,5 @@ .group $ dolar ' (Pb // split a word at ' and translate the first part separately. - + ə E // used in Aberbaijan + ä E diff --git a/phsource/compile_report b/phsource/compile_report index f9131864..ac65428c 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,4 +1,4 @@ -64 phoneme tables +65 phoneme tables new total base 107 107 consonants 9 115 @@ -17,17 +17,17 @@ consonants 9 115 jbo 2 114 nci 3 123 fi 40 133 - fr 55 137 - fr-ca 11 137 - hi 58 149 - ta 20 151 + fr 58 140 + fr-ca 11 140 + hi 59 150 + ta 21 153 hu 24 121 lv 29 125 nl 24 125 pl 20 118 sk 28 133 cs 6 133 - hr 26 138 + hr 25 138 mk 3 139 sr 14 138 it 18 126 @@ -55,15 +55,16 @@ consonants 9 115 hy 23 117 da 24 120 rw 15 130 - ml 13 150 - ne 18 156 - pa 14 150 + ml 13 151 + ne 18 157 + pa 14 151 prs 8 111 sl 7 133 gd 6 107 bg 10 119 nso 8 107 - ht 11 137 + ht 11 140 + az 10 127 Data file Used by b/b [b] base @@ -341,8 +342,8 @@ l/l_ [l/] base [l/] fr l/l_@ [l/3] base [l/] fr -l/l@ [l#] base - [€¦] base +l/l@ [h&w] base + [l#] base [l] fr [l/2] fr l/L1_aL [l/] base @@ -367,14 +368,14 @@ l/L2_oL [l/2] base l/L2_uL [l/2] base l/l_3 [l/] de l/l_4 [ll] sq -l/la [l#] base - [€¦] base +l/la [h&w] base + [l#] base [l] fr [l/2] fr l/l_a [l/3] base [l/] fr -l/le [l#] base - [€¦] base +l/le [h&w] base + [l#] base [l] fr [l/2] fr l/l_e [l/3] base @@ -383,8 +384,8 @@ l/L_eL_af [&] af [&:] af l/l_front [L] sq l/l_front_ [l/4] sq -l/li [l#] base - [€¦] base +l/li [h&w] base + [l#] base [l] fr [l/2] fr [l] zh @@ -395,15 +396,15 @@ ll/ll [L] bg ll/_ll [L] bg l/l_long [l] base [l] fr -l/lo [l#] base - [€¦] base +l/lo [h&w] base + [l#] base [l] fr [l/2] fr l/l_o [l/3] base [l/] fr l^/l_rfx [l.] base -l/lu [l#] base - [€¦] base +l/lu [h&w] base + [l#] base [l] fr [l/2] fr l/l_u [l/3] base @@ -731,6 +732,7 @@ ustop/p_asp [ph] consonants [bh] hi [ph] zh [p#] hy +ustop/percus02 [#X2] hi ustop/percus10 [#X1] base ustop/pl [p] base [p-] consonants @@ -834,6 +836,7 @@ vdiph/0i [OI] pt vdiph/0i_2 [OI] en-sc [OI] en-wi [AI] no +vdiph2/8@ [U@] en vdiph2/e@ [3:] en-sc [e@] en-sc [e@] en-wi @@ -1047,8 +1050,7 @@ vdiph/@u [u:] en-wm [@U] vi [@:U] vi vdiph/@u_2 [oU] en-rp -vdiph/@u_3 [o3] fr - [@U] ro +vdiph/@u_3 [@U] ro vdiph/@u_en [oU] en [@U] id vdiph/ui [uI] base2 @@ -1202,6 +1204,7 @@ vowel/& [a] en-rp [&:] lv [&] sv [&#] da + [&] az vowel/0 [0] en [O] hi [O] pt @@ -1238,6 +1241,7 @@ vowel/@_4 [@] en-us [@] no vowel/@_6 [@] en [W] fr + [W2] fr vowel/8 [o-] zh vowel/8_2 [U] en-us [8] sv @@ -1343,6 +1347,7 @@ vowel/aa [A] fr-ca [A:] no [aa] zhy [a] hy + [a] az vowel/aa# [O] en-us [0] en-wi [a2] fi @@ -1422,7 +1427,6 @@ vowel/e_5 [i] en-sc vowel/e_6 [e] ht vowel/e_8 [E:] de [e] fr -vowel/e_9 [E2] fr vowel/ee [E] en-n [E] sv vowel/e_e [E] en-sc @@ -1497,6 +1501,7 @@ vowel/e_mid2 [E] af [E] da [e] bg [e] nso + [e] az vowel/@_fnt [@] en-wi [@2] en-wi [@2] hr @@ -1535,7 +1540,6 @@ vowel/i_2 [i2] de [i:] la [i:] sv vowel/i_3 [i] af - [I] fr [i:] sk vowel/i_4 [i] fi [i] hu @@ -1605,6 +1609,7 @@ vowel/ii_4 [I2] en vowel/ii_5 [I] la [i] zh [i] bg + [i] az vowel/ii_6 [I] en-wm [I] en-wi [I2] en-wi @@ -1683,10 +1688,12 @@ vowel/oe [W] af vowel/oe_2 [W] no vowel/oe_4 [W] sv vowel/o_mid [U@] en-rp + [O] fr [o] hu [o] tr [o] ne [o] bg + [o] az vowel/o_mid2 [O] fr [O] ht vowel/oo [o] base @@ -1750,7 +1757,6 @@ vowelr/o_r [o@] en-sc vowelr/r-voc [r-] base [r-] sk [r:] sk - [r-] hr vowelr/V3_r [VR] en [3] en-sc [@r] zh @@ -1784,15 +1790,18 @@ vowel/u#_4 [U] en-sc [u:] en-sc vowel/u_5 [u] sw [u] nso + [u] az vowel/u#_5 [y] vi vowel/u_6 [u:] en-rp [u] ta + [u2] ta [u:] ta [U] pt-pt [u] pt-pt [u] ku vowel/u_7 [u] vi vowel/u#_7 [@] tr + [@] az vowel/u_bck [u] base2 [U] cy [u] fi @@ -1849,6 +1858,7 @@ vowel/V [3] en-sc [@] bg vowel/V_2 [V] en [a] af + [V] fr [V] ru [V#] ru [V] ku @@ -1873,6 +1883,7 @@ vowel/y [y] base2 [yu] zhy [y] sq [y] da + [y] az vowel/y# [Y] base2 [3:] en-wm [Y:] de @@ -1888,6 +1899,7 @@ vowel/y_2 [y:] la [y] zh vowel/y#_2 [Y] hu [Y:] sv + [W] az vowel/y_3 [y] af vowel/y#_3 [W] is [W:] is diff --git a/phsource/intonation b/phsource/intonation index 0a6b7e73..ad53fce1 100644 --- a/phsource/intonation +++ b/phsource/intonation @@ -99,7 +99,7 @@ tune c3 prehead 46 57 headenv fall 16 head 4 80 30 -5 -15 -headextend 25 63 38 13 0 +headextend 0 63 38 13 0 nucleus0 fall-rise 75 40 endtune @@ -122,3 +122,4 @@ headextend 16 82 50 32 16 nucleus0 fall 92 8 nucleus fall 92 80 76 8 endtune + diff --git a/phsource/ph_afrikaans b/phsource/ph_afrikaans index cfa51cff..0c311bad 100755 --- a/phsource/ph_afrikaans +++ b/phsource/ph_afrikaans @@ -25,6 +25,7 @@ endphoneme phoneme a // short A vowel starttype #a endtype #a + ipa ɐ length 140 FMT(vowel/V_2) endphoneme @@ -38,6 +39,7 @@ endphoneme phoneme I // short I, Schwa vowel starttype #@ endtype #@ + ipa ə length 140 IF nextPh(r/) THEN Length 190 @@ -106,6 +108,7 @@ endphoneme phoneme e@ // long E vowel starttype #i endtype #@ + ipa iə length 230 FMT(vdiph/i@_2) endphoneme @@ -121,6 +124,7 @@ endphoneme phoneme o@ // long O vowel starttype #u endtype #@ + ipa ʊə length 250 FMT(vdiph2/o@) endphoneme @@ -165,6 +169,7 @@ endphoneme phoneme eI vowel starttype #e endtype #i + ipa ɛɪ length 170 IfNextVowelAppend(;) FMT(vdiph/@i_2) @@ -181,6 +186,7 @@ endphoneme phoneme oI vowel starttype #o endtype #i + ipa ʊɪ length 290 IfNextVowelAppend(;) FMT(vdiph/oi_2) @@ -325,4 +331,3 @@ phoneme c // used in -tjie WAV(ustop/ki) endphoneme - diff --git a/phsource/ph_catalan b/phsource/ph_catalan index b7855ea1..441adff1 100644 --- a/phsource/ph_catalan +++ b/phsource/ph_catalan @@ -12,6 +12,7 @@ endphoneme phoneme a# vowel starttype #@ endtype #@ + ipa ɐ unstressed length 170 FMT(vowel/a#_3) diff --git a/phsource/ph_croatian b/phsource/ph_croatian index 56f35904..98c39733 100644 --- a/phsource/ph_croatian +++ b/phsource/ph_croatian @@ -230,13 +230,6 @@ phoneme x endphoneme -phoneme r- // syllabic r - vowel starttype #@ endtype #@ - length 240 - FMT(vowelr/r-voc) -endphoneme - - phoneme R import_phoneme base/R endphoneme @@ -245,7 +238,7 @@ endphoneme phoneme r* vowel nonsyllabic unstressed - ipa r + ipa NULL length 50 starttype #@ endtype #@ AppendPhoneme(*) diff --git a/phsource/ph_english b/phsource/ph_english index 7d345863..6b8d96fa 100644 --- a/phsource/ph_english +++ b/phsource/ph_english @@ -204,6 +204,7 @@ endphoneme phoneme i // optional variant of [I] for end of words vowel starttype #i endtype #i + ipa ɪ length 140 IfNextVowelAppend(;) FMT(vowel/ii_en) @@ -334,7 +335,7 @@ endphoneme phoneme aI vowel starttype #a endtype #i length 240 - IF nextPh(#a) OR nextPh(#o) THEN + IF nextPh(#a) THEN AppendPhoneme(;) ENDIF FMT(vdiph/ai_2) @@ -383,6 +384,9 @@ phoneme U@ vowel starttype #u endtype #@ length 200 IfNextVowelAppend(r-) + IF thisPh(isUnstressed) THEN + FMT(vdiph2/8@) + ENDIF FMT(vdiph2/uu@) endphoneme diff --git a/phsource/ph_french b/phsource/ph_french index 3e6843be..7de54e40 100644 --- a/phsource/ph_french +++ b/phsource/ph_french @@ -1,7 +1,7 @@ //==================================================== // French //==================================================== -// Updated 2010-07-16 Michel Such +// Updated 2010-07-25 Michel Such phoneme #l virtual // Used for l and l/ @@ -24,7 +24,7 @@ endphoneme procedure pre_r IF prevPh(y) THEN VowelEnding(vwl_fr/y2r) - ELIF prevPh(E) OR prevPh(E2) THEN + ELIF prevPh(E) THEN VowelEnding(vwl_fr/e_2r) ELIF prevPh(A~) THEN VowelEnding(vwl_fr/aa2r) @@ -47,7 +47,7 @@ endprocedure procedure post_r - IF nextPh(E) OR nextPh(E2) THEN + IF nextPh(E) THEN VowelStart(vwl_fr/re2) ELIF nextPh(W) THEN VowelStart(vwl_fr/r@2) @@ -285,6 +285,11 @@ phoneme a endphoneme +phoneme a# // For english words + import_phoneme en/a# +endphoneme + + phoneme e vowel starttype #e endtype #e @@ -313,14 +318,6 @@ phoneme E endphoneme -phoneme E2 // Between e and E - vowel starttype #e endtype #e - length 170 - - FMT(vowel/e_9) -endphoneme - - phoneme i vowel starttype #i endtype #i palatal @@ -347,15 +344,13 @@ phoneme i endphoneme -phoneme I // longer than i - vowel starttype #i endtype #i - palatal - length 240 - ipa i +phoneme I // For english words + import_phoneme en/I +endphoneme - IfNextVowelAppend(;) - FMT(vowel/i_3) +phoneme I2 // For english words + import_phoneme en/I2 endphoneme @@ -396,18 +391,22 @@ phoneme O vowel starttype #o endtype #o length 170 - IF nextPhW(z) OR nextPhW(z2) OR nextPhW(z3) THEN - ChangePhoneme(o) + IF thisPh(isFinalVowel) THEN + FMT(vowel/o_mid2) + ENDIF + IF nextPhW(#l) AND next2Ph(isNotVowel) THEN + FMT(vowel/o_mid2) + ENDIF + IF nextPhW(#r) AND next2Ph(isNotVowel) THEN + FMT(vowel/o_mid2) ENDIF - FMT(vowel/o_mid2) + FMT(vowel/o_mid) endphoneme -phoneme o3 // almost like english oU - vowel starttype #@ endtype #u - length 220 - FMT(vdiph/@u_3) +phoneme oU + import_phoneme en/oU endphoneme @@ -451,6 +450,15 @@ phoneme W endphoneme +phoneme W2 // For english words + vowel starttype #@ endtype #@ + length 100 + unstressed + + FMT(vowel/@_6) +endphoneme + + phoneme Y vowel starttype #@ endtype #@ length 170 @@ -714,14 +722,14 @@ phoneme p Vowelout f1=0 f2=1000 -500 -350 f3=-300 80 rms=22 IF nextPh(isPause2) THEN - WAV(ustop/p_, 70) + WAV(ustop/p_, 80) ELIF nextPh(@-) THEN - WAV(ustop/p_unasp, 60) + WAV(ustop/p_unasp, 70) ELIF nextPh(#l) THEN - WAV(ustop/pl, 30) + WAV(ustop/pl, 40) ELIF nextPh(#r) THEN length 40 - WAV(ustop/p_, 60) + WAV(ustop/p_, 70) ENDIF WAV(ustop/p_unasp_, 90) endphoneme @@ -849,6 +857,14 @@ phoneme v FMT(voc/v) addWav(vocw/v, 60) endphoneme +phoneme V // For english words + vowel starttype #a endtype #@ + length 140 + + ChangeIfDiminished(@) + FMT(vowel/V_2) +endphoneme + phoneme z vcd alv frc sibilant @@ -895,4 +911,82 @@ phoneme z3 // "six" and "dix". [s] before pause, [z] before vowel, else [] endphoneme +// translate from English to French phonemes +equivalents en +remove_stress +0 O +3 W r +3: W : r +@ W +@- W +@2 W +@5 W +@L W l +a a +a# a# +A: a : +A@ a r +aa a : +aI a j +aI@ a j W2 r +aU a w +aU@ a w @ +A~ A~ +E E +e: e +e@ E : r +eI E : j/ +i i +I I +I2 I2 +i: i : +i@ i r +i@3 i : r +O O +O: O : +o: o +O@ O r +o@ O r +OI O j +oU oU +O~ O~ +U u +u: u: +U@ u r +V V +IR i r +VR W r +b b +C C +d d +D D +dZ dZ +f f +g g +h h +j j +k k +l l +l# l# +m m +n n +N N +n^ n^ +p p +Q Q +r r +r- r +s s +S S +t t +T T +t2 t +tS tS +v v +w w/ +x x +z z +Z Z +endphoneme + diff --git a/phsource/ph_german b/phsource/ph_german index 4f6ee98f..93b85876 100755 --- a/phsource/ph_german +++ b/phsource/ph_german @@ -110,7 +110,7 @@ endphoneme phoneme A // reduces to [a] if not stressed vowel starttype #a endtype #a length 250 - ChangeIfNotStressed(a) + ChangeIfUnstressed(a) FMT(vowel/aa_6) endphoneme @@ -377,3 +377,81 @@ phoneme UR endphoneme + + +// translate from English to German phonemes +equivalents en +0 O +3 3 +3: W : +@ @ +@- @- +@2 @ +@5 @ +@L U l +a a +a# a +A: A: +A@ A: r +aa a +aI aI +aI@ aI 3 +aU aU +aU@ aU 3 +A~ O n +E E +e: e: +e@ E: r +eI e: +i I +I I +I2 I +i: i: +i@ i: 3 +i@3 i: r +O O +O: O : +o: o: +O@ O : r +o@ O : r +OI OY +oU o: +O~ O n +U U +u: u: +U@ U r +V W +IR I r +VR W r +b b +C C +d d +D D +dZ dZ +f f +g g +h h +j j +k k +l l +l# l# +m m +n n +N N +n^ n^ +p p +Q Q +r r +r- r +s s +S S +t t +T T +t2 t +tS tS +v v +w w +x x +z z +Z Z +endphoneme diff --git a/phsource/ph_hindi b/phsource/ph_hindi index 7e20326c..afbe6f45 100644 --- a/phsource/ph_hindi +++ b/phsource/ph_hindi @@ -477,5 +477,12 @@ phoneme gh FMT(g2/xg) addWav(ustop/k_asp, 70) endphoneme +//================ + +phoneme #X2 // click, use for indicating combining long vowels + vls alv frc sibilant + lengthmod 3 + WAV(ustop/percus02) +endphoneme diff --git a/phsource/ph_slovak b/phsource/ph_slovak index 8226d5fd..cf4766db 100644 --- a/phsource/ph_slovak +++ b/phsource/ph_slovak @@ -102,14 +102,14 @@ endphoneme -phoneme r- +phoneme r- // syllabic r vowel starttype #@ endtype #@ ipa rU+0329 length 220 FMT(vowelr/r-voc) endphoneme -phoneme r: +phoneme r: // syllabic r vowel starttype #@ endtype #@ ipa rU+0329ː length 300 diff --git a/phsource/ph_swedish b/phsource/ph_swedish index fabfa70b..3f0e99b3 100644 --- a/phsource/ph_swedish +++ b/phsource/ph_swedish @@ -53,6 +53,7 @@ endphoneme phoneme E- vowel starttype #@ endtype #@ + ipa ə unstressed length 140 FMT(vowel/ee#_2) @@ -74,6 +75,7 @@ endphoneme phoneme u- vowel starttype #u endtype #u + ipa ʉ length 200 FMT(vowel/u#_2) endphoneme diff --git a/phsource/ph_tamil b/phsource/ph_tamil index 9ebcc7bf..6ee50b78 100644 --- a/phsource/ph_tamil +++ b/phsource/ph_tamil @@ -85,8 +85,15 @@ phoneme u FMT(vowel/u_6) endphoneme +phoneme u2 // as [u] but don't reduce + vowel starttype #u endtype #u + length 110 + FMT(vowel/u_6) +endphoneme + phoneme U vowel starttype #u endtype #u + ipa ʉ length 110 FMT(vowel/u#_3) endphoneme @@ -103,6 +110,7 @@ endphoneme phoneme U: vowel starttype #u endtype #u + ipa ʉ length 240 FMT(vowel/u#_3) endphoneme diff --git a/phsource/ph_turkish b/phsource/ph_turkish index cd03992f..c8f9c236 100644 --- a/phsource/ph_turkish +++ b/phsource/ph_turkish @@ -84,14 +84,17 @@ phoneme u FMT(vowel/u_2) endphoneme + phoneme U vowel starttype #u endtype #u length 150 FMT(vowel/uu_2) endphoneme -phoneme @ // previously u# + +phoneme @ vowel starttype #@ endtype #@ + ipa ɯ length 150 FMT(vowel/u#_7) endphoneme diff --git a/phsource/phonemes b/phsource/phonemes index 291a231e..35b3d19c 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -198,6 +198,7 @@ endphoneme phoneme m- vowel starttype #@ endtype #@ + ipa mU+0329 length 170 IF thisPh(isWordStart) THEN @@ -211,6 +212,7 @@ endphoneme phoneme n- vowel starttype #@ endtype #@ + ipa nU+0329 length 170 IF thisPh(isWordStart) THEN @@ -224,6 +226,7 @@ endphoneme phoneme N- vowel starttype #e endtype #e + ipa ŋU+0329 length 190 FMT(nn/nn-syl) endphoneme @@ -1811,3 +1814,6 @@ include ph_northern-sotho phonemetable ht fr include ph_haitian + +phonemetable az tr +include ph_azerbaijani diff --git a/phsource/vdiph2/vowelchart.png b/phsource/vdiph2/vowelchart.png index ddd857f9105a2aa0a0c692e6b8eeea43598de461..94e1bc0398db9604559237a833e088d0f1065043 100644 GIT binary patch literal 52429 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%0APgmow`m?31cnnIWDfQcPE=oJP zE>i0X-44Sky~cmR3oJl?hOeEcT0%S3@RiYMi^}5u-xvNKz#K35Q`Gzr6-4jcayc8r zz`DVfqM9SdZJtK;lj}Srzb+3(|9*F+P~2kU^tqXvCwlbpc7KLicqE1w(_7+??|`5z z{j;53hI8(lj*gDc@6F^Qnm5otH40|9Cm;6dzUvU^CtF!6A9~A2%|Pqmc7y)?>CKc) z*PC%v&q#6qx3rH}pO&4o7Ob(qTlQ=0KEi~^P?W<6!WyAUu^5%=ji50EQL)g6X0QD9 z>((KBX{4=v`~Lk|Cs*yx7sl_21AdQ)gAamg6WClq3+EL$01?iM`)@2ZuG#fE!p0dI zFxUfO8-)V|L*szeP3=VBAlF_Mbx}A@Tecx)0-J;@Tyj>2ek(}w3Jx~#f4N-;mGlz& zNr{O&b!Pp?`9O%OfJW!^iQfkmZri_Kd&7sOrVHoK3&^5;D}U3qhn-ZLZ>*hX9E`C0 z?Af!anp`9Rs6;8ih`){R77kqUKl_TmJsDiYrQ5IwVOuu_7FIB3bb#|<*3|?{O3ix8 zsRf(w+pC_&mIuEtU3Zc1K+BVe&NsP}ltdS{grIo-fzajD&Zwv;a12meiWlAmMR)G# zz_{bMdtZ6@GeT)pxBvzk3Kadg@&hdPLrMV!-FakrCNdUaM-g$FiVN7+mWq9&-~}gT z8b^CvZ*I7@F6Z?(&YyRCopcYGJ3^R47+g3^F^cgI-5cW-M+{6Ij_?Z@U-(fgMl}uv zj6M7#s)x}@4TAs0r3HVpRJh*F@n*Bvv*NJCb^oU$^MBE(|Bv_izq|DMhMdD_&XB^uAD zyVAWc@~s_PQB&C1Jp{fX&~$C{@IW-;@y+bS&D40I*DMvg((LtfnmL$AH##_A+H`hy z=56ZkdVBlQHR=|eZOa@_Qi-vD@sQpv#Yqxy*Ccd@&MXx53CPyGc(G{KiQ2!Y;ZlBE zMxh>+iy+qR_5Zz%KXI2b3e2Q#(Nt8&0Wx{?*|l{$5xcx|fVxrtt}wo}|JhyHO-%u| zextmxx`qa#IB-Tlg4fm$*J%6i0p0pm{h?f$>&;)w3!8=CJ32Wb`nYM~%R5Cy2azxP rdqY--3goOg_4lcu@!M#W-=5?yFi49wVeN3Io^D~b+Vr}y%aQ*F;;GT* literal 52296 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 Aga7~l diff --git a/phsource/vowel/& b/phsource/vowel/& index 5d0ee30dafae0698b61888b5691beb2ee20a14e7..f22100fb169bea013ee7dd2c164705a2077ed053 100644 GIT binary patch delta 241 zcmaE8^3X&eIKb68BskEBk%56hjg28{qriL?aRzQN<^twOpim^kdnSFx2TTmYhnNmc zKE@(1(!ejnB*Vl4RL{bAnumcohL?eR^G_BDR9!!qOyRmTI8k-o<@wD7))mc(q05T# v1rvkF8KyInyLeG`J?D80(Y2QsP1k286~+%xU2g= zkFm&$FbF(ge89*8RL{bAnumcohW7x^=ASGQsJebInZk8xaH8tE%k!HFtSg!mLzflf t3nm5;kX>E8sJfo>Jcj7n%ZsM#Gm{GA2dJ($f~dOA@qB~mk{5E~004YJIFSGV diff --git a/platforms/big_endian/espeak-phoneme-data.c b/platforms/big_endian/espeak-phoneme-data.c index 24155cdb..4f88f2fc 100644 --- a/platforms/big_endian/espeak-phoneme-data.c +++ b/platforms/big_endian/espeak-phoneme-data.c @@ -288,7 +288,7 @@ void swap_phonindex (const char *infile, const char *outfile) {//========================================================== FILE *in, *out; char buf_4[4]; - unsigned int val; + unsigned short val; in = fopen (infile, "rb"); if (in == NULL) { @@ -324,7 +324,7 @@ void swap_phonindex (const char *infile, const char *outfile) void swap_phontab (const char *infile, const char *outfile) {//======================================================== FILE *in, *out; - char buf_4[4]; + char buf_8[8]; int i, n_phoneme_tables; in = fopen (infile, "rb"); @@ -339,18 +339,18 @@ void swap_phontab (const char *infile, const char *outfile) exit (1); } - fread (buf_4, 4, 1, in); - fwrite (buf_4, 4, 1, out); - n_phoneme_tables = buf_4[0]; + fread (buf_8, 4, 1, in); + fwrite (buf_8, 4, 1, out); + n_phoneme_tables = buf_8[0]; for (i = 0; i < n_phoneme_tables; i++) { int n_phonemes, j; char tab_name[N_PHONEME_TAB_NAME]; - fread (buf_4, 4, 1, in); - fwrite (buf_4, 4, 1, out); + fread (buf_8, 8, 1, in); + fwrite (buf_8, 8, 1, out); - n_phonemes = buf_4[0]; + n_phonemes = buf_8[0]; fread (tab_name, N_PHONEME_TAB_NAME, 1, in); fwrite (tab_name, N_PHONEME_TAB_NAME, 1, out); diff --git a/src/compiledata.cpp b/src/compiledata.cpp index 8dd96ce4..0a6ee71e 100644 --- a/src/compiledata.cpp +++ b/src/compiledata.cpp @@ -149,6 +149,7 @@ enum { kPROCEDURE, kENDPHONEME, kENDPROCEDURE, + kEQUIVALENTS, kPHONEMENUMBER, kPHONEMETABLE, kINCLUDE, @@ -243,6 +244,7 @@ static keywtab_t keywords[] = { {"procedure", tSTATEMENT, kPROCEDURE}, {"endphoneme", tSTATEMENT, kENDPHONEME}, {"endprocedure", tSTATEMENT, kENDPROCEDURE}, + {"equivalents", tSTATEMENT, kEQUIVALENTS}, {"import_phoneme", tSTATEMENT, kIMPORT_PH}, {"stress_type",tSTATEMENT, kSTRESSTYPE}, {"starttype", tSTATEMENT, kSTARTTYPE}, @@ -363,6 +365,10 @@ static PHONEME_TAB *phoneme_tab2; static int phoneme_flags; static int place_articulation; +static char *p_equivalence; +static char equivalence_buf[20000]; + + #define N_PROCS 50 int n_procs; int proc_addr[N_PROCS]; @@ -2479,6 +2485,23 @@ static int CompileSwitch(int type) +static PHONEME_TAB_LIST *FindPhonemeTable(const char *string) +{//========================================================== + int ix; + + for(ix=0; ix 0) + { + // terminate the list of phoneme equivalence tables + pw = (int *)p_equivalence; + pw[0] = 0; + + // write the equivalence data into phondata, and remember it's address + ix = ftell(f_phdata); + fprintf(f_phcontents,"Q 0x%.5x %s\n", ix, phoneme_tab_list2[n_phoneme_tabs-1].name); + phoneme_tab_list2[n_phoneme_tabs-1].equivalence_tables = ix; + fwrite(equivalence_buf, length+4, 1, f_phdata); + } } @@ -3092,11 +3124,12 @@ static void StartPhonemeTable(const char *name) if(gui_flag) progress->Update(n_phoneme_tabs); + memset(&phoneme_tab_list2[n_phoneme_tabs], 0, sizeof(PHONEME_TAB_LIST)); phoneme_tab_list2[n_phoneme_tabs].phoneme_tab_ptr = phoneme_tab2 = p; - memset(phoneme_tab_list2[n_phoneme_tabs].name, 0, N_PHONEME_TAB_NAME); strncpy0(phoneme_tab_list2[n_phoneme_tabs].name, name, N_PHONEME_TAB_NAME); n_phcodes = 1; phoneme_tab_list2[n_phoneme_tabs].includes = 0; + p_equivalence = equivalence_buf; if(n_phoneme_tabs > 0) { @@ -3131,6 +3164,111 @@ static void StartPhonemeTable(const char *name) } // end of StartPhonemeTable +static void CompileEquivalents() +{//============================= + // a list of phonemes in another language and the equivalent phoneme strings in this language + + int ix; + int n_names; + int n_bytes; + int foreign_phoneme; + int foreign_error = 0; + int remove_stress = 0; + char *p_start; + char *p; + int foreign_table; + char foreign_table_name[40]; + char line_buf[80]; + char names[6][80]; + char phcode[7]; + char save_voice_name[80]; + + NextItem(tSTRING); + strcpy(foreign_table_name, item_string); + strcpy(save_voice_name,voice_name2); + + if((foreign_table = SelectPhonemeTableName(foreign_table_name)) < 0) + { + error("Unknown phoneme table '%s'", foreign_table_name); + foreign_error = 1; + foreign_phoneme = 0; + } + + p_start = p_equivalence; + p_equivalence += 8; + + p_start[0] = foreign_table; + + linenum--; + while(!feof(f_in)) + { + linenum++; + if(fgets(line_buf, sizeof(line_buf), f_in) == NULL) + break; + + if((p = strstr(line_buf,"//")) != NULL) + *p = 0; + + for(ix=0; ix<6; ix++) + names[ix][0] = 0; + n_names = sscanf(line_buf,"%s %s %s %s %s %s",names[0],names[1],names[2],names[3],names[4],names[5]); + if(n_names < 1) + continue; + + if(strcmp(names[0],"endphoneme") == 0) + break; + + if(strcmp(names[0],"remove_stress") == 0) + { + remove_stress = 1; + continue; + } + + if(p_equivalence > &equivalence_buf[sizeof(equivalence_buf) - 16]) + { + error("'equivalents' tables are too large",NULL); + break; + } + + if(foreign_error == 0) + { + phcode[0] = foreign_phoneme = LookupPhonemeString(names[0]); + if(foreign_phoneme == 0) + { + sprintf(line_buf,"%s/%s", foreign_table_name, names[0]); + error("Unknown phoneme '%s'", line_buf); + } + } + + for(ix=1; ix 2) || (phcode[0] != phcode[1])) + { + // write: foreign phoneme number, then a string of local phoneme numbers + memcpy(p_equivalence, phcode, n_names); + p_equivalence += n_names; + *p_equivalence++ = 0; + } + } + *p_equivalence++ = 0; + + p_equivalence = (char *)((int)(p_equivalence + 3) & ~0x3); // align to word boundary + n_bytes = p_equivalence - p_start; + p_start[1] = remove_stress; + n_bytes = n_bytes / 4; + p_start[2] = n_bytes >> 8; // index of next table + p_start[3] = n_bytes; + + LoadVoice(voice_name2,0); // reset the original phoneme table + LoadVoiceVariant(save_voice_name,0); +} // end of CompileEquivalents + + + static void CompilePhonemeFiles() {//============================== int item; @@ -3161,8 +3299,9 @@ static void CompilePhonemeFiles() item = NextItem(tKEYWORD); - if(item == kINCLUDE) + switch(item) { + case kINCLUDE: NextItem(tSTRING); sprintf(buf,"%s%s",path_source,item_string); if((stack_ix < N_STACK) && (f = fopen_log(f_errors,buf,"rb")) != NULL) @@ -3176,32 +3315,36 @@ static void CompilePhonemeFiles() strncpy0(current_fname,item_string,sizeof(current_fname)); linenum = 1; } - } - else - if(item == kPHONEMETABLE) - { + break; + + case kPHONEMETABLE: EndPhonemeTable(); NextItem(tSTRING); // name of the new phoneme table StartPhonemeTable(item_string); - } - else - if(item == kPHONEMESTART) - { + break; + + case kPHONEMESTART: if(n_phoneme_tabs == 0) { Error("phonemetable is missing"); return; } CompilePhoneme(1); - } - else - if(item == kPROCEDURE) - { + break; + + case kPROCEDURE: CompilePhoneme(0); + break; + + case kEQUIVALENTS: + CompileEquivalents(); + break; + + default: + if(!feof(f_in)) + Error("Keyword 'phoneme' expected"); + break; } - else - if(!feof(f_in)) - Error("Keyword 'phoneme' expected"); } phoneme_tab2[n_phcodes+1].mnemonic = 0; // terminator } // end of CompilePhonemeFiles @@ -3275,6 +3418,7 @@ memset(markers_used,0,sizeof(markers_used)); "# S - A SPECT_SEQ structure\n" "# W - A wavefile segment\n" "# E - An envelope\n" +"# Q - Phoneme equivalence tables\n" "#\n" "# Address is the displacement within phondata of this item\n" "#\n" diff --git a/src/compiledict.cpp b/src/compiledict.cpp index faccbeb3..c6ef8e5a 100644 --- a/src/compiledict.cpp +++ b/src/compiledict.cpp @@ -53,6 +53,7 @@ static char *hash_chains[N_HASH_DICT]; static char letterGroupsDefined[N_LETTER_GROUPS]; MNEM_TAB mnem_rules[] = { + {"unpr", 0x01}, {"w_alt2", 0x12}, {"w_alt3", 0x13}, {"w_alt", 0x11}, // note: put longer names before their sub-strings @@ -192,8 +193,8 @@ char *print_dictionary_flags(unsigned int *flags) -char *DecodeRule(const char *group_chars, int group_length, char *rule) -{//==================================================================== +char *DecodeRule(const char *group_chars, int group_length, char *rule, int control) +{//================================================================================= /* Convert compiled match template to ascii */ unsigned char rb; @@ -268,16 +269,20 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule) if(rb == RULE_DOLLAR) { - p[0] = '$'; - name = LookupMnemName(mnem_rules, *rule++); - strcpy(&p[1],name); - p += (strlen(name)+1); + value = *rule++ & 0xff; + if((value != 0x01) || (control & FLAG_UNPRON_TEST)) + { + p[0] = '$'; + name = LookupMnemName(mnem_rules, value); + strcpy(&p[1],name); + p += (strlen(name)+1); + } c = ' '; } else if(rb == RULE_ENDING) { - static const char *flag_chars = "ei vtfq t"; + static const char *flag_chars = "eipvdfq tba "; flags = ((rule[0] & 0x7f)<< 8) + (rule[1] & 0x7f); suffix_char = 'S'; if(flags & (SUFX_P >> 8)) diff --git a/src/dictionary.cpp b/src/dictionary.cpp index fcba0acc..202e1749 100644 --- a/src/dictionary.cpp +++ b/src/dictionary.cpp @@ -38,15 +38,16 @@ int dictionary_skipwords; char dictionary_name[40]; extern char *print_dictionary_flags(unsigned int *flags); -extern char *DecodeRule(const char *group_chars, int group_length, char *rule); +extern char *DecodeRule(const char *group_chars, int group_length, char *rule, int control); // accented characters which indicate (in some languages) the start of a separate syllable //static const unsigned short diereses_list[7] = {L'ä',L'ë',L'ï',L'ö',L'ü',L'ÿ',0}; static const unsigned short diereses_list[7] = {0xe4,0xeb,0xef,0xf6,0xfc,0xff,0}; // convert characters to an approximate 7 bit ascii equivalent -// used for checking for vowels -static unsigned char remove_accent[] = { +// used for checking for vowels (up to 0x259=schwa) +#define N_REMOVE_ACCENT 0x25e +static unsigned char remove_accent[N_REMOVE_ACCENT] = { 'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0c0 'd','n','o','o','o','o','o', 0, 'o','u','u','u','u','y','t','s', // 0d0 'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i', // 0e0 @@ -73,7 +74,9 @@ static unsigned char remove_accent[] = { 'r','r','r','r','u','u','u','u','s','s','t','t','y','y','h','h', // 210 'n','d','o','o','z','z','a','a','e','e','o','o','o','o','o','o', // 220 'o','o','y','y','l','n','t','j','d','q','a','c','c','l','t','s', // 230 -'z', 0 }; +'z', 0, 0, 'b','u','v','e','e','j','j','q','q','r','r','y','y', // 240 +'a','a','a','b','o','c','d','d','e','e','e','e','e','e' }; + @@ -86,8 +89,8 @@ void strncpy0(char *to,const char *from, int size) } -static int reverse_word_bytes(int word) -{//============================= +int Reverse4Bytes(int word) +{//======================== // reverse the order of bytes from little-endian to big-endian #ifdef ARCH_BIG int ix; @@ -170,9 +173,9 @@ static void InitGroups(Translator *tr) pw = (unsigned int *)(tr->langopts.replace_chars); while(*pw != 0) { - *pw = reverse_word_bytes(*pw); + *pw = Reverse4Bytes(*pw); pw++; - *pw = reverse_word_bytes(*pw); + *pw = Reverse4Bytes(*pw); pw++; } #endif @@ -275,7 +278,7 @@ int LoadDictionary(Translator *tr, const char *name, int no_error) pw = (int *)(tr->data_dictlist); - length = reverse_word_bytes(pw[1]); + length = Reverse4Bytes(pw[1]); if(size <= (N_HASH_DICT + sizeof(int)*2)) { @@ -283,10 +286,10 @@ int LoadDictionary(Translator *tr, const char *name, int no_error) return(2); } - if((reverse_word_bytes(pw[0]) != N_HASH_DICT) || + if((Reverse4Bytes(pw[0]) != N_HASH_DICT) || (length <= 0) || (length > 0x8000000)) { - fprintf(stderr,"Bad data: '%s' (%x length=%x)\n",fname,reverse_word_bytes(pw[0]),length); + fprintf(stderr,"Bad data: '%s' (%x length=%x)\n",fname,Reverse4Bytes(pw[0]),length); return(2); } tr->data_dictrules = &(tr->data_dictlist[length]); @@ -742,7 +745,7 @@ static int IsLetter(Translator *tr, int letter, int group) } else { - if((letter >= 0xc0) && (letter <= 0x241)) + if((letter >= 0xc0) && (letter < N_REMOVE_ACCENT)) return(tr->letter_bits[remove_accent[letter-0xc0]] & (1L << group)); } @@ -753,107 +756,31 @@ static int IsLetter(Translator *tr, int letter, int group) } -static int IsVowel(Translator *tr, int letter) -{//=========================================== - return(IsLetter(tr, letter, 0)); +int IsVowel(Translator *tr, int letter) +{//==================================== + return(IsLetter(tr, letter, LETTERGP_VOWEL2)); } -static int Unpronouncable_en(Translator *tr, char *word) -{//===================================================== -/* Determines whether a word in 'unpronouncable', i.e. whether it should - be spoken as individual letters. - - This function is language specific. -*/ - +static int Unpronouncable2(Translator *tr, char *word) +{//=================================================== int c; - int vowel_posn=9; - int index; - int count; - int ix; - int apostrophe=0; + int end_flags; + char ph_buf[N_WORD_PHONEMES]; - static unsigned char initials_bitmap[86] = { - 0x00, 0x00, 0x00, 0x00, 0x22, 0x08, 0x00, 0x88, // 0 - 0x20, 0x24, 0x20, 0x80, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x08, 0x00, 0x88, 0x22, 0x04, 0x00, // 16 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x88, 0x22, 0x04, 0x00, 0x02, 0x00, 0x04, // 32 - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x28, 0x8a, 0x03, 0x00, 0x00, 0x40, 0x00, // 48 - 0x02, 0x00, 0x41, 0xca, 0xbb, 0x06, 0x20, 0x80, - 0x91, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, // 64 - 0x08, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, }; - - - // words which we pass through to the dictionary, even though they look unpronouncable - static const char *exceptions[] = { - "'s ", "st ","nd ","rd ","th ",NULL }; - - if((*word == ' ') || (*word == 0)) - return(0); - - for(ix=0; exceptions[ix] != NULL; ix++) - { - // Seemingly uncpronouncable words, but to be looked in the dictionary rules instead - if(memcmp(word,exceptions[ix],3)==0) - return(0); - } - - index=0; - count=0; - for(;;) - { - index += utf8_in(&c,&word[index]); - count++; - - if((c==0) || (c==' ') || (c == '\'')) - break; - - if(IsVowel(tr, c) || (c == 'y')) - { - vowel_posn = count; - break; - } - - if(c == '\'') - apostrophe = 1; - else - if(!IsAlpha(c)) - return(0); // letter (not vowel) outside Latin character range or apostrophe, abort test - } - if((vowel_posn > 5) || ((word[0]!='s') && (vowel_posn > 4))) - return(1); // no vowel, or no vowel in first four letters - - /* there is at least one vowel, is the initial letter combination valid ? */ - - if(vowel_posn < 3) - return(0); /* vowel in first two letters, OK */ - - if(apostrophe) - return(0); // first two letters not a-z, abort test - - index = (word[0]-'a') * 26 + (word[1]-'a'); - if(initials_bitmap[index >> 3] & (1L << (index & 7))) - return(0); - else - return(1); /****/ -} /* end of Unpronounceable */ - - -static int Unpronouncable_de(Translator *tr, char *word) -{//===================================================== - if(memcmp(word,"tsch",4)==0) - return(0); - return(2); + ph_buf[0] = 0; + c = word[-1]; + word[-1] = ' '; // ensure there is a space before the "word" + end_flags = TranslateRules(tr, word, ph_buf, sizeof(ph_buf), NULL, FLAG_UNPRON_TEST, NULL); + word[-1] = c; + if((end_flags == 0) || (end_flags & SUFX_UNPRON)) + return(1); + return(0); } - int Unpronouncable(Translator *tr, char *word) {//=========================================== /* Determines whether a word in 'unpronouncable', i.e. whether it should @@ -868,18 +795,6 @@ int Unpronouncable(Translator *tr, char *word) int index; int count; int apostrophe=0; - int result=2; // unknown - - if(tr->translator_name == L('e','n')) - { - return(Unpronouncable_en(tr,word)); - } - if(tr->translator_name == L('d','e')) - { - result = Unpronouncable_de(tr,word); - } - if(result < 2) - return(result); utf8_in(&c,word); if((tr->letter_bits_offset > 0) && (c < 0x241)) @@ -899,9 +814,12 @@ int Unpronouncable(Translator *tr, char *word) for(;;) { index += utf8_in(&c,&word[index]); - if((c==0) || (c==' ') || (c == '\'')) + if((c==0) || (c==' ')) break; + if((c=='\'') && (count > 1)) + break; // "tv'" but not "l'" + if(count==0) c1 = c; count++; @@ -916,11 +834,14 @@ int Unpronouncable(Translator *tr, char *word) apostrophe = 1; else if(!iswalpha(c)) - return(0); // letter (not vowel) outside a-z range or apostrophe, abort test + return(0); } - if((vowel_posn < 9) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) - return(0); // option means allow any word with a vowel + if((vowel_posn > 2) && (tr->langopts.param[LOPT_UNPRONOUNCABLE] == 2)) + { + // Lookup unpronounable rules in *_rules + return(Unpronouncable2(tr, word)); + } if(c1 == tr->langopts.param[LOPT_UNPRONOUNCABLE]) vowel_posn--; // disregard this as the initial letter when counting @@ -1813,6 +1734,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ int match_type; /* left, right, or consume */ int failed; + int unpron_ignore; int consumed; /* number of letters consumed from input */ int count; /* count through rules in the group */ int syllable_count; @@ -1858,6 +1780,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ /* search through dictionary rules */ while(rule[0] != RULE_GROUP_END) { + unpron_ignore = word_flags & FLAG_UNPRON_TEST; match_type=0; consumed = 0; letter = 0; @@ -1874,6 +1797,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ /* work through next rule until end, or until no-match proved */ rule_start = rule; + failed = 0; while(!failed) { @@ -1904,6 +1828,14 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ break; case RULE_PRE: match_type = RULE_PRE; + if(word_flags & FLAG_UNPRON_TEST) + { + // checking the start of the word for unpronouncable character sequences, only + // consider rules which explicitly match the start of a word + if(rule[0] != ' ') + failed = 1; + unpron_ignore = 0; + } break; case RULE_POST: match_type = RULE_POST; @@ -2046,8 +1978,14 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ case RULE_DOLLAR: command = *rule++; + if(command == 0x01) + { + match.end_type = SUFX_UNPRON; // $unpron + } + else if((command & 0xf0) == 0x10) { + // $w_alt if(dict_flags & (1 << (BITNUM_FLAG_ALT + (command & 0xf)))) add_points = 23; else @@ -2056,6 +1994,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ else if((command & 0xf0) == 0x20) { + // $p_alt // make a copy of the word up to the post-match characters ix = *word - word_start + consumed + group_length + 1; memcpy(word_buf, word_start-1, ix); @@ -2151,8 +2090,8 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ break; case RULE_DEL_FWD: - // find the next 'e' in the word and replace by '' - for(p = *word + group_length; *p != ' '; p++) + // find the next 'e' in the word and replace by 'E' + for(p = *word + group_length; p < post_ptr; p++) { if(*p == 'e') { @@ -2366,9 +2305,11 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ match.points += add_points; } - if(failed == 2) + + if((failed == 2) && (unpron_ignore == 0)) { /* matched OK, is this better than the last best match ? */ + if(match.points >= best.points) { memcpy(&best,&match,sizeof(match)); @@ -2386,7 +2327,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ if(group_length > 1) pts += 35; // to account for an extra letter matching DecodePhonemes(match.phonemes,decoded_phonemes); - fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group_chars, group_length, rule_start),decoded_phonemes); + fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group_chars, group_length, rule_start, word_flags), decoded_phonemes); } } @@ -2469,7 +2410,10 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c wordbuf[ix] = c; } wordbuf[ix] = 0; - fprintf(f_trans,"Translate '%s'\n",wordbuf); + if(word_flags & FLAG_UNPRON_TEST) + fprintf(f_trans,"Unpronouncable? '%s'\n",wordbuf); + else + fprintf(f_trans,"Translate '%s'\n",wordbuf); } p = p_start; @@ -2597,7 +2541,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c } // no match, try removing the accent and re-translating the word - if((letter >= 0xc0) && (letter <= 0x241) && ((ix = remove_accent[letter-0xc0]) != 0)) + if((letter >= 0xc0) && (letter < N_REMOVE_ACCENT) && ((ix = remove_accent[letter-0xc0]) != 0)) { // within range of the remove_accent table if((p[-2] != ' ') || (p[n] != ' ')) @@ -2682,7 +2626,11 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c strcpy(phonemes,match1.phonemes); return(0); } - + + if(word_flags & FLAG_UNPRON_TEST) + return(match1.end_type | 1); + match1.end_type &= ~SUFX_UNPRON; + if((match1.end_type != 0) && (end_phonemes != NULL)) { /* a standard ending has been found, re-translate the word without it */ @@ -3524,7 +3472,8 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) if((strcmp(ending,"s")==0) || (strcmp(ending,"es")==0)) end_flags |= FLAG_SUFX_S; - if(strcmp(ending,"'s")==0) +// if(strcmp(ending,"'s")==0) + if(ending[0] == '\'') end_flags &= ~FLAG_SUFX; // don't consider 's as an added suffix return(end_flags); diff --git a/src/espeakedit.cpp b/src/espeakedit.cpp index ee559136..efa9f3fe 100644 --- a/src/espeakedit.cpp +++ b/src/espeakedit.cpp @@ -233,6 +233,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame) EVT_MENU(MENU_LEXICON_DE, MyFrame::OnTools) EVT_MENU(MENU_LEXICON_IT, MyFrame::OnTools) EVT_MENU(MENU_LEXICON_IT2, MyFrame::OnTools) + EVT_MENU(MENU_LEXICON_TEST, MyFrame::OnTools) EVT_MENU(MENU_TO_UTF8, MyFrame::OnTools) EVT_MENU(MENU_COUNT_WORDS, MyFrame::OnTools) EVT_MENU(MENU_TEST, MyFrame::OnTools) @@ -608,6 +609,7 @@ void MyFrame::OnTools(wxCommandEvent& event) case MENU_LEXICON_DE: case MENU_LEXICON_IT: case MENU_LEXICON_IT2: + case MENU_LEXICON_TEST: CompareLexicon(event.GetId()); // Compare a lexicon with _rules translation break; diff --git a/src/extras.cpp b/src/extras.cpp index e04f5477..0df0b04d 100644 --- a/src/extras.cpp +++ b/src/extras.cpp @@ -763,6 +763,75 @@ void Lexicon_De() } +extern int IsVowel(Translator *tr, int letter); + +void Lexicon_Test() +{//================ + int c1, c2, c3; + char *p; + int prev_c1=0; + int prev_c2=0; + int prev_c3 = 0; + FILE *f_in; + FILE *f_out; + char buf[200]; + + wxString s_fname = wxFileSelector(_T("List of UTF-8 words with Combining Grave Accent U+300 to indicate stress"),path_dir1, + _T(""),_T(""),_T("*"),wxOPEN); + if(s_fname.IsEmpty()) + return; + strcpy(buf,s_fname.mb_str(wxConvLocal)); + path_dir1 = wxFileName(s_fname).GetPath(); + + if((f_in = fopen(buf,"r")) == NULL) + { + wxLogError(_T("Can't read file: ") + wxString(buf,wxConvLocal)); + return; + } + + strcat(buf,"_1"); + if((f_out = fopen(buf,"w")) == NULL) + { + wxLogError(_T("Can't write file: ") + wxString(buf,wxConvLocal)); + fclose(f_in); + return; + } + + while(!feof(f_in)) + { + if((p = fgets(buf,sizeof(buf),f_in)) == NULL) + break; + + if(buf[0] == 0) + continue; + + p += utf8_in(&c1, p); + p += utf8_in(&c2, p); + p += utf8_in(&c3, p); + + c1 = towlower(c1); + c2 = towlower(c2); + c3 = towlower(c3); + + if(IsVowel(translator, c1)) + continue; + if(IsVowel(translator, c2)) + continue; + + if((prev_c1 != c1) || (prev_c2 != c2) || ((prev_c3 != c3) && !IsVowel(translator,c3))) + fputc('\n',f_out); + prev_c1 = c1; + prev_c2 = c2; + prev_c3 = c3; + fprintf(f_out,"%s",buf); + + } + fclose(f_in); + fclose(f_out); +} // end of Lexicon_Test + + + void Lexicon_Bg() {//============== // Bulgarian: compare stress markup in a list of words with lookup using bg_rules @@ -1275,6 +1344,9 @@ void CompareLexicon(int id) case MENU_LEXICON_IT2: Lexicon_It(2); break; + case MENU_LEXICON_TEST: + Lexicon_Test(); + break; } } // end of CompareLexicon diff --git a/src/main.h b/src/main.h index 90942259..be1c9a87 100755 --- a/src/main.h +++ b/src/main.h @@ -161,6 +161,7 @@ enum { MENU_LEXICON_DE, MENU_LEXICON_IT, MENU_LEXICON_IT2, + MENU_LEXICON_TEST, MENU_TO_UTF8, MENU_COUNT_WORDS, MENU_TEST, diff --git a/src/menus.cpp b/src/menus.cpp index 7a450db4..93c21575 100644 --- a/src/menus.cpp +++ b/src/menus.cpp @@ -128,6 +128,7 @@ wxMenuBar *MakeMenu(int type, const char *dict_name) lexicon_menu->Append(MENU_LEXICON_DE, _("German")); lexicon_menu->Append(MENU_LEXICON_IT, _("Italian")); lexicon_menu->Append(MENU_LEXICON_IT2, _("Italian, pass 2")); +// lexicon_menu->Append(MENU_LEXICON_TEST, _("Test")); tools_menu = new wxMenu; tools_menu->Append(MENU_VOWELCHART, _("Make &Vowels Chart"), vowelchart_menu); diff --git a/src/numbers.cpp b/src/numbers.cpp index 772d1416..a2cbdb7d 100644 --- a/src/numbers.cpp +++ b/src/numbers.cpp @@ -766,7 +766,7 @@ static int CheckDotOrdinal(Translator *tr, char *word, char *word_end, WORD_TAB if(word_end[0] == '.') utf8_in(&c2, &word_end[2]); else - utf8_in(&c2, &word_end[1]); + utf8_in(&c2, &word_end[0]); if((word_end[1] != 0) && ((c2 == 0) || (wtab[0].flags & FLAG_COMMA_AFTER) || IsAlpha(c2))) { @@ -850,8 +850,8 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) flags[0] = 0; flags[1] = 0; - if((tr->langopts.numbers & NUM_ROMAN_CAPITALS) && !(wtab[0].flags & FLAG_ALL_UPPER)) - return(0); + if(((tr->langopts.numbers & NUM_ROMAN_CAPITALS) && !(wtab[0].flags & FLAG_ALL_UPPER)) || isdigit(word[-2])) + return(0); // not '2xx' word_start = word; while((c = *word++) != ' ') @@ -889,6 +889,10 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) prev = value; n_digits++; } + + if(isdigit(word[0])) + return(0); // eg. 'xx2' + acc += prev; if(acc < tr->langopts.min_roman) return(0); @@ -896,6 +900,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) if(acc > tr->langopts.max_roman) return(0); + Lookup(tr, "_roman",ph_roman); // precede by "roman" if _rom is defined in *_list p = &ph_out[0]; @@ -931,6 +936,10 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) return(0); } } + else + { + wtab[0].flags |= FLAG_ORDINAL; + } } tr->prev_dict_flags = 0; @@ -1071,6 +1080,10 @@ static int LookupThousands(Translator *tr, int value, int thousandplex, int thou } } sprintf(ph_out,"%s%s",ph_of,ph_thousands); + + if((value == 1) && (thousandplex == 1) && (tr->langopts.numbers & NUM_OMIT_1_THOUSAND)) + return(1); + return(found_value); } diff --git a/src/phoneme.h b/src/phoneme.h index 353b6746..8d39de4e 100644 --- a/src/phoneme.h +++ b/src/phoneme.h @@ -130,7 +130,8 @@ typedef struct { char name[N_PHONEME_TAB_NAME]; PHONEME_TAB *phoneme_tab_ptr; int n_phonemes; - int includes; // also include the phonemes from this other phoneme table + int includes; // also include the phonemes from this other phoneme table + int equivalence_tables; // lists of equivalent phonemes to match other languages, byte index into phondata } PHONEME_TAB_LIST; diff --git a/src/prosodydisplay.cpp b/src/prosodydisplay.cpp index cc08acf8..f7706e35 100644 --- a/src/prosodydisplay.cpp +++ b/src/prosodydisplay.cpp @@ -613,7 +613,7 @@ void MyFrame::OnProsody(wxCommandEvent& WXUNUSED(event)) prosodyframe->CreateStatusBar(); int width, height; - wxMDIClientWindow *clientwin = this->GetClientWindow(); + wxMDIClientWindow *clientwin = (wxMDIClientWindow *)this->GetClientWindow(); clientwin->GetClientSize(&width, &height); #ifdef deleted diff --git a/src/readclause.cpp b/src/readclause.cpp index ffadad85..12d304a6 100644 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -1995,8 +1995,8 @@ static MNEM_TAB xml_char_mnemonics[] = { {NULL,-1}}; -int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type) -{//============================================================================================================= +int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change) +{//================================================================================================================================= /* Find the end of the current clause. Write the clause into buf @@ -2051,6 +2051,7 @@ int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix tr->clause_lower_count = 0; end_of_input = 0; *tone_type = 0; + *voice_change = 0; f_input = f_in; // for GetC etc @@ -2218,16 +2219,11 @@ f_input = f_in; // for GetC etc if(terminator & CLAUSE_BIT_VOICE) { - // a change in voice, write the new voice name to the end of the buf - p = current_voice_id; - while((*p != 0) && (ix < (n_buf-1))) - { - buf[ix++] = *p++; - } - buf[ix++] = 0; + strcpy(voice_change, current_voice_id); } return(terminator); } + c1 = ' '; c2 = GetC(); continue; } diff --git a/src/synth_mbrola.cpp b/src/synth_mbrola.cpp index 4919a890..b1d96dc0 100644 --- a/src/synth_mbrola.cpp +++ b/src/synth_mbrola.cpp @@ -73,7 +73,7 @@ BOOL load_MBR() if(hinstDllMBR != NULL) return TRUE; // already loaded - if (!(hinstDllMBR=LoadLibraryA("mbrola.dll"))) + if ((hinstDllMBR=LoadLibraryA("mbrola.dll")) == 0) return FALSE; init_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"init_MBR"); write_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"write_MBR"); diff --git a/src/synthdata.cpp b/src/synthdata.cpp index 1e9b7e86..4f450396 100644 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,8 +35,8 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.43.57 18.Jul.10"; -const int version_phdata = 0x014354; +const char *version_string = "1.43.63 02.Aug.10"; +const int version_phdata = 0x014361; int option_device_number = -1; FILE *f_logespeak = NULL; @@ -49,7 +49,7 @@ PHONEME_TAB *phoneme_tab[N_PHONEME_TAB]; unsigned char phoneme_tab_flags[N_PHONEME_TAB]; // bit 0: not inherited USHORT *phoneme_index=NULL; -char *spects_data=NULL; +char *phondata_ptr=NULL; unsigned char *wavefile_data=NULL; static unsigned char *phoneme_tab_data = NULL; @@ -116,16 +116,17 @@ int LoadPhData() int result = 1; int length; unsigned char *p; + int *pw; if((phoneme_tab_data = (unsigned char *)ReadPhFile((void *)(phoneme_tab_data),"phontab",NULL)) == NULL) return(-1); if((phoneme_index = (USHORT *)ReadPhFile((void *)(phoneme_index),"phonindex",NULL)) == NULL) return(-1); - if((spects_data = ReadPhFile((void *)(spects_data),"phondata",NULL)) == NULL) + if((phondata_ptr = ReadPhFile((void *)(phondata_ptr),"phondata",NULL)) == NULL) return(-1); if((tunes = (TUNE *)ReadPhFile((void *)(tunes),"intonations",&length)) == NULL) return(-1); - wavefile_data = (unsigned char *)spects_data; + wavefile_data = (unsigned char *)phondata_ptr; n_tunes = length / sizeof(TUNE); // read the version number from the first 4 bytes of phondata @@ -150,7 +151,9 @@ int LoadPhData() n_phonemes = p[0]; phoneme_tab_list[ix].n_phonemes = p[0]; phoneme_tab_list[ix].includes = p[1]; - p += 4; + pw = (int *)p; + phoneme_tab_list[ix].equivalence_tables = Reverse4Bytes(pw[1]); + p += 8; memcpy(phoneme_tab_list[ix].name,p,N_PHONEME_TAB_NAME); p += N_PHONEME_TAB_NAME; phoneme_tab_list[ix].phoneme_tab_ptr = (PHONEME_TAB *)p; @@ -168,10 +171,10 @@ void FreePhData(void) {//================== Free(phoneme_tab_data); Free(phoneme_index); - Free(spects_data); + Free(phondata_ptr); phoneme_tab_data=NULL; phoneme_index=NULL; - spects_data=NULL; + phondata_ptr=NULL; } @@ -226,7 +229,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, frame_t *frame; static frameref_t frames_buf[N_SEQ_FRAMES]; - seq = (SPECT_SEQ *)(&spects_data[fmt_params->fmt_addr]); + seq = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt_addr]); seqk = (SPECT_SEQK *)seq; nf = seq->n_frames; @@ -279,7 +282,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, { // a secondary reference has been returned, which is not a wavefile // add these spectra to the main sequence - seq2 = (SPECT_SEQ *)(&spects_data[fmt_params->fmt2_addr]); + seq2 = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt2_addr]); seqk2 = (SPECT_SEQK *)seq2; // first frame of the addition just sets the length of the last frame of the main seq @@ -371,7 +374,7 @@ unsigned char *GetEnvelope(int index) fprintf(stderr,"espeak: No envelope\n"); return(envelope_data[0]); // not found, use a default envelope } - return((unsigned char *)&spects_data[index]); + return((unsigned char *)&phondata_ptr[index]); } diff --git a/src/synthesize.cpp b/src/synthesize.cpp index 74873304..0805c53a 100644 --- a/src/synthesize.cpp +++ b/src/synthesize.cpp @@ -254,6 +254,9 @@ static int DoSample2(int index, int which, int std_length, int control, int leng wav_length = (p[1] * 256); wav_length += p[0]; // length in bytes + if(wav_length == 0) + return(0); + min_length = speed.min_sample_len; if(wav_scale==0) @@ -1656,7 +1659,8 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) { InterpretPhoneme2(p->tone_ph, &phdata_tone); pitch_env = GetEnvelope(phdata_tone.pitch_env); - amp_env = GetEnvelope(phdata_tone.amp_env); + if(phdata_tone.amp_env > 0) + amp_env = GetEnvelope(phdata_tone.amp_env); } StartSyllable(); diff --git a/src/synthesize.h b/src/synthesize.h index 3eef6a24..910f440c 100644 --- a/src/synthesize.h +++ b/src/synthesize.h @@ -533,6 +533,7 @@ int SelectPhonemeTableName(const char *name); void Write4Bytes(FILE *f, int value); int Read4Bytes(FILE *f); +int Reverse4Bytes(int word); int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, char *err_name,int flags); diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp index cf8103cb..cd6cbf51 100644 --- a/src/tr_languages.cpp +++ b/src/tr_languages.cpp @@ -130,7 +130,7 @@ static Translator* NewTranslator(void) memset(tr->letter_bits,0,sizeof(tr->letter_bits)); memset(tr->letter_groups,0,sizeof(tr->letter_groups)); - // 0-5 sets of characters matched by A B C E F G in pronunciation rules + // 0-5 sets of characters matched by A B C H F G Y in pronunciation rules // these may be set differently for different languages SetLetterBits(tr,0,"aeiou"); // A vowels, except y SetLetterBits(tr,1,"bcdfgjklmnpqstvxz"); // B hard consonants, excluding h,r,w @@ -424,7 +424,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.stress_rule = STRESSPOSN_1L; SetLetterVowel(tr,'y'); - tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_HUNDRED_AND | NUM_OMIT_1_HUNDRED | NUM_ORDINAL_DOT | NUM_1900; + tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_HUNDRED_AND | NUM_OMIT_1_HUNDRED | NUM_ORDINAL_DOT | NUM_1900 | NUM_ROMAN | NUM_ROMAN_CAPITALS | NUM_ROMAN_ORDINAL; } break; @@ -440,8 +440,9 @@ Translator *SelectTranslator(const char *name) tr->langopts.param[LOPT_LONG_VOWEL_THRESHOLD] = 175/2; memcpy(tr->stress_lengths,stress_lengths_de,sizeof(tr->stress_lengths)); - tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | 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'); + tr->langopts.param[LOPT_UNPRONOUNCABLE] = 2; // use de_rules for unpronouncable rules } break; @@ -458,6 +459,8 @@ Translator *SelectTranslator(const char *name) tr->langopts.numbers = NUM_HUNDRED_AND | NUM_ROMAN | NUM_1900; tr->langopts.param[LOPT_COMBINE_WORDS] = 2; // allow "mc" to cmbine with the following word tr->langopts.suffix_add_e = 'e'; + tr->langopts.param[LOPT_UNPRONOUNCABLE] = 2; // use en_rules for unpronouncable rules + SetLetterBits(tr,6,"aeiouy"); // Group Y: vowels, including y } break; @@ -547,7 +550,7 @@ Translator *SelectTranslator(const char *name) 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_ROMAN | NUM_ROMAN_AFTER; + 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; if(name2 == L('c','a')) { @@ -559,6 +562,10 @@ Translator *SelectTranslator(const char *name) { tr->langopts.stress_flags = 0x100 | 0x6 | 0x30; // stress last syllable unless word ends with a vowel } + else + { + tr->langopts.param[LOPT_UNPRONOUNCABLE] = 2; // use es_rules for unpronouncable rules + } } break; @@ -702,7 +709,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.param[LOPT_IT_DOUBLING] = 1; tr->langopts.param[LOPT_ANNOUNCE_PUNCT] = 2; // don't break clause before announcing . ? ! - tr->langopts.numbers = NUM_DFRACTION_5 | NUM_ALLOW_SPACE | NUM_ROMAN | NUM_ROMAN_ORDINAL | NUM_ROMAN_CAPITALS | NUM_ORDINAL_DOT | NUM_OMIT_1_HUNDRED; + tr->langopts.numbers = NUM_DFRACTION_5 | NUM_ALLOW_SPACE | NUM_ROMAN | NUM_ROMAN_ORDINAL | NUM_ROMAN_CAPITALS | NUM_ORDINAL_DOT | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND; tr->langopts.thousands_sep = ' '; // don't allow dot as thousands separator tr->langopts.decimal_sep = ','; tr->langopts.max_roman = 899; @@ -879,7 +886,7 @@ SetLengthMods(tr,3); // all equal tr->letter_groups[0] = vowels_cyrillic; tr->langopts.stress_rule = STRESSPOSN_3R; // antipenultimate - tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED | NUM_DFRACTION_2; + tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_DFRACTION_2; tr->langopts.numbers2 = 0x8a; // variant numbers before thousands,milliards } break; @@ -1098,7 +1105,7 @@ SetLengthMods(tr,3); // all equal if(name2 == L('t','a')) { tr->letter_bits_offset = OFFSET_TAMIL; - tr->langopts.numbers = 0x1; + tr->langopts.numbers = NUM_OMIT_1_THOUSAND ; } if(name2 == L('m','r')) { @@ -1140,8 +1147,8 @@ SetLengthMods(tr,3); // all equal case L('t','r'): // Turkish { - static const unsigned char stress_amps_tr[8] = {18,16, 20,20, 20,21, 21,20 }; - static const short stress_lengths_tr[8] = {190,180, 200,200, 0,0, 240,250}; + 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, 200,230, 0,0, 240,250}; SetupTranslator(tr,stress_lengths_tr,stress_amps_tr); tr->charset_a0 = charsets[9]; // ISO-8859-9 - Latin5 @@ -1149,7 +1156,7 @@ SetLengthMods(tr,3); // all equal tr->langopts.stress_rule = 7; // stress on the last syllable, before any explicitly unstressed syllable tr->langopts.stress_flags = 0x20; //no automatic secondary stress - tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_OMIT_1_HUNDRED | NUM_DFRACTION_2; + tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_DFRACTION_2; tr->langopts.max_initial_consonants = 2; } break; diff --git a/src/translate.cpp b/src/translate.cpp index 74816a85..10df8492 100644 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -667,6 +667,98 @@ static int CheckDottedAbbrev(char *word1, WORD_TAB *wtab) } // end of CheckDottedAbbrev +extern char *phondata_ptr; + +int ChangeEquivalentPhonemes(Translator *tr, int lang2, char *phonemes) +{//==================================================================== +// tr: the original language +// lang2: phoneme table number for the temporary language +// phonemes: the phonemes to be replaced + + int ix; + int len; + char phon; + char *p; + unsigned char *pb; + char *eqlist; + char *p_out; + char *p_in; + int remove_stress = 0; + char phonbuf[N_WORD_PHONEMES]; + + // has a phoneme equivalence table been specified for thus language pair? + if((ix = phoneme_tab_list[tr->phoneme_tab_ix].equivalence_tables) == 0) + return(0); + + pb = (unsigned char *)&phondata_ptr[ix]; + + for(;;) + { + if(pb[0] == 0) + return(0); // table not found + + if(pb[0] == lang2) + break; + + len = (pb[2] << 8) + pb[3]; // size of this table in words + pb += (len * 4); + } + remove_stress = pb[1]; + + if(option_phonemes == 2) + { + DecodePhonemes(phonemes, phonbuf); + fprintf(f_trans,"(%s) %s -> (%s) ", phoneme_tab_list[lang2].name, phonbuf, phoneme_tab_list[tr->phoneme_tab_ix].name); + } + + p_in = phonemes; + eqlist = (char *)&pb[8]; + p_out = phonbuf; + + while((phon = *p_in++) != 0) + { + if(remove_stress && ((phon & 0xff) < phonSTRESS_PREV)) + continue; // remove stress marks + + // is there a translation for this phoneme code? + p = eqlist; + while(*p != 0) + { + len = strlen(&p[1]); + if(*p == phon) + { + strcpy(p_out, &p[1]); + p_out += len; + break; + } + p += (len + 2); + } + if(*p == 0) + { + // no translation found + *p_out++ = phon; + } + } + *p_out = 0; + + if(remove_stress) + { + SetWordStress(tr, phonbuf, NULL, -1, 0); + } + + strcpy(phonemes, phonbuf); + + if(option_phonemes == 2) + { + SelectPhonemeTable(tr->phoneme_tab_ix); + DecodePhonemes(phonemes, phonbuf); + fprintf(f_trans,"%s\n\n", phonbuf); + } + return(1); +} // end of ChangeEquivalentPhonemes + + + int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab) {//=========================================================================== @@ -1148,6 +1240,12 @@ strcpy(phonemes2,phonemes); strcpy(word_phonemes,phonemes); return(0); } + +if(dictionary_flags2[0] & FLAG_ABBREV) +{ + // Removing the suffix leaves a word which should be spoken as individual letters + // Not yet implemented +} if(dictionary_flags[0]==0) { dictionary_flags[0] = dictionary_flags2[0]; @@ -1697,6 +1795,19 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa p[1] = phonSCHWA; p[2] = 0; } + +// ?? Option to convert from language2 phonemes to the equivalent language1 phonemes +// ?? Option to set the word-stress according to language1 rules eg. lang=fr) + if(ChangeEquivalentPhonemes(tr, switch_phonemes, (char *)p)) + { + switch_phonemes = -1; + } + + if(switch_phonemes == -1) + { + strcpy(dictionary_name, old_dictionary_name); + SelectPhonemeTable(voice->phoneme_tab_ix); + } } if(!(word_flags & FLAG_HYPHEN)) @@ -2196,6 +2307,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t short charix[N_TR_SOURCE+4]; WORD_TAB words[N_CLAUSE_WORDS]; + static char voice_change_name[40]; int word_count=0; // index into words char sbuf[N_TR_SOURCE]; @@ -2218,7 +2330,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t for(ix=0; ixlangopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre { // return new voice name if an embedded voice change command terminated the clause if(terminator & CLAUSE_BIT_VOICE) - *voice_change = &source[source_index]; + *voice_change = voice_change_name; else *voice_change = NULL; } diff --git a/src/translate.h b/src/translate.h index 92a487d9..492cf414 100644 --- a/src/translate.h +++ b/src/translate.h @@ -112,6 +112,8 @@ #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 #define FLAG_NO_PREFIX 0x20000000 +#define FLAG_UNPRON_TEST 0x80000000 // do unpronounability test on the beginning of the word + // prefix/suffix flags (bits 8 to 14, bits 16 to 22) don't use 0x8000, 0x800000 #define SUFX_E 0x0100 // e may have been added @@ -125,6 +127,8 @@ #define SUFX_B 0x20000 // break, this character breaks the word into stem and suffix (used with SUFX_P) #define SUFX_A 0x40000 // remember that the suffix starts with a vowel +#define SUFX_UNPRON 0x8000 // used to return $unpron flag from *_rules + #define FLAG_ALLOW_TEXTMODE 0x02 // allow dictionary to translate to text rather than phonemes #define FLAG_SUFX 0x04 @@ -221,9 +225,9 @@ typedef const char * constcharptr; typedef struct { - int points; + int points; const char *phonemes; - int end_type; + int end_type; char *del_fwd; } MatchRecord; @@ -388,6 +392,7 @@ typedef struct { #define NUM_AND_HUNDRED 0x40000 #define NUM_THOUSAND_AND 0x80000 #define NUM_VIGESIMAL 0x100000 +#define NUM_OMIT_1_THOUSAND 0x200000 #define NUM_ROMAN 0x1000000 #define NUM_ROMAN_CAPITALS 0x2000000 @@ -413,6 +418,7 @@ typedef struct { // bit18= 'and' before hundreds // bit19= 'and' after thousands if there are no hundreds // bit20= vigesimal number, if tens are not found + // bit21= omit "one" before "thousand" // bit24= recognize roman numbers // bit25= Roman numbers only if upper case @@ -484,7 +490,8 @@ typedef struct char phon_out[300]; char phonemes_repeat[20]; - int phonemes_repeat_count; + int phonemes_repeat_count; + int phoneme_tab_ix; unsigned char stress_amps[8]; unsigned char stress_amps_r[8]; @@ -650,7 +657,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, int TranslateRules(Translator *tr, char *p, char *phonemes, int size, char *end_phonemes, int end_flags, unsigned int *dict_flags); int TranslateWord(Translator *tr, char *word1, int next_pause, WORD_TAB *wtab); void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *tone, char **voice_change); -int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type); +int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change); void SetVoiceStack(espeak_VOICE *v); void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata); diff --git a/src/voices.cpp b/src/voices.cpp index 40200de2..508efcfd 100644 --- a/src/voices.cpp +++ b/src/voices.cpp @@ -978,6 +978,7 @@ voice_t *LoadVoice(const char *vname, int control) fprintf(stderr,"Unknown phoneme table: '%s'\n",phonemes_name); } voice->phoneme_tab_ix = ix; + new_translator->phoneme_tab_ix = ix; error = LoadDictionary(new_translator, new_dictionary, control & 4); if(dictionary_name[0]==0) return(NULL); // no dictionary loaded diff --git a/src/vowelchart.cpp b/src/vowelchart.cpp index 81cae2eb..394e728e 100644 --- a/src/vowelchart.cpp +++ b/src/vowelchart.cpp @@ -41,7 +41,7 @@ */ extern wxString path_phsource; -extern char *spects_data; +extern char *phondata_ptr; extern USHORT *phoneme_index; extern int n_phoneme_tables; @@ -664,7 +664,7 @@ void MakeVowelLists(void) { ix = vowelfmt_addr[vowelfmt_ix]; - seq = (SPECT_SEQ *)(&spects_data[ix]); + seq = (SPECT_SEQ *)(&phondata_ptr[ix]); seqk = (SPECT_SEQK *)seq; if(seq->frame[0].frflags & FRFLAG_KLATT)