Browse Source

[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
master
jonsd 17 years ago
parent
commit
99e2976c86
53 changed files with 1091 additions and 434 deletions
  1. 4
    0
      dictsource/cs_list
  2. 0
    1
      dictsource/cs_rules
  3. 3
    0
      dictsource/de_list
  4. 39
    45
      dictsource/dict_phonemes
  5. 53
    17
      dictsource/en_list
  6. 3
    1
      dictsource/en_rules
  7. 1
    1
      dictsource/es_list
  8. 12
    5
      dictsource/es_rules
  9. 4
    2
      dictsource/fr_list
  10. 5
    2
      dictsource/fr_rules
  11. 93
    0
      dictsource/grc_rules
  12. 7
    1
      dictsource/hbs_list
  13. 5
    4
      dictsource/is_rules
  14. 23
    0
      dictsource/nl_list
  15. 34
    6
      dictsource/pl_list
  16. 1
    10
      dictsource/pl_rules
  17. 100
    77
      dictsource/pt_list
  18. 3
    4
      dictsource/pt_rules
  19. 2
    2
      dictsource/sk_list
  20. 27
    0
      dictsource/sv_list
  21. 6
    6
      dictsource/sv_rules
  22. 45
    0
      dictsource/ta_list
  23. 14
    8
      dictsource/ta_rules
  24. 49
    0
      dictsource/tr_list
  25. 8
    2
      docs/dictionary.html
  26. 40
    11
      docs/languages.html
  27. 6
    1
      docs/voices.html
  28. 15
    63
      phsource/compile_report
  29. 5
    2
      phsource/ph_english_us
  30. 2
    9
      phsource/ph_portugal
  31. 1
    1
      phsource/ph_pt_brazil
  32. 0
    1
      phsource/ph_spanish
  33. 6
    6
      phsource/phonemes
  34. BIN
      phsource/vowel/&
  35. BIN
      phsource/vowel/i#
  36. BIN
      phsource/vowel/ii
  37. BIN
      phsource/vwl_en_us/i_final3
  38. BIN
      phsource/vwl_en_us/ii
  39. 12
    2
      platforms/windows/make_espeak.iss
  40. 3
    3
      platforms/windows/make_espeakedit.iss
  41. 18
    2
      src/compiledict.cpp
  42. 57
    28
      src/dictionary.cpp
  43. 5
    3
      src/espeak.cpp
  44. 2
    2
      src/intonation.cpp
  45. 217
    47
      src/numbers.cpp
  46. 1
    1
      src/readclause.cpp
  47. 2
    0
      src/speak.cpp
  48. 2
    2
      src/synthdata.cpp
  49. 7
    3
      src/tr_languages.cpp
  50. 40
    14
      src/translate.cpp
  51. 4
    2
      src/translate.h
  52. 2
    2
      src/voices.cpp
  53. 103
    35
      src/wave_pulse.cpp

+ 4
- 0
dictsource/cs_list View File

@@ -48,6 +48,10 @@ y ipsilon
_z zet
ž Zet

ë $accent
ö $accent
ü $accent


_#9 t'ap
_#32 m'ezeRa // space

+ 0
- 1
dictsource/cs_rules View File

@@ -625,7 +625,6 @@ _flegma) ti ti
ž (_G Z

.group
ä e
ë e
ĺ l-
ö e:

+ 3
- 0
dictsource/de_list View File

@@ -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:*

+ 39
- 45
dictsource/dict_phonemes View File

@@ -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

a a: e E: i i: o O
O: u y
Dictionary ja_dict

c d h k l m n N
p s t


Dictionary hbs_dict
@@ -389,36 +387,32 @@ r R s S t tS v w
x z


Dictionary ja_dict
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 v w x z


Dictionary tr_dict

a e E i I o O u
u# W y Y
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
* 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
a e 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

* : 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
: 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

+ 53
- 17
dictsource/en_list View File

@@ -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

+ 3
- 1
dictsource/en_rules View File

@@ -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

+ 1
- 1
dictsource/es_list View File

@@ -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


+ 12
- 5
dictsource/es_rules View File

@@ -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

+ 4
- 2
dictsource/fr_list View File

@@ -5,7 +5,7 @@

// 2006-11-18 Gilles Casse <[email protected]>
//
// Updated 2008-02-29 Michel Such <[email protected]>
// Updated 2008-03-01 Michel Such <[email protected]>
//
// * 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~





+ 5
- 2
dictsource/fr_rules View File

@@ -4,7 +4,7 @@

// 2006-11-18 Gilles Casse <[email protected]>
//
// Updated: 2008-02-26 Michel Such <[email protected]>
// Updated: 2008-03-04 Michel Such <[email protected]>
//
// * 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





+ 93
- 0
dictsource/grc_rules View File

@@ -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:

+ 7
- 1
dictsource/hbs_list View File

@@ -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

+ 5
- 4
dictsource/is_rules View File

@@ -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

+ 23
- 0
dictsource/nl_list View File

@@ -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

+ 34
- 6
dictsource/pl_list View File

@@ -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

+ 1
- 10
dictsource/pl_rules View File

@@ -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

+ 100
- 77
dictsource/pt_list View File

@@ -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&

i i // speak i v x as letters, not Roman numbers
v ve
$accent
$accent
_à $accent
_â $accent
_ã $accent
_ç $accent
_é $accent
_ê $accent
_í $accent
_ó $accent
_ô $accent
_õ $accent
_ú $accent
_ü $accent
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





+ 3
- 4
dictsource/pt_rules View File

@@ -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

+ 2
- 2
dictsource/sk_list View File

@@ -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



+ 27
- 0
dictsource/sv_list View File

@@ -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



+ 6
- 6
dictsource/sv_rules View File

@@ -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

+ 45
- 0
dictsource/ta_list View File

@@ -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_

+ 14
- 8
dictsource/ta_rules View File

@@ -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

+ 49
- 0
dictsource/tr_list View File

@@ -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

+ 8
- 2
docs/dictionary.html View File

@@ -3,7 +3,6 @@

<head>
<title>eSpeak: Pronunciation Dictionaries</title>
<meta name="GENERATOR" content="Quanta Plus">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
@@ -489,10 +488,14 @@ A word (or group of words) may be given one or more flags, either instead of, or
<td>&nbsp;</td>
</tr>
<tr>
<td>$accent</td>
<td>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 "&#xe2;" is spoken as "a" "circumflex".</td>
</tr>
<tr>
<td>$alt &nbsp; $alt2</td>
<td>These are language specific. Their use should be described in the language's **_list file</td>
</tr>
<tr>
<tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
@@ -583,6 +586,9 @@ _0 to _9 &nbsp;
<td>The numbers 0 to 9
</tr>
<tr>
<td>_13<td>etc. Any pronunciations which are needed for specific numbers in the range _11 to _99 &nbsp;
</tr>
<tr>
<td>_2X &nbsp;_3X<td>Twenty, thirty, etc., used to make numbers 10 to 99 &nbsp;
</tr>
<tr>

+ 40
- 11
docs/languages.html View File

@@ -79,7 +79,7 @@ The eSpeak speech synthesizer does text to speech for the following additional l
<p>
<dt>
<strong>af &nbsp;Afrikaans</strong><br>
<dd>This has been worked on by a native speaker and it should be OK.</dd>
<dd>This has been worked on by native speakers and it should be OK.</dd>
<p>
<dt>
<strong>bs &nbsp;Bosnian</strong><br>
@@ -110,7 +110,13 @@ The eSpeak speech synthesizer does text to speech for the following additional l
<p>
<dt>
<strong>es &nbsp;Spanish</strong><br>
<dd>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.</dd>
<dd>Spanish has good spelling rules, so it should be OK.</dd>
<p>
<dt>
<strong>es-la &nbsp;Spanish - Latin America</strong><br>
<dd>
This contains a few changes from <strong>es</strong>, notably the pronunciation of "z","ce","ci".
</dd>
<p>
<dt>
<strong>fi &nbsp;Finnish</strong><br>
@@ -119,7 +125,7 @@ The eSpeak speech synthesizer does text to speech for the following additional l
<p>
<dt>
<strong>fr &nbsp;French</strong><br>
<dd>Needs improvement, both for spelling-to-phoneme rules and the sounds and prosody.
<dd>This has been improved by a native speaker, and should be OK.
</dd>
<p>
<dt>
@@ -137,6 +143,12 @@ The eSpeak speech synthesizer does text to speech for the following additional l
<dd>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].</dd>
<p>
<dt>
<strong>ku &nbsp;Kurdish</strong><br>
<dd>
Not much work yet, but Kurdish has good spelling rules so it should be OK.
</dd>
<p>
<dt>
<strong>pt &nbsp;Portuguese (Brazil)</strong><br>
<dd>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.<p>
</dd>
@@ -153,7 +165,7 @@ The eSpeak speech synthesizer does text to speech for the following additional l
<p>
<dt>
<strong>sk &nbsp;Slovak</strong><br>
<dd>A little initial feedback.
<dd>This has had assistance from a nativ speaker, so it should be OK.
</dd>
<p>
<dt>
@@ -171,6 +183,25 @@ The eSpeak speech synthesizer does text to speech for the following additional l
<dd>Not much feedback yet, but the spelling and stress rules are fairly regular, so it's probably usable.
</dd>
<p>
<dt>
<strong>ta &nbsp;Tamil</strong><br>
<dd>
Not much work yet, but I'm told it sounds reasonable.
</dd>
<p>
<dt>
<strong>tr &nbsp;Turkish</strong><br>
<dd>
Not much work yet, but I'm told it sounds reasonable.
</dd>
<p>
<dt>
<strong>zh &nbsp;Mandarin Chinese</strong><br>
<dd>
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:
<a href="http://espeak.sourceforge.net/data/">http://espeak.sourceforge.net/data/</a>.
</dd>
<p>
</dl></ul>
<h3>3.5 Provisional Languages</h3>
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
</dd>
<p>
<dt>
<strong>id &nbsp;Indonesian</strong><br>
<dd>An initial guess, no feedback yet.
</dd>
<p>
<dt>
<strong>is &nbsp;Icelandic</strong><br>
<dd>An initial guess, awaiting feedback.
</dd>
@@ -239,13 +275,6 @@ Russian stress position is unpredictable so a large lookup dictionary is needed
</dd>
<p>
<dt>
<strong>zh &nbsp;Mandarin Chinese</strong><br>
<dd>
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:
<a href="http://espeak.sourceforge.net/data/">http://espeak.sourceforge.net/data/</a>.
</dd>
<p>
<dt>
<strong>zhy &nbsp;Cantonese Chinese</strong><br>
<dd>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: <a href="http://espeak.sourceforge.net/data/">http://espeak.sourceforge.net/data/</a>.<br>The voice can also read Jyutping romanised text.
</dd>

