From 99e2976c8645e0ee5e58f0ae16e4f73d95547715 Mon Sep 17 00:00:00 2001 From: jonsd Date: Wed, 5 Mar 2008 13:29:41 +0000 Subject: [PATCH] [1.32] Fix: espeak --stdout, set a (large) data size. espeak --voices. Include mbrola voices only if a language is specified. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@156 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/cs_list | 4 + dictsource/cs_rules | 1 - dictsource/de_list | 3 + dictsource/dict_phonemes | 92 +++++---- dictsource/en_list | 70 +++++-- dictsource/en_rules | 4 +- dictsource/es_list | 2 +- dictsource/es_rules | 17 +- dictsource/fr_list | 6 +- dictsource/fr_rules | 7 +- dictsource/grc_rules | 93 +++++++++ dictsource/hbs_list | 8 +- dictsource/is_rules | 9 +- dictsource/nl_list | 23 +++ dictsource/pl_list | 40 +++- dictsource/pl_rules | 11 +- dictsource/pt_list | 175 +++++++++-------- dictsource/pt_rules | 7 +- dictsource/sk_list | 4 +- dictsource/sv_list | 27 +++ dictsource/sv_rules | 12 +- dictsource/ta_list | 45 +++++ dictsource/ta_rules | 22 ++- dictsource/tr_list | 49 +++++ docs/dictionary.html | 10 +- docs/languages.html | 51 +++-- docs/voices.html | 7 +- phsource/compile_report | 78 ++------ phsource/ph_english_us | 7 +- phsource/ph_portugal | 11 +- phsource/ph_pt_brazil | 2 +- phsource/ph_spanish | 1 - phsource/phonemes | 12 +- phsource/vowel/& | Bin 6237 -> 6237 bytes phsource/vowel/i# | Bin 5806 -> 5806 bytes phsource/vowel/ii | Bin 6237 -> 6238 bytes phsource/vwl_en_us/i_final3 | Bin 962 -> 0 bytes phsource/vwl_en_us/ii | Bin 6238 -> 6238 bytes platforms/windows/make_espeak.iss | 14 +- platforms/windows/make_espeakedit.iss | 6 +- src/compiledict.cpp | 20 +- src/dictionary.cpp | 85 +++++--- src/espeak.cpp | 8 +- src/intonation.cpp | 4 +- src/numbers.cpp | 266 +++++++++++++++++++++----- src/readclause.cpp | 2 +- src/speak.cpp | 2 + src/synthdata.cpp | 4 +- src/tr_languages.cpp | 10 +- src/translate.cpp | 54 ++++-- src/translate.h | 6 +- src/voices.cpp | 4 +- src/wave_pulse.cpp | 138 +++++++++---- 53 files changed, 1095 insertions(+), 438 deletions(-) delete mode 100644 phsource/vwl_en_us/i_final3 diff --git a/dictsource/cs_list b/dictsource/cs_list index bb8340d9..7e00cef9 100644 --- a/dictsource/cs_list +++ b/dictsource/cs_list @@ -48,6 +48,10 @@ y ipsilon _z zet ž Zet +ë $accent +ö $accent +ü $accent + _#9 t'ap _#32 m'ezeRa // space diff --git a/dictsource/cs_rules b/dictsource/cs_rules index 042f2cb2..aa4fb32d 100644 --- a/dictsource/cs_rules +++ b/dictsource/cs_rules @@ -625,7 +625,6 @@ _flegma) ti ti ž (_G Z .group - ä e ë e ĺ l- ö e: diff --git a/dictsource/de_list b/dictsource/de_list index 59624a3f..11f4adc8 100644 --- a/dictsource/de_list +++ b/dictsource/de_list @@ -43,6 +43,9 @@ _— g@d'ank@nSt@-*,IC _#9 t,abu:l'Ato:* _#32 l'e:*ts'aIC@n _?? zymb'o:l +_?A b'UxstA:b@ +_cap g@-*'o:s + // accent names _lig l'i:gat,u:* diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index c7dacb3b..7773bc46 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -72,10 +72,11 @@ aU@ E e@ eI I I2 i: i@ i@3 IR O O: o: O@ o@ OI oU O~ U u: U@ V VR -; b C d D dZ f g -h j k l m n N p -Q r r- s S t T t2 -tS v w x z Z +: ; ? b C d D dZ +f g h j k l m n +N n^ p Q r r- s S +t T t2 tS v w x z +Z Dictionary eo_dict @@ -93,8 +94,8 @@ o O oI u * ** : b B d D f g j J J^ k l m n -n^ p Q r R s t T -tS v v# w x z +N n^ p Q r R s t +T tS v v# w x z Dictionary fi_dict @@ -222,9 +223,9 @@ Z Dictionary sv_dict -8 @ a a2 A: E e: E: -I i: O o: U u- u: W -y y: Y: +8 @ a a2 A: E E- e: +E: I i: O o: U u- u: +W y y: Y: : ; b d f g h j k l m n N p R s @@ -264,11 +265,13 @@ tS v w z Dictionary ta_dict -a a: e E: i o o: u -u: +a a: e e: E: i i: o +o: U u u: V -: d dZ g j l m n -p r t t. +: b c C d d. dZ g +j k l l. m n N n. +n^ p r R s S s. t +t. tS v z Dictionary pt_dict @@ -303,11 +306,11 @@ Dictionary is_dict i I o O oU oU2 u W y y# Yy -* : ; b c C d D -f g h j J k l l# -m m# n N n# N# n^ n^# -p Q r R r# R2 s S -t T tl# v x z +* ** : ; b c C d +D f g h j J k l +l# m m# n N n# N# n^ +n^# p Q r R r# R2 s +S t T tl# v x z Dictionary la_dict @@ -357,13 +360,8 @@ l m n N p R s S t tS v w x z Z -Dictionary th_dict +Dictionary ja_dict -a a: e E: i i: o O -O: u y - -c d h k l m n N -p s t Dictionary hbs_dict @@ -389,31 +387,6 @@ r R s S t tS v w x z -Dictionary ja_dict - - - -Dictionary tr_dict - -a e E i I o O u -u# W y Y - -b c d dZ f g h j -J k l m n p r R -s S t tS v z Z - - -Dictionary ku_dict - -a e E eI eU i I o -u U y - -: b d dZ f g h j -k l m n p q r R -s S t tS v w x z -Z - - Dictionary rw_dict a e i o u @@ -422,3 +395,24 @@ a e i o u g h j J k l m n N n^ p q s S S; t tS v w x z + + +Dictionary tr_dict + +a e E i I o O u +U u# W y Y + +* b c d dZ f g h +j J k l m n p r +R s S t tS v z Z + + +Dictionary ku_dict + +a e E E# eI eU i I +o u U y + +: b c d dZ f g h +j J k l m n p q +r R s S t tS v w +x z Z diff --git a/dictsource/en_list b/dictsource/en_list index 8b2d7b12..c17a1750 100644 --- a/dictsource/en_list +++ b/dictsource/en_list @@ -50,18 +50,20 @@ z zEd // sounds are specified for these accented characters // use the $accent attribute here to force the use of the // accent table when speaking the name of the character. -_é $accent +à $accent $atend // this can be a word +ç $accent +é $accent ê $accent -_ä $accent -_ë $accent -_ï $accent -_ö $accent -_ü $accent -_č $accent -_š $accent -_ş $accent -_ž $accent -_ñ $accent +ä $accent +ë $accent +ï $accent +ö $accent +ü $accent +č $accent +š $accent +ş $accent +ž $accent +ñ $accent // accent names _lig l,Iga2tS@ @@ -80,10 +82,18 @@ _rng r'INg _stk str'oUk _tld t'Ild@ +_smc sm'O:lk,ap +_rev rI2v'3:sd +_tur t'3:nd +_bar _b'A@ +_rfx r'Etr@flEks +_crl k'3:l +_hok h'Uk + // character names _cap k,ap@-t@L -_?A lEt3 +_?A l,Et3 _?? sImb@L _#9 tab _#32 speIs @@ -96,7 +106,7 @@ _$ d0l3 _% p3s'Ent ?5 _% pVRs'Ent _& amp@sand -_' praIm +_' kwoUt _( lEftbrakIt _) raItbrakIt _* ast@rIsk @@ -120,7 +130,7 @@ _` bakpraIm _{ lEftbreIs _| vi:b'A@ _} raItbreIs -_~ tIld@ +~ tIld@ _¡ I2nv3:tI2dEkskl@m'eIS@n _¦ broUk@nb'A@ _¨ daIa2r'i:sI2s @@ -189,16 +199,41 @@ _₠ jU@roU ♯ SA@p ♭ flat ¬ n0t_|saIn + +ß S,A@p'Es ə SwA: -æ eI'i: þ TO@n ŋ ENg +ɲ n^E ð ED ʃ ES ʒ EZ ĸ krA: -ɛ oUp@n'i: -ɔ oUp@n'oU +ɛ oUp@n'E:_ +ɔ oUp@n'O:_ +ɤ ramshO@n +ɾ _'A@tap +ʔ gl'0?@Lst0p +ʧ tSES +ʤ dZEZ + +// phonetic modifiers +ː lENT@nd_ +U+2b0 aspI2reItI2d_ // supr-h +//U+2b2 su:p3skrIptdZ'eI_ // supr-j +U+2b2 m,0ddZ'eI +U+2bc I2dZEktI2v_ +U+2c8 strEs +U+2cc s'Ek@ndrI2str,Es + +// combining diacritics +U+300 grA:v_ +U+303 tIld@_ +U+30a rINg_ +U+31e a2pr'0ksIm@nt_ +U+325 rINg_ +U+32a dEnt@L_ +U+32f n,0nsI2l'abI2k // numeric @@ -1533,6 +1568,7 @@ proceed $verb proceed $only progeny pr0dZ@nI2 progress proUgrEs $only +?3 progress pr0grEs $only progress $verb project pr0dZEkt $onlys project $verb diff --git a/dictsource/en_rules b/dictsource/en_rules index fb457578..db9165d4 100644 --- a/dictsource/en_rules +++ b/dictsource/en_rules @@ -2306,6 +2306,7 @@ _) ev (ict I2v ev (il i:v _) ev (is I2v +?3 _) ev (olu Ev abbr) ev i:v all) ev i:v @@ -4132,6 +4133,7 @@ probab pr0b@b pro (ced pr@ pro (cee pr@ +?3 pro (cess pr0 pro (cessi pr@ pro (clai pr@ pro (cur pr@ @@ -5155,6 +5157,7 @@ // non-ascii characters with specified pronunciations // List the accented characters in en_list with the $accent attribute + à a é eI _) é I2 ê E: @@ -5165,7 +5168,6 @@ ü u: ç s ß s - _) ß (_ b'i:t@_ č tS š S ş S diff --git a/dictsource/es_list b/dictsource/es_list index c3e5cfe1..9bc4ce1b 100644 --- a/dictsource/es_list +++ b/dictsource/es_list @@ -3,7 +3,7 @@ // letters -_cap m'aJ^us +_cap m'aJ^us // should be "mayúscula" after the letter? _?? s'imbOlo _#32 Esp'aTjo diff --git a/dictsource/es_rules b/dictsource/es_rules index 3e09c51c..47bcb10f 100644 --- a/dictsource/es_rules +++ b/dictsource/es_rules @@ -39,7 +39,6 @@ _) d (_ de d D _) d d - l) d d m) d d n) d d @@ -48,7 +47,9 @@ _) e (_ e e e e (CK E + e (r E e (Ch e + Ar) e E ei eI ey (K eI ey (_ 'eI @@ -113,15 +114,18 @@ n (v m n (f m n (p m -// n (g N // ?? -// n (k N // ?? + n (g N // ?? + n (k N // ?? + n (j N .group o _) o (_ o o o o (CK O + o (r O o (Ch o + Ar) o O oi oI oy (K oI oy (_ 'oI @@ -143,11 +147,14 @@ _) r (_ E**e r R _) r R + r (_ * + r (t ** A) r (A ** C) r (A ** l) r (A R m) r (A R n) r (A R + s) r (A R rr *R @@ -155,8 +162,6 @@ _) s (_ Ese s s &) s (_S1 s - s (L02 z - s (gY s .group t @@ -219,6 +224,8 @@ .group z _) z (_ TEta z T +?2 z (L02 z + .group diff --git a/dictsource/fr_list b/dictsource/fr_list index 3154ca89..067d712f 100755 --- a/dictsource/fr_list +++ b/dictsource/fr_list @@ -5,7 +5,7 @@ // 2006-11-18 Gilles Casse // -// Updated 2008-02-29 Michel Such +// Updated 2008-03-01 Michel Such // // * Numbers, a few abbreviations and exceptions. // @@ -34,6 +34,7 @@ g Ze h aS i i ï $accent +î $accent j Zi k ka l El @@ -102,7 +103,7 @@ _; pw'E~viRg'yl _< E~feRjWR _= egal _> sypeRjWR -_? kEstjO~ +_? pwE~dE~terogasj'O~ _[ uvR@-_kRoSE _\ b'aksl'aS _] f'ERm_kRoS'E @@ -670,3 +671,4 @@ vincent vE~sA~ + diff --git a/dictsource/fr_rules b/dictsource/fr_rules index f80c0453..a402ef07 100755 --- a/dictsource/fr_rules +++ b/dictsource/fr_rules @@ -4,7 +4,7 @@ // 2006-11-18 Gilles Casse // -// Updated: 2008-02-26 Michel Such +// Updated: 2008-03-04 Michel Such // // * The rules are based on Cicero TTS. // Y @@ -168,6 +168,8 @@ ell El // selle el (C El // celsius el (_ El // caramel + _) em (me A~ // emmitouffler + X') em (me A~ // s'emmitouffler em (me a // femme patiemment em (b A~ // décembre em (m A~ // emmancher @@ -184,7 +186,7 @@ qu) en (ds_ A~ pati) en A~ // patient patience - _) en (nu A~ // ennui + X) en (nu A~ // ennui C) en (A @n // menu @@ -1204,3 +1206,4 @@ C) te (_ t@- // patte + diff --git a/dictsource/grc_rules b/dictsource/grc_rules index db45ae44..3e7b3e26 100644 --- a/dictsource/grc_rules +++ b/dictsource/grc_rules @@ -342,6 +342,99 @@ w ω // (long o; not standard transliteration but may be easier to type h h +// Latin letters to equivalent Greek sounds (plus 'q = η' 'w = ω' +.group a + a a + ai aI + au aU + +.group b + b b + +.group d + d d + +.group e + e e + ei e: + eu eU + +.group f + f f + +.group g + g g + gg Ng + +.group i + i i + +.group ï + ï i + +.group j + j j + +.group k + k k + kh x + +.group l + l l + +.group m + m m + +.group n + n n + +.group o + o o + oi oI + ou u: + +.group p + p p + ph f + +.group q + q E: + qi EI: + qu EU: + +.group r + r R + +.group s + s s + +.group t + t t + th T + +.group u + u y + ui yI + +.group v + v v + +.group w + w O: + wi OI + wu OU + +.group x + x x + +.group y + y y + yi yI + +.group z + z z + + .group ὰ 'a ᾳ aI: diff --git a/dictsource/hbs_list b/dictsource/hbs_list index 2a773c15..e6238483 100644 --- a/dictsource/hbs_list +++ b/dictsource/hbs_list @@ -41,6 +41,12 @@ z z@ ž Z@ +_á $accent +_é $accent +_í $accent +_ó $accent +_ú $accent + // accent names _lig l'ig&t,UR& _acu 'akUt @@ -50,7 +56,7 @@ _ced ts'EdIl& _cir ts'iRkUmflEks _dia 'uml&Ut _dot t'otSk& -//_grv +_grv n'agl&s&k _hac kv'atSIts& _mcn m'akr**on _ogo 'ogonEk diff --git a/dictsource/is_rules b/dictsource/is_rules index e12cf78d..3fc54184 100644 --- a/dictsource/is_rules +++ b/dictsource/is_rules @@ -224,11 +224,12 @@ .group r _) r R2 - C) r @-* + C) r @-R + l) r **R A) r (A R - B) r r# - r (B r# - r (_ r# + B) r rr# + r (B rr# + r (_ rr# r R rr R* rl dl diff --git a/dictsource/nl_list b/dictsource/nl_list index dd29a71b..a6a7984a 100644 --- a/dictsource/nl_list +++ b/dictsource/nl_list @@ -9,6 +9,29 @@ _s Es _t te: +_cap k'a:pita:l +_?A l'Et@r +_?? s'imbo:l + +// accent names +_lig l'ixa:tyr +_acu 'a:ix,y +_ac2 d'8bEl'a:ixy +_brv b@-*'e:v@ +_ced s'e:dIl@ +_cir s'IrkOnfle:ks@ +_dia '8mlVUt +_dot p'8nt +_grv Q@-*'a:v@ +_hac h'a:tSEk +_mcn m'Ak@-*On +_ogo 'o:xo:nEk +_rng k'o:*o:na: +_stk st@-*'e:p +_tld t'Ild@ + + +// punctuation _. p8nt // numbers diff --git a/dictsource/pl_list b/dictsource/pl_list index 267c03fe..9445ad56 100644 --- a/dictsource/pl_list +++ b/dictsource/pl_list @@ -61,6 +61,29 @@ _0M4 b;ilj'Onuf _dpt _pSEts;'inEk_ +// accent names +_lig ligat'u*a +_acu 'Ost@-*y +_ac2 pOdv'ujny_'Ost@-*y +_brv b@-*'Evis +_ced tsEd;'ilE +_cir pSEts;'ONgwy +_dia 'umlawt +_dot k@-*Opka +_grv ts;'E~Sci +_hac h'atSEk +_mcn m'ak@-*On +_ogo Og'OnEk +_rng k'OwO +_stk dz;ElOnE +_tld t'ylda + + +_cap v;'Elka +_?A lit'E*a +_?? s'ymbOl + + _a a ą O~ b bE @@ -100,7 +123,6 @@ _z zEt // all my keyboard... _! vykSykn^ik -_= *'uvna||S;E _< mn^EjSE _> w;ENkSE _" tsudzyswuf @@ -119,17 +141,23 @@ _] p@-*avy||nav;as||kvad@-*atOvy _{ lEvy||nav;as||klam@-*atOvy _} p@-*avy||nav;as||klam@-*atOvy _' apOst@-*Of -_/ dz;ElOnE _* gv;astka _\ bEkslES -_| k@-*Eska||p;OnOva -_# haS _$ dOla* -_% p@-*OtsEnt -_^ pOtENga // what's be better? _& ampE*sant _` Odv@-*Otny||apOst@-*Of +@ mawpa ++ plus +/ dz;ElOnE += *'uvna||S;E +% p@-*OtsEnt +€ Ew*O +^ pOtENga +# haS +| k@-*Eska||p;OnOva + + // some exceptions arcus arkus jebut $2 diff --git a/dictsource/pl_rules b/dictsource/pl_rules index 417bd513..75300102 100644 --- a/dictsource/pl_rules +++ b/dictsource/pl_rules @@ -396,14 +396,5 @@ // ... and some common non-alphabetic characters .group $ dOla* - @ mawpa - % p@-*OtsEnt - + plus - # haS - = *'uvna||S;E - / dz;ElOnE * gv;astka - | k@-*Eska||p;OnOva - ^ pOtENga - & End - ` Odv@-*Otny||apOst@-*Of + & _End diff --git a/dictsource/pt_list b/dictsource/pt_list index f5981cd7..f334e7f0 100755 --- a/dictsource/pt_list +++ b/dictsource/pt_list @@ -5,37 +5,63 @@ // ?1 European Portuguese // ?2 Brazilian Portuguese +// Note for "pt-pt" [R] is the same sound as [r] +// for "pt" [y] is the same sound as [i] + // Letters // If a letter has a "word" pronunciation which is different from its // "letter" name, then include the letter name here, with the letter // prefixed by a _ character. +// accent names +_lig ligad'u*& +_acu &g'udU +_ac2 &g'udUd'uplU +_brv bR'Evi +_ced sedZ'ilj& +?1 _ced syd'il^& +_cir sirkuNfl'EksU +_dia tR'em& +_dot p'oNtU +_grv gR'avi +_hac ka*'oN +_mcn makR'oN +_ogo ogon'ek +_rng &~n'EU +?1 _rng &~n'El +_stk b'ax& +_tld tS'iU +?1 _tld til + // character names -_á ,a&g'udU -_à ,agR'avi -_â ,asirkuNfl'EksU -_ã ,atS'iU -_ç s,esed'elj& -_é ,e&g'udU -_ê ,asirkuNfl'EksU -_í ,i&g'udU -_ó ,o&g'udU -_ô ,osirkuNfl'EksU -_õ ,otS'iU -_ú ,u&g'udU -_ü ,utR'em& +_á $accent +_à $accent +_à $accent +_â $accent +_ã $accent +_ç $accent +_é $accent +_ê $accent +_í $accent +_ó $accent +_ô $accent +_õ $accent +_ú $accent +_ü $accent -i i // speak i v x as letters, not Roman numbers -v ve +v ve // not Roman numbers x Sis# _cap maI'uskulU _?A l'etR&_ _?? s'imbolU_ +_#32 esp'asU +?1 _#32 Sp'asU +_#9 tab _. p'oNtU _! ,eskl&mas'&U~ @@ -46,7 +72,7 @@ _" 'asp&s# _$ s,ifR'&U~ _% pors'eINtU _& 'e -?1 _' ap'Ost@-*,ofy +?1 _' ap'Ostr,ofy ?2 _' ap'OstR,ofU _( ,abRipa*'eINtezi _) f,ES&pa*'eINtezi @@ -90,8 +116,7 @@ _" 'abRi;'asp&||d'upl&s# ?1 _1 'um ?2 _1 'uN _2 d'oIs# -?1 _3 tr'es# -?2 _3 tR'es# + _3 tr'es# ?1 _4 kw'atru ?2 _4 kw'atRu _5 s'iNku @@ -103,16 +128,13 @@ _" 'abRi;'asp&||d'upl&s# ?2 _9 n'Ovi _10 d'Es# -?1_11 'oNzy -?2_11 'oNzi -?1_12 d'ozy -?2_12 d'ozi +_11 'oNzy +_12 d'ozy ?1_13 tr'ezy ?2_13 tR'ezi ?1_14 k&t'orzy ?2_14 kat'orzi -?1_15 k'iNzy -?2_15 k'iNzi +_15 k'iNzy ?1_16 dyz&s'eis# ?2_16 d,ezes'eIs# ?1_17 dyz&s'Ety @@ -123,8 +145,7 @@ _" 'abRi;'asp&||d'upl&s# ?2_19 dezen'Ovi ?1_2X v'iNty ?2_2X v'iNtSi -?1 _3X tr'iNt& -?2 _3X tR'iNt& +_3X tr'iNt& ?1_4X kw&r'eNt& ?2_4X kwa*'eINt& @@ -245,15 +266,16 @@ te $u nos $u //se $u -este $u+ 'estSi // this -estes $u+ 'estSis // these -esta 'Est& $brk $u+ -esse $u+ 'esi // that +?2 este $u+ 'estSi // this +?2 estes $u+ 'estSis // these +?2 esta 'Est& $brk $u+ +?2 esse $u+ 'esi // that essa 'Es& $brk $u+ aquele $u+ // that aquela $u+ -que $u $pause +?1 que ky $u +?2 que $u $pause // possessive adjectives meu $u+ @@ -268,10 +290,10 @@ seu $u+ sua $u+ seus $u+ suas $u+ -nosso $u+ n'OsU -nossa $u+ n'Os& -nossos $u+ n'OsUs -nossas $u+ n'Os&s +?2 nosso $u+ n'OsU +?2 nossa $u+ n'Os& +?2 nossos $u+ n'OsUs +?2 nossas $u+ n'Os&s dele $u+ dela $u+ deles $u+ @@ -292,7 +314,7 @@ dumas $u em $u $brk // in,on,at no nu $u $brk na $u $brk -nos nus# $u $brk +?2 nos nus# $u $brk nas $u $brk num $u $brk numa $u $brk @@ -301,9 +323,9 @@ numas $u $brk por $u $brk // by,for,through pelo $u $brk -pela $u $brk p'el& +?2 pela $u $brk p'el& pelos $u $brk -pelas $u $brk p'el&s +?2 pelas $u $brk p'el&s a $u $brk // to,at ?1 a & $u $brk @@ -315,7 +337,6 @@ aos $u $brk para $u $brk // for,to pro $u $brk pra $u $brk -?1 pra pr& $u $brk pros $u $brk pras $u $brk prò $u $brk @@ -324,60 +345,61 @@ pròs $u $brk pràs $u $brk com $u $brk // with -sem $pause // without -até $u $pause // until -desde $u $pause // from,since -entre $pause // between,among -por $u $pause // by,for,through -sobre $pause // on,above,about -sob $pause // under,below -debaixo $pause // under,below +?2 sem $pause // without +?2 até $u $pause // until +?2 desde $u $pause // from,since +?2 entre $pause // between,among +?2 por $u $pause // by,for,through +?2 sobre $pause // on,above,about +?2 sob $pause // under,below +?2 debaixo $pause // under,below -durante $pause +?2 durante $pause // conjunctions -e i $u $pause // and +?1 e i $u // and +?2 e i $u $pause // and se $u $brk // if -mas $u $pause // but -porém $pause // however -todavia $pause // yet -contudo $pause // nevertheless +?2 mas $u $pause // but +?2 porém $pause // however +?2 todavia $pause // yet +?2 contudo $pause // nevertheless -ou $u $pause // or -quer $pause // whether +?2 ou $u $pause // or +?2 quer $pause // whether -assim $pause // thus -portanto $pause // therefore +?2 assim $pause // thus +?2 portanto $pause // therefore -porque $pause // because -pois $pause // because -como $u $pause // as +?2 porque $pause // because +?2 pois $pause // because +?2 como $u $pause // as -embora $pause // although -apesar $pause // despite +?2 embora $pause // although +?2 apesar $pause // despite -caso $pause // if -(desde que) d'esdZiki/ $pause // provided that -(exceto se) es'Etusi/ $pause // unless -(salvo se) s'alvusi/ $pause // unless +?2 caso $pause // if +?2 (desde que) d'esdZiki/ $pause // provided that +?2 (exceto se) es'Etusi/ $pause // unless +?2 (salvo se) s'alvusi/ $pause // unless -(para que) p,a*&ki/ $pause // so that +?2 (para que) p,a*&ki/ $pause // so that -quando $pause // when -onde $u $pause // where -apenas $pause // as soon as -mal $pause // as soon as, hardly -(logo que) l'Oguki/ $pause // as soon as -(antes que) '&~NtSiski/ $pause // before -(depois que) dep'OIski/ $pause // after -(sempre que) s'eNpriki/ $pause // whenever -enquanto $pause // while +?2 quando $pause // when +?2 onde $u $pause // where +?2 apenas $pause // as soon as +?2 mal $pause // as soon as, hardly +?2 (logo que) l'Oguki/ $pause // as soon as +?2 (antes que) '&~NtSiski/ $pause // before +?2 (depois que) dep'OIski/ $pause // after +?2 (sempre que) s'eNpriki/ $pause // whenever +?2 enquanto $pause // while // negative @@ -799,3 +821,4 @@ volkmann f'Olkman + diff --git a/dictsource/pt_rules b/dictsource/pt_rules index 0086af19..530ae83b 100755 --- a/dictsource/pt_rules +++ b/dictsource/pt_rules @@ -585,8 +585,7 @@ ?1 A) r (_A r ?2 A) r (_A * rr x -?1 C) r (A r -?2 C) r (A R + C) r (A R // for "pt-pt" [R] is the same as [r] _) r x l) r x n) r x @@ -725,7 +724,7 @@ ß s % pors'eNtu - $ sif@-*'&U~ + $ sifR'&U~ _r_) $ − m'enus + maIs @@ -733,7 +732,7 @@ @ ax'ob& ¤ 'eU*u € 'eU*u - § pa*'ag@-*,afu + § pa*'agR,afu D_) º %o // ordinal D_) ª %a // ordinal diff --git a/dictsource/sk_list b/dictsource/sk_list index 08fd9f67..445271a6 100644 --- a/dictsource/sk_list +++ b/dictsource/sk_list @@ -59,9 +59,9 @@ _dot s_b'otkoU _grv s_'obRa:t;,eni:md'l:Zn^om _hac s_m'ektSen^om _mcn s_m'akRonom -_ogo s_'ogon^ek +_ogo s_'ogon^kom _rng s_kR'u:Skom -_stk S'ikmi: d'l:Zen^ +_stk so_S'ikmi:md'l:Zn^om _tld s_v'l-novkoU diff --git a/dictsource/sv_list b/dictsource/sv_list index 050a6664..6dbcb1cb 100755 --- a/dictsource/sv_list +++ b/dictsource/sv_list @@ -36,6 +36,33 @@ x Eks y y: z s'E:ta2 +_é $accent + + +_cap st'u:Rt +_?A b'u:kstavE-n +_?? s'ymbu:lE-n +_#32 bl'aNk +_#9 tab + +// accent names +_lig l'i:gat,u-R +_acu 'A:ku-t +_ac2 d'8bE-l'A:ku-t +_brv bR'e:vi:s +_ced s'e:dIlj +_cir s'IRk8mflEks +_dia 'Omju-d +_dot p'8Nkt +_grv gR'A:v +_hac h'A:kE- +_mcn stR'Ek +_ogo sv'ans +_rng R'IN +_stk sn'e:dstRE-k +_tld t'IldE- + +// punctuation _. p'8Nkt diff --git a/dictsource/sv_rules b/dictsource/sv_rules index c82b99c4..87952f8c 100755 --- a/dictsource/sv_rules +++ b/dictsource/sv_rules @@ -217,12 +217,12 @@ ch) e (f E: e (ta E e (x E - &) e (_ E - &) es (_ Es - &) en (_ En - &) ens (_ Ens - &) er (_ ER - &) et (_S2 Et // ?? + &) e (_ %E + &) es (_ %Es + &) en (_ %En + &) ens (_ %Ens + &) er (_ %ER + &) et (_S2 %Et // ?? e (ve E t) e (lef E h) et (_ e:t diff --git a/dictsource/ta_list b/dictsource/ta_list index 357b7e8b..22566247 100644 --- a/dictsource/ta_list +++ b/dictsource/ta_list @@ -2,6 +2,51 @@ // This file is UTF8 encoded // Spelling to phoneme words and exceptions for Tamil + +// letters (consonants) +க ik +ங iN +ச itS +ஜ idZ +ஞ in^ +ட it. +ண in. +த it +ந in +ன in // ?? +ப ip +ம im +ய ij +ர ir +ற iR +ல il +ள il. +ழ iz +வ iv +U+bb6 iS +ஷ is. +ஸ is +ஹ iC +U+b82 anUsvVRV +ஃ visVRgV +U+bcd viRVmV + + +// symbols +_?? kuRij,i:d.U +_cap kapit.Vl // guess +_. pul.l.i +_, kVma: +_; ka:RbUl.l.,i +_: arE:pp,Ul.l.V +_? ke:l.vikk,URi +_! a:ctS:Vr,ijVkk,URi +% sadVv,igid,Vm += samVm +U+bf9 ru:ba:j + + +// numbers _0 pu:dZjam_ // ?? _1 ondru_ _2 irandu_ diff --git a/dictsource/ta_rules b/dictsource/ta_rules index 70a6d5d6..93b07d83 100644 --- a/dictsource/ta_rules +++ b/dictsource/ta_rules @@ -57,8 +57,8 @@ ்) க (B g _) க kV _) க (B k - க்க k:V - க்க (B k: + க்க kkV + க்க (B kk ங NV ங (B N @@ -67,8 +67,8 @@ ச (B dZ _) ச sa _) ச (B s - ச்ச tS:V - ச்ச (B tS: + ச்ச ctS:V + ச்ச (B ctS: ஜ dZV ஜ (B dZ @@ -80,8 +80,8 @@ ட (B d. _) ட t.V _) ட (B t. - ட்ட t.V - ட்ட (B t. + ட்ட t.t.V + ட்ட (B t.t. ண n.V ண (B n. @@ -103,8 +103,8 @@ ப (B b _) ப pV _) ப (B p - ப்ப p:V - ப்ப (B p: + ப்ப ppV + ப்ப (B pp ஃ) ப fa ஃ) ப (B f @@ -175,5 +175,11 @@ ௗ : // aU length mark +.group 0xe0a4 // devanagari + \340\244 _^_HI // switch to hindi voice +.group 0xe0a5 // devanagari + \340\245 _^_HI + .group + ் // virama $ dolV diff --git a/dictsource/tr_list b/dictsource/tr_list index 98d7f89e..dbadaa6f 100644 --- a/dictsource/tr_list +++ b/dictsource/tr_list @@ -35,7 +35,56 @@ x Eks y jE z zE +_cap byj'Yk _?? sEmb'Ol +_?A haRf + +// accent names +//_lig +_acu vURg'UimI +_ac2 tS'IftvURg'UimI +_brv ku#s'altmaimI +_ced tSEnJ'El +_cir Sapk'a +_dia Umla'Ut +_dot YstnOkt'a +_grv 'aksanimI +_hac t'ERsSapk'a +_mcn uz'atmaimI +_ogo ogon'Ek +_rng halk'a +//_stk +_tld tIld'E + + +// symbols +_. nOkt'a +_, vIRJ'Yl +_; nOktal'u#vIRJ'Yl +_: ik'InOkt'a +_… 'YtSnOkt'a +_? soR'UiSa*et,I +_! Ynl'EmiSa*et,I +_- k'u#satSIzg'I +_– 'uzUntSIzg'I +_/ ej'IktSIzg'I +_" tu#Rn'akiSa*et'I +_' apOstR'Of +_^ IndZ'EltmEiSa*et'I +& _!v'E +_& v'EiSa*et'I +_* j'u#ldu#z +_@ kUjRUkl'U'a +_\\ t'ERs||ej,IktSIzg'I +¶ pa*agR'af +§ tSEnJ'El +° de*edZ'E +_# dij'Ez +_~ jaklaS'u#k +__ ,alttSIzg'I ++ aRt'u# +€ avR'O + _0 su#fu#R _1 biR diff --git a/docs/dictionary.html b/docs/dictionary.html index afdbd09f..22034028 100644 --- a/docs/dictionary.html +++ b/docs/dictionary.html @@ -3,7 +3,6 @@ eSpeak: Pronunciation Dictionaries - @@ -489,10 +488,14 @@ A word (or group of words) may be given one or more flags, either instead of, or   + $accent + Used for the pronunciation of a single alphabetic character. The character name is spoken as the base-letter name plus the accent (diacritic) name. eg. It can be used to specify that "â" is spoken as "a" "circumflex". + + $alt   $alt2 These are language specific. Their use should be described in the language's **_list file - +     @@ -583,6 +586,9 @@ _0 to _9   The numbers 0 to 9 +_13etc. Any pronunciations which are needed for specific numbers in the range _11 to _99   + + _2X  _3XTwenty, thirty, etc., used to make numbers 10 to 99   diff --git a/docs/languages.html b/docs/languages.html index 001a4484..17414292 100644 --- a/docs/languages.html +++ b/docs/languages.html @@ -79,7 +79,7 @@ The eSpeak speech synthesizer does text to speech for the following additional l

