From 417395b0335a31182d6fb5d1f4e5ae1c742a63e4 Mon Sep 17 00:00:00 2001 From: jonsd Date: Thu, 28 Feb 2008 20:54:03 +0000 Subject: [PATCH] [1.31.19} Fix: Events callback, fix word length information for words with multibyte characters. Fix: Re-translating a word in a different language after the first langauge has started speaking individual letters, gave silence. Announce punctuation. If character name is not defined, use English. Announce punctuation. Fix pitch of the voice which announces punctuation characters. [[Phonemes]] text input. Allow the language-switch phoneme eg. [[_^_EN hEloU _^_FR]] in the input. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@152 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/dict_phonemes | 36 +++--- dictsource/en_list | 75 ++++++++++-- dictsource/en_rules | 6 +- dictsource/eo_list | 1 - dictsource/es_list | 30 ++--- dictsource/es_rules | 8 +- dictsource/fr_list | 34 ++++-- dictsource/fr_rules | 70 +++++++---- dictsource/grc_rules | 222 ++++++++++++++++++---------------- dictsource/pt_list | 4 +- dictsource/ta_rules | 8 +- dictsource/zh_rules | 9 +- phsource/compile_report | 109 +++++++++-------- phsource/n^/n^@ | Bin 10627 -> 10627 bytes phsource/n^/n^a | Bin 11591 -> 11591 bytes phsource/n^/n^e | Bin 18339 -> 18339 bytes phsource/n^/n^o | Bin 27015 -> 27015 bytes phsource/n^/n^u | Bin 13519 -> 13519 bytes phsource/ph_english | 16 +-- phsource/ph_english_us | 2 +- phsource/phonemes | 12 +- phsource/r3/{@tap_i => @tap2} | Bin 3542 -> 3541 bytes phsource/ustop/q.wav | Bin 758 -> 760 bytes phsource/vdiph/8u | Bin 12676 -> 12676 bytes phsource/vwl_en_us/a | Bin 6237 -> 6237 bytes phsource/vwl_en_us/er | Bin 6238 -> 6238 bytes phsource/vwl_en_us/ii | Bin 6238 -> 6238 bytes src/dictionary.cpp | 37 ++++-- src/numbers.cpp | 47 +++++-- src/readclause.cpp | 148 +++++++++++++++++------ src/synthdata.cpp | 2 +- src/synthesize.h | 3 +- src/tr_english.cpp | 2 +- src/translate.cpp | 77 ++++++++++-- src/translate.h | 5 +- src/wavegen.cpp | 14 ++- 36 files changed, 630 insertions(+), 347 deletions(-) rename phsource/r3/{@tap_i => @tap2} (74%) diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index c8274534..5418390d 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -43,9 +43,9 @@ x z Dictionary de_dict 3 @ @- a A A: aI aU -E E2 E: e: EI I i2 i: -O o: OY U u: W y y: -Y: +E E2 E: e: EI I i2 I: +i: O o: OY U u: W y +y: Y: * : ; b C C2 d D dZ f g h j k l m @@ -88,8 +88,8 @@ r R s t ts v z Z Dictionary es_dict -@- a aI aU e E eI eU -i o O oI u +a aI aU e E eI eU i +o O oI u * ** : b B d D f g j J J^ k l m n @@ -116,10 +116,10 @@ i i: o O O~ u W w^i W~ y Y * : ; b c d dZ f -g h j k l L m n -N n2 n^ p p2 r R s -S t t2 tS v w z Z -z2 z3 +g h j k l m n N +n2 n^ p p2 r R s S +t t2 tS v w z Z z2 +z3 Dictionary hi_dict @@ -281,7 +281,7 @@ u U uI u~ y g h j k l l^ m n N n^ p Q r R r- s S s# s; t T tS ts v -w x z Z +w w2 x z Z Dictionary ro_dict @@ -340,10 +340,10 @@ Dictionary zh_dict i i. i[ iou N- o o- ou u uai y -(u) : f h j k kh l -m n N p ph r s s. -S; t th ts ts. ts. tS; tS; -tsh v w x z z. +: f j k kh l m n +N p ph r R s s. S; +t th ts ts. ts. tS; tS; tsh +v w x z z. Dictionary jbo_dict @@ -417,7 +417,7 @@ Dictionary rw_dict a e i o u -* b B c d dZ f g -h j J k l m n N -n^ p q s S S; t tS -w x z +* : b B c d dZ f +g h j J k l m n +N n^ p q s S S; t +tS v w x z diff --git a/dictsource/en_list b/dictsource/en_list index 82175ec7..bd499170 100644 --- a/dictsource/en_list +++ b/dictsource/en_list @@ -57,6 +57,7 @@ _?? sImb@L _#9 tab _#32 speIs +_  hA@dspeIs // U+00A0 no-break-space _! Ekskl@m'eIS@n _" kwoUts _# haS @@ -65,8 +66,8 @@ _% p3s'Ent ?5 _% pVRs'Ent _& amp@sand _' praIm -_( ElbrakIt -_) A@brakIt +_( lEftbrakIt +_) raItbrakIt _* ast@rIsk _+ plVs _, k0m@ @@ -80,24 +81,72 @@ _= i:kw@Lz _> A@aNg@L _? kwEstS@n _@ at|saIn -_[ Elskwe@ +_[ lEftskwe@ _\ bakstroUk -_] A@skwe@ +_] raItskwe@ _^ s3:kVmfl,Eks ?5 _^ sIRkVmfl,Eks __ 'Vnd3sk,o@ _` bakpraIm -_{ ElbreIs +_{ lEftbreIs _| vi:b'A@ -_} A@breIs +_} raItbreIs _~ tIld@ +_¡ I2nv3:tI2dEkskl@m'eIS@n +_¦ broUk@nb'A@ +_¨ daIa2r'i:sI2s +_ª fEmI2nI2n'O@dI2n@L +_« lEft'ang@LkwoUts +_­ makr0n +_² su:p@skrIptt'u: +_³ su:p@skrIptT'ri: +_´ a2kju:taksEnt +_· mId@Ld0t +_¸ sEd'Il@ +_¹ su:p@skrIptw'0n +_º maskjUlI2n'O@dI2n@L +_» raIt'ang@LkwoUts +_¿ I2nv3:tI2dkw'EstS@n +_‐ haIf@n +_‑ haIf@n +_‒ daS +_– daS +_— EmdaS +_― h0rIz,0nt@Lb'A@ +_‖ d,Vb@Lb'A@ +_‘ lEftkwoUt +_’ raItkwoUt +_‚ loUkwoUt +_‛ lEftkwoUt +_“ lEftkwoUts +_” raItkwoUts +_„ loUkwoUts +_‟ lEftkwoUts +_† dag3 +_‡ dVb@Ldag3 +_• bUlI2t +_‣ bUlI2t +_․ d0t +_‥ tu:d0ts +_… I2lIpsI2s +_‰ p3:m'i:l +_′ praIm +_″ dVb@LpraIm +_‴ trIp@LpraIm +_‼ Ekskla2m'eIS@nz +_₠ jU@roU + +¢ sEnts £ paUnd ¥ jEn +₨ ru:pi: +₩ w0n § sEkS@n -_¶ par@graf // in en_rules +¶ par@graf // in en_rules ¤ kVr@nsI2saIn © k0pI2raIt +® rEdZIst3d ° dI2gri:z − maIn@s ± plVs@maIn@s @@ -110,7 +159,14 @@ _¶ par@graf // in en_rules € jU@roUz ♯ SA@p ♭ flat +¬ n0t_|saIn ə SwA: +æ eI'i: +ɛ oUp@n'i: +ɔ oUp@n'oU +ð ED +ʃ ES +ʒ EZ // numeric @@ -1112,6 +1168,7 @@ leant lEnt leapt lEpt lego lEgoU leisure l'EZ3 +lemme lElI // let me lemonade $3 leo li:oU leopard lEp@d @@ -2625,7 +2682,7 @@ although OlD'oU $pause and %and $pause $only as ,az $pause $only (as is) ,az,Iz $pause -(as it is) azIt'Iz_ +(as it is) ,azIt,Iz $u+ because bIk'Vz $pause once $pause or %O@ $pause $only @@ -2717,7 +2774,7 @@ like laIk $strend2 - +// ?6 'one' = [wVn], 'of' = [Vv] ?6 noone noUwVn ?6 anyone EnIwVn ?6 everyone EvrIwVn diff --git a/dictsource/en_rules b/dictsource/en_rules index 3b2c30ca..0d9fcf56 100644 --- a/dictsource/en_rules +++ b/dictsource/en_rules @@ -5130,7 +5130,7 @@ μ m'ju:_ ν n'ju:_ ξ ks'aI_ - ο oUm'aIkr0n_ + ο 'oUmIkr0n_ .group 0xcf // Greek letters @@ -5146,7 +5146,7 @@ ψ ps'aI_ ω 'oUmIg@_ ώ 'oUmIg@_ - ό oUm'aIkr0n_ + ό 'oUmIkr0n_ // default group for "non of the above" @@ -5171,6 +5171,7 @@ ž Z þ T ð D + ñ n^ \\ bakstroUk @@ -5226,5 +5227,4 @@ %%) % (_ _:: // extra symbols (mostly in en_list) - ¶ par@graf ¶¶ par@grafs diff --git a/dictsource/eo_list b/dictsource/eo_list index 4a2f5dd6..39735e56 100644 --- a/dictsource/eo_list +++ b/dictsource/eo_list @@ -1,6 +1,5 @@ // This file is UTF-8 encoded - // Numbers _0 nul _1 'unu diff --git a/dictsource/es_list b/dictsource/es_list index d459e9fa..53d5a646 100644 --- a/dictsource/es_list +++ b/dictsource/es_list @@ -15,27 +15,27 @@ _; p,untoik'oma _: d,Osp'untOs _! TE*R'aRaDmi**aTj'On _? TE*R'aRintE*R,oQaTj'On -_¡ aB@-*'iRaDmi**aTj'On -_¿ aB@-*'iRintE*R,oQaTj'On +_¡ aB**'iRaDmi**aTj'On +_¿ aB**'iRintE*R,oQaTj'On _= iQw'al _< men'ORke _> maJ^'ORke -_' apOst@-*'ofo +_' apOst**'ofo _" kom'iJ^as _+ s'iQnOdesum'aR _$ dolar _# almoaD'iJ^a _* aste*'isko _- gJ^On -__ suB@-*aJ^'aDo +__ suB**aJ^'aDo _/ ba*Ra _\ b'a*RaimbERt'iDa -_` aT'EntOg@-*'aBe -_( ,aB@-*epa**'Entesis +_` aT'EntOg**'aBe +_( ,aB**epa**'Entesis _) Tj,E*Rapa**'Entesis -_[ ,aB@-*ekORtS'ete +_[ ,aB**ekORtS'ete _] Tj,E*RakORtS'ete -_{ ,aB@-*eJ^'aBe +_{ ,aB**eJ^'aBe _} Tj,E*RaJ^'aBe _« kom'iJ^as||iTkJ^'ERDas _» kom'iJ^as||dE**'EtSas @@ -47,7 +47,7 @@ _» kom'iJ^as||dE**'EtSas @ a*R'oBa / ba*Ra © kopi*R'aIt -£ liB@-*as +£ liB**as ¶ p'a*Rafo § sEkTj'On @@ -56,8 +56,8 @@ _» kom'iJ^as||dE**'EtSas _0 Te*o _1 'uno _2 d'Os -_3 t@-*'es -_4 kw'at@-*o +_3 t**'es +_4 kw'at**o _5 T'inko _6 s'eIs _7 sj'ete @@ -66,12 +66,12 @@ _9 nw'eve _1X dj'ET _11 'OnTe _12 d'oTe -_13 t@-*'eTe +_13 t**'eTe _14 kat'ORTe _15 k'inTe _20 v'eInte _2X v'eInt -_3X t@-*'eInta +_3X t**'eInta _4X kwa*'Enta _5X Tinkw'Enta _6X sEs'Enta @@ -339,8 +339,8 @@ _o o o o $atend v uve x Ekis -_y ,ig@-*'iEQa -y ,ig@-*'iEQa $atend +_y ,ig**'iEQa +y ,ig**'iEQa $atend ch tSe ll Ejje á 'a||aTEntw'aDa diff --git a/dictsource/es_rules b/dictsource/es_rules index 470f133f..719a13b8 100644 --- a/dictsource/es_rules +++ b/dictsource/es_rules @@ -6,6 +6,7 @@ // ?2 Latin America .L01 j w l r d g n m +.L02 b d g n m // change [s] to [z] before these .group a _) a (_ a @@ -38,6 +39,7 @@ _) d (_ de d D _) d d + l) d d m) d d n) d d @@ -142,7 +144,7 @@ r R _) r R A) r (A ** - C) r (A @-* + C) r (A ** rr *R @@ -150,6 +152,8 @@ _) s (_ Ese s s &) s (_S1 s + s (L02 z + s (gY s .group t @@ -199,7 +203,7 @@ .group y - _) y (_ ,ig@-*'iEQa + _) y (_ ,ig**'iEQa y i _) y J _m) y J diff --git a/dictsource/fr_list b/dictsource/fr_list index 16aad238..b5d64811 100755 --- a/dictsource/fr_list +++ b/dictsource/fr_list @@ -65,7 +65,7 @@ _y i:gR'Ek //_cap k,ap@-t@L _?A lEt@ -_?? sE~b'OL +_?? sE~b'Oll _#9 tabylasjO~ _#32 Espas @@ -229,9 +229,11 @@ prof $dot // articles le $u $nounf +le $u $verb $verbextend la $u $nounf +la $u $verb $verbextend les lez2 $u $nounf -?2 les lez2 $u $nounf +les lez2 $u $verb $verbextend un $u $nounf une $u $nounf @@ -278,7 +280,15 @@ lui $u $verbf ce $u $nounf cette $u $nounf -ces sEz2 $u $nounf +ces sez2 $u $nounf +ceci $verbf +cela $verbf +(celle ci) sEl||si $verbf +(celle là) sEl||la $verbf +(ceux ci) sY||si $verbf +(ceux là) sY||la $verbf +(celles ci) sEl||si $verbf +(celles là) sEl||la $verbf // possessives ma $u+ $nounf @@ -292,16 +302,21 @@ son $u+ $nounf ses sez2 $u+ $nounf notre $u+ $nounf votre $u+ $nounf -leur $u+ +leur $u+ $nounf +leur $u+ $verb $verbextend +(la leur) la||l@r $u+ $verbf +(le leur) l@||l@r $u+ $verbf nos $u+ $nounf vos $u+ $nounf -leurs $u+ +leurs $u+ $nounf +leurs $u+ $verb $verbextend +(les leur) le||l@r $u+ $verbf +(les leurs) le||l@r $u+ $verbf // prepositions de $u $nounf du $u+ $nounf des dez2 $u $nounf -?2 des dez2 $u+ $nounf à $u @@ -321,7 +336,7 @@ avec $u sans $u sous $u entre $u $brk -contre $u $brk +contre $u durant $brk @@ -385,8 +400,7 @@ couvent k'uvt2 $verb dessus d@sy dessous d@su divers divErz2 -parent paR'A~ -parent p'art2 $verb +hareng _!arA~ pastis pastis poing pwE~ ressent r@s'A~t2 @@ -438,6 +452,7 @@ sus sy $verb vénus venys +gens ZA~ mens mA~z2 sens sA~s sens sA~z2 $verb @@ -636,4 +651,3 @@ vincent vE~sA~ - diff --git a/dictsource/fr_rules b/dictsource/fr_rules index 0297f7f5..f80c0453 100755 --- a/dictsource/fr_rules +++ b/dictsource/fr_rules @@ -4,7 +4,7 @@ // 2006-11-18 Gilles Casse // -// Updated: 2008-02-24 Michel Such +// Updated: 2008-02-26 Michel Such // // * The rules are based on Cicero TTS. // Y @@ -140,6 +140,10 @@ _noeu) d (_ // noeud r) d (_ // lourd placard d d // don bled + _expé) dien (t_ djA~ // expédient + V_expé) dien (t_ di // expédient + _ingré) dien (t_ djA~ // ingrédient + dien (t_ di // étudient (verbe) // group d: English section day (_ _^_en @@ -176,7 +180,6 @@ C) en (d_ A~ // comprend dépend od) en (dr E~ // rhododendron C) en (ds_ A~ - cipi) en (C A~ // récipient qu) en (d_ A~ qu) en (ds_ A~ @@ -194,7 +197,9 @@ _C) en (t_ A~ // cent vent lent dent cc) en (t_ A~ // accent Asc) en (t_ A~ // luminescent - dol) en (t_ A~ // dolent + _dol) en (t_ A~ // dolent + ol) en (t_ A~ // somnolent, violent + Vol) en (t_ // somnolent, violent imCoC) en (t_ A~ // impotent inCoC) en (t_ A~ // innocent, indolent @@ -210,13 +215,21 @@ oémin) en (t_ A~ // proéminent jac) en (t_ A~ // sous-jacent, adjacent _lat) en (t_ A~ // latent - lig) en (t_ A~ // intelligent + + @@Cig) en (t_ A~ // intransigent, intelligent + _dilig) en (t_ A~ // diligent + XACig) en (t_ A~ // dirigent, exigent + VXACig) en (t_ // dirigent, exigent (verbe) + flig) en (t_ A~ // affligent + Vflig) en (t_ // infligent (verbe) + Xig) en (t_ // figent, pigent + oblig) en (t_ A~ // obligent, d‚sobligent + Voblig) en (t_ // obligent (verbe) + man) en (t_ A~ // permanent - ndig) en (t_ A~ // indigent + @@ing) en (t_ A~ // astreingent, contingentindigent _pat) en (t_ A~ // patent rmam) en (t_ A~ // firmament - xig) en (t_ A~ // exigent - Vxig) en (t_ // exigent éCerg) en (t_ A~ // détergent V_éCerg) en (t_ // émergent verg) en (t_ A~ // convergent, divergent @@ -234,21 +247,26 @@ Atim) en (t_ A~ // bâtiment _cim) en (t_ A~ // ciment _pim) en (t_ A~ // piment + + ertin) en (t_ A~ // pertinent, impertinent + ontin) en (t_ A~ // continent, incontinent erm) en (t_ A~ // ferment, serment Vferm) en (t_ // ferment, referment (verbe) Arp) en (t_ A~ // arpent, serpent CArr) en (t_ A~ // conncurrent, torrent + _appar) en (t_ A~ // apparent + spar) en (t_ A~ // transparent + _par) en (t_ A~ // parent + V_par) en (t_ // parent (verbe) + _var) en (t_ A~ // varent mitt) en (t_ A~ // intermittent énit) en (t_ A~ // pénitent tourm) en (t_ A~ // tourment - - ti) en (t_ E~ // retient - ati) en (t_ A~ // patient - oti) en (t_ A~ // quotient - - vi) en (t_ E~ + Cflu) en (t_ A~ // affluent, confluent + VCflu) en (t_ // refluent, influent (verbe) al) en (t_ A~ // talent équivalent + Vival) en (t_ // équivalent (verbe) xcell) en (t_ A~ // excellent nn) en (t_ t2 // prennent, viennent, sonnent @@ -281,7 +299,7 @@ en (t_ // étaient mangent Ci) en (_ E~ // viendra - Ci) en (C E~ // tien + Ci) en (C E~ // viendra Ci) en (c A~ // science @@ -435,11 +453,11 @@ ed (_ _^_en _) edit _^_en ee _^_en // meeting - eing _^_en // being, goeing + eing (_ _^_en // being, boeing eive _^_en // receive ej _^_en eld (_ _^_en // field - enter (_ _^_en // enter, center + _) enter (_ _^_en // enter _) enhan _^_en ack) et (_ _^_en // racket, packet ock) et (_ _^_en // rocket, pocket @@ -605,6 +623,15 @@ _) half _^_en i i // cri ie (ment i // remerciement balbutiement + C) ien (t_ i + dév) ien (t_ i + t) ien (t_ jE~ // vient + v) ien (t_ jE~ // tient + at) ien (t_ jA~ // patient + cip) ien (C jA~ // récipient + vén) ien (C jA~ // inconvénient + ot) ien (t_ jA~ // quotient + i (es_ i // parties i (e_ i i (A j // fermier portier patio renier @@ -688,7 +715,7 @@ _) half _^_en mm m // pomme // group m: English section - mail (A _^_en // mailer + _) mail (_ _^_en // mailer mov (A _^_en // move, movy @@ -971,9 +998,9 @@ C) te (_ t@- // patte a) t (ia s // spatial en) t (ia s // confidentialit� - u) t (ia s // balbutiait + bu) t (iA s // balbutiait r) t (ia s // impartial - i) t (ia s // initia + ini) t (i s // initier p) t (ia s // nuptial an) t (iat s // transsubstantiation @@ -993,8 +1020,9 @@ C) te (_ t@- // patte pa) t (ien s o) t (ien s - Cu) t (ie_ s // minutie - Cu) t (ies_ s + Cu) t (ieX s // minutie + ni) tien (t_ si + bu) tien (t_ si cra) t (ie_ s // démocratie cra) t (ies_ s diff --git a/dictsource/grc_rules b/dictsource/grc_rules index 8c6c4444..db45ae44 100644 --- a/dictsource/grc_rules +++ b/dictsource/grc_rules @@ -8,6 +8,7 @@ // Replace Latin characters by same-shape Greek characters .replace +′ ' a α // Latin->Greek o ο v ν @@ -26,6 +27,32 @@ T Τ Y Υ X Χ +// replace Latin characters by Greek equivalents +th θ +ph φ +kh χ +ps ψ +b β +g γ +d δ +e ε +z ζ +q η // (long e; not standard transliteration but may be easier to type than η) +i ι +k κ +l λ +m μ +n ν +x ξ +p π +r ρ +s σ +t τ +u υ +y υ +w ω // (long o; not standard transliteration but may be easier to type + + // alpha ά ὰ // tonos ά ὰ // oxia @@ -161,184 +188,175 @@ X Χ .group α - α a - αι aI - αὶ 'aI - αυ aU - αὺ 'aU - αhι haI - αhὶ 'haI - αhυ haU - αhὺ 'haU + α a + αι aI + αὶ 'aI + αυ aU + αὺ 'aU + αhι haI + αhὶ 'haI + αhυ haU + αhὺ 'haU .group β - β b + β b .group γ - γ g - γγ Ng + γ g + γγ Ng .group δ - δ d + δ d .group ε - ε e - ει e: - εὶ 'e: - ευ eU - εὺ 'eU - εhι he: - εhὶ 'he: - εhυ heU - εhὺ 'heU + ε e + ει e: + εὶ 'e: + ευ eU + εὺ 'eU + εhι he: + εhὶ 'he: + εhυ heU + εhὺ 'heU .group ζ - ζ z + ζ z .group η - η E: - ηι EI: - ηὶ 'EI: - ηυ EU: - ηὺ 'EU: - ηhι hEI: - ηhὶ 'hEI: - ηhυ hEU: - ηhὺ 'hEU: + η E: + ηι EI: + ηὶ 'EI: + ηυ EU: + ηὺ 'EU: + ηhι hEI: + ηhὶ 'hEI: + ηhυ hEU: + ηhὺ 'hEU: .group θ - θ T + θ T .group ι - ι i + ι i .group ϊ - ϊ i + ϊ i .group κ - κ k + κ k .group λ - λ l + λ l .group μ - μ m + μ m .group ν - ν n + ν n .group ξ - ξ ks + ξ ks .group ο - ο o - οι oI - οὶ 'oI - ου u: - οὺ 'u: - οhι hoI - οhὶ 'hoI - οhυ hu: - οhὺ 'hu: + ο o + οι oI + οὶ 'oI + ου u: + οὺ 'u: + οhι hoI + οhὶ 'hoI + οhυ hu: + οhὺ 'hu: .group π - π p + π p .group ρ - ρ R + ρ R .group ς - ς s + ς s .group σ - σ s + σ s .group τ - τ t + τ t .group υ - υ y - υι yI - υὶ 'yI - υhι hyI - υhὶ 'hyI + υ y + υι yI + υὶ 'yI + υhι hyI + υhὶ 'hyI .group ϋ - ϋ y - ϋι yI - ϋὶ 'yI - ϋhι hyI - ϋhὶ 'hyI + ϋ y + ϋι yI + ϋὶ 'yI + ϋhι hyI + ϋhὶ 'hyI .group φ - φ f + φ f .group χ - χ x + χ x .group ψ - ψ ps + ψ ps .group ω - ω O: - ωι OI: - ωὶ 'OI: - ωυ OU: - ωὺ 'OU: - ωhι hOI: - ωhὶ 'hOI: - ωhυ hOU: - ωhὺ 'hOU: + ω O: + ωι OI: + ωὶ 'OI: + ωυ OU: + ωὺ 'OU: + ωhι hOI: + ωhὶ 'hOI: + ωhυ hOU: + ωhὺ 'hOU: .group h // dasia (rough breathing) - h h + h h .group - ὰ 'a - ᾳ aI: - ᾲ 'aI: - ὲ 'e - ὴ 'E: - ῃ EI: - ῂ 'EI: - ὶ 'i - ῒ 'i - ὸ 'o - ὺ 'y - ῢ 'y - ὼ 'O: - ῳ OI: - ῲ 'OI: - - - - - - - - - - + ὰ 'a + ᾳ aI: + ᾲ 'aI: + ὲ 'e + ὴ 'E: + ῃ EI: + ῂ 'EI: + ὶ 'i + ῒ 'i + ὸ 'o + ὺ 'y + ῢ 'y + ὼ 'O: + ῳ OI: + ῲ 'OI: + ' = // apostrophe used as tonos, stress on previous syllable diff --git a/dictsource/pt_list b/dictsource/pt_list index 2f5b5e8c..f5981cd7 100755 --- a/dictsource/pt_list +++ b/dictsource/pt_list @@ -34,8 +34,8 @@ x Sis# _cap maI'uskulU -_?A l'etR& -_?? s'imbolU +_?A l'etR&_ +_?? s'imbolU_ _. p'oNtU _! ,eskl&mas'&U~ diff --git a/dictsource/ta_rules b/dictsource/ta_rules index c010790c..0d1e2867 100644 --- a/dictsource/ta_rules +++ b/dictsource/ta_rules @@ -55,7 +55,7 @@ க (் g ்) க ga ்) க (B g - _) க kV + _) க ka _) க (B k க்க k:a க்க (B k: @@ -78,7 +78,7 @@ ட d.a ட (B d. - _) ட t.V + _) ட t.a _) ட (B t. ட்ட t.a ட்ட (B t. @@ -88,7 +88,7 @@ த da த (B d - _) த tV + _) த ta _) த (B t த்த t:a த்த (B t: @@ -101,7 +101,7 @@ ப ba ப (B b - _) ப pV + _) ப pa _) ப (B p ப்ப p:a ப்ப (B p: diff --git a/dictsource/zh_rules b/dictsource/zh_rules index 34853fa6..6f84d45d 100644 --- a/dictsource/zh_rules +++ b/dictsource/zh_rules @@ -82,7 +82,7 @@ language). .group c c tsh - ch ts.h + ch (+ ts.h @) c (K _^_EN .group d @@ -150,6 +150,7 @@ language). .group l l l @) l (K _^_EN + @) l (v l .group m m m @@ -188,7 +189,7 @@ language). .group s s s - sh s. + sh (+ s. @) s (K _^_EN .group t @@ -239,7 +240,7 @@ language). n) ve yE //üe .group w -// @) w (K _^_EN + @) w (K _^_EN wa wA //wa wan wang wai wai wa1i wai55 @@ -270,7 +271,7 @@ language). .group z z ts - zh ts. + zh (+ ts. @) z (K _^_EN //tone number diff --git a/phsource/compile_report b/phsource/compile_report index 7ab510f5..3b30fc7a 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,55 +1,55 @@ 50 phoneme tables new total - base 99 99 - base2 24 118 - en 53 147 - en_n 30 147 - en_us 34 147 - en_sc 39 149 - en_rp 34 147 - en_wm 30 147 - en_wi 30 147 - af 38 131 - cy 29 125 - de 33 126 - eo 13 111 - jbo 4 112 - fi 40 130 - fr 44 125 - fr_ca 11 125 - hi 51 136 - ta 16 139 - hu 23 115 - nl 28 122 - pl 15 110 - sk 29 128 - cs 6 128 - hr 20 133 - mk 3 134 - sr 14 133 - ru 38 129 - it 17 121 - la 21 117 - es 9 119 - es_la 1 119 - pt 27 134 - pt_pt 20 134 - ro 36 142 - el 8 118 - grc 12 123 - sv 25 121 - no 28 125 - is 32 124 - vi 42 137 - zhy 40 132 - zh 65 149 - sw 14 108 - th 50 142 - id 14 120 - tr 18 123 - ku 13 120 - ja 7 104 - rw 12 123 + base 98 98 + base2 24 117 + en 51 144 + en_n 30 144 + en_us 34 144 + en_sc 39 146 + en_rp 34 144 + en_wm 30 144 + en_wi 30 144 + af 38 130 + cy 29 124 + de 33 125 + eo 13 110 + jbo 4 111 + fi 40 129 + fr 44 124 + fr_ca 11 124 + hi 51 135 + ta 16 138 + hu 23 114 + nl 28 121 + pl 15 109 + sk 29 127 + cs 6 127 + hr 20 132 + mk 3 133 + sr 14 132 + ru 38 128 + it 17 120 + la 21 116 + es 9 118 + es_la 1 118 + pt 27 133 + pt_pt 20 133 + ro 36 141 + el 8 117 + grc 12 122 + sv 25 120 + no 28 124 + is 32 123 + vi 42 136 + zhy 40 131 + zh 65 148 + sw 14 107 + th 50 141 + id 14 119 + tr 18 122 + ku 13 119 + ja 7 103 + rw 12 122 Data file Used by b/b [b] base @@ -501,6 +501,7 @@ r3/rx [*] base r3/rz_cs [R^] sk [R^/] sk r3/@tap [**] base +r3/@tap2 [**] base r/r [r] base [r-] base [r] en_sc @@ -1024,7 +1025,6 @@ vdiph/@u_3 [@U] ro vdiph/@u_en [oU] en [@U] id vdiph/ui [uI] base2 - [uI] en [uI] eo [ui] fi [uI] vi @@ -1083,8 +1083,7 @@ vnasal/oo_n2 [O~] hi vnasal/u_n [u~] hi [u~] pt [u] zh -vnasal/W_n [W~] en - [E~] fr +vnasal/W_n [E~] fr [W~] fr voc/bh [B] base voc/dh [D] base @@ -1455,8 +1454,7 @@ vowel/i_5 [i:] en_sc vowel/i#_5 [y] pt_pt [i/] pt_pt [y] ro -vowel/i_6 [i:] en_us - [i] ta +vowel/i_6 [i] ta [i] hr [i] id [i] tr @@ -1464,6 +1462,7 @@ vowel/i_6 [i:] en_us vowel/i#_6 [i.] zh vowel/i#_7 [i[] zh vowel/i_en [i:] en + [i:] en_us [i:] fr [i] vi vowel/i_fnt [i:] en_wi diff --git a/phsource/n^/n^@ b/phsource/n^/n^@ index 33737b1c0ca0ced7c42f0c8949bc4ca41f1bb110..59ca9722e9298ddc20954839b720394f7426e0f5 100644 GIT binary patch delta 21 bcmZn;ZVujXnw>Fo^BMNT%s^@a_h(rEVay1v delta 21 bcmZn;ZVujXnw>Fk^BMNT%s^@a_h(rEVk-!@ diff --git a/phsource/n^/n^a b/phsource/n^/n^a index 540a570070a1969178d0a738b440257db0fe9080..c66e6f110ceb42bb14d43fa8ad4c6f85c7e3322c 100644 GIT binary patch delta 21 bcmX>ebv$YVI}2mxW)7Ca%s}c4d$lS6SbGP3 delta 21 bcmX>ebv$YVI}2mpW)7Ca%s}c4d$lS6SlS1N diff --git a/phsource/n^/n^e b/phsource/n^/n^e index 30118f2eb6a59b67193b97d4090a95593cd88fdf..9eb972473f8bd4cb73219d282f2d5b5701c84a19 100644 GIT binary patch delta 30 lcmZ47&$zgsal>hL#>~xU*bg%UsR`WcnHgC(JMbr4006h&3akJC delta 30 lcmZ47&$zgsal>hL#=OmE*bg%UsR`WcnHgC&JMbr4006jt3bghL#>~xU*bg%UsR`WQV*z>V3Hty5 delta 23 dcmZp_%-DXJal>hL#=OmE*bg%UsR`WQV*z?f3IzZF diff --git a/phsource/n^/n^u b/phsource/n^/n^u index 59b57d4c5113a52eccb74e8764bfff1d80bf71e3..e4a261b9c616981f3f0a3e134b31b2656c5acd61 100644 GIT binary patch delta 14 VcmX?~c|LQ)X?DiU&1cw|bpbY;1`_}P delta 14 VcmX?~c|LQ)X?DiE&1cw|bpbZH1{eSU diff --git a/phsource/ph_english b/phsource/ph_english index 433e5dad..ecb1c71a 100644 --- a/phsource/ph_english +++ b/phsource/ph_english @@ -292,7 +292,7 @@ endphoneme phoneme e@ vowel starttype (e) endtype (@) - length 220 + length 230 formants vowel/ee_1 linkout r- endphoneme @@ -361,13 +361,6 @@ formants vdiph/eu endphoneme -phoneme uI - vowel starttype (u) endtype (i) - length 240 - formants vdiph/ui -endphoneme - - phoneme IR // used for "ir" when [3:] is split (Scottish) vowel starttype (@) endtype (@) length 190 @@ -405,13 +398,6 @@ phoneme O~ endphoneme -phoneme W~ - vowel starttype (@) endtype (@) - length 260 - formants vnasal/W_n -endphoneme - - phoneme y: vowel starttype (u) endtype (u) length 220 diff --git a/phsource/ph_english_us b/phsource/ph_english_us index 1d4d8457..e9f25b67 100644 --- a/phsource/ph_english_us +++ b/phsource/ph_english_us @@ -136,7 +136,7 @@ endphoneme phoneme i: vowel starttype (i) endtype (i) length 170 - formants vowel/i_6 + formants vowel/i_en linkout ; endphoneme diff --git a/phsource/phonemes b/phsource/phonemes index f6ef5ca7..066889cc 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -31,7 +31,6 @@ phonemenumber 24 _:: // long pause phonemenumber 25 t# // reduced version of [t] phonemenumber 26 '! // stress - emphasized phonemenumber 27 _;_ // clause pause -phonemenumber 28 _^^ // Change language + phoneme table number // The base phoneme table contains the utility phonemes, the consonants, // and a schwa. The vowels are defined in the language specific phoneme @@ -150,13 +149,6 @@ phoneme _^_ // Change dictionary (followed by language-code in ascii lengthmod 1 endphoneme -phoneme _^^ // Change phoneme table (followed by phoneme table number) - pause - starttype _ endtype _ - length 1 - lengthmod 1 -endphoneme - phoneme _X1 // a language specific action pause starttype _ endtype _ @@ -605,9 +597,7 @@ phoneme ** // TEST flap vowelout f1=3 f2=1600 -300 300 f3=-300 80 rms=35 len=15 vowelin f1=2 f2=1600 -300 300 f3=-100 80 len=20 formants r3/@tap -// vowelin f1=3 f2=1600 -300 300 f3=-300 80 -// before (i) r3/@tap_i+r3/rx -// before (e) r3/@tap_i+r3/rx + after (e) r3/@tap2 endphoneme diff --git a/phsource/r3/@tap_i b/phsource/r3/@tap2 similarity index 74% rename from phsource/r3/@tap_i rename to phsource/r3/@tap2 index 6f6ec4005e97b6cb7d00b7e83ee88c8b71178916..15775662f8b8cab40bc46a3318cf371425c3b7e1 100644 GIT binary patch delta 270 zcmca6eO1~ZIKb68B-k~Om4Si5p(L@uh?OA)$V3JXtWTj_2d4iM4UIJ%*cb$5m>w{K zM2~Pfa6e##utT^RI3eus|2=paI5zgMF@h8eArvzpE9Qb}1S;m7yo>QE6Z4753z_5? znI|7$Qjj^q$-wju2n~6^Fg)R5U@&1eVXow7W3u6AVA%YJsht_9u7wSu&V+X}TwM&m lEF)Om0XDEY4=x2sn0c|hyFuz0LFSq8YctwxZsZDO1^}T=I>P_} delta 272 zcmcaAeN9>@IKb68B-k~Oje&u|p(L>&K69d=9OM0o2F4l-Ss6rRm>w_!Wf)XA9k?Gb zLfCtF9zfaO|CjIyaBl2oV+1M|kU%J&!HZCA!3SfP@O|K#yp!=M6HCwJ1x#{`jFa~> zDae#?GBCXZLPOp!3?94;j3&$`%$59XOey>fOq+i*wKLl?DljWBUt!c^xWUN48N?jK z%+2n@;K0Vf2GXX)RmG41HNu22*^ob%5ZnbEqi2csetp#&+SwM`L98rxV(s!A=fCY8CUC{ndWP_ZSY zDY2F&Qjvxth^?W5i&~NfsYGd+scB~V|L1(4$#e5wym^xMT{vgftgrxBIz2eEa7&Rt z82~UrN)RCHCV+rsSesvz|2ol0f@Sa(-oSQ9gYWPQieVVIuncd(Y&z_;#8yYgM)TsE zXs2Z5S1TpBiagIe58T`29?I>~9s9zKkr)4}J41FC#9c$XkMVxO4>PyEa5pqZ8n`RVYK<>OC%12+y$x9*n<@v_+=H3gbf(G{!njNS^CPp0L}t zl3d5#*;XxVHkl6DnR>KtbB;NabqEi5 zq~6OPYOD3m%2icjIZWqmR7xQ}%4slMJe3F3S5;umQ30#cx~7WpJ>8*ITu!Zer>>_( zSd2Sl9p2>qyb!BJE(&}A6X7N*j*oRNRUu?jB_)`2-S5<{< z##^FAtQY(66dvaB&+Xy09IHmHRP8Dtz4ETOCK@qITowf)AbMgA z&!Y}{Xcn6^9e0Foa>CATr@`s3XE=Vnz&xZUR6_G9PCa=Lr*JQD!#du}<($ubxR!s= zD7t67R8B2sw=Q>H*(LTQ`=>qGS>bHdF%zc`R6%>m$0PUx*U-Sk|JAxx*E=WeHTEMr mLkAOEQxg6>NQV@fN=L}gk6DOJ)n7KjW0Oo-(1b1w-r>gXf8dnu+wb=x5qD%bbIigMsK>;MuO5LTesORRKUS^tAA7$}O zkuQZ@W8JcjSS_N5wUfbhIDu|zq~9>Y6Qx_GSw2}RA6PloJz>)goWwkOYOZLn-VR$> z9#0i6I7||9`Enk`Ja82nX%-IaK|N%)(pgAiE||cJmuKmrScLK=>(Om*ss~AXo6c zyr1`SH~YYnp_Lv(4Li&`#S(df2gD0Ud}zQLlv(nZ9239!6mR6o{2lA#n|M9n&-OtH zj$j-fGHyMhqV#7qp<2`#m8y$Xm-6T`{En9}6FV`6=F)t6P8*?$PS9yOPY$|4tAgi! z=9{U-1RT)aYTB-|)9t%kNN57`PrV dK4ARJBgw?W%fJp|GxJ}ZtSBqKnN78h2LSJxBY6M- diff --git a/phsource/vwl_en_us/a b/phsource/vwl_en_us/a index 1f5cf20ae3dfa2c618aecb92a688eaecd47b7400..86cef1d1af4b74143bce4b6e9815432323f96da1 100644 GIT binary patch delta 248 zcmca>aMwT}IKb68B-k~Ok%56Bk&Pi`qkt_-Pymp_z!1U6z_WoxhUq<%KH~}|2L1@9 z3rrELQy3<&F^C2+-(vFOlwmx_`GNld;{(RiJPgbScx8A%?0tNSjNAAvI6-WXISR6N z%$w)4>|zc~0rEJQVCMc{GKHHP$T|aVt~=)+2AH{bd44m&%-zB#g=DT72hiNjt2hob t%QA3-ocV*vig5$fnO>~Z8FbhfgiM(CZ0_P=Wnuro%D@NWOcOZH4gl`DKYIWG delta 248 zcmca>aMwT}IKb68B-k~Ok%56Bk&Pi~qkt_-PzsR4z!1QAfMWxT4AXlieZ~b$47?Fc z7nmYgr!bshix32|n7lY;7>{sX;CaCKfbldB1M>mi4V)nMK0Zapo%|8(AU4Px1=$9s z>7yF$cy2c^pg;j14>>bAK?Ig3J{JnH$JD188o6ILKUg&OZ!CI2!~(`tS1mW;(#@ z!3$z<;ge$A!mq&vG1rVkL3YOGRUC(zWe;#cjI(0gz{J20GR}*2IztGXk1)`<&0RdK QEbJ_78vG#6G=byn00|94ga7~l diff --git a/phsource/vwl_en_us/er b/phsource/vwl_en_us/er index a3da4331c652de884b873af9b510cc43a4c7c89c..530c6e926dda259aea38d71d64d29b37b26e3f84 100644 GIT binary patch delta 245 zcmca-aL-^v2um^_;~GwX=5>tjOj8*om>PtInRu8o*={m?VEZmo%oM@2iBp>K4JU)} z1I7o8S9x|a#PBlkgV-W`b6G_A8Mr}g1_mFFT{3%_A#5|h3b|4y2%CXHL)m@vc9xaQ z^)QPZnWn)lieuXhw`eEl7Y3L`S9mtSEz05ZM6$>W$s%tKG>gENo|C*Ql`5O9kfn delta 245 zcmca-aL-^v2urd&BLi0w^EyU%rl|}nObjACOgv1PY&RKX*cXV_FhwwJ;*@55!+AjX z0pkP4t2{dyGI%}sL2MDexh(wr9^4={1A`C81DS)&5Vo0Lg~uN|nu4NK_V7 V%g{*F`ls!rYpi!;^L>tbegHuJLu~*6 diff --git a/phsource/vwl_en_us/ii b/phsource/vwl_en_us/ii index de744c3b305e9f57bd23a601b6c1d42e9aac9801..75726b43db190f511cb06b0674053bfacc7e271d 100644 GIT binary patch delta 351 zcmca-aL-_Zhu0hi28M%7PnZfAw=-xkGBB)UT*qj{5x}s9gMlHBDUYd%>ji@YHv_{1 z#s`ePylWT^@Iu%N`L!7<_#tct26v7L(iqMf&TuMbX&KC$^MOD}VMJWvS}6U-6G zjKy$A1aXAI9Z|-0814vL-kESmc<|pxa)gr}!Vzf}2uC=_!yKW=_euV;&SkSydt3Jt Oey(BrH{axF?085$TF#FsEG zVRYs2XIR0`ApDi_3u86cZjhmZc0fbzcxNzp@G=O1EGy%G&9H!Zy3H6{q#IbK5 0) || (p[wc_bytes-1] > ' ')) && !iswpunct(wc)) + if(iswalpha(wc)) { - // an unrecognised character in a word, indicate with clicks - match1.phonemes = str_unknown; - match1.points = 1; + if((any_alpha > 1) || (p[wc_bytes-1] > ' ')) + { + // an unrecognised character in a word, indicate with clicks + match1.phonemes = str_unknown; + match1.points = 1; + } + } + else + { + LookupLetter(wc, -1, ph_buf); + if(ph_buf[0]) + { + match1.phonemes = ph_buf; + match1.points = 1; + } } p += (wc_bytes-1); } diff --git a/src/numbers.cpp b/src/numbers.cpp index ffbcefe7..d514273b 100644 --- a/src/numbers.cpp +++ b/src/numbers.cpp @@ -45,6 +45,31 @@ void Translator::LookupLetter(unsigned int letter, int next_byte, char *ph_buf1) char ph_stress[2]; char ph_buf3[30]; + ph_buf1[0] = 0; + len = utf8_out(letter,&single_letter[2]); + single_letter[len+2] = ' '; + + if(next_byte == -1) + { + // speaking normal text, not individual characters + if(Lookup(&single_letter[2],ph_buf1) != 0) + return; + + single_letter[1] = '_'; + if(Lookup(&single_letter[1],ph_buf3) != 0) + return; // the character is specified as _* so ignore it when speaking normal text + + // check whether this character is specified for English + SetTranslator2("en"); + if(translator2->Lookup(&single_letter[2], ph_buf3) != 0) + { + // yes, switch to English and re-translate the word + sprintf(ph_buf1,"%c",phonSWITCH); + } + SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table + return; + } + if((letter <= 32) || iswspace(letter)) { // lookup space as _&32 etc. @@ -53,10 +78,6 @@ void Translator::LookupLetter(unsigned int letter, int next_byte, char *ph_buf1) return; } - - len = utf8_out(letter,&single_letter[2]); - single_letter[len+2] = ' '; - if(next_byte != ' ') next_byte = RULE_SPELLING; single_letter[3+len] = next_byte; // follow by space-space if the end of the word, or space-0x31 @@ -91,8 +112,8 @@ void Translator::LookupLetter(unsigned int letter, int next_byte, char *ph_buf1) -int Translator::TranslateLetter(char *word, char *phonemes, int control) -{//===================================================================== +int Translator::TranslateLetter(char *word, char *phonemes, int control, int word_length) +{//====================================================================================== // get pronunciation for an isolated letter // return number of bytes used by the letter // control 2=say-as glyphs, 3-say-as chars @@ -134,11 +155,17 @@ int Translator::TranslateLetter(char *word, char *phonemes, int control) return(0); } - if(ph_buf[0] == 0) + if((ph_buf[0] == 0) && (word_length == 1) && (translator_name != L('e','n'))) { -// ?? speak as English ?? - sprintf(phonemes,"%c",phonSWITCH); - return(0); + // speak as English, check whether there is a translation for this character + SetTranslator2("en"); + translator2->LookupLetter(letter, word[n_bytes], ph_buf); + SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table + if(ph_buf[0] != 0) + { + sprintf(phonemes,"%c",phonSWITCH); + return(0); + } } if(ph_buf[0] == 0) diff --git a/src/readclause.cpp b/src/readclause.cpp index 7f8f960f..a418cf7d 100644 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -63,11 +63,11 @@ static const char *punct_stop = ".:!?"; // pitch fall if followed by space static const char *punct_close = ")]}>;'\""; // always pitch fall unless followed by alnum // alter tone for announce punctuation or capitals -static const char *tone_punct_on = "\001+50R\001+10T"; // add reverberation, reduce low frequencies -static const char *tone_punct_off = "\001R\001T"; +static const char *tone_punct_on = "\0016T"; // add reverberation, lower pitch +static const char *tone_punct_off = "\001T"; // punctuations symbols that can end a clause -static const unsigned short punct_chars[] = {',','.','?','!',':',';', +const unsigned short punct_chars[] = {',','.','?','!',':',';', 0x2013, // en-dash 0x2014, // em-dash 0x2026, // elipsis @@ -477,22 +477,38 @@ static void UngetC(int c) } +const char *WordToString2(unsigned int word) +{//======================================== +// Convert a language mnemonic word into a string + int ix; + static char buf[5]; + char *p; -const char *Translator::LookupSpecial(const char *string) -{//====================================================== + p = buf; + for(ix=3; ix>=0; ix--) + { + if((*p = word >> (ix*8)) != 0) + p++; + } + *p = 0; + return(buf); +} + + +const char *Translator::LookupSpecial(const char *string, char* text_out) +{//====================================================================== unsigned int flags[2]; char phonemes[55]; char phonemes2[55]; - static char buf[60]; char *string1 = (char *)string; if(LookupDictList(&string1,phonemes,flags,0,NULL)) { SetWordStress(phonemes,flags[0],-1,0); DecodePhonemes(phonemes,phonemes2); - sprintf(buf,"[[%s]] ",phonemes2); + sprintf(text_out,"[[%s]]",phonemes2); option_phoneme_input = 1; - return(buf); + return(text_out); } return(NULL); } @@ -503,26 +519,78 @@ const char *Translator::LookupCharName(int c) // Find the phoneme string (in ascii) to speak the name of character c int ix; - const char *p; - static char buf[24]; + unsigned int flags[2]; + char single_letter[24]; + char phonemes[60]; + char phonemes2[60]; + char *lang_name = NULL; + char *string; + static char buf[60]; - buf[0] = '_'; - ix = utf8_out(c,&buf[1]); - buf[1+ix]=0; + buf[0] = 0; + flags[0] = 0; + flags[1] = 0; + single_letter[0] = 0; + single_letter[1] = '_'; + ix = utf8_out(c,&single_letter[2]); + single_letter[2+ix]=0; - if((p = LookupSpecial(buf)) == NULL) + string = &single_letter[1]; + if(LookupDictList(&string, phonemes, flags, 0, NULL) == 0) { - p = LookupSpecial(&buf[1]); + // try _* then * + string = &single_letter[2]; + if(LookupDictList(&string, phonemes, flags, 0, NULL) == 0) + { + // now try the rules + single_letter[1] = ' '; + TranslateRules(&single_letter[2], phonemes, sizeof(phonemes), NULL,0,0); + } } - if(p != NULL) - return(p); - if((p = LookupSpecial("_??")) == NULL) + if((phonemes[0] == 0) && (translator_name != L('e','n'))) { - p = "symbol"; + // not found, try English + SetTranslator2("en"); + string = &single_letter[1]; + single_letter[1] = '_'; + if(translator2->LookupDictList(&string, phonemes, flags, 0, NULL) == 0) + { + string = &single_letter[2]; + translator2->LookupDictList(&string, phonemes, flags, 0, NULL); + } + if(phonemes[0]) + { + lang_name = "en"; + } + else + { + SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table + } } - strcpy(buf,p); -// sprintf(buf,"%s%d ",p,c); + + if(phonemes[0]) + { + if(lang_name) + { + translator2->SetWordStress(phonemes,flags[0],-1,0); + DecodePhonemes(phonemes,phonemes2); + sprintf(buf,"[[_^_%s %s _^_%s]]","en",phonemes2,WordToString2(translator_name)); + SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table + } + else + { + SetWordStress(phonemes,flags[0],-1,0); + DecodePhonemes(phonemes,phonemes2); + sprintf(buf,"[[%s]] ",phonemes2); + } + } + else + { + strcpy(buf,"[[(X1)(X1)(X1)]]"); + } + + option_phoneme_input = 1; return(buf); } @@ -714,7 +782,9 @@ int Translator::AnnouncePunctuation(int c1, int c2, char *buf, int bufix) p = &buf[bufix]; if(punct_count==1) + { sprintf(p,"%s %s %s",tone_punct_on,punctname,tone_punct_off); + } else if(punct_count < 4) { @@ -1769,8 +1839,8 @@ int Translator::ReadClause(FILE *f_in, char *buf, unsigned short *charix, int n_ const char *p; wchar_t xml_buf[N_XML_BUF+1]; -#define N_XML_BUF2 12 - char buf2[N_XML_BUF2+2]; +#define N_XML_BUF2 20 + char xml_buf2[N_XML_BUF2+2]; // for & and & sequences static char ungot_string[N_XML_BUF2+4]; static int ungot_string_ix = -1; @@ -1859,26 +1929,26 @@ f_input = f_in; // for GetC etc c1 = c2; while(!Eof() && (iswalnum(c1) || (c1=='#')) && (n_xml_buf < N_XML_BUF2)) { - buf2[n_xml_buf++] = c1; + xml_buf2[n_xml_buf++] = c1; c1 = GetC(); } - buf2[n_xml_buf] = 0; + xml_buf2[n_xml_buf] = 0; c2 = GetC(); - sprintf(ungot_string,"%s%c%c",&buf2[0],c1,c2); + sprintf(ungot_string,"%s%c%c",&xml_buf2[0],c1,c2); if(c1 == ';') { - if(buf2[0] == '#') + if(xml_buf2[0] == '#') { // character code number - if(buf2[1] == 'x') - found = sscanf(&buf2[2],"%x",(unsigned int *)(&c1)); + if(xml_buf2[1] == 'x') + found = sscanf(&xml_buf2[2],"%x",(unsigned int *)(&c1)); else - found = sscanf(&buf2[1],"%d",&c1); + found = sscanf(&xml_buf2[1],"%d",&c1); } else { - if((found = LookupMnem(xml_char_mnemonics,buf2)) != -1) + if((found = LookupMnem(xml_char_mnemonics,xml_buf2)) != -1) { c1 = found; if(c2 == 0) @@ -2050,14 +2120,15 @@ f_input = f_in; // for GetC etc clause_upper_count++; if((option_capitals == 2) && !iswupper(cprev)) { - p = LookupSpecial("_cap"); - if(p != NULL) + char text_buf[40]; + char text_buf2[30]; + if(LookupSpecial("_cap",text_buf2) != NULL) { - sprintf(buf2,"%s%s%s",tone_punct_on,p,tone_punct_off); - j = strlen(buf2); + sprintf(text_buf,"%s%s%s",tone_punct_on,text_buf2,tone_punct_off); + j = strlen(text_buf); if((ix + j) < n_buf) { - strcpy(&buf[ix],buf2); + strcpy(&buf[ix],text_buf); ix += j; } } @@ -2186,11 +2257,14 @@ if(option_ssml) parag=1; if(speech_parameters[espeakSILENCE]==1) continue; + j = ix+1; + ix += utf8_out(c1,&buf[ix]); // buf[ix++] = c1; if(!iswspace(c1) && !IsBracket(c1)) { charix[ix] = count_characters - clause_start_char; + while(j < ix) + charix[j++] = 0xffff; // subsequent bytes of a multibyte character } - ix += utf8_out(c1,&buf[ix]); // buf[ix++] = c1; if(((ix > (n_buf-20)) && !IsAlpha(c1) && !iswdigit(c1)) || (ix >= (n_buf-2))) { diff --git a/src/synthdata.cpp b/src/synthdata.cpp index 2e74be2a..1dbfeff8 100755 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,7 +35,7 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.31.18 25.Feb.08"; +const char *version_string = "1.31.19 28.Feb.08"; const int version_phdata = 0x013105; int option_device_number = -1; diff --git a/src/synthesize.h b/src/synthesize.h index 73e918c2..922d81db 100755 --- a/src/synthesize.h +++ b/src/synthesize.h @@ -51,7 +51,7 @@ #define EMBED_A 3 // amplitude/volume #define EMBED_R 4 // pitch range/expression #define EMBED_H 5 // echo/reverberation -#define EMBED_T 6 // different tone +#define EMBED_T 6 // different tone for announcing punctuation #define EMBED_I 7 // sound icon #define EMBED_S2 8 // speed (used in synthesize) #define EMBED_Y 9 // say-as commands @@ -274,5 +274,6 @@ int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int int DoSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB *next_ph, int which, PHONEME_LIST *plist, int modulation); int PauseLength(int pause); +int LookupPhonemeTable(const char *name); void InitBreath(void); diff --git a/src/tr_english.cpp b/src/tr_english.cpp index 61fd0f58..75a1f2c6 100644 --- a/src/tr_english.cpp +++ b/src/tr_english.cpp @@ -111,7 +111,7 @@ int Translator_English::Unpronouncable(char *word) if(c == '\'') apostrophe = 1; else - if((c < 'a') || (c > 0x241)) + 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))) diff --git a/src/translate.cpp b/src/translate.cpp index 1a0ac100..c94cb4f3 100755 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -752,7 +752,7 @@ if((wmark > 0) && (wmark < 8)) while(*wordx != ' ') { - wordx += TranslateLetter(wordx, phonemes,spell_word); + wordx += TranslateLetter(wordx, phonemes,spell_word, word_length); posn++; if(phonemes[0] == phonSWITCH) { @@ -779,7 +779,7 @@ if((wmark > 0) && (wmark < 8)) // This word looks "unpronouncable", so speak letters individually until we // find a remainder that we can pronounce. emphasize_allcaps = 0; - wordx += TranslateLetter(wordx,phonemes,0); + wordx += TranslateLetter(wordx,phonemes,0, word_length); posn++; if(phonemes[0] == phonSWITCH) { @@ -825,12 +825,12 @@ if((wmark > 0) && (wmark < 8)) // characters not recognised, speak them individually utf8_in(&wc, wordx, 0); - if(!iswpunct(wc)) + if((word_length == 1) && IsAlpha(wc)) { posn = 0; while(*wordx != ' ') { - wordx += TranslateLetter(wordx, phonemes, 4); + wordx += TranslateLetter(wordx, phonemes, 4, word_length); posn++; if(phonemes[0] == phonSWITCH) { @@ -1278,9 +1278,12 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne int first_phoneme = 1; int source_ix; int len; + int ix; int sylimit; // max. number of syllables in a word to be combined with a preceding preposition const char *new_language; unsigned char bad_phoneme[4]; + int word_copy_len; + char word_copy[N_WORD_BYTES]; len = wtab->length; if(len > 31) len = 31; @@ -1355,11 +1358,42 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne if(word_flags & FLAG_PHONEMES) { // The input is in phoneme mnemonics, not language text - EncodePhonemes(word,word_phonemes,bad_phoneme); + int c1; + char lang_name[12]; + + if(memcmp(word,"_^_",3)==0) + { + // switch languages + word+=3; + for(ix=0;;) + { + c1 = *word++; + if((c1==' ') || (c1==0)) + break; + lang_name[ix++] = tolower(c1); + } + lang_name[ix] = 0; + + if((ix = LookupPhonemeTable(lang_name)) > 0) + { + SelectPhonemeTable(ix); + word_phonemes[0] = phonSWITCH; + word_phonemes[1] = ix; + word_phonemes[2] = 0; + } + } + else + { + EncodePhonemes(word,word_phonemes,bad_phoneme); + } flags = FLAG_FOUND; } else { + ix = 0; + while((word_copy[ix] = word[ix]) != ' ') ix++; + word_copy_len = ix; + flags = translator->TranslateWord(word, next_pause, wtab); if((flags & FLAG_ALT2_TRANS) && ((sylimit = langopts.param[LOPT_COMBINE_WORDS]) > 0)) @@ -1420,6 +1454,8 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne if(p[0] == phonSWITCH) { // this word uses a different language + memcpy(word, word_copy, word_copy_len); + new_language = (char *)(&p[1]); if(new_language[0]==0) new_language = "en"; @@ -1523,6 +1559,15 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne // Add the phonemes to the first stage phoneme list (ph_list2) ph = phoneme_tab[ph_code]; + + if(ph_code == phonSWITCH) + { + ph_list2[n_ph_list2].phcode = ph_code; + ph_list2[n_ph_list2].sourceix = 0; + ph_list2[n_ph_list2].synthflags = embedded_flag; + ph_list2[n_ph_list2++].tone_number = *p++; + } + else if(ph->type == phSTRESS) { // don't add stress phonemes codes to the list, but give their stress @@ -1924,8 +1969,14 @@ void *Translator::TranslateClause(FILE *f_text, const void *vp_input, int *tone_ for(j=0; charix[j]==0; j++); words[0].sourceix = charix[j]; - for(k=j; charix[k]!=0; k++); - words[0].length = k-j; + k = 0; + while(charix[j] != 0) + { + // count the number of characters (excluding multibyte continuation bytes) + if(charix[j++] != 0xffff) + k++; + } + words[0].length = k; while(!finished && (ix < (int)sizeof(sbuf))&& (n_ph_list2 < N_PHONEME_LIST-4)) { @@ -2327,10 +2378,16 @@ if((c == '/') && (langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(prev_ou words[word_count].start = ix; words[word_count].flags = 0; - for(j=source_index; charix[j] == 0; j++); + for(j=source_index; charix[j] == 0; j++); // skip blanks words[word_count].sourceix = charix[j]; - for(k=j; charix[k]!=0; k++); - words[word_count].length = k-j; + k = 0; + while(charix[j] != 0) + { + // count the number of characters (excluding multibyte continuation bytes) + if(charix[j++] != 0xffff) + k++; + } + words[word_count].length = k; word_flags = next_word_flags; next_word_flags = 0; diff --git a/src/translate.h b/src/translate.h index 84e9bb87..cbef4ca8 100755 --- a/src/translate.h +++ b/src/translate.h @@ -417,7 +417,7 @@ public: private: int TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int next_pause); - int TranslateLetter(char *letter, char *phonemes, int control); + int TranslateLetter(char *letter, char *phonemes, int control, int word_length); void SetSpellingStress(char *phonemes, int control, int n_chars); void WriteMnemonic(int *ix, int mnem); void MakePhonemeList(int post_pause, int new_sentence); @@ -427,7 +427,7 @@ private: int AnnouncePunctuation(int c1, int c2, char *buf, int ix); const char *LookupDict2(const char *word, const char *word2, char *phonetic, unsigned int *flags, int end_flags, WORD_TAB *wtab); - const char *LookupSpecial(const char *string); + const char *LookupSpecial(const char *string, char *text_out); const char *LookupCharName(int c); void LookupLetter(unsigned int letter, int next_byte, char *ph_buf); int LookupNum2(int value, int control, char *ph_out); @@ -539,6 +539,7 @@ extern char skip_marker[N_MARKER_LENGTH]; #define N_PUNCTLIST 60 extern wchar_t option_punctlist[N_PUNCTLIST]; // which punctuation characters to announce extern unsigned char punctuation_to_tone[INTONATION_TYPES][PUNCT_INTONATIONS]; +extern const unsigned short punct_chars[]; // punctuation chars fo end-of-clause extern int speech_parameters[]; diff --git a/src/wavegen.cpp b/src/wavegen.cpp index 50cdfdbd..1a91b769 100755 --- a/src/wavegen.cpp +++ b/src/wavegen.cpp @@ -144,7 +144,7 @@ int wcmdq_head=0; int wcmdq_tail=0; // pitch,speed, -int embedded_default[N_EMBEDDED_VALUES] = {0,50,170,100,50, 0,50, 0,170,0,0,0,0,0}; +int embedded_default[N_EMBEDDED_VALUES] = {0,50,170,100,50, 0,0, 0,170,0,0,0,0,0}; static int embedded_max[N_EMBEDDED_VALUES] = {0,0x7fff,360,300,99,99,99, 0,360,0,0,0,0,4}; #define N_CALLBACK_IX N_WAV_BUF-2 // adjust this delay to match display with the currently spoken word @@ -813,6 +813,12 @@ static void WavegenSetEcho(void) amp = embedded_value[EMBED_H]; delay = 130; } + if(embedded_value[EMBED_T] > 0) + { + // announcing punctuation + amp = embedded_value[EMBED_T] * 10; + delay = 130; + } if(delay == 0) amp = 0; @@ -1517,8 +1523,9 @@ void SetEmbedded(int control, int value) switch(command) { - case EMBED_P: case EMBED_T: + WavegenSetEcho(); // and drop through to case P + case EMBED_P: // adjust formants to give better results for a different voice pitch if((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE) pitch_value = MAX_PITCH_VALUE; @@ -1528,7 +1535,7 @@ void SetEmbedded(int control, int value) { wvoice->freq[ix] = (wvoice->freq2[ix] * factor)/256; } - factor = (embedded_value[EMBED_T] - 50)*2; + factor = embedded_value[EMBED_T]*3; wvoice->height[0] = (wvoice->height2[0] * (256 - factor*2))/256; wvoice->height[1] = (wvoice->height2[1] * (256 - factor))/256; break; @@ -1623,6 +1630,7 @@ if(option_log_frames) if((pitch_value = embedded_value[EMBED_P]) > MAX_PITCH_VALUE) pitch_value = MAX_PITCH_VALUE; + pitch_value -= embedded_value[EMBED_T]; // adjust tone for announcing punctuation if(pitch_value < 0) pitch_value = 0;