+ 6
- 1
docs/voices.html View File

@@ -3,7 +3,6 @@

<head>
<title>eSpeak: Voice Files</title>
<meta name="GENERATOR" content="Quanta Plus">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
@@ -115,6 +114,12 @@ don't have their own <strong>tone</strong> statement.
Adjusts the strength of formant-synthesized sounds (vowels and sonorant consonants).
<p>
<dt>
<strong>consonants &nbsp;&lt;value&gt;&nbsp;&lt;value&gt;</strong><br>
<dd> Default values: 100, 100.<br>

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".
<p>
<dt>
<strong>breath &nbsp;&lt;up to 8 integer values&gt;</strong><br>
<dd> Default values: 0.<br>


+ 15
- 63
phsource/compile_report View File

@@ -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

+ 5
- 2
phsource/ph_english_us View File

@@ -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


+ 2
- 9
phsource/ph_portugal View File

@@ -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



+ 1
- 1
phsource/ph_pt_brazil View File

@@ -1,6 +1,6 @@

//====================================================
// Portuguese - based on Italian
// Portuguese - based on Base2
//====================================================

phoneme e~

+ 0
- 1
phsource/ph_spanish View File

@@ -85,4 +85,3 @@ endphoneme





+ 6
- 6
phsource/phonemes View File