af  Afrikaans
-
This has been worked on by a native speaker and it should be OK.
+
This has been worked on by native speakers and it should be OK.

bs  Bosnian
@@ -110,7 +110,13 @@ The eSpeak speech synthesizer does text to speech for the following additional l

es  Spanish
-
Not much feedback yet, but spelling is regular and stress is explicitly marked when it deviates from the normal rules, so it might be reasonably intelligible. This would be a good opportunity for a native Spanish speaker to assist. Perhaps we could have different variants for Castilian Spanish, Mexican Spanish, etc., in a similar way to how I've done different English accents.
+
Spanish has good spelling rules, so it should be OK.
+

+

+es-la  Spanish - Latin America
+
+This contains a few changes from es, notably the pronunciation of "z","ce","ci". +

fi  Finnish
@@ -119,7 +125,7 @@ The eSpeak speech synthesizer does text to speech for the following additional l

fr  French
-
Needs improvement, both for spelling-to-phoneme rules and the sounds and prosody. +
This has been improved by a native speaker, and should be OK.

@@ -137,6 +143,12 @@ The eSpeak speech synthesizer does text to speech for the following additional l
This has had some feedback from a native speaker but more work is needed. Spelling is fairly regular, but stress marks and vowel accents are often omitted from text, so for some words the dictionary/exceptions list will need to determine the stress position or whether to use open/close [e] or [E] and [o] or [O].

+ku  Kurdish
+
+Not much work yet, but Kurdish has good spelling rules so it should be OK. +
+

+

pt  Portuguese (Brazil)
Brazilian Portuguese. This has had assistance from a native speaker and it should be OK. Like Italian there is further work to do about the ambiguity in the spelling between open/close "e" and "o" vowels.

@@ -153,7 +165,7 @@ The eSpeak speech synthesizer does text to speech for the following additional l

sk  Slovak
-
A little initial feedback. +
This has had assistance from a nativ speaker, so it should be OK.

@@ -171,6 +183,25 @@ The eSpeak speech synthesizer does text to speech for the following additional l
Not much feedback yet, but the spelling and stress rules are fairly regular, so it's probably usable.

+

+ta  Tamil
+
+Not much work yet, but I'm told it sounds reasonable. +
+

+

+tr  Turkish
+
+Not much work yet, but I'm told it sounds reasonable. +
+

+

+zh  Mandarin Chinese
+
+This speaks Pinyin text and Chinese characters. There is only a simple one-to-one translation of Chinese characters to a single Pinyin pronunciation. There is no attempt yet at recognising different pronunciations of Chinese characters in context, or of recognising sequences of characters as "words". The eSpeak installation includes a basic set of Chinese characters. More are available in an additional data file for Mandarin Chinese at: + http://espeak.sourceforge.net/data/. +
+