@@ -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


BIN
phsource/vowel/& View File


BIN
phsource/vowel/i# View File


BIN
phsource/vowel/ii View File


BIN
phsource/vwl_en_us/i_final3 View File


BIN
phsource/vwl_en_us/ii View File


+ 12
- 2
platforms/windows/make_espeak.iss View File

@@ -2,7 +2,7 @@
[Setup]
AppName=eSpeak
AppVerName=eSpeak version 1.30
AppVerName=eSpeak version 1.32
AppCopyright=Licensed under GNU General Public License version 3. (See file License.txt for details).
WindowVisible=yes
@@ -54,12 +54,14 @@ Name: "hr"; MessagesFile: "compiler:Languages\Croatian.isl"
Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl"
Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
Name: "no"; MessagesFile: "compiler:Languages\Norwegian.isl"
Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "ro"; MessagesFile: "compiler:Languages\Romanian.isl"
Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "sk"; MessagesFile: "compiler:Languages\Slovak.isl"
Name: "sr"; MessagesFile: "compiler:Languages\Serbian.isl"
Name: "tr"; MessagesFile: "compiler:Languages\Turkish.isl"
[CustomMessages]
v1=Select which voices to install
@@ -110,7 +112,7 @@ begin
$07: Result := 'de';
$08: Result := 'el';
$09: Result := 'en';
$0a: Result := 'es';
$0a: Result := 'es-la';
$0b: Result := 'fi';
$0c: Result := 'fr';
$0e: Result := 'hu';
@@ -125,16 +127,21 @@ begin
$1a: Result := 'hr';
$1b: Result := 'sk';
$1d: Result := 'sv';
$1f: Result := 'tr';
$21: Result := 'id';
$2a: Result := 'vi';
$2f: Result := 'mk';
$36: Result := 'af';
$39: Result := 'hi';
$41: Result := 'sw';
$49: Result := 'ta';
$52: Result := 'cy';
end;
// is there a match on the full language code?
case language of
$40a: Result := 'es';
$c0a: Result := 'es';
$816: Result := 'pt-pt';
$41a: Result := 'hr';
$81a: Result := 'sr';
@@ -176,6 +183,7 @@ begin
'hr': value := $41a;
'hu': value := $40e;
'is': value := $40f;
'id': value := $421;
'it': value := $410;
'mk': value := $42f;
'nl': value := $413;
@@ -188,6 +196,8 @@ begin
'sr': value := $81a;
'sv': value := $41d;
'sw': value := $441;
'ta': value := $449;
'tr': value := $41f;
'vi': value := $42a;
'zh': value := $804;
// mbrola voices

+ 3
- 3
platforms/windows/make_espeakedit.iss View File

@@ -1,7 +1,7 @@
[Setup]
AppName=eSpeakEdit
AppVerName=eSpeakEdit version 1.30
AppVerName=eSpeakEdit version 1.32
DefaultDirName={pf}\eSpeak
DefaultGroupName=eSpeak
OutputBaseFilename=setup_espeakedit
@@ -34,12 +34,12 @@ Name: "hr"; MessagesFile: "compiler:Languages\Croatian.isl"
Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl"
Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
Name: "no"; MessagesFile: "compiler:Languages\Norwegian.isl"
Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "ro"; MessagesFile: "compiler:Languages\Romanian.isl"
Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "sk"; MessagesFile: "compiler:Languages\Slovak.isl"
Name: "sr"; MessagesFile: "compiler:Languages\Serbian.isl"
Name: "tr"; MessagesFile: "compiler:Languages\Turkish.isl"

+ 18
- 2
src/compiledict.cpp View File

@@ -183,6 +183,7 @@ int compile_line(char *linebuf, char *dict_line, int *hash)
int len_word;
int len_phonetic;
int text_not_phonemes; // this word specifies replacement text, not phonemes
unsigned int wc;
char *mnemptr;
char *comment;
@@ -415,6 +416,13 @@ static char nullstring[] = {0};
}
}