3.5 Provisional Languages

These languages are only initial naive implementations which have had little or no feedback and improvement from native speakers. @@ -193,6 +224,11 @@ These languages are only initial naive implementations which have had little or

+id  Indonesian
+
An initial guess, no feedback yet. +
+

+

is  Icelandic
An initial guess, awaiting feedback.
@@ -239,13 +275,6 @@ Russian stress position is unpredictable so a large lookup dictionary is needed

-zh  Mandarin Chinese
-
-This speaks Pinyin text and Chinese characters. There is only a simple one-to-one translation of Chinese characters to a single Pinyin pronunciation. There is no attempt yet at recognising different pronunciations of Chinese characters in context, or of recognising sequences of characters as "words". The eSpeak installation includes a basic set of Chinese characters. More are available in an additional data file for Mandarin Chinese at: - http://espeak.sourceforge.net/data/. -
-

-

zhy  Cantonese Chinese
Just a naive simple one-to-one translation from single Simplified Chinese characters to phonetic equivalents in Cantonese. There is limited attempt at disambiguation, grouping characters into words, or adjusting tones according to their surrounding syllables. This voice needs Chinese character to phonetic translation data, which is available as a separate download for Cantonese at: http://espeak.sourceforge.net/data/.
The voice can also read Jyutping romanised text.
diff --git a/docs/voices.html b/docs/voices.html index e50ca8ca..41d4df18 100644 --- a/docs/voices.html +++ b/docs/voices.html @@ -3,7 +3,6 @@ eSpeak: Voice Files - @@ -115,6 +114,12 @@ don't have their own tone statement. Adjusts the strength of formant-synthesized sounds (vowels and sonorant consonants).

+consonants  <value> <value>
+
Default values: 100, 100.
+ + Adjusts the strength of noise sounds which are used in consonants. The first value is the strength of unvoiced consonants such as "s" and "t". The second value is the strength of the noise component of voiced consonants such as "z" and "d". +

+

breath  <up to 8 integer values>
Default values: 0.
diff --git a/phsource/compile_report b/phsource/compile_report index da938d7c..fd4c853f 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,4 +1,4 @@ -50 phoneme tables +49 phoneme tables new total base 98 98 base2 24 117 @@ -44,10 +44,9 @@ zhy 40 131 zh 65 148 sw 14 107 - th 50 141 - id 14 119 tr 18 122 - ku 13 119 + ku 17 121 + id 14 119 ja 7 103 rw 12 122 @@ -174,6 +173,7 @@ dzh/dzh_ [dZ] base dzh/dz_pzd [J] base [J2] hi [J] tr + [J] ku dzh/dz_pzd_ [J] base [J2] hi dzh/xdzh [dZ] base @@ -186,8 +186,6 @@ dzh/xdz_pzd [J] base [J2] hi envelope/i_risefall [11] zh envelope/p_214 [214] zh - [5] th -envelope/p_451 [3] th envelope/p_512 [8] vi envelope/p_fall [2] vi [7] vi @@ -198,8 +196,6 @@ envelope/p_fall [2] vi [22] zh [33] zh [53] zh - [1] th - [2] th envelope/p_fallrise [4] vi envelope/p_level [1] vi [3] zhy @@ -210,7 +206,6 @@ envelope/p_rise [3] vi [5] zhy [44] zh [35] zh - [4] th envelope/vi_5 [5] vi envelope/vi_5amp [5] vi envelope/vi_6 [6] vi @@ -506,17 +501,14 @@ r/r [r] base [r-] base [r] en_sc [r] de - [R] pt_pt r/_r [r] base [r] en_sc - [R] pt_pt r/r_ [r] base [r] en_sc [r] de [r] fi [r2] nl [r] ru - [R] pt_pt [r] ro [r] sw r/r@ [(@)] base @@ -539,7 +531,6 @@ r/tr [r] base [r] en_sc [r] fr [r/] fr - [R] pt_pt r/trr [r/] base [r/] af [r] de @@ -624,8 +615,8 @@ ufric/x [x] base ufric/x2 [x2] af [x2] nl [x2] pt -ufric/x_hr [x] hr [x] ku +ufric/x_hr [x] hr ufric/x_sr [h] sr [x] sr ustop/c [c] base @@ -646,7 +637,6 @@ ustop/k_ [k] base [k] el [kh] zh [k] sw - [kh] th ustop/ki [c] base [k] base [k] base2 @@ -662,6 +652,8 @@ ustop/ki [c] base [k] sw [J] tr [c] tr + [J] ku + [c] ku ustop/kl [k] base [k] base2 [k] en @@ -693,14 +685,12 @@ ustop/k_unasp [k] base [k] el [k] zhy ustop/k_unasp_ [k] zh - [k] th ustop/null [?] base ustop/p [p] base [p] fr [p2] fr [ph] hi [p] zhy - [ph] th ustop/p_ [p] base [p] fr [p2] fr @@ -736,7 +726,6 @@ ustop/p_unasp [p] base [p] la [p;] ro [p] zh - [p] th ustop/p_unasp_ [p] base2 [p] fi [p] hi @@ -760,7 +749,6 @@ ustop/t_ [t] base [t] sk [t] el [th] zh - [th] th ustop/t_dnt [t] base [t[] base [t] base2 @@ -802,9 +790,7 @@ ustop/t_short [t.] hi [t] sk [t] el ustop/tsh_pzd [tS;] zh - [ch] th ustop/tsh_pzd_unasp [tS;] zh - [c] th ustop/tsh_sr [tS] sr ustop/ts_pzd [tS;] base [ts;] base @@ -821,12 +807,10 @@ ustop/ts_rfx_unasp [ts.] zh ustop/ts_sr [tS;] sr [dZ;] sr ustop/ts_unasp [ts] zh -ustop/t_unasp [t] th ustop/t_unasp2 [t] zh vdiph/0i [OI] pt [OI] grc [OI] vi - [O:I] th vdiph/0i_2 [OI] en_sc [OI] en_wi [AI] no @@ -843,8 +827,6 @@ vdiph2/i@ [i@] en_n vdiph2/i@_2 [i@] en_wm vdiph2/ie [i@] en_wi [ie] fi - [ia] th - [i:a] th vdiph2/ii@ [i@] en [i@3] en vdiph2/ii@_3 [i@] vi @@ -852,7 +834,6 @@ vdiph2/iioo [io] zh vdiph2/iu [iU] base2 [iU] vi [iu] zhy - [iU] th vdiph2/iu_2 [iu] fi vdiph2/iu_3 [iu] af vdiph2/iu_4 [Iu] cy @@ -866,15 +847,12 @@ vdiph2/o_oo [o@] en_wi [o] is [o] zh vdiph2/u-@ [y@] vi - [y:a] th vdiph2/u#@ [U@] en_sc vdiph2/uo [uo] fi vdiph2/uu@ [U@] en [U@] en_n [U@] en_wm [u@] vi - [ua] th - [u:a] th vdiph2/y@ [y@] zh vdiph2/y#@ [Y@] af vdiph2/yu [yU] nl @@ -906,8 +884,6 @@ vdiph/ai [aI] base2 [aI] it [aI] pt [a:I] vi - [aI] th - [a:I] th [aI] id vdiph/ai_2 [aI] cy [aY] cy @@ -924,8 +900,6 @@ vdiph/aoo [aU] en_us vdiph/au [aU] en [aU] af [a:U] vi - [aU] th - [a:U] th vdiph/au# [aU] en_sc vdiph/au_2 [au] zhy vdiph/au_3 [aU] en_rp @@ -952,7 +926,6 @@ vdiph/eeu [EU] pt [EU] grc [EU] vi [eu] zhy - [E:U] th vdiph/eeu_2 [EU] la [EU] pt_pt vdiph/eeu_3 [aU] en_n @@ -974,10 +947,7 @@ vdiph/eu [eU] base2 [eU] sk [eU] pt [eU] vi - [eU] th - [e:U] th vdiph/eu_2 [eu] fi -vdiph/@i [@:I] th vdiph/&i [&i] fi [aI] hi vdiph/@i_2 [eI] af @@ -997,7 +967,6 @@ vdiph/oi [oI] base2 [oI] it [OI] la [oI] vi - [o:I] th vdiph/oi_2 [oI] af vdiph/ooi [OI] en [OI] en_n @@ -1029,8 +998,6 @@ vdiph/ui [uI] base2 [ui] fi [uI] vi [ui] zhy - [uI] th - [u:I] th vdiph/u-i [yI] vi vdiph/ui_2 [uI] af vdiph/ui_3 [uI] cy @@ -1061,6 +1028,7 @@ vnasal/a#_n [&~] pt vnasal/a#u_n [&U~] pt [&U~] pt_pt vnasal/ee_n [E~] en + [a] en_us [E~] fr_ca vnasal/ee_n2 [E~] hi [E~] pl @@ -1169,7 +1137,6 @@ vowel/@ [@] base [@] en_rp [V] cy [@4] hi - [@] th vowel/@- [@-] base [r*] hr vowel/& [a] en_rp @@ -1200,7 +1167,6 @@ vowel/3_3 [3:] en_rp vowel/3_en [3:] en [e@] en_wm [3:] af - [@:] th vowel/@_4 [@] nl [@] no vowel/8 [o-] zh @@ -1223,8 +1189,6 @@ vowel/a [a] en_n [a] hr [a] it [a] zh - [a] th - [a:] th [a] id [a] ja vowel/a# [a/] base2 @@ -1329,8 +1293,6 @@ vowel/e [e] base2 [e] pt_pt [e] grc [e] vi - [e] th - [e:] th [e] id [e] rw [e#] rw @@ -1350,6 +1312,7 @@ vowel/ee [E] fr [E] sv vowel/e_e [E] en_sc [e] is +vowel/ee# [E#] ku vowel/ee_1 [E] base2 [e@] en [e@] en_n @@ -1371,8 +1334,6 @@ vowel/ee_3 [&] af vowel/ee_6 [E] en_n [&] sk [E3] sv - [E] th - [E:] th vowel/e_mid [E] en_rp [e] jbo [E] fr_ca @@ -1386,9 +1347,9 @@ vowel/e_mid [E] en_rp [E] pt_pt [E] no [E] is + [E] tr [E] id [E2] id - [E] tr [e] ja vowel/e_mid2 [E] af [E] de @@ -1427,13 +1388,10 @@ vowel/i [i] base2 [i] zhy [i] zh [i] sw - [i] th - [i:] th [i] ja [i] rw [i#] rw -vowel/i# [i] en_us - [i] en_rp +vowel/i# [i] en_rp [y:] cy vowel/i_2 [i:] en_rp [i2] de @@ -1448,17 +1406,15 @@ vowel/i_4 [i] fi [i] hu [I] it [i] is -vowel/i#_4 [y] th - [y:] th vowel/i_5 [i:] en_sc vowel/i#_5 [y] pt_pt [i/] pt_pt [y] ro vowel/i_6 [i] ta [i] hr - [i] id [i] tr [i] ku + [i] id vowel/i#_6 [i.] zh vowel/i#_7 [i[] zh vowel/i_en [i:] en @@ -1529,8 +1485,6 @@ vowel/o [o] base2 [o] pt_pt [o] grc [o:] sv - [o] th - [o:] th [o] id [o] rw [o#] rw @@ -1569,10 +1523,8 @@ vowel/oo [O:] en_sc [O] sv [O] no [o] zhy - [O] th - [O:] th - [O] id [O] tr + [O] id [o] ja vowel/oo_1 [O:] en_n [O:] en_rp @@ -1626,8 +1578,6 @@ vowel/u [u:] en_wi [u:] ta [u:] cs [U] la - [u] th - [u:] th [u] id vowel/u# [u:] en_sc [Y] tr @@ -1698,6 +1648,7 @@ vowel/V_2 [V] en [a] af [V] ru [V#] ru + [V] ku vowel/V_3 [V] en_rp [V] hi [V] ta @@ -1791,6 +1742,7 @@ vwl_en_us/ee [E] en_us vwl_en_us/er [e@] en_us vwl_en_us/ii [I] en_us [I2] en_us +vwl_en_us/ii_2 [i] en_us vwl_en_us/ir [i@3] en_us [i@3] en_sc vwl_en_us/oor [O@] en_us diff --git a/phsource/ph_english_us b/phsource/ph_english_us index e9f25b67..c9bdd59a 100644 --- a/phsource/ph_english_us +++ b/phsource/ph_english_us @@ -29,6 +29,9 @@ phoneme a vowel starttype (a) endtype (@) length 210 formants vwl_en_us/a + before n vnasal/ee_n + before N vnasal/ee_n + before m vnasal/ee_n reduceto a2 0 endphoneme @@ -79,8 +82,8 @@ endphoneme phoneme i // optional variant of [I] for end of words vowel starttype (i) endtype (i) length 190 -// formants vwl_en_us/i_final3 - formants vowel/i# + formants vwl_en_us/ii_2 +// formants vowel/i# linkout ; endphoneme diff --git a/phsource/ph_portugal b/phsource/ph_portugal index 96cb6713..44dbe1bf 100644 --- a/phsource/ph_portugal +++ b/phsource/ph_portugal @@ -140,15 +140,8 @@ phoneme x // [r] for Portugal endphoneme -phoneme R - liquid starttype r endtype r - length 100 - lengthmod 7 - beforenotvowel r/ - trill - formants r/r - after _ r/_r t r/tr p r/tr k r/tr - before _ r/r_ +phoneme R // for Portugal this is same the as [r] + import_phoneme r pt endphoneme diff --git a/phsource/ph_pt_brazil b/phsource/ph_pt_brazil index ecbcd04a..5c068f61 100644 --- a/phsource/ph_pt_brazil +++ b/phsource/ph_pt_brazil @@ -1,6 +1,6 @@ //==================================================== -// Portuguese - based on Italian +// Portuguese - based on Base2 //==================================================== phoneme e~ diff --git a/phsource/ph_spanish b/phsource/ph_spanish index 05460cdb..dc8e451c 100644 --- a/phsource/ph_spanish +++ b/phsource/ph_spanish @@ -85,4 +85,3 @@ endphoneme - diff --git a/phsource/phonemes b/phsource/phonemes index 066889cc..6cabc10f 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -598,6 +598,8 @@ phoneme ** // TEST flap vowelin f1=2 f2=1600 -300 300 f3=-100 80 len=20 formants r3/@tap after (e) r3/@tap2 + after (i) r3/@tap2 + lengthmod 3 endphoneme @@ -1263,20 +1265,18 @@ include ph_zh phonemetable sw base include ph_swahili -phonemetable th base -include ph_thai - -phonemetable id base2 -include ph_indonesian - phonemetable tr base2 include ph_turkish phonemetable ku base2 include ph_kurdish +phonemetable id base2 +include ph_indonesian + phonemetable ja base include ph_japanese phonemetable rw base2 include ph_kinyarwanda + diff --git a/phsource/vowel/& b/phsource/vowel/& index 46166ea8083646ef5ca1a0816c248c29314ef1fa..ac60abe5ac193021ee8d97dfe3126239b502f520 100644 GIT binary patch delta 99 zcmca>aMxf%D2reNk2rGy^Lr+J#urQsBJNC^Hm9-tW`+v?U^0aZ7jYm7Tfv3vc;LdH UnN%1*Ffj;4GacL9C2*M?0Jr8HCIA2c delta 99 zcmca>aMxf%D2pHik2rGy^Lr+J#urQsqMA%oHm9-tW`+v?U^0aZ7jYm7Tfv3vc;LdH SnN%1*Ffj;&4CxZM%nkq_lo}EM diff --git a/phsource/vowel/i# b/phsource/vowel/i# index e871d029af7d5daaf837a25182b4eb3f3b19c892..38e3d2859620f3305b94137a4c78e69a72752350 100644 GIT binary patch delta 36 rcmZ3dyH0n51Pi0VW=WRA%s}cc`*~(29*)iHxDPQiDr_#~w`B(a(zgo3 delta 36 rcmZ3dyH0n51Pi0aW=WRA%s}cc`*~)jU+kOLaUWu4aL+(GIKb68B-k~OiGhJ3Gn0)W2}nc1Mkx*!mhU&GG;CI50kVGFbZD4t#G%d@ nzd4HI0W-_bMcoHB+wlNpeqMj~V6&G1koBvrC17)y2s;Y^p`sj; delta 91 zcmca-aMwU8IKb68B-k~Ok%581lZ_z-NHH+j|LUA^VWTt$3(K!1rxP}-vw&FpUwoKs q%%RShvN@XL0W-_5TlY3>w&wxKe4XI1*;@d}`rW}dVRN_$I|~3`r5}y} diff --git a/phsource/vwl_en_us/i_final3 b/phsource/vwl_en_us/i_final3 deleted file mode 100644 index 1c6c4b522b9946fc46f98eefff4c915eb2940505..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 962 zcmdUtO=}ZT6o#KklgURrP7;%n*fs{EF-oweej*7Cv;{YYmQ*PST0u%HD!LF{X6ep< zAX#*grQoIuk$|Eb7cK-{X6d3-cZvw{&7DqLf`7m{+&k}i=bSs-htphKm|JcxEJc8g z+iM#S@7zB(!d+ztpL*zX%ggJ*58q!Hx$iA1_c~s3HoOw(S%ZSMMS9cvVQO39tn#;LJ;PPjctedGQ=Dg7QDH`^!W{G5 zq)LG^a<6cm6*3$lO`cO+q@jG8GDYd5B#00uq}?H=Jwg;)jxEn7s5SWR;F4sVNu86G za!9Fvg45>z6LNDp-z9D;9cF)jd~KVX*F#_0MoJ%;yQ^>*V^k3n#Q{r?TuS6J zT7&Ot4yz}x-i+SkhGug2l-WPeo9~ARnRLi&D1T(UF4#V`w)HFF&s!%PkNOn0qyCJ+ T{=7le-8wLDoxK_R->Cfs^eT!; diff --git a/phsource/vwl_en_us/ii b/phsource/vwl_en_us/ii index 75726b43db190f511cb06b0674053bfacc7e271d..0a2135cf25d750f1308bdba2c4a73835bb4d5a6b 100644 GIT binary patch delta 139 zcmca-aL-^v9*Y!%5Fb+>Q#IFah6P*j_% MOkfo|1eUP_0HALpw*UYD delta 139 zcmca-aL-^v9*Y!@FdtJMQ#IFah6P+Eg4#?E80~mxFeLDv;oscB@`)KLU&eJ9E^o^_ z6Cyu_;}5e;1s8*$9n(A}Pu?{Q6}$`r4;UXXD)C1%PT*(Z-n@qA142alangopts.listx) + { + compile_dictlist_file(path,"list"); + compile_dictlist_file(path,"listx"); + } + else + { + compile_dictlist_file(path,"listx"); + compile_dictlist_file(path,"list"); + } compile_dictlist_file(path,"extra"); compile_dictlist_end(f_out); diff --git a/src/dictionary.cpp b/src/dictionary.cpp index f3901011..9eb899bb 100755 --- a/src/dictionary.cpp +++ b/src/dictionary.cpp @@ -40,6 +40,7 @@ int dictionary_skipwords; char dictionary_name[40]; extern MNEM_TAB mnem_flags[]; +extern PHONEME_TAB_LIST phoneme_tab_list[N_PHONEME_TABS]; // 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}; @@ -488,6 +489,13 @@ void DecodePhonemes(const char *inptr, char *outptr) *outptr++ = c; mnem = mnem >> 8; } + if(phcode == phonSWITCH) + { + while(isalpha(*inptr)) + { + *outptr++ = *inptr++; + } + } } } *outptr = 0; /* string terminator */ @@ -519,6 +527,7 @@ void Translator::GetTranslatedPhonemeString(char *phon_out, int n_phon_out) int ix; int phon_out_ix=0; int stress; + char *p; PHONEME_LIST *plist; static const char *stress_chars = "==,,''"; @@ -550,6 +559,17 @@ void Translator::GetTranslatedPhonemeString(char *phon_out, int n_phon_out) // syllablic consonant WriteMnemonic(&phon_out_ix,phoneme_tab[phonSYLLABIC]->mnemonic); } + if(plist->ph->code == phonSWITCH) + { + // the tone_ph field contains a phoneme table number + p = phoneme_tab_list[plist->tone_ph].name; + while(*p != 0) + { + phon_out[phon_out_ix++] = *p++; + } + phon_out[phon_out_ix++] = ' '; + } + else if(plist->tone_ph > 0) { WriteMnemonic(&phon_out_ix,phoneme_tab[plist->tone_ph]->mnemonic); @@ -2244,8 +2264,8 @@ void Translator::MatchRule(char *word[], const char *group, char *rule, MatchRec -int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, int dict_flags) -{//=========================================================================================================================== +int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char *end_phonemes, int word_flags, unsigned int *dict_flags) +{//===================================================================================================================================== /* Translate a word bounded by space characters Append the result to 'phonemes' and any standard prefix/suffix in 'end_phonemes' */ @@ -2262,8 +2282,9 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char int letter; int any_alpha=0; int ix; - int digit_count=0; + unsigned int digit_count=0; char *p; + int dict_flags0=0; MatchRecord match1; MatchRecord match2; char ph_buf[40]; @@ -2275,6 +2296,9 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char if(data_dictrules == NULL) return(0); + if(dict_flags != NULL) + dict_flags0 = dict_flags[0]; + for(ix=0; ix<(N_WORD_BYTES-1);) { c = p_start[ix]; @@ -2359,13 +2383,13 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char group_name[1] = c2; group_name[2] = 0; p2 = p; - MatchRule(&p2, group_name, groups2[g], &match2, word_flags, dict_flags); + MatchRule(&p2, group_name, groups2[g], &match2, word_flags, dict_flags0); if(match2.points > 0) match2.points += 35; /* to acount for 2 letters matching */ /* now see whether single letter chain gives a better match ? */ group_name[1] = 0; - MatchRule(&p, group_name, groups1[c], &match1, word_flags, dict_flags); + MatchRule(&p, group_name, groups1[c], &match1, word_flags, dict_flags0); if(match2.points >= match1.points) { @@ -2384,11 +2408,11 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char group_name[1] = 0; if(groups1[c] != NULL) - MatchRule(&p, group_name, groups1[c], &match1, word_flags, dict_flags); + MatchRule(&p, group_name, groups1[c], &match1, word_flags, dict_flags0); else { // no group for this letter, use default group - MatchRule(&p, "", groups1[0], &match1, word_flags, dict_flags); + MatchRule(&p, "", groups1[0], &match1, word_flags, dict_flags0); if((match1.points == 0) && ((option_sayas & 0x10) == 0)) { @@ -2397,23 +2421,27 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char if((letter >= 0xc0) && (letter <= 0x241) && ((ix = remove_accent[letter-0xc0]) != 0)) { // within range of the remove_accent table - p2 = p-1; - p[-1] = ix; - while((p[0] = p[n]) != ' ') p++; - while(n-- > 0) *p++ = ' '; // replacement character must be no longer than original - - if(langopts.param[LOPT_DIERESES] && (lookupwchar(diereses_list,letter) > 0)) + if((p[-2] != ' ') || (p[n] != ' ')) { - // vowel with dieresis, replace and continue from this point - p = p2; - continue; + // not the only letter in the word + p2 = p-1; + p[-1] = ix; + while((p[0] = p[n]) != ' ') p++; + while(n-- > 0) *p++ = ' '; // replacement character must be no longer than original + + if(langopts.param[LOPT_DIERESES] && (lookupwchar(diereses_list,letter) > 0)) + { + // vowel with dieresis, replace and continue from this point + p = p2; + continue; + } + + phonemes[0] = 0; // delete any phonemes which have been produced so far + p = p_start; + word_vowel_count = 0; + word_stressed_count = 0; + continue; // start again at the beginning of the word } - - phonemes[0] = 0; // delete any phonemes which have been produced so far - p = p_start; - word_vowel_count = 0; - word_stressed_count = 0; - continue; // start again at the beginning of the word } else if((letter >= 0x3200) && (letter < 0xa700) && (end_phonemes != NULL)) @@ -2430,14 +2458,15 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char if(match1.points == 0) { - static const char str_unknown[4] = {phonCAPITAL,phonCAPITAL,phonCAPITAL,0}; - if(iswalpha(wc)) + if(IsAlpha(wc)) { if((any_alpha > 1) || (p[wc_bytes-1] > ' ')) { - // an unrecognised character in a word, indicate with clicks - match1.phonemes = str_unknown; - match1.points = 1; + // an unrecognised character in a word, abort and then spell the word + phonemes[0] = 0; + if(dict_flags != NULL) + dict_flags[0] |= FLAG_SPELLWORD; + break; } } else @@ -2492,7 +2521,7 @@ int Translator::TranslateRules(char *p_start, char *phonemes, int ph_size, char } // any language specific changes ? - ApplySpecialAttribute(phonemes,dict_flags); + ApplySpecialAttribute(phonemes,dict_flags0); memcpy(p_start,word_copy,strlen(word_copy)); return(0); } /* end of TranslateRules */ diff --git a/src/espeak.cpp b/src/espeak.cpp index 34295cd6..ee7a3a52 100644 --- a/src/espeak.cpp +++ b/src/espeak.cpp @@ -65,6 +65,8 @@ static const char *help_text = "--punct=\"\"\n" "\t Speak the names of punctuation characters during speaking. If\n" "\t = is omitted, all punctuation is spoken.\n" +"--split=\"\"\n" +"\t Starts a new WAV file every . Used with -w\n" "--voices=\n" "\t List the available voices for the specified language.\n" "\t If is omitted, then list all voices.\n" @@ -196,8 +198,8 @@ int OpenWavFile(char *path, int rate) { static unsigned char wave_hdr[44] = { 'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ', - 0x10,0,0,0,1,0,1,0, 0,0,0,0, 0,0,0,0, - 2,0,0x10,0,'d','a','t','a', 0,0,0,0 }; + 0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0, + 2,0,0x10,0,'d','a','t','a', 0xff,0xff,0xff,0x7f}; if(path == NULL) return(2); @@ -215,7 +217,7 @@ int OpenWavFile(char *path, int rate) fwrite(wave_hdr,1,24,f_wavfile); Write4Bytes(f_wavfile,rate); Write4Bytes(f_wavfile,rate * 2); - fwrite(&wave_hdr[32],1,8,f_wavfile); + fwrite(&wave_hdr[32],1,12,f_wavfile); return(0); } return(1); diff --git a/src/intonation.cpp b/src/intonation.cpp index 4b45e6c6..f3b7dd2e 100755 --- a/src/intonation.cpp +++ b/src/intonation.cpp @@ -216,8 +216,8 @@ static int drops_0[8] = {0x400,0x400,0x700,0x700,0x700,0xa00,0x1800,0x0e00}; static short oflow[] = {0, 20, 12, 4, 0}; static short oflow_emf[] = {5, 24, 15, 10, 5}; static short oflow_less[] = {3, 19, 12, 7, 2}; -static short oflow_test2[] = {20, 0, 20, 0, 20}; -static short back_emf[] = {35, 32, 0}; +// static short oflow_test2[] = {20, 0, 20, 0, 20}; +// static short back_emf[] = {35, 32, 0}; #define N_TONE_HEAD_TABLE 13 diff --git a/src/numbers.cpp b/src/numbers.cpp index d648a7f4..d1f81a8b 100644 --- a/src/numbers.cpp +++ b/src/numbers.cpp @@ -37,22 +37,33 @@ #define M_NAME 0 -#define M_ACUTE 1 -#define M_BREVE 2 -#define M_CARON 3 -#define M_CEDILLA 4 -#define M_CIRCUMFLEX 5 -#define M_DIAERESIS 6 -#define M_DOUBLE_ACUTE 7 -#define M_DOT_ABOVE 8 -#define M_GRAVE 9 -#define M_MACRON 10 -#define M_OGONEK 11 -#define M_RING 12 -#define M_STROKE 13 -#define M_TILDE 14 +#define M_SMALLCAP 1 +#define M_TURNED 2 +#define M_REVERSED 3 +#define M_CURL 4 -#define M_MIDDLE_DOT 8 // duplicate of M_DOT_ABOVE +#define M_ACUTE 5 +#define M_BREVE 6 +#define M_CARON 7 +#define M_CEDILLA 8 +#define M_CIRCUMFLEX 9 +#define M_DIAERESIS 10 +#define M_DOUBLE_ACUTE 11 +#define M_DOT_ABOVE 12 +#define M_GRAVE 13 +#define M_MACRON 14 +#define M_OGONEK 15 +#define M_RING 16 +#define M_STROKE 17 +#define M_TILDE 18 + +#define M_BAR 19 +#define M_RETROFLEX 20 +#define M_HOOK 21 + + +#define M_MIDDLE_DOT M_DOT_ABOVE // duplicate of M_DOT_ABOVE +#define M_IMPLOSIVE M_HOOK typedef struct { char *name; @@ -62,6 +73,11 @@ int flags; // these are tokens to look up in the *_list file. ACCENTS accents_tab[] = { {"_lig", 1}, +{"_smc", 1}, // smallcap +{"_tur", 1}, // turned +{"_rev", 1}, // reversed +{"_crl", 0}, // curl + {"_acu", 0}, // acute {"_brv", 0}, // breve {"_hac", 0}, // caron/hacek @@ -76,12 +92,38 @@ ACCENTS accents_tab[] = { {"_rng", 0}, // ring {"_stk", 0}, // stroke {"_tld", 0}, // tilde + +{"_bar", 0}, // bar +{"_rfx", 0}, // retroflex +{"_hok", 0}, // hook }; #define CAPITAL 0 -#define LETTER(ch,mod1,mod2) ch+(mod1 << 8) -#define LIGATURE(ch1,ch2,mod1) ch1+(ch2 << 8)+0x8000 +#define LETTER(ch,mod1,mod2) (ch-59)+(mod1 << 6)+(mod2 << 11) +#define LIGATURE(ch1,ch2,mod1) (ch1-59)+((ch2-59) << 6)+(mod1 << 12)+0x8000 + + +#define L_ALPHA 60 // U+3B1 +#define L_SCHWA 61 // U+259 +#define L_OPEN_E 62 // U+25B +#define L_GAMMA 63 // U+3B3 +#define L_IOTA 64 // U+3B9 +#define L_OE 65 // U+153 +#define L_OMEGA 66 // U+3C9 + +#define L_PHI 67 // U+3C6 +#define L_ESH 68 // U+283 +#define L_UPSILON 69 // U+3C5 +#define L_EZH 70 // U+292 +#define L_GLOTTAL 71 // U+294 +#define L_RTAP 72 // U+27E + + +static const short non_ascii_tab[] = { + 0, 0x3b1, 0x259, 0x25b, 0x3b3, 0x3b9, 0x153, 0x3c9, +0x3c6, 0x283, 0x3c5, 0x292, 0x294, 0x27e }; + // characters U+00e0 to U+017f const short letter_accents_0e0[] = { @@ -179,11 +221,11 @@ LETTER('l',M_ACUTE,0), CAPITAL, LETTER('l',M_CEDILLA,0), CAPITAL, -LETTER('1',M_CARON,0), +LETTER('l',M_CARON,0), CAPITAL, -LETTER('1',M_MIDDLE_DOT,0), // U+0140 +LETTER('l',M_MIDDLE_DOT,0), // U+0140 CAPITAL, -LETTER('1',M_STROKE,0), +LETTER('l',M_STROKE,0), CAPITAL, LETTER('n',M_ACUTE,0), CAPITAL, @@ -248,6 +290,98 @@ LETTER('s',M_NAME,0), // long-s // U+17f }; +// characters U+0250 to U+029F +const short letter_accents_250[] = { +LETTER('a',M_TURNED,0), // U+250 +LETTER(L_ALPHA,0,0), +LETTER(L_ALPHA,M_TURNED,0), +LETTER('b',M_IMPLOSIVE,0), +0, // open-o +LETTER('c',M_CURL,0), +LETTER('d',M_RETROFLEX,0), +LETTER('d',M_IMPLOSIVE,0), +LETTER('e',M_REVERSED,0), // U+258 +0, // schwa +LETTER(L_SCHWA,M_HOOK,0), +0, // open-e +LETTER(L_OPEN_E,M_REVERSED,0), +LETTER(L_OPEN_E,M_HOOK,M_REVERSED), +0,//LETTER(L_OPEN_E,M_CLOSED,M_REVERSED), +LETTER('j',M_BAR,0), +LETTER('g',M_IMPLOSIVE,0), // U+260 +LETTER('g',0,0), +LETTER('g',M_SMALLCAP,0), +LETTER(L_GAMMA,0,0), +0, // ramshorn +LETTER('h',M_TURNED,0), +LETTER('h',M_HOOK,0), +0,//LETTER(L_HENG,M_HOOK,0), +LETTER('i',M_BAR,0), // U+268 +LETTER(L_IOTA,0,0), +LETTER('i',M_SMALLCAP,0), +LETTER('l',M_TILDE,0), +LETTER('l',M_BAR,0), +LETTER('l',M_RETROFLEX,0), +LIGATURE('l','z',0), +LETTER('m',M_TURNED,0), +0,//LETTER('m',M_TURNED,M_LEG), // U+270 +LETTER('m',M_HOOK,0), +0,//LETTER('n',M_LEFTHOOK,0), +LETTER('n',M_RETROFLEX,0), +LETTER('n',M_SMALLCAP,0), +LETTER('o',M_BAR,0), +LIGATURE('o','e',M_SMALLCAP), +0,//LETTER(L_OMEGA,M_CLOSED,0), +LETTER(L_PHI,0,0), // U+278 +LETTER('r',M_TURNED,0), +0,//LETTER('r',M_TURNED,M_LEG), +LETTER('r',M_RETROFLEX,M_TURNED), +0,//LETTER('r',M_LEG,0), +LETTER('r',M_RETROFLEX,0), +0, // r-tap +LETTER(L_RTAP,M_REVERSED,0), +LETTER('r',M_SMALLCAP,0), // U+280 +LETTER('r',M_TURNED,M_SMALLCAP), +LETTER('s',M_RETROFLEX,0), +0, // esh +0,//LETTER('j',M_BAR,L_IMPLOSIVE), +LETTER(L_ESH,M_REVERSED,0), +LETTER(L_ESH,M_CURL,0), +LETTER('t',M_TURNED,0), +LETTER('t',M_RETROFLEX,0), // U+288 +LETTER('u',M_BAR,0), +LETTER(L_UPSILON,0,0), +LETTER('v',M_HOOK,0), +LETTER('v',M_TURNED,0), +LETTER('w',M_TURNED,0), +LETTER('y',M_TURNED,0), +LETTER('y',M_SMALLCAP,0), +LETTER('z',M_RETROFLEX,0), // U+290 +LETTER('z',M_CURL,0), +0, // ezh +LETTER(L_EZH,M_CURL,0), +0, // glottal stop +LETTER(L_GLOTTAL,M_REVERSED,0), +LETTER(L_GLOTTAL,M_TURNED,0), +0,//LETTER('c',M_LONG,0), +0, // bilabial click // U+298 +LETTER('b',M_SMALLCAP,0), +0,//LETTER(L_OPEN_E,M_CLOSED,0), +LETTER('g',M_IMPLOSIVE,M_SMALLCAP), +LETTER('h',M_SMALLCAP,0), +LETTER('j',M_CURL,0), +LETTER('k',M_TURNED,0), +LETTER('l',M_SMALLCAP,0), +LETTER('q',M_HOOK,0), // U+2a0 +LETTER(L_GLOTTAL,M_STROKE,0), +LETTER(L_GLOTTAL,M_STROKE,M_REVERSED), +LIGATURE('d','z',0), +0, // dezh +LIGATURE('d','z',M_CURL), +LIGATURE('t','s',0), +0, // tesh +LIGATURE('t','s',M_CURL), +}; int Translator::LookupLetter2(unsigned int letter, char *ph_buf) {//============================================================= @@ -257,14 +391,15 @@ int Translator::LookupLetter2(unsigned int letter, char *ph_buf) single_letter[0] = 0; single_letter[1] = '_'; len = utf8_out(letter, &single_letter[2]); - single_letter[2+len] = 0; + single_letter[len+2] = ' '; + single_letter[len+3] = 0; if(Lookup(&single_letter[1],ph_buf) == 0) { single_letter[1] = ' '; if(Lookup(&single_letter[2],ph_buf) == 0) { - TranslateRules(&single_letter[2], ph_buf, 20, NULL,0,0); + TranslateRules(&single_letter[2], ph_buf, 20, NULL,0,NULL); } } return(ph_buf[0]); @@ -274,45 +409,79 @@ int Translator::LookupLetter2(unsigned int letter, char *ph_buf) void Translator::LookupAccentedLetter(unsigned int letter, char *ph_buf) {//===================================================================== // lookup the character in the accents table - int accent_data; - int accent1; + int accent_data = 0; + int accent1 = 0; + int accent2 = 0; int basic_letter; int letter2=0; char ph_letter1[30]; char ph_letter2[30]; char ph_accent1[30]; + char ph_accent2[30]; if((letter >= 0xe0) && (letter < 0x17f)) { accent_data = letter_accents_0e0[letter - 0xe0]; + } + else + if((letter >= 0x250) && (letter <= 0x2a8)) + { + accent_data = letter_accents_250[letter - 0x250]; + } - basic_letter = accent_data & 0x7f; - if((accent1 = (accent_data >> 8) & 0x7f) != 0) + if(accent_data != 0) + { + basic_letter = (accent_data & 0x3f) + 59; + if(basic_letter < 'a') + basic_letter = non_ascii_tab[basic_letter-59]; + + if(accent_data & 0x8000) { - if(accent_data & 0x8000) - { - letter2 = accent1; - accent1 = 0; - } + letter2 = (accent_data >> 6) & 0x3f; + letter2 += 59; + accent2 = (accent_data >> 12) & 0x7; + } + else + { + accent1 = (accent_data >> 6) & 0x1f; + accent2 = (accent_data >> 11) & 0xf; + } - if(Lookup(accents_tab[accent1].name, ph_accent1) != 0) - { - if(LookupLetter2(basic_letter, ph_letter1) != 0) + if(Lookup(accents_tab[accent1].name, ph_accent1) != 0) + { + + if(LookupLetter2(basic_letter, ph_letter1) != 0) + { + if(accent2 != 0) + { + if(Lookup(accents_tab[accent2].name, ph_accent2) == 0) + { +// break; + } + + if(accents_tab[accent2].flags & 1) + { + strcpy(ph_buf,ph_accent2); + ph_buf += strlen(ph_buf); + ph_accent2[0] = 0; + } + } + if(letter2 != 0) + { + //ligature + LookupLetter2(letter2, ph_letter2); + sprintf(ph_buf,"%s%c%s%c%s%s",ph_accent1, phonPAUSE_VSHORT, ph_letter1, phonSTRESS_P, ph_letter2, ph_accent2); + } + else { if(accent1 == 0) - { - //ligature - LookupLetter2(letter2, ph_letter2); - sprintf(ph_buf,"%s%c%s%s",ph_accent1, phonPAUSE_VSHORT, ph_letter1, ph_letter2); - } + strcpy(ph_buf, ph_letter1); else - { - if(langopts.accents & 1) - sprintf(ph_buf,"%s%c%s", ph_accent1, phonPAUSE_VSHORT, ph_letter1); - else - sprintf(ph_buf,"%s%c%s%c", ph_letter1, phonPAUSE_VSHORT, ph_accent1, phonPAUSE_VSHORT); - } + if((langopts.accents & 1) || (accents_tab[accent1].flags & 1)) + sprintf(ph_buf,"%s%c%c%s", ph_accent1, phonPAUSE_VSHORT, phonSTRESS_P, ph_letter1); + else + sprintf(ph_buf,"%s%c%s%c", ph_letter1, phonPAUSE_VSHORT, ph_accent1, phonPAUSE_VSHORT); } } } @@ -379,7 +548,7 @@ void Translator::LookupLetter(unsigned int letter, int next_byte, char *ph_buf1) single_letter[1] = ' '; if(Lookup(&single_letter[2],ph_buf3) == 0) { - TranslateRules(&single_letter[2], ph_buf3, sizeof(ph_buf3), NULL,0,0); + TranslateRules(&single_letter[2], ph_buf3, sizeof(ph_buf3), NULL,0,NULL); } } @@ -451,7 +620,8 @@ int Translator::TranslateLetter(char *word, char *phonemes, int control, int wor return(0); } - if((ph_buf[0] == 0) && (word_length == 1) && (translator_name != L('e','n'))) + if((ph_buf[0] == 0) && (translator_name != L('e','n'))) +// if((ph_buf[0] == 0) && (word_length == 1) && (translator_name != L('e','n'))) { // speak as English, check whether there is a translation for this character SetTranslator2("en"); @@ -473,7 +643,7 @@ int Translator::TranslateLetter(char *word, char *phonemes, int control, int wor if((ph_buf[0]==0) && !iswspace(letter)) Lookup("_??",ph_buf); - if((control==4) && (ph_buf[0] != 0)) + if(ph_buf[0] != 0) { // speak the hexadecimal number of the character code sprintf(hexbuf,"%x",letter); diff --git a/src/readclause.cpp b/src/readclause.cpp index 15d9bac9..1da0558a 100644 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -545,7 +545,7 @@ const char *Translator::LookupCharName(int c) { // now try the rules single_letter[1] = ' '; - TranslateRules(&single_letter[2], phonemes, sizeof(phonemes), NULL,0,0); + TranslateRules(&single_letter[2], phonemes, sizeof(phonemes), NULL,0,NULL); } } diff --git a/src/speak.cpp b/src/speak.cpp index ea6ec81e..82fb2d9a 100755 --- a/src/speak.cpp +++ b/src/speak.cpp @@ -99,6 +99,8 @@ static const char *help_text = "--punct=\"\"\n" "\t Speak the names of punctuation characters during speaking. If\n" "\t = is omitted, all punctuation is spoken.\n" +"--split=\"\"\n" +"\t Starts a new WAV file every . Used with -w\n" "--voices=\n" "\t List the available voices for the specified language.\n" "\t If is omitted, then list all voices.\n" diff --git a/src/synthdata.cpp b/src/synthdata.cpp index a9572fe7..70bb0b63 100755 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,8 +35,8 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.31.20 01.Mar.08"; -const int version_phdata = 0x013105; +const char *version_string = "1.32 04.Mar.08"; +const int version_phdata = 0x013200; int option_device_number = -1; diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp index ef48b7d1..9b8c4a89 100644 --- a/src/tr_languages.cpp +++ b/src/tr_languages.cpp @@ -330,6 +330,7 @@ Translator *SelectTranslator(const char *name) tr->langopts.param[LOPT_REGRESSIVE_VOICING] = 0x3; tr->langopts.max_initial_consonants = 5; tr->langopts.spelling_stress = 1; + tr->langopts.accents = 1; tr->langopts.numbers = 0x140d + 0x4000 + NUM_ROMAN_UC; tr->langopts.numbers2 = 0x4a; // variant numbers before thousands,milliards @@ -442,8 +443,8 @@ SetLengthMods(tr,3); // all equal case L('k','u'): // Kurdish { - static const unsigned char stress_amps_ku[8] = {16,16, 20,20, 20,24, 24,22 }; - static const short stress_lengths_ku[8] = {170,170, 190,170, 0,0, 230,240}; + static const unsigned char stress_amps_ku[8] = {18,18, 20,20, 20,24, 24,22 }; + static const short stress_lengths_ku[8] = {180,180, 190,180, 0,0, 230,240}; tr = new Translator(); SetupTranslator(tr,stress_lengths_ku,stress_amps_ku); @@ -451,7 +452,7 @@ SetLengthMods(tr,3); // all equal tr->langopts.stress_rule = 7; // stress on the last syllable, before any explicitly unstressed syllable - tr->langopts.numbers = 0x100469; + tr->langopts.numbers = 0x100461; tr->langopts.max_initial_consonants = 2; } break; @@ -501,6 +502,7 @@ SetLengthMods(tr,3); // all equal SetLetterVowel(tr,'y'); tr->langopts.numbers = 0x11c19; + tr->langopts.accents = 1; memcpy(tr->stress_lengths,stress_lengths_nl,sizeof(tr->stress_lengths)); } break; @@ -630,6 +632,7 @@ SetLengthMods(tr,3); // all equal SetLetterVowel(tr,'y'); // SetLetterBits(tr,6,"eiyäö"); // soft vowels NOTE accented letters don't work in SetLetterBits tr->langopts.numbers = 0x1909; + tr->langopts.accents = 1; } break; @@ -762,6 +765,7 @@ SetLengthMods(tr,3); // all equal if(name2 == L('z','h')) { tr->langopts.textmode = 1; + tr->langopts.listx = 1; // compile zh_listx after zh_list } } break; diff --git a/src/translate.cpp b/src/translate.cpp index c94cb4f3..44db22aa 100755 --- a/src/translate.cpp +++ b/src/translate.cpp @@ -758,6 +758,8 @@ if((wmark > 0) && (wmark < 8)) { // change to another language in order to translate this word strcpy(word_phonemes,phonemes); + if(word_length > 1) + return(FLAG_SPELLWORD); // a mixture of languages, retranslate as individual letters, separated by spaces return(0); } } @@ -785,7 +787,7 @@ if((wmark > 0) && (wmark < 8)) { // change to another language in order to translate this word strcpy(word_phonemes,phonemes); - return(0); + return(FLAG_SPELLWORD); } p = &wordx[word_length-3]; // this looks wrong. Doesn't consider multi-byte chars. @@ -810,7 +812,7 @@ if((wmark > 0) && (wmark < 8)) { // Translate the stem unpron_length = strlen(phonemes); - end_type = TranslateRules(wordx, phonemes, N_WORD_PHONEMES, end_phonemes, wflags, dictionary_flags[0]); + end_type = TranslateRules(wordx, phonemes, N_WORD_PHONEMES, end_phonemes, wflags, dictionary_flags); if(phonemes[0] == phonSWITCH) { @@ -859,11 +861,11 @@ if((wmark > 0) && (wmark < 8)) // remove any standard suffix and confirm that the prefix is still recognised phonemes2[0] = 0; - end2 = TranslateRules(wordx, phonemes2, N_WORD_PHONEMES, end_phonemes2, wflags|FLAG_NO_PREFIX|FLAG_NO_TRACE, dictionary_flags[0]); + end2 = TranslateRules(wordx, phonemes2, N_WORD_PHONEMES, end_phonemes2, wflags|FLAG_NO_PREFIX|FLAG_NO_TRACE, dictionary_flags); if(end2) { RemoveEnding(wordx,end2,word_copy); - end_type = TranslateRules(wordx, phonemes, N_WORD_PHONEMES, end_phonemes, wflags|FLAG_NO_TRACE, dictionary_flags[0]); + end_type = TranslateRules(wordx, phonemes, N_WORD_PHONEMES, end_phonemes, wflags|FLAG_NO_TRACE, dictionary_flags); memcpy(wordx,word_copy,strlen(word_copy)); if((end_type & SUFX_P) == 0) { @@ -920,7 +922,7 @@ if((wmark > 0) && (wmark < 8)) found = LookupDictList(&wordpf, phonemes, dictionary_flags, SUFX_P, wtab); // without prefix if(found == 0) { - end_type = TranslateRules(wordpf, phonemes, N_WORD_PHONEMES, end_phonemes, 0, dictionary_flags[0]); + end_type = TranslateRules(wordpf, phonemes, N_WORD_PHONEMES, end_phonemes, 0, dictionary_flags); sprintf(prefix_phonemes,"%s%s%s",phonemes,end_phonemes,prefix_phonemes2); } prefix_flags = 1; @@ -942,7 +944,7 @@ if((wmark > 0) && (wmark < 8)) prefix_flags = 1; if(found == 0) { - end_type = TranslateRules(wordx, phonemes, N_WORD_PHONEMES, end_phonemes, 0, dictionary_flags[0]); + end_type = TranslateRules(wordx, phonemes, N_WORD_PHONEMES, end_phonemes, 0, dictionary_flags); if(phonemes[0] == phonSWITCH) { @@ -1011,9 +1013,9 @@ strcpy(phonemes2,phonemes); else { if(end_flags & FLAG_SUFX) - TranslateRules(wordx, phonemes, N_WORD_PHONEMES, NULL,wflags | FLAG_SUFFIX_REMOVED, dictionary_flags[0]); + TranslateRules(wordx, phonemes, N_WORD_PHONEMES, NULL,wflags | FLAG_SUFFIX_REMOVED, dictionary_flags); else - TranslateRules(wordx, phonemes, N_WORD_PHONEMES, NULL,wflags,dictionary_flags[0]); + TranslateRules(wordx, phonemes, N_WORD_PHONEMES, NULL,wflags,dictionary_flags); if(phonemes[0] == phonSWITCH) { @@ -1041,12 +1043,12 @@ strcpy(phonemes2,phonemes); { // s or 's suffix, append [s], [z] or [Iz] depending on previous letter if(last_char == 'f') - TranslateRules(&word_ss[1], phonemes, N_WORD_PHONEMES, NULL, 0, 0); + TranslateRules(&word_ss[1], phonemes, N_WORD_PHONEMES, NULL, 0, NULL); else if((last_char==0) || (strchr_w("hsx",last_char)==NULL)) - TranslateRules(&word_zz[1], phonemes, N_WORD_PHONEMES, NULL, 0, 0); + TranslateRules(&word_zz[1], phonemes, N_WORD_PHONEMES, NULL, 0, NULL); else - TranslateRules(&word_iz[1], phonemes, N_WORD_PHONEMES, NULL, 0, 0); + TranslateRules(&word_iz[1], phonemes, N_WORD_PHONEMES, NULL, 0, NULL); } wflags |= emphasize_allcaps; @@ -1396,6 +1398,13 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne flags = translator->TranslateWord(word, next_pause, wtab); + if(flags & FLAG_SPELLWORD) + { + // re-translate the word as individual letters, separated by spaces + memcpy(word, word_copy, word_copy_len); + return(flags); + } + if((flags & FLAG_ALT2_TRANS) && ((sylimit = langopts.param[LOPT_COMBINE_WORDS]) > 0)) { char *p2; @@ -2094,8 +2103,8 @@ if((c == '/') && (langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(prev_ou c = ' '; } #endif - if((c == 0x92) || (c == 0xb4) || (c == 0x2019)) - c = '\''; // 'microsoft' quote or sexed closing single quote - possibly used as apostrophe + if((c == 0x92) || (c == 0xb4) || (c == 0x2019) || (c == 0x2032)) + c = '\''; // 'microsoft' quote or sexed closing single quote, or prime - possibly used as apostrophe if((c == '?') && IsAlpha(prev_out) && IsAlpha(next_in)) { @@ -2425,6 +2434,7 @@ if((c == '/') && (langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(prev_ou for(ix=0; ixlanguages[0] != 0) && (strcmp(&v->languages[1],"variant") != 0)) + if((v->languages[0] != 0) && (strcmp(&v->languages[1],"variant") != 0) && (memcmp(v->identifier,"mb/",3) != 0)) { voices[j++] = v; } diff --git a/src/wave_pulse.cpp b/src/wave_pulse.cpp index f8cd664d..d5fbc8c1 100755 --- a/src/wave_pulse.cpp +++ b/src/wave_pulse.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifndef PLATFORM_WINDOWS #include @@ -48,6 +49,18 @@ enum {ONE_BILLION=1000000000}; +enum { +// /* 100ms. +// If a greater value is set (several seconds), +// please update _pulse_timeout_start accordingly */ +// PULSE_TIMEOUT_IN_USEC = 100000, + + /* return value */ + PULSE_OK = 0, + PULSE_ERROR = -1, + PULSE_NO_CONNECTION = -2 +}; + #ifdef USE_PULSEAUDIO static t_wave_callback* my_callback_is_output_enabled=NULL; @@ -62,6 +75,8 @@ static t_wave_callback* my_callback_is_output_enabled=NULL; #define MINREQ 880 #define FRAGSIZE 0 +static pthread_mutex_t pulse_mutex; + static pa_context *context = NULL; static pa_stream *stream = NULL; static pa_threaded_mainloop *mainloop = NULL; @@ -81,7 +96,7 @@ if (!mainloop || \ !context || pa_context_get_state(context) != PA_CONTEXT_READY || \ !stream || pa_stream_get_state(stream) != PA_STREAM_READY) { \ if (warn) \ - printf("Connection died: %s\n", context ? pa_strerror(pa_context_errno(context)) : "NULL"); \ + SHOW("Connection died: %s\n", context ? pa_strerror(pa_context_errno(context)) : "NULL"); \ goto label; \ } \ } while(0); @@ -91,6 +106,11 @@ do { \ if (!connected) return retval; \ } while (0); +#define CHECK_CONNECTED_NO_RETVAL(id) \ + do { \ + if (!connected){ SHOW("CHECK_CONNECTED_NO_RETVAL: !pulse_connected\n", ""); return; } \ + } while (0); + //> @@ -136,7 +156,7 @@ static void subscribe_cb(struct pa_context *c, enum pa_subscription_event_type t return; if (!(o = pa_context_get_sink_input_info(c, index, info_cb, NULL))) { - printf("pa_context_get_sink_input_info() failed: %s\n", pa_strerror(pa_context_errno(c))); + SHOW("pa_context_get_sink_input_info() failed: %s\n", pa_strerror(pa_context_errno(c))); return; } @@ -365,20 +385,21 @@ fail: pa_threaded_mainloop_unlock(mainloop); } -static void drain(void) { +static int drain(void) { pa_operation *o = NULL; int success = 0; + int ret = PULSE_ERROR; ENTER(__FUNCTION__); - CHECK_CONNECTED(); + CHECK_CONNECTED(ret); pa_threaded_mainloop_lock(mainloop); CHECK_DEAD_GOTO(fail, 0); SHOW_TIME("pa_stream_drain (call)"); if (!(o = pa_stream_drain(stream, stream_success_cb, &success))) { - printf("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context))); + SHOW("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context))); goto fail; } @@ -389,8 +410,12 @@ static void drain(void) { } SHOW_TIME("pa_threaded_mainloop_wait (ret)"); - if (!success) - printf("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context))); + if (!success) { + SHOW("pa_stream_drain() failed: %s\n", pa_strerror(pa_context_errno(context))); + } + else { + ret = PULSE_OK; + } fail: SHOW_TIME("pa_operation_unref (call)"); @@ -399,6 +424,8 @@ fail: pa_threaded_mainloop_unlock(mainloop); SHOW_TIME("drain (ret)"); + + return ret; } @@ -413,12 +440,7 @@ static void pulse_close(void) { if (mainloop) pa_threaded_mainloop_stop(mainloop); - if (stream) { - SHOW_TIME("pa_stream_disconnect (call)"); - pa_stream_disconnect(stream); - pa_stream_unref(stream); - stream = NULL; - } + connected = 0; if (context) { SHOW_TIME("pa_context_disconnect (call)"); @@ -443,12 +465,15 @@ static int pulse_open() pa_sample_spec ss; pa_operation *o = NULL; int success; + int ret = PULSE_ERROR; assert(!mainloop); assert(!context); assert(!stream); assert(!connected); + pthread_mutex_init( &pulse_mutex, (const pthread_mutexattr_t *)NULL); + ss.format = ESPEAK_FORMAT; ss.rate = SAMPLE_RATE; ss.channels = ESPEAK_CHANNEL; @@ -464,7 +489,7 @@ static int pulse_open() SHOW_TIME("pa_threaded_mainloop_new (call)"); if (!(mainloop = pa_threaded_mainloop_new())) { - printf("Failed to allocate main loop\n"); + SHOW("Failed to allocate main loop\n",""); goto fail; } @@ -472,7 +497,7 @@ static int pulse_open() SHOW_TIME("pa_context_new (call)"); if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), "eSpeak"))) { - printf("Failed to allocate context\n"); + SHOW("Failed to allocate context\n",""); goto unlock_and_fail; } @@ -481,13 +506,14 @@ static int pulse_open() SHOW_TIME("pa_context_connect (call)"); if (pa_context_connect(context, NULL, (pa_context_flags_t)0, NULL) < 0) { - printf("Failed to connect to server: %s", pa_strerror(pa_context_errno(context))); + SHOW("Failed to connect to server: %s", pa_strerror(pa_context_errno(context))); + ret = PULSE_NO_CONNECTION; goto unlock_and_fail; } SHOW_TIME("pa_threaded_mainloop_start (call)"); if (pa_threaded_mainloop_start(mainloop) < 0) { - printf("Failed to start main loop"); + SHOW("Failed to start main loop",""); goto unlock_and_fail; } @@ -496,13 +522,16 @@ static int pulse_open() pa_threaded_mainloop_wait(mainloop); if (pa_context_get_state(context) != PA_CONTEXT_READY) { - printf("Failed to connect to server: %s", pa_strerror(pa_context_errno(context))); + SHOW("Failed to connect to server: %s", pa_strerror(pa_context_errno(context))); + ret = PULSE_NO_CONNECTION; + if (mainloop) + pa_threaded_mainloop_stop(mainloop); goto unlock_and_fail; } SHOW_TIME("pa_stream_new"); if (!(stream = pa_stream_new(context, "unknown", &ss, NULL))) { - printf("Failed to create stream: %s", pa_strerror(pa_context_errno(context))); + SHOW("Failed to create stream: %s", pa_strerror(pa_context_errno(context))); goto unlock_and_fail; } @@ -522,7 +551,7 @@ static int pulse_open() SHOW_TIME("pa_connect_playback"); if (pa_stream_connect_playback(stream, NULL, &a_attr, (pa_stream_flags_t)(PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE), &volume, NULL) < 0) { - printf("Failed to connect stream: %s", pa_strerror(pa_context_errno(context))); + SHOW("Failed to connect stream: %s", pa_strerror(pa_context_errno(context))); goto unlock_and_fail; } @@ -531,14 +560,14 @@ static int pulse_open() pa_threaded_mainloop_wait(mainloop); if (pa_stream_get_state(stream) != PA_STREAM_READY) { - printf("Failed to connect stream: %s", pa_strerror(pa_context_errno(context))); + SHOW("Failed to connect stream: %s", pa_strerror(pa_context_errno(context))); goto unlock_and_fail; } /* Now subscribe to events */ SHOW_TIME("pa_context_subscribe"); if (!(o = pa_context_subscribe(context, PA_SUBSCRIPTION_MASK_SINK_INPUT, context_success_cb, &success))) { - printf("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context))); + SHOW("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context))); goto unlock_and_fail; } @@ -550,7 +579,7 @@ static int pulse_open() } if (!success) { - printf("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context))); + SHOW("pa_context_subscribe() failed: %s", pa_strerror(pa_context_errno(context))); goto unlock_and_fail; } @@ -558,7 +587,7 @@ static int pulse_open() /* Now request the initial stream info */ if (!(o = pa_context_get_sink_input_info(context, pa_stream_get_index(stream), info_cb, NULL))) { - printf("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context))); + SHOW("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context))); goto unlock_and_fail; } @@ -569,7 +598,7 @@ static int pulse_open() } /* if (!volume_valid) { */ -/* printf("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context))); */ +/* SHOW("pa_context_get_sink_input_info() failed: %s", pa_strerror(pa_context_errno(context))); */ /* goto unlock_and_fail; */ /* } */ @@ -583,7 +612,9 @@ static int pulse_open() pa_threaded_mainloop_unlock(mainloop); SHOW_TIME("pulse_open (ret true)"); - return true; + // return true; + return PULSE_OK; + unlock_and_fail: @@ -594,13 +625,29 @@ unlock_and_fail: fail: + // pulse_close(); + + if (ret == PULSE_NO_CONNECTION) { + if (context) { + SHOW_TIME("pa_context_disconnect (call)"); + pa_context_disconnect(context); + pa_context_unref(context); + context = NULL; + } + + if (mainloop) { + SHOW_TIME("pa_threaded_mainloop_free (call)"); + pa_threaded_mainloop_free(mainloop); + mainloop = NULL; + } + } + else { pulse_close(); + } - SHOW_TIME("pulse_open (ret false)"); - - return false; - - + SHOW_TIME("pulse_open (ret false)"); + + return ret; } @@ -661,13 +708,16 @@ size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSiz size_t aTotalFreeMem=0; + pthread_mutex_lock(&pulse_mutex); + while (1) { if (my_callback_is_output_enabled && (0==my_callback_is_output_enabled())) { SHOW_TIME("wave_write > my_callback_is_output_enabled: no!"); - return 0; + theSize=0; + goto terminate; } aTotalFreeMem = pulse_free(); @@ -698,9 +748,10 @@ size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSiz pulse_write(aBuffer, bytes_to_write); - + terminate: + pthread_mutex_unlock(&pulse_mutex); + SHOW("wave_write: theSize=%d", theSize); SHOW_TIME("wave_write > LEAVE"); - return theSize; } @@ -711,9 +762,18 @@ int wave_close(void* theHandler) { SHOW_TIME("wave_close > ENTER"); + int a_status = pthread_mutex_lock(&pulse_mutex); + if (a_status) { + SHOW("Error: pulse_mutex lock=%d (%s)\n", a_status, __FUNCTION__); + return PULSE_ERROR; + } + drain(); - return 0; + pthread_mutex_unlock(&pulse_mutex); + SHOW_TIME("wave_close (ret)"); + + return PULSE_OK; } //> @@ -738,8 +798,16 @@ void wave_terminate() // Pa_Terminate(); + int a_status; + pthread_mutex_t* a_mutex = NULL; + a_mutex = &pulse_mutex; + a_status = pthread_mutex_lock(a_mutex); + pulse_close(); + SHOW_TIME("unlock mutex"); + a_status = pthread_mutex_unlock(a_mutex); + pthread_mutex_destroy(a_mutex); } //>