if(sscanf(word,"U+%x",&wc) == 1)
{
// Character code
ix = utf8_out(wc, word);
word[ix] = 0;
}
else
if((word[0] & 0x80)==0) // 7 bit ascii only
{
// If first letter is uppercase, convert to lower case. (Only if it's 7bit ascii)
@@ -1515,8 +1523,16 @@ int CompileDictionary(const char *dsource, const char *dict_name, FILE *log, cha

fprintf(f_log,"Using phonemetable: '%s'\n",PhonemeTabName());
compile_dictlist_file(path,"roots");
compile_dictlist_file(path,"list");
compile_dictlist_file(path,"listx");
if(translator->langopts.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);

+ 57
- 28
src/dictionary.cpp View File

@@ -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 */

+ 5
- 3
src/espeak.cpp View File

@@ -65,6 +65,8 @@ static const char *help_text =
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
"--split=\"<minutes>\"\n"
"\t Starts a new WAV file every <minutes>. Used with -w\n"
"--voices=<langauge>\n"
"\t List the available voices for the specified language.\n"
"\t If <language> 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);

+ 2
- 2
src/intonation.cpp View File

@@ -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

+ 217
- 47
src/numbers.cpp View File

@@ -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_MIDDLE_DOT 8 // duplicate of M_DOT_ABOVE
#define M_SMALLCAP 1
#define M_TURNED 2
#define M_REVERSED 3
#define M_CURL 4

#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,46 +409,80 @@ 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];
}

if(accent_data != 0)
{
basic_letter = (accent_data & 0x3f) + 59;
if(basic_letter < 'a')
basic_letter = non_ascii_tab[basic_letter-59];

basic_letter = accent_data & 0x7f;
if((accent1 = (accent_data >> 8) & 0x7f) != 0)
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(accent1 == 0)
if(Lookup(accents_tab[accent2].name, ph_accent2) == 0)
{
//ligature
LookupLetter2(letter2, ph_letter2);
sprintf(ph_buf,"%s%c%s%s",ph_accent1, phonPAUSE_VSHORT, ph_letter1, ph_letter2);
// break;
}
else

if(accents_tab[accent2].flags & 1)
{
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);
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)
strcpy(ph_buf, ph_letter1);
else
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);

+ 1
- 1
src/readclause.cpp View File

@@ -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);
}
}


+ 2
- 0
src/speak.cpp View File

@@ -99,6 +99,8 @@ static const char *help_text =
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
"--split=\"<minutes>\"\n"
"\t Starts a new WAV file every <minutes>. Used with -w\n"
"--voices=<langauge>\n"
"\t List the available voices for the specified language.\n"
"\t If <language> is omitted, then list all voices.\n"

+ 2
- 2
src/synthdata.cpp View File

@@ -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;


+ 7
- 3
src/tr_languages.cpp View File

@@ -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;

+ 40
- 14
src/translate.cpp View File

@@ -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; ix<word_count; ix++)
{
int j;
int c_temp;
char *pn;
char *pw;
char number_buf[80];
@@ -2478,8 +2488,24 @@ if((c == '/') && (langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(prev_ou
else
{
dict_flags = TranslateWord2(word, &words[ix], words[ix].pre_pause, words[ix+1].pre_pause);

if(dict_flags & FLAG_SPELLWORD)
{
// redo the word, speaking single letters
for(pw = word; *pw != ' ';)
{
memset(number_buf,' ',9);
j = utf8_in(&c_temp, pw, 0);
memcpy(&number_buf[2],pw,j);
TranslateWord2(&number_buf[2], &words[ix], 0, 0 );
pw += j;
}
}

if(dict_flags & FLAG_SKIPWORDS)
ix += dictionary_skipwords; // dictionary indicates skip next word(s)
{
ix += dictionary_skipwords; // dictionary indicates skip next word(s)
}

if((dict_flags & FLAG_DOT) && (ix == word_count-1) && (terminator == CLAUSE_PERIOD))
{

+ 4
- 2
src/translate.h View File

@@ -46,6 +46,7 @@
#define FLAG_STRESS_END2 0x1000 /* full stress if at end of clause, or only followed by unstressed */
#define FLAG_UNSTRESS_END 0x2000 /* reduce stress at end of clause */
#define FLAG_ATEND 0x4000 /* use this pronunciation if at end of clause */
#define FLAG_SPELLWORD 0x8000 // re-translate the word as individual letters, separated by spaces

#define FLAG_DOT 0x10000 /* ignore '.' after word (abbreviation) */
#define FLAG_ABBREV 0x20000 // spell as letters, even with a vowel, OR use specified pronunciation rather than split into letters
@@ -85,7 +86,7 @@
#define FLAG_HAS_PLURAL 0x4 /* upper-case word with s or 's lower-case ending */
#define FLAG_PHONEMES 0x8 /* word is phonemes */
#define FLAG_LAST_WORD 0x10 /* last word in clause */
//#define FLAG_STRESSED_WORD 0x20 /* this word has explicit stress */
//#define FLAG_SPELLING 0x20 // speak the word as individual letters
#define FLAG_EMBEDDED 0x40 /* word is preceded by embedded commands */
#define FLAG_HYPHEN 0x80
#define FLAG_NOSPACE 0x100 // word is not seperated from previous word by a space
@@ -360,6 +361,7 @@ typedef struct {
char ideographs; // treat as separate words
char textmode; // the meaning of FLAG_TEXTMODE is reversed (to save data when *_list file is compiled)
int testing; // testing options: bit 1= specify stressed syllable in the form: "outdoor/2"
int listx; // compile *_listx after *list
const unsigned int *replace_chars; // characters to be substitutes
} LANGUAGE_OPTIONS;

@@ -451,7 +453,7 @@ private:
void AppendPhonemes(char *string, int size, const char *ph);
char *DecodeRule(const char *group, char *rule);
void MatchRule(char *word[], const char *group, char *rule, MatchRecord *match_out, int end_flags, int dict_flags);
int TranslateRules(char *p, char *phonemes, int size, char *end_phonemes, int end_flags, int dict_flags);
int TranslateRules(char *p, char *phonemes, int size, char *end_phonemes, int end_flags, unsigned int *dict_flags);
void ApplySpecialAttribute(char *phonemes, int dict_flags);

int IsLetter(int letter, int group);

+ 2
- 2
src/voices.cpp View File

@@ -1670,11 +1670,11 @@ ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec)
}
else
{
// omit variant voices
// list all: omit variant voices and mbrola voices
j = 0;
for(ix=0; (v = voices_list[ix]) != NULL; ix++)
{
if((v->languages[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;
}

+ 103
- 35
src/wave_pulse.cpp View File

@@ -37,6 +37,7 @@
#include <sys/time.h>
#include <time.h>
#include <pulse/pulseaudio.h>
#include <pthread.h>

#ifndef PLATFORM_WINDOWS
#include <unistd.h>
@@ -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();

SHOW_TIME("pulse_open (ret false)");
return false;
// 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 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);
}

//>

Loading…
Cancel
Save