Browse Source

Merge branch 'master' into build

Conflicts:
	src/compiledata.cpp
master
Reece Dunn 14 years ago
parent
commit
fa1e735d12
63 changed files with 7458 additions and 2650 deletions
  1. 497
    96
      dictsource/da_list
  2. 2752
    1403
      dictsource/da_rules
  3. 38
    23
      dictsource/dict_phonemes
  4. 47
    2
      dictsource/el_list
  5. 10
    7
      dictsource/en_list
  6. 31
    16
      dictsource/en_rules
  7. 37
    0
      dictsource/es_list
  8. 24
    8
      dictsource/fr_list
  9. 9
    3
      dictsource/fr_rules
  10. 66
    11
      dictsource/hu_list
  11. 461
    335
      dictsource/hu_rules
  12. 2
    0
      dictsource/it_list
  13. 153
    125
      dictsource/it_listx
  14. 1
    0
      dictsource/it_rules
  15. 480
    0
      dictsource/nl_list
  16. 116
    15
      dictsource/nl_rules
  17. 34
    34
      dictsource/no_list
  18. 146
    140
      dictsource/no_rules
  19. 61
    8
      dictsource/ta_list
  20. 683
    169
      dictsource/ta_rules
  21. 50
    16
      phsource/compile_report
  22. BIN
      phsource/j2/j2@
  23. BIN
      phsource/j2/j2e
  24. 1
    0
      phsource/mbrola/hu1
  25. 5
    1
      phsource/ph_dutch
  26. 12
    0
      phsource/ph_hungarian
  27. 1
    1
      phsource/ph_norwegian
  28. 2
    2
      phsource/ph_tamil
  29. 21
    0
      phsource/phonemes
  30. BIN
      phsource/vowel/i#_2
  31. 91
    41
      platforms/big_endian/espeak-phoneme-data.c
  32. 8
    0
      platforms/windows/espeakedit/espeakedit.dsp
  33. 1
    0
      platforms/windows/espeakedit/src/speech.h
  34. 1
    0
      platforms/windows/espeakedit/src_copy/speech.h
  35. 8
    0
      platforms/windows/windows_cmd/espeak.dsp
  36. 1
    0
      platforms/windows/windows_cmd/src/speech.h
  37. 8
    0
      platforms/windows/windows_dll/espeak.dsp
  38. 66
    57
      platforms/windows/windows_dll/src/speak_lib.h
  39. 1
    0
      platforms/windows/windows_dll/src/speech.h
  40. 1
    0
      platforms/windows/windows_sapi/src/speech.h
  41. 8
    0
      platforms/windows/windows_sapi/ttseng.dsp
  42. 2
    2
      platforms/windows/windows_sapi/ttsengobj.cpp
  43. 5
    4
      src/Makefile
  44. 2
    1
      src/compiledata.cpp
  45. 23
    5
      src/compiledict.cpp
  46. 53
    26
      src/dictionary.cpp
  47. 4
    2
      src/espeakedit.cpp
  48. 96
    27
      src/extras.cpp
  49. 0
    1
      src/main.h
  50. 0
    1
      src/menus.cpp
  51. 44
    19
      src/numbers.cpp
  52. 14
    12
      src/setlengths.cpp
  53. 967
    0
      src/sonic.cpp
  54. 138
    0
      src/sonic.h
  55. 1
    1
      src/speak.cpp
  56. 2
    2
      src/speak_lib.cpp
  57. 15
    2
      src/synthdata.cpp
  58. 2
    0
      src/synthesize.h
  59. 22
    6
      src/tr_languages.cpp
  60. 2
    2
      src/translate.cpp
  61. 7
    2
      src/translate.h
  62. 6
    2
      src/voices.cpp
  63. 119
    20
      src/wavegen.cpp

+ 497
- 96
dictsource/da_list
File diff suppressed because it is too large
View File


+ 2752
- 1403
dictsource/da_rules
File diff suppressed because it is too large
View File


+ 38
- 23
dictsource/dict_phonemes View File

@@ -53,27 +53,28 @@ p r s S t T v w
x z


Dictionary da_dict 2010-08-26
Dictionary da_dict 2010-12-02

& &# 0 3 @ @- a A
e E i o O u V W
W# y Y
aI e E i o O u V
W W# y Y

* - : ? b B d D
dZ f g h j J k l
l/2 l/3 m n N p r R
s S t T tS v w z
s S t T tS v w x
z


Dictionary hu_dict 2010-09-13
Dictionary hu_dict 2010-12-02

A a: E e: i i: o o:
u u: Y y y: Y:
a A a: E e: i i: o
o: u u: Y y y: Y:

- : b c d dZ dz f
g h j J k l m n
n^ p r R R2 s S s2
t tS ts v z Z
- : b c C d dZ dz
f g h j J k l m
n n^ p r R R2 s S
s2 t t2 tS ts v z Z


Dictionary de_dict 2010-08-25
@@ -89,7 +90,7 @@ n N p pF r s S t
tS ts v w x z Z


Dictionary el_dict 2010-08-26
Dictionary el_dict 2010-11-16

a aI e i o oI u

@@ -99,7 +100,7 @@ p Q r R s s; t T
ts v x z z;


Dictionary en_dict 2010-09-14
Dictionary en_dict 2010-11-18

0 3 3: @ @- @2 @5 @L
a a# A: A@ aa aI aI@ aU
@@ -126,7 +127,7 @@ s S t T tS ts v w
x z Z


Dictionary es_dict 2010-07-28
Dictionary es_dict 2010-11-16

a aI aU e E eI eU i
o O oI u
@@ -149,7 +150,7 @@ l m n N p r s S
s2 t v w Z


Dictionary fr_dict 2010-09-04
Dictionary fr_dict 2010-11-15

@ @- a A~ e E E: E~
i I o O O~ u u: w
@@ -199,7 +200,7 @@ q r r. s S s. t T
t. th th. v w x z


Dictionary ta_dict 2010-09-14
Dictionary ta_dict 2010-12-01

a a: aI aU e E e: i
I i: o o: u U u2 u:
@@ -248,7 +249,7 @@ n^# p Q r R r# R2 s
S s2 t T tl# v x z


Dictionary it_dict 2009-04-03
Dictionary it_dict 2010-12-03

@- a a/ aI aU e E eI
i I o O u
@@ -324,7 +325,7 @@ k l m n p R s S
t tS v w x


Dictionary nl_dict 2010-09-13
Dictionary nl_dict 2010-12-03

8 @ @- a A a: A~ E
E2 e: EI eU i I o O
@@ -337,9 +338,9 @@ n^ p Q r s S t tS
v v# w x z Z


Dictionary no_dict 2010-01-20
Dictionary no_dict 2010-10-25

@ @2 a A a: A: AI aI
@ a A a# a: A: AI aI
aU E E: e: I i: O o:
OI U u- u-: u-I u: W y
y: Y: Yy
@@ -523,12 +524,14 @@ l m n N p r s t
tS v w z


Dictionary am_dict 2010-01-17
Dictionary am_dict 2010-10-02

@ a e i o u y

b d h l m q R s
S t tS
? b d dZ f g h j
k l m n N n^ p R
s S t tS ts v w x
z Z


Dictionary ml_dict 2009-10-10
@@ -659,3 +662,15 @@ W y
h j J k l m n p
Q R s S t tS v w
x z Z


Dictionary wo_dict 2010-11-30

@ @: a a: e E e: E:
i i: m- n- N- o O O:
o: u u:

: b c d f g h j
J k l m n N n^ p
q R R2 s s2 t v w
x z

+ 47
- 2
dictsource/el_list View File

@@ -48,9 +48,54 @@ _1M2 'ena|ekatom'irio
_0M2 ekatom'iria
_1M3 'ena|Disekatom'irio
_0M3 Disekatom'iria
_dpt k'oma
_dpt _k'oma
_. tel'ia
_#ος %os // ordinal suffix

_#ος os // ordinal suffix
_#η i
_#ο o
_ord os // default ordinal suffix

// ordinal numbers
_0o miDenik'
_1o pr'ot
_2o D'efter
_3o tr'it
_4o t'etart
_5o p'empt
_6o 'ekt
_7o 'evDom
_8o 'oQDo
_9o 'enat
_10o D'ekat
_11o enD'ekat
_12o DoD'ekat
_1Xo D'ekat
_2Xo ikost'
_3Xo triakost'
_4Xo tessarakost'
_5Xo pedikost'
_6Xo eksikost'
_7Xo evDomikost'
_8Xo oQDoIkost'
_9Xo enenikost'
_1Co ekatost'
_2Co D;akos;ost'
_3Co tr;akos;ost'
_4Co tetrakos;ost'
_5Co pedakos;ost'
_6Co eksakos;ost'
_7Co eptakos;ost'
_8Co oktakos;ost'
_9Co eneakos;ost'
_0M1o Cil^ost'
_1M1o Cil^ost'
_2M1o DisCil^ost'
_3M1o trisCil^ost'


// symbols
% t'is||ekat'o

// articles
ο o $u // definate article

+ 10
- 7
dictsource/en_list View File

@@ -675,6 +675,7 @@ beryl bEr@L
basal beIs@L
best bEst
beta bi:t@
betake bI2teIk
beverage bEv@rI2dZ
bias baI@s
biased baI@st
@@ -811,6 +812,7 @@ closer kloUs3
closely kloUslI $verbf // not kloUzlI
closet kl0zI2t
cloth kloUD $verb
c'mon k@m0n
coauthor koU'O:T3
cobol koUb0l
cocoa koUkoU
@@ -1253,7 +1255,6 @@ hmmm h'@m
hmpf h'@mpf
holme hoUm
holster hoUlst3
holy hoUlI
homeowner hoUmoUn3
homepage hoUmpeIdZ
hominem h0mInEm
@@ -1351,13 +1352,11 @@ iron aI@n
irony aIr@nI
isosceles aIs'0s@li:z
itinerary aIt'In@r@rI
ivory aIv@rI

jagged dZagI2d
japan dZ@pan
jasmine dZazmIn
jesus dZi:z@s
joky dZoUkI
jour ZU@ // french
jukebox dZu:kb0ks
july dZu:l'aI
@@ -1508,7 +1507,7 @@ militia m@lIS@
minibus mInIbVs
mining maInI2N // not mini
minuet mInju:'Et
minutely maIn'ju:tlI
minute mInIt $onlys
mirage mIrA:Z
misery mIz@rI
misled mIsl'Ed
@@ -1708,7 +1707,7 @@ pharaoh fe@roU
philistine fIlI2staIn
philosophy fI2l0s@fI
phoenix fi:nIks
photograph foUt@graf
photographer f@t'0gr@f@
piano pI'anoU
piecemeal p'i:sm,i:l
pier pi@3
@@ -1728,10 +1727,9 @@ piteous pIti@s
pituitary $2
plaguing pleIgIN
plicate $2
plugin plVgIn
plumber plVm3
plus plVs
poky poUkI
poly p0lI
politer p@l'aIt3
politic p0l@tIk
poll poUl
@@ -1956,6 +1954,7 @@ saucepan sO:sp@n
saudi saUdI
saute sO:teI
says sEz
scaly skeIlI
salmon sam@n
scalpel skalp@L
scared ske@d
@@ -2345,6 +2344,7 @@ Cheadle tSi:d@L
Cheshire tSES3
Chiswick tSIzIk
Clwyd klu:Id
Dagenham dag@n@m
Devon dEv@n
Dolgellau d0lg'EClaI
Dover doUv3
@@ -2605,6 +2605,7 @@ Alison alI2s@n
Amanda $2
Amy eImI
Andre 0ndreI
Anita a#ni:t@
Anthony ant@nI
Anton ant0n
Aoife i:f@
@@ -2711,6 +2712,7 @@ Leroy li:rOI
Liam li:@m
Lindsay lInzi
Llewellyn l#@w'ElIn
Llywelyn l#@w'ElIn
Lois loUIs
Louis lu:I
Louise lu:w'i:z
@@ -2806,6 +2808,7 @@ Chrysler kraIzl3
Disney dIznI
Dolce d0ltSeI
Dvorak d@-vo@Zak
Gibson gIbs@n
Hades heIdi:z
Patel pa#tEl
Primavera pri:m@v'e@r@

+ 31
- 16
dictsource/en_rules View File

@@ -564,6 +564,7 @@
al (ity 'al
p) al (et al
qu) al (@ 0l
c) all (K O:l
b) al (m A:
c) al (m A:
p) al (m A:
@@ -1152,7 +1153,7 @@
_) bug (le bju:g
@) bury (_S4i br%I
?3 @) bury (_S4i bEr%I
_) by baI
_) byte baIt


.group be
@@ -1187,6 +1188,8 @@
be (see bI2
be (sie bI2
_) be (sto bI2
_) beta b,i:t@
?3 _) beta b,eIt@
_) be (th bE
be (tray bI2
_) be (w bI2
@@ -1553,6 +1556,7 @@
delu (g dElju:
de (lv+ dE
de (ma dI2
de (magog dE
demea dI2m'i:
de (men dI2
de (mise dI2
@@ -2256,6 +2260,8 @@
&) erize (_ @raIz
&) eris (a @raIz
&) eriz (a @raIz
@) er (Cal_ '3:
@) er (Cic_ '3:
p) ermea (b 3:mi@
_f) erme (nt %3:mE
er (nal_ '3:
@@ -2507,6 +2513,7 @@
bo) g (Ey g
&) gia (_ dZ@
&) gia (C_ dZ@
go) g (ic_ g
&) giu (m dZ@
_) g (id g
_) g (im g
@@ -2522,6 +2529,7 @@
gue (_ g
_) gue gE
_) guer (n g3:
o) g (y_ g

.group h
h h
@@ -2529,7 +2537,7 @@
h (_
_B) h
@) hammed h'amId
A) han (_ h'an // places
A) han (_ han // places
ha (st heI
_) he' %hi:
@) head (_S4 hEd
@@ -2565,6 +2573,7 @@
i (Bee I
i (Bel_ I
i (Bet_ I
_) i (Bo aI
i (CCi_ 'I
XC) i (Ca_ i:
@) i (Cate_ =I
@@ -2932,7 +2941,7 @@
_) in (disP2 ,In
_) in (divP2 ,In
_) in (dol In
in (exP2 ,In
_) in (exP2 ,In
_) inex (or In'Eks
_) infa (l %Infa
_) in (fam In
@@ -3044,6 +3053,7 @@
in (ee In
c) in (e In
inc) in (e In
g) in (e In
bas) in (_ @n
@c) ine (_ i:n
&d) ine (_ i:n
@@ -3070,9 +3080,12 @@
infor (matio Inf3
ino (_ 'i:noU
_m) in (us aIn
_m) inu (te aIn'ju:
_m) inute (m InIt
_) intra Intr@
_) intra (CC %Intra


.group io
io (_ =I2oU
?7 io (_ =i:oU
@@ -3176,7 +3189,6 @@
an) ism (_S3d Iz@m
@iB) ism (_S3d Iz@m
@) ism (_S3de Iz@m
_) is (o aIs
is (o_ aIz
is (or_ aIz
issimo (_ 'IsImoU
@@ -3537,6 +3549,7 @@
o (Ba_ 'oU
_) o (Bal oU
XC) o (Bal oU
X) o (By oU
o (Be# oU
o (BeCo_ 0
o (BenC oU
@@ -3579,8 +3592,7 @@
_) obs (er %0bz
obso (l 0bs@
o (bstin 0
o (bt %0
o (bu %0
_) o (bt %0
o (by_ oU
f) o (cA oU
_l) o (cA oU
@@ -3601,6 +3613,7 @@
o (cre_ 'oU
_h) o (cu oU
cr) o (cu oU
_b) o (dy 0
cust) o (d @
k) o (dA oU
meth) o (d_ @
@@ -3643,10 +3656,11 @@
o (geny '0
r) o (ger 0
l) o (gies @
@) ographer '0graf@
r) ogue oUg
v) ogue oUg
@@) ogue 0g
l) o (gy @
@l) og (y =@dZ
oh oU
o (hA oU
j) oh (n 0
@@ -3667,6 +3681,7 @@
oix (_ wa
o (ky_ oU
@) o (lo_ 0
@) ometer '0mIt@
?3 g) o (ng O
?3 r) o (ng O
?3 s) o (ng O
@@ -3731,7 +3746,6 @@
oy (A_ 'OI
d) o (zen V
_) o (zo oU
o (zy_ oU


.group ol
@@ -3772,7 +3786,6 @@
at) oll 0l
w) oll oUl
olm (_ oUm
olo (gy '0l@
olo (gi '0l@
olo (gic @l'0
v) olt oUlt
@@ -3875,7 +3888,6 @@
w) on (k 0n
w) on (t 0n
&) ony (_ @n%I
XC) ony oUnI
onymous '0nIm@s

.group oo
@@ -4045,7 +4057,7 @@
exp) ost 0st
hyp) ost 0st
osure 'oUZ3
_C) os (y oUz
X) os (y oUz

.group ou
ou aU
@@ -4289,8 +4301,7 @@
photo foUtoU
photon foUt0n
photocop foUt@k0p
photo (grapher f@t0
photo (graphy f@t0
phot (ograph foUt
photo (met foUt'0
_) phyco f,aIkoU
p (hole p
@@ -4358,6 +4369,7 @@
_) pre (diP3 pr%i
_) pre (dic pr%I
_) pre (emp pr%I
_) pre (fec pri:
_) pre (feren prE
pre (fix pri:
_) pre (gn prE
@@ -4870,7 +4882,7 @@
ther (_ D3
ther (er D3
th (erC D
there (_ D3 // thering
there (_ D3 // thering
th (est D
ea) th (er D
n) th (er+ T
@@ -4949,6 +4961,7 @@
u (ga_ 'u:
f) u (gal 'ju:
ug (er_ u:g
pl) ug Vg
s) ugge (st @dZE
h) ugh ju:
mp) ug (n ju:
@@ -4982,7 +4995,7 @@
?8 &f) ully (_ Vl%I
&) u (lous_ =jU
b) ul (r Ul
&ic) ul (t @L
&ic) ul (t_ @L
_) ultra (@ ,Ultra
u (lul V
@) u (lum =jU
@@ -5017,7 +5030,6 @@
?5 usurp ju:z'VRp
b) us (y Iz
b) u (tch U
min) u (te I
r) u (th u:
_) u (til ju:
u (tion 'ju:
@@ -5030,6 +5042,7 @@
l) uxur VgZu:3
uy aI
uy (A_ 'u:j
u (zzi_ 'u:


.group ue
@@ -5240,6 +5253,7 @@
_) y' (CP2 j@
y (C_ I
y (CC I
XoB) y (@+ I
_) y (C@ I
_) y (n@ V
_) y (s@ V
@@ -5482,6 +5496,7 @@
α 'alf@_
ά 'alf@_
β b'i:t@_
?3 β b'eIt@_
γ g'am@_
δ d'Elt@_
ε 'EpsIl0n_

+ 37
- 0
dictsource/es_list View File

@@ -118,6 +118,43 @@ _0and i
_dpt koma
//_roman Rom'ano

// ordinal numbers
_#º o
_#ª a
_ord o

_1o p**im'E**
_2o seQ'und
_3o tERT'E**
_4o kw'a**t
_5o kint
_6o s'Ekst
_7o s'Etim
_8o Okt'aB
_9o noB'en
_10o D'ETim
_11o und'ETim
_12o DwoD'ETim
_13o DeTimotERT'E**
_14o DeTimokw'a**t
_15o DeTimok'int
_16o DeTimos'Ekst
_17o DeTimos'Eptim
_18o DeTimOkt'aB
_19o DeTimonoB'en
_2Xo Bix'Esim
_3Xo t**ix'Esim
_4Xo kwaD**ax'Esim
_5Xo kinkwax'Esim
_6Xo seQsax'Esim
_7Xo sEptwax'Esim
_8Xo Oktox'Esim
_9Xo nonax'Esim
_0Co TEnt'Esim
_1Co TEnt'Esim
_0M1o mil'Esim


vi bi // not a Roman number



+ 24
- 8
dictsource/fr_list View File

@@ -24,7 +24,7 @@

// 2006-11-18 Gilles Casse <[email protected]>
//
// Updated 2010-07-25 Michel Such <[email protected]>
// Updated 2010-10-15 Michel Such <[email protected]>
//
// * Numbers, a few abbreviations and exceptions.
//
@@ -133,9 +133,6 @@ _` aks'A~_gr'av
_{ akOlad_goS
_| bar_vErtik'al
_} akOlad_drwat
² pyis'A~s||d'Y
_« uvre||gijm'E
_» fErme||gijm'E
_’ apostr'Of
_‘ apostr'Of
_µ mikr'o
@@ -151,16 +148,29 @@ _& _e_komErsi'al
~ tilde
€ @r'o $u+
¢ sEnt
¥ iEn
¥ jEn
£ livr
± pl'yz_'u_mw'E~
± pl'yzumw'E~
× myltipli'e_p'ar
÷ diviz'e_p'ar
¼ W~_k'ar
½ W~_d@m'i
¾ trwa_k'ar
© _^_EN
® mark||depoz'e
™ markd@fabrik
¬ tirE_fakyltatif
¦ separatWr||vEtikal
© _^_en
_« uvre||gijm'E
® markdepoz'e
¯ makrO~
² pyis'A~s||d'Y
³ pyisA~s||trwa
¶ paragraf
· pwE~
¸ sedij
º d@gre
_» fErme||gijm'E
¿ pwE~||dE~terogasjO~||E~vErse


// numeric
@@ -239,6 +249,7 @@ adn ad,eEn
adsl ad,eEsEl
alt _::alt
amd a,Emde
android A~droid
aol a,oEl
api ap,ei
ascii aski
@@ -645,6 +656,7 @@ alleluia alelui'a
alterego altErego
anis anis
armageddon armagedO~
aujourd'hui aujourdui $text
auvent ovA~
beta beta
bien biE~n2
@@ -662,11 +674,13 @@ canyon kanjOn
charles Sarl
(chef d'oeuvre) chédeuvre $text
(chef d'oeuvres) chédeuvres $text
chienlit SjA~li
choeur kWr
cinema sinema
cocus kOky
couscous kuskus
delete _^_en
dengue dE~g
dernier dErnjer2
doppler dOplEr
dot dOt
@@ -692,6 +706,7 @@ gus gys
gym Zim
han _|A~
hélas elas $u+
jackpot dZakpOt
jacques Zak
karaoke karaoke
kevin kevin
@@ -947,3 +962,4 @@ venezuela venezyEla
wallis walis
futuna futuna
zimbabwe zimbabwe


+ 9
- 3
dictsource/fr_rules View File

@@ -27,7 +27,7 @@
// http://www.fluxnic.net/cicero
//
// Rules are now maintained by Michel Such <[email protected]>
// Last update: 2010-09-04 Michel Such <[email protected]>
// Last update: 2010-10-15 Michel Such <[email protected]>
//

// Letter classes:
@@ -37,7 +37,7 @@
// K not a vowel (i.e. consonant, space, )

.replace
œ oe
œ oe


.L01 d e l n r t u
@@ -63,7 +63,7 @@
// When these diphtonges are after a consonant folllowing e, e is not mute
.L10 ia ie io ua ue ui uo
.L11 b p
.L12 é è al ib ie l om on ré
.L12 é è aï al ib ie l om on ré

// Words ending "son" pust sound english if preceded by L13
.L13 d g k l p er hn
@@ -138,6 +138,7 @@ _C) aud (_ od // Maud
ay Ej // paye
ay (ak aj // kayak
ay (_ E // display
bb) aye (_ aj // cobbaye layer
Xl) ayer (X EjWr // player, layer
h) am (_S2 am
w) an (_ an
@@ -169,6 +170,7 @@ _) be (L15A _^_en
_) c (d se
_) ch (arism k // charisme, charismatique
_) ch (irop k // chiroptère
_) coe (la se // coelacante
a) ch (_ k // almanach
ar) c (ti // arctique
e) ch (_ k // varech
@@ -617,6 +619,7 @@ gu) eu (ler Y // gueuler

.group ë
u) ë // ambiguë
no) ë (_ e // canoë
ë E // citroën noël


@@ -936,6 +939,7 @@ _re) name _^_en
oi wa // poil
oê (l wa // poêle
om (L11 O~ // bombe, pompe
om (t O~ // comte
n) om (X O~ // nom
om (_ Om // www.web.com

@@ -1217,6 +1221,7 @@ L13) ston (_ _^_en
t (_
peti) t (_ t2
th (L12++ t
th (ArA++ t
or) th (++ t
_) th (erm t
ts (_S1 z2 // silent at end of word unless next word starts with a vowel
@@ -1358,6 +1363,7 @@ g) ton (_ _^_en // try, country
g) u (A // fatigue
g) u (ï y // ambiguïté
g) u (ë y // ambiguë
p) u (tsch u // putsch
uz (z W

// group u: English section

+ 66
- 11
dictsource/hu_list View File

@@ -9,9 +9,9 @@ _2 kEt:Y:
_2a ke:t // for 200, 2000
_3 ha:R2om
_4 ne:J
_5 Yt
_6 hAt
_7 he:t
_5 Yt2 // [t2] changes a following [t] to [t:]
_6 hAt2 // [t2] changes a following [t] to [t:]
_7 he:t2 // [t2] changes a following [t] to [t:]
_8 n^olts
_9 kilEnts
_10 ti:z
@@ -187,6 +187,7 @@ _#-ikának a:nAk
(1-ike) elseje $text $alt2
(1-ikei) elsejei $text $alt2
(1-éhez) elsejéhez $text $alt2
(1-jét) elsejét $text $alt2
(2-i) másodikai $text $alt2
(2-ig) másodikáig $text $alt2
(2-étől) másodikától $text $alt2 //this is not mistake, don't change!
@@ -236,8 +237,10 @@ _#-ikának a:nAk
(0-n) nul:a:n
(00-n) nul:Anul:a:n
(0-ról) nul:a:R2o:l
(0-st) nul:a:St
(1-gyet) EJ:Et
(1-gyes) EJ:ES
(2-szer) ke:ts:ER2
(2-őt) kEt:Y:t
(2-őn) kEt:Y:n
(2-n) kEt:Y:n
@@ -271,17 +274,19 @@ _#-ikának a:nAk
(6-tal) hAt:Al
(6-tól) hAt:o:l
(6-tól) h'Atodika:to:l $alt2
(6-szor) hAts:oR2
(7-től) he:t:Y:l
(7-től) hEtEdike:tY:l $alt2
(7-tel) he:t:El
(7-el) he:t:El
(7-sekre) hEtESEkR2E
(7-sel) hEtES:El
(7-szer) he:ts:ER2
(8-cal) n^olts:Al
(8-al) n^olts:Al
(9-el) kilEnts:El
(9-cel) kilEnts:El
(9-cet) kilEntsEt
_10e tiz
_20e hus
(10-szer) ti:s:ER2
@@ -289,6 +294,7 @@ _20e hus
(10-t) tizEt



//special number exceptions
(10-el) ti:zzEl
(20-al) hu:s:Al
@@ -302,6 +308,8 @@ _20e hus

//Special roman number suffixes and exceptions
(XVI-ig) tizEnhAtodikig //Special roman number suffix exception
//following roman number examples need defining, but this examples are not working for example bigger than 20.
//Very interesting, if I using normal numbers (for example 12-el, Espeak general sending tizEnkEt:Y:vEl phoneme right.
(II-el) kEt:Y:vEl
(III-al) ha:R2om:Al
(IV-el) ne:J:El
@@ -310,6 +318,19 @@ _20e hus
(VII-el) he:t:El
(VIII-al) n^olts:Al
(IX-el) kilEnts:El
(X-el) ti:zzEl //I don't no why, but this exception is not working.
(XII-el) tizEnkEt:Y:vEl
(XIII-al) tizEnha:R2om:Al
(XIV-el) tizEnne:J:El //this is the right phoneme, not tizEnE:JEl
(XV-el) tizEnYt:El //this is the right phoneme, not tizEnYtEl
(XVI-al) tizEnhAt:Al //this is the right phoneme, not tizEnhAtAl
(XVII-el) tizEnhe:t:El
(XVIII-al) tizEnn^olts:Al
(XIX-el) tizEnkilEnts:El
(XX-al) hu:s:Al
XXX-al) hAR2mints:al
//etc, need do general rule similar with normal number exceptions, please test for example 22-el, 32-el, 42-el, 52-el, 40-el, 50-el, 60-al, 70-el etc
//phonemes if this is possible.
(CD-ellenőrzést) tse:de:El:EnY:R2ze:St //this is not a mistake, default Espeak spokening roman number before the ellenőrzés word

// These words mean that a dot after number, immediately preceding, does not mean an ordinal number
@@ -368,7 +389,6 @@ végén $alt
elején $alt
folyamán $alt
úton $alt
út $alt

// accent names
_lig ligAtu:R2A
@@ -396,6 +416,7 @@ _?? kAR2AktEr||ko:d // unknown characters (change this)

// Abbreviations
ADSL a:de:ESEl $allcaps //Internet connection type, we pronouns this with ádéesel
ÁFAa:fA $allcaps
ÁNTSZ a:Ente:Es $allcaps
ATM a:te:Em $allcaps //The ATM stands. We pronouns this abbreviation with átéem word. Default, Espeak pronouns this abbreviation with atéem word.
cm tsEntime:tER2
@@ -413,6 +434,7 @@ MLSZ EmElEs $allcaps
ORTT $abbrev $allcaps
ORFK oEREfka: $abbrev $allcaps
MÁV ma:v $allcaps
LMP ElEmpe: $allcaps
MTI $abbrev $allcaps
mm milime:tER2
RAM R2Am $allcaps //Espeak normaly spokening this abbreviation with erraem, but this is not good
@@ -424,7 +446,7 @@ LST ElESte: $allcaps
BAR bAR2 $allcaps
//SS EsEs $allcaps

(a . m .) An^n^i||m'int
(a . m .) An^n^i||m'int $hasdot
ún u:JnEvEzEt: $hasdot
dr doktoR2 $hasdot
mr mistER2 $hasdot //in hungarian we not use, but lot of books contains this word.
@@ -444,9 +466,9 @@ pl pe:lda:ul $hasdot
stb SAtYb:i $hasdot
u.n u:JnEvEzEt: $hasdot
ú.n u:JnEvEzEt: $hasdot
vö v'EZd||_'Yss2E
vö v'EZd||_'Yss2E $hasdot
(u . i .) $abbrew
NVDA Enve:de:A $allcaps


// Articles
@@ -520,6 +542,7 @@ elé $unstressend
előtt $alt $alt3 $unstressend
este $alt3
estéjén $alt3
éjszakára $alt3
mögül $unstressend // behind
mögött $unstressend
mögé $unstressend
@@ -551,6 +574,8 @@ nekem $unstressend
közül $unstressend
közé $unstressend
között $u $alt3
idén $alt3
környékén $alt3
an $u // so many persons
as $u
ba $unstressend // into
@@ -616,7 +641,13 @@ csütörtökig $alt3
péntekig $alt3
szombatig $alt3
vasárnapig $alt3

hétfőn $alt $alt3
kedden $alt3
szerdán $alt3
csütörtökön $alt3
pénteken $alt3
szombaton $alt3
vasárnapon $alt3
sok $unstressend // many
kevés $unstressend // few
se $unstressend // neither
@@ -707,7 +738,7 @@ jut $unstressend
legyen $unstressend
azt $unstressend
ezt $unstressend
út $unstressend
út $alt $unstressend
tiszt $unstressend
vesz $unstressend
cég $unstressend
@@ -1190,6 +1221,13 @@ szerzett $unstressend
járni $unstressend
döntöttek $unstressend
írt $unstressend
méltó $unstressend
dől $unstressend
nyomsz $unstressend
elnök $unstressend
itthon $unstressend
otthon $unstressend
köszönhető $unstressend

// word pairs

@@ -1309,6 +1347,7 @@ _. pont
~ tildE
° fokjEl
Ft foR2int
(Ft-tal) foR2int:Al
\ bEks2lES $max3
^ fYlfEle:n^i:l

@@ -1324,7 +1363,7 @@ _– gondolAtjEl
_— kviR2tmi:nus
_" ide:zY:jEl
_( b'Alza:R2o:jEl $max3
_) j'obbza:R2o:jEl $max3
_) j'obza:R2o:jEl $max3
_[ n^'ito:sYglEtES $max3
_] z'a:R2o:sYglEtES $max3
_{ k'EzdY:kAptSoS $max3
@@ -1387,6 +1426,7 @@ nato na:to:

$textmode
MSZP emeszpé
MSZMP emeszempé
SZDSZ eszdéesz


@@ -1434,3 +1474,18 @@ CD-m) cédém
(USA-ban) usában
(USA-ba) usába
(pc-n) pécén
(PC-s) pécés
//following entries are NVDA screen reader suffixes in hungarian
//normal NVDA abbreviation is defined $allcaps attribute, but if this abbrewiation is containing a suffix, need pronounce another hungarian word.
(NVDA-ba) envédéába
(NVDA-ban) envédéában
(NVDA-ból) envédéából
(NVDA-hoz) envédéához
(NVDA-nak) envédéának
(NVDA-s) envédéás
(NVDA-t) envédéát
(NVDA-tól) envédéától
(NVDA-val) envédéával
(%-kal) százalékkal
(ÁFÁ-t) áfát
(MB-al) megabájttal

+ 461
- 335
dictsource/hu_rules
File diff suppressed because it is too large
View File


+ 2
- 0
dictsource/it_list View File

@@ -149,6 +149,8 @@ _0Z3 mill'ezimi // 1000ths

// abbreviations
(http ://) 'ak:at,i:t,i:p'i:_
www 'vu'vu'vu
avv avvocato $text $hasdot

// articles
i $u $only

+ 153
- 125
dictsource/it_listx
File diff suppressed because it is too large
View File


+ 1
- 0
dictsource/it_rules View File

@@ -27,6 +27,7 @@
@) a (ggine_ 'a

_) ae (r aI
// @) a (no_ =a //ByFilo, this seems to make it_listx longer
@) avano (_S5 'avano
a (tterA_ 'a


+ 480
- 0
dictsource/nl_list View File

@@ -8,6 +8,7 @@
b be:
c se:
d de:
e e:
f Ef
g Qe:
h ha:
@@ -407,6 +408,7 @@ inkader $alt
jakker $alt
jammer $alt
joeker $alt
jonger $alt
kader $alt
kaffer $alt
kalefater $alt
@@ -770,12 +772,474 @@ vedette v@d'Et@
violette $3
wasserette $3

// ending -el is stressed
isabel $3
libel $2
mirabel $3
tabel $2

// ending -eum is stressed ['e:8m]
atheneum $alt
colosseum $alt
jubileum $alt
lyceum $alt
mausoleum $alt
museum $alt
carbolineum $alt
linoleum $alt $2
marmoleum $alt
petroleum $alt $2

// ending -ot is stressed
fagot $2
kapot $2
patriot $3
komplot $2
poliglot $3
marmot $2
schavot $2

// words ending in el, elt, elde, elden, elend, elende, eld, ele, elen
// with stress on the previous syllable,
// also words ending in er. etc.

beter $alt

// adjectives
edel $alt
enkel $alt
gammel $alt
heikel $alt
ijdel $alt
jofel $alt
kregel $alt
kreupel $alt
luttel $alt
nobel $alt
nozel $alt
schamel $alt
sensibel $alt
simpel $alt
sjofel $alt
soepel $alt
troebel $alt
vermetel $alt
// nouns
amandel $alt
appel $alt
artikel $alt
beginsel $alt
discipel dIs'ip@l $alt
engel $alt
fabel $alt
gruwel $alt
heuvel $alt
letsel $alt
mazel $alt
meubel $alt
middel $alt
mirakel $alt
mossel $alt
parabel $alt
perikel pe:r'ik@l $alt
raadsel $alt
roersel $alt
schepsel $alt
schijnsel $alt
stoppel $alt
zemel $alt
// verbs
aarzel $alt
adel $alt
angel $alt
babbel $alt
barrel $alt
bazel $alt
bedel be:d@l $alt
beitel $alt
bengel $alt
beugel $alt
beuzel $alt
biggel $alt
bikkel $alt
bobbel $alt
bochel $alt
boemel $alt
borrel $alt
borstel $alt
bottel $alt
brabbel $alt
breidel $alt
broddel $alt
brokkel $alt
bubbel $alt
buffel $alt
buitel $alt
bundel $alt
bungel $alt
bussel $alt
cirkel $alt
dartel $alt
diggel $alt
dissel $alt
dobbel $alt
doezel $alt
dommel $alt
dompel $alt
dremmel $alt
drentel $alt
dreutel $alt
drevel $alt
dribbel $alt
droppel $alt
druppel $alt
dubbel $alt
duikel $alt
duimel $alt
duivel $alt
duizel $alt
duvel $alt
dwarrel $alt
eikel $alt
fakkel $alt
fezel $alt
fiedel $alt
foefel $alt
foezel $alt
fonkel $alt
friemel $alt
frommel $alt
frummel $alt
frutsel $alt
futsel $alt
gaffel $alt
gesel Qe:s@l $alt
giebel $alt
giechel $alt
gijzel $alt
gispel $alt
gniffel $alt
goochel $alt
gorgel $alt
grabbel $alt
grendel $alt
greppel $alt
griezel $alt
griffel $alt
gruizel $alt
guichel $alt
hachel $alt
hagel $alt
hakkel $alt
haksel $alt
handel $alt
haspel $alt
heibel $alt
hekel $alt
hemel $alt
hengel $alt
hevel $alt
hinkel $alt
hobbel $alt
hoepel $alt
hompel $alt
huichel $alt
huikel $alt
huppel $alt
hussel $alt
hutsel $alt
ijzel $alt
jengel $alt
jodel $alt
joekel $alt
jubel $alt
kabbel $alt
kabel $alt
kachel $alt
kakel $alt
kantel $alt
kapittel $alt
kapsel $alt
karbonkel $alt
kartel $alt
kavel $alt
kegel $alt
ketel $alt
keutel $alt
keuvel $alt
kevel $alt
kibbel $alt
kietel $alt
kinkel $alt
kittel $alt
klepel $alt
klingel $alt
klippel $alt
klungel $alt
knabbel $alt
kneukel $alt
knevel $alt
knibbel $alt
knobbel $alt
knokel $alt
knuffel $alt
knuppel $alt
knutsel $alt
koepel $alt
kogel $alt
konkel $alt
koppel $alt
korrel $alt
krabbel $alt
krauwel $alt
krengel $alt
kreukel $alt
kribbel $alt
kriebel $alt
kringel $alt
krinkel $alt
kroezel $alt
kronkel $alt
kruimel $alt
kukel $alt
kunstel $alt
kwabbel $alt
kwakkel $alt
kwansel $alt
kwartel $alt
kwebbel $alt
kwezel $alt
kwispel $alt
label le:b@l $alt
lepel $alt
lispel $alt
lummel $alt
mangel $alt
martel $alt
mazzel $alt
mengel $alt
mergel $alt
metsel $alt
mispel $alt
moffel $alt
mommel $alt
monkel $alt
morrel $alt
mummel $alt
murmel $alt
nachel $alt
nagel $alt
nestel $alt
netel $alt
neutel $alt
neuzel $alt
nevel $alt
nikkel $alt
orakel $alt
paddel pEd@l $alt
pantoffel $alt
parel $alt
pegel $alt
pekel $alt
pendel $alt
peuzel $alt
piemel $alt
piepel $alt
pimpel $alt
pingel $alt
pinkel $alt
poedel $alt
poekel $alt
popel $alt
prevel $alt
priegel $alt
prikkel $alt
pruttel $alt
puzzel $alt
rafel $alt
raffel $alt
rakel $alt
rammel $alt
ransel $alt
ratel $alt
rebbel $alt
regel $alt
reutel $alt
reuzel $alt
ribbel $alt
riffel $alt
rijmel $alt
rimpel $alt
ringel $alt
rinkel $alt
ritsel $alt
rochel $alt
roddel $alt
rodel $alt
roefel $alt
roffel $alt
rommel $alt
rompel $alt
ronsel $alt
sabbel $alt
sabel $alt
sappel $alt
schakel $alt
scharminkel $alt
scharrel $alt
schimmel $alt
schnabbel $alt
schoffel $alt
schommel $alt
schotel $alt
schrikkel $alt
schrompel $alt
schuifel $alt
scrabbel skrEb@l $alt
settel $alt
shuffel S8f@l
shuttel S8t@l
siepel $alt
sijpel $alt
sikkel $alt
singel $alt
sjoemel $alt
sleutel $alt
slungel $alt
smiespel $alt
smikkel $alt
smispel $alt
smoezel $alt
smokkel $alt
snabbel $alt
sneuvel $alt
snoezel $alt
snorkel $alt
snuffel $alt
spartel $alt
spiegel $alt
spijbel $alt
spikkel $alt
sprankel $alt
sprenkel $alt
sprokkel $alt
staffel $alt
stamel $alt
stapel $alt
stechel $alt
steggel $alt
stempel $alt
stiefel $alt
stijfsel $alt
stippel $alt
stommel $alt
strengel $alt
stribbel $alt
strompel $alt
strubbel $alt
struikel $alt
stuntel $alt
suizel $alt
sukkel $alt
swaffel $alt
tackel tEk@l
tafel $alt
takel $alt
tegel $alt
tempel $alt
teugel $alt
teutel $alt
tichel $alt
tingel $alt
tinkel $alt
tintel $alt
tippel $alt
titel $alt
tokkel $alt
tortel $alt
trappel $alt
treuzel $alt
trippel $alt
troetel $alt
troggel $alt
trommel $alt
tuimel $alt
tunnel $alt
tuttel $alt
twijfel $alt
twinkel $alt
vendel $alt
vezel $alt
vijzel $alt
vlegel $alt
vleugel $alt
vogel $alt
wafel $alt
waffel $alt
waggel $alt
wakkel $alt
wandel $alt
wankel $alt
warrel $alt
wauwel $alt
weifel $alt
wemel $alt
wentel $alt
wervel $alt
wichel $alt
wiebel $alt
wiegel $alt
wiemel $alt
wikkel $alt
wimpel $alt
winkel $alt
wissel $alt
worstel $alt
wortel $alt
wriemel $alt
zabbel $alt
zadel $alt
zamel $alt
zegel $alt
zetel $alt
zoedel $alt
zwachtel $alt
zwavel $alt
zwendel $alt
zwengel $alt
zwiebel $alt
zwijmel $alt


// -s is not plural
chaos xa:Os


beiaard b'EIa:rt
boomgaard $1
dronkaard $1
gierigaard $1
grijsaard $1
gulzigaard $1
lafaard $1
slechtaard $1
snoodaard $1
standaard $1
valsaard $1
woestaard $1


// pronunciation exceptions
aangrijpend $2
accessoires aksEsw'ar@s
actiepunt Aksip8nt
agenda $2
amino $1
amnestie $3
bijziend $2 // bijziendheid
boudoir budv#'a:r
bourgondier burx'o:ndi:@r
braille brAj@
circuit sIrku'i
chalet Sa:lE
champagne SAmp'An^@
@@ -788,15 +1252,24 @@ chat tSEt
check tSEk
chiffon Sif'On
contour ko:nt'ur
divers div'Ers
dynastie $3
eensgelijks e:nsQ@l'EIks
emaille ,e:m'Aij@
eucharistie $4
inductie $2
ingewikkeld $3
ingrijpend $2
ingeval $3
ingevolge $3
ingrediënt $4
ingenieur Inzj@nj'Y:r
informatie $3
journaal Surn'a:l
maxima $1
meteen mEt'e:n
minima $1
nabij nab'EI
ongastvrij OnQAstv@-*'EI
ongelooflijk $3
ongemakkelijk $3
@@ -805,7 +1278,9 @@ ongerieflijk $3
ongrondwettig $3
proces $2
renaissance rEne:s'A~s@
reservoir re:zErvv#'a:r
sacristie $3
salomo $1
tegenaan $3
tegenin $3
tegenover $3
@@ -814,6 +1289,8 @@ tegennatuur $4
tegenstrijdig $3
tegenwoordig $3
travestie $3
verderop $3
volledig $2
waarschijnlijk $2


@@ -825,3 +1302,6 @@ Ingeborg INe:bOrx
Ingmar INmAr
Ingrid IN@-*It
kennedy kEn@dE

// places
canada $1

+ 116
- 15
dictsource/nl_rules View File

@@ -10,15 +10,24 @@
au VU
ay a:j

@@C) a (_ =a:
_) aan (@P3 'a:n
aa (rd_ 'a:
aa (t_ 'a:
aa (C_ 'a:
@) abel (_ 'a:bE2l
@) abele (_ 'a:b@l@
_) af (C@P2 'Af
age (_ 'a:Z@
age (_N 'a:Z@
ages (_S1 s
age (_$w_alt a:Q@
aire (_ 'E:r
air (_ 'Er
@) agne (_ 'An^@
ale (_ 'a:l@
@) ant (_ 'Ant
@) ant (e_ 'Ant
@) ant (en_ 'Ant
@) ant (er_ 'Ant

@) a (de_ 'a:
@) a (ta_ 'a:
@@ -32,13 +41,21 @@
&) baar (_ =ba:r
_) be (@P2 b@
_) b (ee+ b
_) bei (de bEI
_) be (ren bI:
_) be (rm bE
_) be (stia bE
_) be (ter be:
_) be (ven_ be:
_) bever be:v@r
_) be (zem be:
_) bezig be:z@x
_) beu bY:
_) bij (C@P3 b'EI
_) brand br'And
_) bureau byr'o:
_) buurt (@@P5 b'yrt // buurtbewoner



.group c
@@ -68,11 +85,17 @@
_) ch (or x
_) ch (r x
&) che (_ =S
ci (a S
@) ci (eel S
@) ci (ë S
ci (o S
ck k
cieel S'e:l
ciële S'e:l@
coach ko:tS

_) congres kOnQr'Es


.group d
d d // auto-devoice at end-of-word
@@ -83,7 +106,7 @@

.group e
e e:
&C) e (_S1q @
&C) e (_S1qd @
e (_ @
e (CK E
e (x E
@@ -95,6 +118,7 @@
eeuw eU
eu Y:

ea (_ 'e:a:
eau o: //words with French origin
@) ee (_ 'e:
@) ee (X_ 'e:
@@ -104,29 +128,57 @@
@) ee (rde_ 'I:
@) ee (rden_ 'I:
it) eit (_ 'EIt
&) el (_ @l
&) el (_ E2l
&) eld (_ @ld
&) ele (_ 'e:l@

&) el (_$p_alt =@l
&) el (e_$p_alt =@l
&) el (en_$p_alt =@l
&) el (t_$p_alt =@l
&) el (de_$p_alt =@l
&) el (den_$p_alt =@l
&) el (end_$p_alt =@l

&) er (_$p_alt =@r
&) er (e_$p_alt =@r
&) er (en_$p_alt =@r
&) er (t_$p_alt =@r
&) er (d_$p_alt =@r
&) er (de_$p_alt =@r
&) er (den_$p_alt =@r
&) er (end_$p_alt =@r

&) elijks @l@ks
&) em (_ @m
&) en (_S2qd @n
&) ens (_S3q @ns
&) end (_ @nd
&) ende (_ @nd@
@) ent (_ 'Ent
@) ent (e_ 'Ent
@) ent (en_ 'Ent
@) ent (er_ 'Ent
&) er (_ @r
&) ere (_ @r@
&) er (en_$p_alt @r // where 'eren' is not a verb ending
eren (_ 'I:r@n
&) es (_ @s
@) etten (_S3 @n
eum (_$w_alt 'e:8m
@mus) eum (_ ,e:8m // compounds
@) eur (_ 'Y:r

_) er (@P2 Er
@) e (raar_ @
&) e (nB@ E2
id) e (nt E
_) er (@P2 Er
&) era (_ @ra:
@) e (raar_ @
&) e (rC@ E2

c) e (ntrum E // not @
_) expositie Ekspo:z'itsi



.group f
@@ -141,11 +193,15 @@
_) ge (@P2 Q@
_) gee Qe:
gener (aal Q,e:n@r
gelijk Q@lEIk
_) gelijk Q@lEIk
_) ge (rC QE
_) geu QY:
_) ge (ven Qe:
_) ge (ver Qe:
_) ge (ving Qe:

ge (sprek Q@ // in compounds


.group h
h h
@@ -153,6 +209,7 @@

_) her (@P3 hEr
_) her (en hI:r
&) heid (_S4 hEIt


.group i
@@ -168,17 +225,26 @@
m) ie (_ 'i
p) ie (_ 'i

@) ibel (_ 'ib@l
@) ibele (_ 'ib@l@
&) ica (_ =ika:
&) ico (_ =iko:
ie (X 'i
ie (ren_ 'i
ie (rd_ 'i
@) ig (_S2d @x
@) ig (_S2dq @x
@) ige (_ @Q@
ij (_ 'EI
ij (e_ 'EI
@) ij (n_ 'EI
&) ika (_ =ika:
&) iko (_ =iko:
_) in (C@P2 'In
// _) in (gP2 'In
io (nage iO
@) isch (_ =is
@) ische (_ =is@
@) isme (_ 'Ism@
@) ist (_ 'Ist


@@ -203,12 +269,15 @@
@) loog (_ lo:x



.group m
m m
m) m

manage (ment ma:nIdZ
mail me:Il
management ma:nIdZm@nt
_) mee (@P3 m'e:
menu (_ m@ny


.group n
@@ -216,8 +285,10 @@
n) n
ng N
nj n^
n (kel N

_) na (C@@P2 n'a:
_) na (tion na:


.group o
@@ -233,10 +304,16 @@
ou VU
ou (rage u

@@C) o (_ =o:
oe (X_ 'u
oir (_ 'v#a:r
pr) o (gram o:
oo (X 'o:
telef) oo (n 'o:
oon 'o:n // in compounds, eg. telefoongesprek
_) op (@@P2 'Op
_) open (@P4 'o:p@n
_) op (era 'o:p
_) op (tion Op
_) over (@P4 'o:v@r


@@ -271,6 +348,9 @@
_) ph f
ph (K f

_) politie (@ po:l'itsi



.group q
q k
@@ -282,9 +362,11 @@

.group r
r r
A) r (A *
C) r (A @-*
rr *r
A) r (A r
C) r (A r
rr *r

route rut@ // route(s)

.group re
_) re (geren r@
@@ -292,19 +374,29 @@
_) re (cent r@
_) re (cept r@
_) re (ceptief re:
_) re (clam r@
_) re (serve_ r@

.group s
s s
s) s
A) s (A z
sch sx
sch (_ s
sch (e_ s
_) sch (n S
_) sh S
sh (K S
sj S
@@) s (_S1 s

@) si (o S
A) si (o Z
@) ssi (o S

_) standaard (@P9 st'Anda:rt
_vre) s (e s


.group t
t t
@@ -315,6 +407,12 @@
p) tie (_ =si
s) tie (_ =ti
cra) tie (_ ts'i
tiee (l_ S'e:
tië (le_ S'e:
@) ti (a S
@) ti (ë S
@) ti (on S
s) t (i++ t
tj t;
tsj tS
_) th t
@@ -325,11 +423,12 @@

_) team t'i:m
team (_ ti:m
_) train tre:n

.group te
_) tegen (P5 t'e:Q@n
_) terug (P5 t@r'8x
_) te (gelijk t@
_) te (gelijkP2 t@
_) te (gemoetP2 t@
_) te (goed t@
_) te (hui t@ // tehuis
@@ -368,7 +467,7 @@

_) ver (@P3 v@r
_) ver (sie_ vEr
_) ver (der_ vEr
_) verder vErd@r
_) voort (@P5 v'O:rt


@@ -378,6 +477,8 @@
w (CK w

_) weg (@P3 v#'Ex
_) weg (en v#e:Q
_) weg (e_ v#e:Q // bewegelijk


.group x

+ 34
- 34
dictsource/no_list View File

@@ -42,10 +42,10 @@ _4 f'i:RE
_5 f'Em
_6 s'Eks
_7 S'u-:
_8 'Ot:@2
_8 'Ot:a#
_9 n'i:
_10 t'i:
_11 'Elv@2
_11 'Elva#
_12 t'Olv
_13 tR'Et:@n
_14 fj'URt@n
@@ -54,7 +54,7 @@ _16 s'Ekst@n
_17 s'yt:@n
_18 'At:@n
_19 n'It:@n
_2X s;'u-:@2
_2X s;'u-:a#
_3X tR'Et:i:
_4X f'Y:Rti:
_5X f'Emti:
@@ -62,8 +62,8 @@ _6X s'Eksti:
_7X s'yt:i:
_8X 'Ot:i:
_9X n'It:i:
_0C h'u-ndR@2
_1C 'Et||h'u-ndR@2
_0C h'u-ndRa#
_1C 'Et||h'u-ndRa#
_0M1 t'u-:s@n
_1M1 'Et||t'u-:s@n
_0M2 m'Illi:;,u:n@R
@@ -73,32 +73,32 @@ _0and u:g
_dpt kOmmA

// ordinal numbers
_ord @nd@2
_1o f'WRst@2
_2o 'AndR@2
_3o tR'Edj@2
_4o fj'a:R@2
_5o f'Emt@2
_6o S'Et:@2
_8o 'Ot:@nd@2
_11o 'EllEvt@2
_12o t'Olvt@2
_13o tR'Et:@nd@2
_14o fj'URt@md@2
_15o f'Emt@nd@2
_16o s'Ekst@nd@2
_17o s'yt:@nd@2
_18o 'At:@nd@2
_19o n'It:@nd@2
_2Xo s;'u-:@nd@2
_0Co h'u-ndR@d@2
_0M1o t'u-:s@nd@2
_ord @nda#
_1o f'WRsta#
_2o 'AndRa#
_3o tR'Edja#
_4o fj'a:Ra#
_5o f'Emta#
_6o S'Et:a#
_8o 'Ot:@nda#
_11o 'EllEvta#
_12o t'Olvta#
_13o tR'Et:@nda#
_14o fj'URt@mda#
_15o f'Emt@nda#
_16o s'Ekst@nda#
_17o s'yt:@nda#
_18o 'At:@nda#
_19o n'It:@nda#
_2Xo s;'u-:@nda#
_0Co h'u-ndR@da#
_0M1o t'u-:s@nda#


// punctuation and symbols
//========================

* ss;aRn@2 $max3
* ss;aRna# $max3
= aRli:k $max3
+ plu-s $max3
% pR'u:s'Ent $max3
@@ -113,20 +113,20 @@ _$ dOllA:R
_' ApUstR'u:f
_( paRaNt'e:s||b@j'ynn@R
_) paRaNt'e:s||Sl'u-t:
_* ss;aRn@2
_* ss;aRna#
_, kOmmA
_- stRe:k
_. pu-Nktu-:m
_: ku:lOn
_; se:mi:ku:lOn
_< mIndR@2||En
_< mIndRa#||En
_= aRli:k
_> stWR@||En
_? spWRSmOlstENn
@ kRWllAlfA
_[ v'EnstR@2||h'A:ke:paRaNt'e:s
_[ v'EnstRa#||h'A:ke:paRaNt'e:s
_\ OmvEndt||skROstR@k
_] h'YyR@2||h'A:ke:paRaNt'e:s
_] h'YyRa#||h'A:ke:paRaNt'e:s
^ sIRku-mflEks
__ u-ndaRStR@k
_` 'OmvEndt||ApUstR'u:f
@@ -135,11 +135,11 @@ _#09 tA:b
_#32 mEllOmRu:m

_acu A:'ku-t:
_ced s'e:dIll@2
_ced s'e:dIlla#
_cir s'IRku-mflEks
_dia tR'e:mA
_grv gR'A:vi:s
_tld t'Ild@2
_tld t'Ilda#

é $accent
ü $accent
@@ -296,7 +296,7 @@ reader _^_EN
cancel _^_EN
continue _^_EN
magnifier _^_EN
and @2nd $only
and a#nd $only


// MAIN WORD DICTIONARY
@@ -306,7 +306,7 @@ der dE:R
her hE:R
kom kOm
loe lu: $capital
noe nU:@2
noe nU:a#
noen nU:@n // no+en
office Offi:s
system syst'e:m

+ 146
- 140
dictsource/no_rules View File

@@ -1,221 +1,227 @@

// This file is UTF8 encoded
// Spelling-to-phoneme rules for Norwegian

// C% indicates a double consonant (same letter twice)
// First version by Jonathan Duddington
// October 2010 improvements by Eirini Florou <[email protected]>


.group a
a A:
a (CC A
a (_ A
a A:
a (CC A
a (C a
a (_ A
// X) a (CCK A // single syllable with >= 2 final consonants
// // or initial syllable with 3 consonants
ai AI
au aU
ai AI
au aU

aa o: // å
aa (CC O
ae a: // æ
ae (CC a
aa o: // å
aa (CC O
ae a: // æ
ae (CC a


.group b
b b
bb b:
b b
bb b:

_) be (@ b@
_) be (@ b@


.group c
c k
cc k:
_) c (e s
c (i s
c (y s
c (ei s
c (øy s
ch S
c k
cc k:
_) c (e s
c (i s
c (y s
c (ei s
c (øy s
ch S

.group d
d d
dd d:
r) d (_
&) det (_ d@2
d d
dd d:
r) d (_
&) det (_ da#

.group e
e e:
e (CC E
ei aI
e (rC a // ??
&) e (_ @2
&) e (C_ @
X) e (m_ E
&) en (_ @n
&) ene (_ En@2 // @n@2 ??
&) ens (_ @ns
&) es (_ @s
&) et (_ @t
e e:
e (CC E
ei aI
e (rC a // ??
&) e (_ a#
&) e (C_ @
X) e (m_ E
&) en (_ @n
&) ene (_ Ena# // @na# ??
&) ens (_ @ns
&) es (_ @s
&) et (_ @t

.group f
f f
f f

.group g
g g
gg g:
g (n N
gj j
g (i j
g (y j
g (ei j
g (øy j
g g
gg g:
g (n N
gj j
g (i j
g (y j
g (ei j
g (øy j

.group h
h h
hj j
hv v
h h
hj j
hv v

.group i
i i:
i (CC I
&) ig (_ I
i i:
i (CC I
&) ig (_ I

.group j
j j
j j

.group k
k k
kk k:
kj x
k (i x
k (y x
k (ei x
k (øy x
k k
kk k:
kj x
k (i x
k (y x
k (ei x
k (øy x

.group l
l l
ll (K l
lj j
l l
ll (K l
lj j
ld ll

.group m
m m
mm (K m
m m
mm (K m

.group n
n n
nn (K n
ng N
n (k N
n n
nn (K n
ng N
n (k N
nd nn

.group o
o u:
o (CC O
oi OI
o u:
o (CC O
oi OI

oe O@2
@b) oe (_ u:
oe Oa#
@b) oe (_ u:

o (nd U
o (rt U
b) o (rd u:
o (st U
o (nd U
o (rt U
b) o (rd u:
o (st U

.group p
p p
pp p:
p p
pp p:

.group q
q k
qq k:
qu kw
q k
qq k:
qu kw

.group r
r R
rs (_ S
r R
rs (_ S

.group s
s s
ss ss
ss (_ s
sch S
sj S
skj S
sk (i S
sk (y S
sk (ei S
sk (øy S
r) s S
s (l S
A) s (lA s
s s
ss ss
ss (_ s
sch S
sj S
skj S
sk (i S
sk (y S
sk (ei S
sk (øy S
r) s S
s (l S
A) s (lA s

.group t
t t
tt t:
ti (on S
tj s;
t t
tt t:
ti (on S
tj s;



.group u
u u-:
u (CC u-
ui u-I
u u-:
u (CC u-
ui u-I

.group v
v v
vv (_ v
v v
vv (_ v

.group w
w v
w v

.group x
x ks
x (x
x ks
x (x
_) x s

.group y
y y:
y (CC y
y y:
y (CC y

.group z
z s
zz z
zz (_ z
z s
zz z
zz (_ z

.group å
å o:
åe o:@2
å (CC O
å o:
åe o:a#
å (CC O

.group æ
æ E:
æ (r a:
æ (CC a
æ E:
æ (r a:
æ (CC a

.group ø
ø Y:
ø (CC W
øy Yy
ø Y:
ø (CC W
øy Yy

.group ä
ä E:
ä (CC E
ä E:
ä (CC E

.group ö
ö Y:
ö (CC W
ö Y:
ö (CC W

.group
é 'e:
ü y:
é 'e:
ü y:

$ dOllA:R
! _:'u-:tRu:pstENn_:
!) !
$ dOllA:R
! _:'u-:tRu:pstENn_:
!) !

. pu-Nktu-:m
. (. _:
\.) .
. pu-Nktu-:m
. (. _:
\.) .

__) - (_D mi:nu-:s
A_) - (_D _
C_) - (_D _
__) - (_D mi:nu-:s
A_) - (_D _
C_) - (_D _


+ 61
- 8
dictsource/ta_list View File

@@ -97,7 +97,7 @@ _- in.aIppUg // இணைப்புக்
\ p'in||s,a:jvU // பின் சாய்வு
! vijVppU // வியப்பு
_? ke:l.vi // கேள்வி
# en.||kuRi $max3 // எண் குறி
# ;en. $max3 // எண் குறி
= samVnpa:d.U $max3 // சமன்பாடு
+ ku:t.t.Vl $max3 // கூட்டல்
* perUkkVl $max3 // பெருக்கல்
@@ -105,6 +105,9 @@ _? ke:l.vi // கேள்வி
÷ vVgUttVl // வகுத்தல்
% viz.Ukka:d.U $max3 // விழுக்காடு
U+bf9 ru:ba:j
¼ ka:l
½ araI
¾ mukka:l

// abbreviations
ரூ ru:ba:j $dot $only
@@ -195,7 +198,6 @@ tamil தமிழ் $text
பாகம் $alt
பண்தம் $alt
பவனி $alt
பயில்வான் $alt
பாபா $alt
போண்டா $alt
பஜ்ஜி $alt
@@ -224,9 +226,7 @@ tamil தமிழ் $text
பால $alt
பாம்ப் $alt
பீராமண $alt
பிரதர் $alt
பால்ய $alt
பலு $alt
பில் $alt
பந்த் $alt
பில்லி $alt
@@ -253,8 +253,38 @@ tamil தமிழ் $text
பீர் $alt
போயிங் $alt
பலத்தாலான $alt
பெஞ்ச் $alt
பெஞ்சு $alt
பார $alt
பாமா $alt
பென்ஸ் $alt
பாலிய $alt
புக்கு $alt
படுவா $alt
பீரும் $alt
பல்ப் $alt
பிரேக் bre:k
ப்ரேக் bre:k
பெட்ல $alt
பான $alt
பகத் $alt
பலிக் $alt
பலிக்கு $alt
பலிக்குத்தான் $alt
பவ $alt
புஸ் $alt
போஸின் $alt
போனி $alt
பிஸி $alt
பேஷ் $alt
பாவே $alt
பாலு $alt
பீடி $alt
பிசி $alt
போன்சாய் $alt
போன்ஸாய் $alt
பீப் bi:p
ப்யூனஸ் $alt
பவுத்த $alt
பவுத்தம் $alt
(பி . ஏ) bije:


@@ -280,7 +310,6 @@ tamil தமிழ் $text
திட $alt
தேவ $alt
தோ $alt
தினசரி $alt
தரும $alt
தொப் $alt
தொப்பென்று $alt
@@ -301,6 +330,16 @@ tamil தமிழ் $text
திம் $alt
தேவதா $alt
தெனம் $alt
தெனமும் $alt
திடு $alt
தால் $alt
தவ $alt
திக்திக் digdig
தொப்புனு $alt
தருமம் $alt
தாவே $alt
தருமமும் $alt
தராவி $alt


// initial ட
@@ -316,6 +355,13 @@ tamil தமிழ் $text
சிட்டாய் $alt
சேச்சே $alt
சிரம் sirVm
சிலி $alt
சிக் tSik
சர்ச் $alt
டிக் t.ik
ரெட்டி red.d.i
செல்லம் $alt
சிக்கன் $alt


கக $alt // initial க as [g]
@@ -349,10 +395,16 @@ tamil தமிழ் $text
கான $alt
கோத்திர $alt
கும்முன்னு $alt
கூகுல் $alt
கேட் $alt
கேட்டில் $alt
கின் $alt
கம $alt
குட் $alt
காண்டு $alt
கேட்டின் $alt
கேட்டுக்கு $alt
கம்முனு $alt
குஜால் $alt



@@ -383,3 +435,4 @@ tamil தமிழ் $text
ஓகோ o:Ho:
கப் kVp
செட் set.
திக் dik

+ 683
- 169
dictsource/ta_rules
File diff suppressed because it is too large
View File


+ 50
- 16
phsource/compile_report View File

@@ -1,4 +1,4 @@
66 phoneme tables
68 phoneme tables
new total
base 107 107
consonants 9 115
@@ -21,7 +21,7 @@ consonants 9 115
fr-ca 11 140
hi 59 150
ta 21 153
hu 24 121
hu 25 122
lv 29 125
nl 25 126
pl 22 120
@@ -66,6 +66,8 @@ consonants 9 115
ht 11 140
az 10 127
ak 8 109
am 8 123
wo 18 118

Data file Used by
b/b [b] base
@@ -338,27 +340,34 @@ l/_l [l] base
[l/] fr
[l] hu
[l] zh
l/l_ [l/] base
l/l_ [l] base
[l/] base
[l/3] base
[l/] fr
l/l_@ [l/3] base
[l/] fr
l/l@ [hæy] base
l/l@ [há] base
[l#] base
[l] fr
[l/2] fr
[K] nso
l/L1_aL [l/] base
l/L1_aL [l] base
[l/] base
[l/] de
l/L1_eL [l/] base
l/L1_eL [l] base
[l/] base
[l/] de
l/L1_iL [l/] base
l/L1_iL [l] base
[l/] base
[l/] de
l/L1_@L [l/] base
l/L1_@L [l] base
[l/] base
[l/] de
l/L1_oL [l/] base
l/L1_oL [l] base
[l/] base
[l/] de
l/L1_uL [l/] base
l/L1_uL [l] base
[l/] base
[l/] de
l/L2_aL [l/2] base
l/L2_eL [l/2] base
@@ -370,14 +379,14 @@ l/L2_oL [l/2] base
l/L2_uL [l/2] base
l/l_3 [l/] de
l/l_4 [ll] sq
l/la [hæy] base
l/la [há] base
[l#] base
[l] fr
[l/2] fr
[K] nso
l/l_a [l/3] base
[l/] fr
l/le [hæy] base
l/le [há] base
[l#] base
[l] fr
[l/2] fr
@@ -388,7 +397,7 @@ l/L_eL_af [&] af
[&:] af
l/l_front [L] sq
l/l_front_ [l/4] sq
l/li [hæy] base
l/li [há] base
[l#] base
[l] fr
[l/2] fr
@@ -401,7 +410,7 @@ ll/ll [L] bg
ll/_ll [L] bg
l/l_long [l] base
[l] fr
l/lo [hæy] base
l/lo [há] base
[l#] base
[l] fr
[l/2] fr
@@ -409,7 +418,7 @@ l/lo [h
l/l_o [l/3] base
[l/] fr
l^/l_rfx [l.] base
l/lu [hæy] base
l/lu [há] base
[l#] base
[l] fr
[l/2] fr
@@ -730,6 +739,7 @@ ustop/k_unasp [k] base
[k] sq
ustop/k_unasp_ [k] zh
ustop/null [?] base
[t2] hu
ustop/p [p] base
[p2] fr
[p] zhy
@@ -1209,6 +1219,8 @@ vowel/@ [@] base
[@] hy
[@] ml
[@] sl
[@] wo
[@:] wo
vowel/@- [@-] base
[r*] hr
vowel/& [a] en-rp
@@ -1285,6 +1297,7 @@ vowel/a [a] base
[a] id
[a] sl
[a] bg
[a] am
vowel/a# [a] base2
[a/] base2
[a#] en-sc
@@ -1292,6 +1305,7 @@ vowel/a# [a] base2
[&] sr
[a#] rw
[a/] rw
[a] wo
vowel/a_2 [a] base2
[a] en-wi
[A:] en-wi
@@ -1305,6 +1319,7 @@ vowel/a_2 [a] base2
[a] da
[a] rw
vowel/a#_2 [A] nl
[a:] nl
[a#] pl
[&] hr
[a] sv
@@ -1355,6 +1370,7 @@ vowel/a_5 [a:] ta
[a:] ml
vowel/a_6 [a] ca
[a:] vi
[a:] wo
vowel/a_7 [a] en
[a] fr
[a] ht
@@ -1428,6 +1444,8 @@ vowel/e [e] base
[e:] ml
[e] ne
[e] sl
[e] wo
[e:] wo
vowel/e# [I] en-sc
vowel/e_2 [eI] en-sc
[e:] de
@@ -1474,6 +1492,8 @@ vowel/ee_3 [&] af
vowel/ee_4 [E] sq
vowel/ee_5 [E] en
[E] ak
[E] wo
[E:] wo
vowel/ee_6 [&] sk
[E3] sv
[E] ku
@@ -1521,6 +1541,7 @@ vowel/e_mid2 [E] af
[e] bg
[e] nso
[e] az
[e] am
vowel/@_fnt [@] en-wi
[@2] en-wi
[@2] hr
@@ -1553,12 +1574,15 @@ vowel/i [i] base
[i] prs
[i] nso
[i] ak
[i] am
[i:] wo
vowel/i# [y:] cy
vowel/i_2 [i2] de
[i:] de
[i] nl
[i:] la
[i:] sv
vowel/i#_2 [y] am
vowel/i_3 [i] af
[i:] sk
vowel/i_4 [i] fi
@@ -1640,6 +1664,7 @@ vowel/ii_6 [I] en-wm
[i/] pt
[i] is
[I] sq
[i] wo
vowel/ii_en [i] en
[i] sq
vowel/ii_final [i] en-us
@@ -1652,12 +1677,13 @@ vowel/@_low [@] en-rp
[V] hi
[@2] hi
[@] ro
[@2] no
[a#] no
[@] id
[V] ne
[@/] ne
[@] pa
[V] pa
[@] am
vowel/@_low2 [@/] en-us
[@2] en-us
vowel/o [o] base2
@@ -1685,6 +1711,8 @@ vowel/o [o] base2
[o:] pa
[o] sl
[o] ak
[o] wo
[o:] wo
vowel/o_2 [o:] cy
[o:] hi
[o:] hu
@@ -1697,6 +1725,7 @@ vowel/o-_2 [V] en-n
vowel/o_3 [oU] en-sc
vowel/o-_3 [U] en-rp
vowel/o-_4 [o] ro
[o] am
vowel/o_5 [O] nl
[O] da
vowel/o_6 [O:] nl
@@ -1735,6 +1764,8 @@ vowel/oo [o] base
[O] id
[o] prs
[o] bg
[O] wo
[O:] wo
vowel/oo_1 [O:] en-n
[O:] en-rp
[O@] en-rp
@@ -1798,6 +1829,7 @@ vowel/u [u] base
[u:] ml
[u] prs
[u] ak
[u:] wo
vowel/u# [u:] en-sc
[Y] tr
vowel/u_2 [u1] fi
@@ -1808,6 +1840,8 @@ vowel/u_2 [u1] fi
[u] tr
[u] sl
[u] bg
[u] am
[u] wo
vowel/u#_2 [u-] sv
vowel/u#_3 [U] ta
[U:] ta

BIN
phsource/j2/j2@ View File


BIN
phsource/j2/j2e View File


+ 1
- 0
phsource/mbrola/hu1 View File

@@ -26,6 +26,7 @@ volume 32
0 N NULL 0 n
0 C NULL 0 x
0 s2 NULL 0 s
0 t2 NULL 0 t


// map English phonemes to Hungarian

+ 5
- 1
phsource/ph_dutch View File

@@ -78,7 +78,11 @@ phoneme a:
vowel starttype #a endtype #a
length 210
IF thisPh(isUnstressed) THEN
FMT(vowel/a#_4)
IF thisPh(isWordEnd) THEN
FMT(vowel/a#_2)
ELSE
FMT(vowel/a#_4)
ENDIF
ENDIF
FMT(vowel/a)
endphoneme

+ 12
- 0
phsource/ph_hungarian View File

@@ -123,6 +123,18 @@ phoneme t // dental variant of /t/
endphoneme


phoneme t2
// changes to pause when followed by [t], so the [t][ becomes [t:]
vls dnt stop
lengthmod 2
IF nextPh(t) THEN
WAV(ustop/null, 0)
ELSE
ChangePhoneme(t)
ENDIF
endphoneme


phoneme d
vcd dnt stop
voicingswitch t

+ 1
- 1
phsource/ph_norwegian View File

@@ -15,7 +15,7 @@ phoneme @ // close schwa
FMT(vowel/@_4)
endphoneme

phoneme @2 // open schwa
phoneme a# // open schwa
vowel starttype #@ endtype #a
unstressed
length 120

+ 2
- 2
phsource/ph_tamil View File

@@ -66,14 +66,14 @@ endphoneme

phoneme o
vowel starttype #o endtype #o
length 160
length 130
FMT(vowel/o)
endphoneme


phoneme o:
vowel starttype #o endtype #o
length 280
length 300
FMT(vowel/o)
endphoneme


+ 21
- 0
phsource/phonemes View File

@@ -423,6 +423,21 @@ phoneme l
ChangePhoneme(l/)
ENDIF

IF nextPh(isNotVowel) THEN
// in case the next phoneme is no longer a vowel, in pass=2
PrevVowelEndings
VowelEnding(l/L1_@L, -60)
VowelEnding(l/L1_aL, -40)
VowelEnding(l/L1_eL, -30)
VowelEnding(l/L1_iL, -30)
VowelEnding(l/L1_oL, -40)
VowelEnding(l/L1_uL, -40)
EndSwitch

FMT(l/l_)
RETURN
ENDIF

CALL vowelstart_l

IF prevPh(#@) THEN
@@ -1822,3 +1837,9 @@ include ph_azerbaijani

phonemetable ak base
include ph_akan

phonemetable am base2
include ph_amhari

phonemetable wo base
include ph_wolof

BIN
phsource/vowel/i#_2 View File


+ 91
- 41
platforms/big_endian/espeak-phoneme-data.c View File

@@ -1,8 +1,9 @@


// 13.02.10 jonsd: Changed for eSpeak version 1.43
// 14.09.10 Recognize long and short frames in phondata
// 02.09.10 Fix: Q sections were omitted from the converted phondata
// 13.08.10 jonsd: Added Q lines. Use Address to set the displacement in phondata file.
// 13.02.10 jonsd: Changed for eSpeak version 1.43


#include <stdio.h>
@@ -10,6 +11,7 @@
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>

#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
#define IS_BIG_ENDIAN 1
@@ -57,7 +59,8 @@ typedef struct {


// This is a new format for eSpeak 1.41
typedef struct { // 44 bytes
#define FRFLAG_KLATT 0x01 // this frame includes extra data for Klatt synthesizer
typedef struct { // 64 bytes
short frflags;
short ffreq[7];
unsigned char length;
@@ -70,28 +73,29 @@ typedef struct { // 44 bytes
unsigned char klattp2[5]; // continuation of klattp[], Avp, Fric, FricBP, Turb
unsigned char klatt_ap[7]; // Klatt parallel amplitude
unsigned char klatt_bp[7]; // Klatt parallel bandwidth /2
unsigned char spare; // pad to multiple of 4 bytes
} frame_t; // with extra Klatt parameters for parallel resonators

typedef struct { // 44 bytes
short frflags;
short ffreq[7];
unsigned char length;
unsigned char rms;
unsigned char fheight[8];
unsigned char fwidth[6]; // width/4 f0-5
unsigned char fright[3]; // width/4 f0-2
unsigned char bw[4]; // Klatt bandwidth BNZ /2, f1,f2,f3
unsigned char klattp[5]; // AV, FNZ, Tilt, Aspr, Skew
} frame_t2;


#ifdef deleted
// This is the previous format for versions before 1.41
typedef struct {
short frflags;
unsigned char length;
unsigned char rms;
short ffreq[9];
unsigned char fheight[9];
unsigned char fwidth[6];
unsigned char fright[6];
} frame_t;
#endif

#define N_SEQ_FRAMES 25

typedef struct {
short length;
unsigned char n_frames;
unsigned char flags;
unsigned char sqflags;
frame_t frame[N_SEQ_FRAMES];
} SPECT_SEQ;

@@ -106,6 +110,23 @@ void usage (const char *program_name);
int xread; // prevent compiler warning from fread()


int GetFileLength(const char *filename)
{//====================================
struct stat statbuf;
if(stat(filename,&statbuf) != 0)
return(0);
if((statbuf.st_mode & S_IFMT) == S_IFDIR)
// if(S_ISDIR(statbuf.st_mode))
return(-2); // a directory
return(statbuf.st_size);
} // end of GetFileLength




int main (int argc, char *argv[])
{//==============================
const char *indir = "/usr/share/espeak-data";
@@ -147,6 +168,19 @@ int main (int argc, char *argv[])
printf ("Host seems to be little-endian ..\n");
#endif

sprintf (f1, "%s/phondata", indir);
sprintf (f2, "%s/temp_1", outdir);

printf ("Processing phondata ..\n");
swap_phondata (f1, f2, manifest);
if(GetFileLength(f1) != GetFileLength(f2))
{
fprintf(stderr, "Error: phondata length is different from the original\n");
exit(1);
}
sprintf (f1, "%s/phondata", outdir);
rename (f2, f1);

sprintf (f1, "%s/phontab", indir);
sprintf (f2, "%s/temp_1", outdir);

@@ -163,14 +197,6 @@ int main (int argc, char *argv[])
sprintf (f1, "%s/phonindex", outdir);
rename (f2, f1);

sprintf (f1, "%s/phondata", indir);
sprintf (f2, "%s/temp_1", outdir);

printf ("Processing phondata ..\n");
swap_phondata (f1, f2, manifest);
sprintf (f1, "%s/phondata", outdir);
rename (f2, f1);

free (f1);
free (f2);

@@ -218,34 +244,40 @@ void swap_phondata (const char *infile, const char *outfile,

if (line[0] == 'S') {
SPECT_SEQ buf_spect;
size_t ix;
size_t frame_start;
int n;

xread = fread (&buf_spect.length, 2, 1, in);
xread = fread (&buf_spect.n_frames, 1, 1, in);
fseek (in, -3, SEEK_CUR);

ix = (char *)(&buf_spect.frame[buf_spect.n_frames]) -
(char *)(&buf_spect);
ix = (ix+3) & 0xfffc;

xread = fread (&buf_spect, ix, 1, in);

xread = fread(&buf_spect, 4, 1, in);
buf_spect.length = (short) SWAP_USHORT (buf_spect.length);
fwrite(&buf_spect, 4, 1, out);

for (n = 0; n < buf_spect.n_frames; n++) {
int k;

buf_spect.frame[n].frflags = (short)
SWAP_USHORT (buf_spect.frame[n].frflags);
frame_start = ftell(in);
xread = fread(&buf_spect.frame[0], sizeof(frame_t), 1, in);

buf_spect.frame[0].frflags = (short)
SWAP_USHORT (buf_spect.frame[0].frflags);

// Changed for eSpeak 1.41
for (k = 0; k < 7; k++) {
buf_spect.frame[n].ffreq[k] = (short)
SWAP_USHORT (buf_spect.frame[n].ffreq[k]);
buf_spect.frame[0].ffreq[k] = (short)
SWAP_USHORT (buf_spect.frame[0].ffreq[k]);
}
}

fwrite (&buf_spect, ix, 1, out);
// is this a long or a short frame?
if(buf_spect.frame[0].frflags & FRFLAG_KLATT)
{
fwrite(&buf_spect.frame[0], sizeof(frame_t), 1, out);
fseek(in, frame_start + sizeof(frame_t), SEEK_SET);
}
else
{
fwrite(&buf_spect.frame[0], sizeof(frame_t2), 1, out);
fseek(in, frame_start + sizeof(frame_t2), SEEK_SET);
}
}
}
else if (line[0] == 'W') {
long pos;
@@ -286,6 +318,24 @@ void swap_phondata (const char *infile, const char *outfile,
xread = fread (env_buf, 1, 128, in);
fwrite (env_buf, 1, 128, out);
}
else if (line[0] == 'Q') {
unsigned char pb[4];
unsigned length;
char *buf;

xread = fread (pb, 1, 4, in);
fwrite (pb, 1, 4, out);

length = (pb[2] << 8) + pb[3]; // size in words
length *= 4;

buf = (char *) malloc (length);

xread = fread (buf, length, 1, in);
fwrite (buf, length, 1, out);

free (buf);
}
}

fclose (in);

+ 8
- 0
platforms/windows/espeakedit/espeakedit.dsp View File

@@ -609,6 +609,14 @@ SOURCE=.\src\sintab.h
# End Source File
# Begin Source File
SOURCE=.\src\sonic.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sonic.h
# End Source File
# Begin Source File
SOURCE=.\src\speak_lib.cpp
# End Source File
# Begin Source File

+ 1
- 0
platforms/windows/espeakedit/src/speech.h View File

@@ -25,6 +25,7 @@
// comment this out when compiling the "speak" process
//#define SPECT_EDITOR
#define INCLUDE_KLATT
#define INCLUDE_MBROLA
#include <windows.h>
#define PLATFORM_WINDOWS

+ 1
- 0
platforms/windows/espeakedit/src_copy/speech.h View File

@@ -25,6 +25,7 @@
// comment this out when compiling the "speak" process
//#define SPECT_EDITOR
#define INCLUDE_KLATT
#define INCLUDE_MBROLA
#include <windows.h>
#define PLATFORM_WINDOWS

+ 8
- 0
platforms/windows/windows_cmd/espeak.dsp View File

@@ -118,6 +118,10 @@ SOURCE=.\src\setlengths.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sonic.cpp
# End Source File
# Begin Source File
SOURCE=.\src\speak.cpp
# End Source File
# Begin Source File
@@ -171,6 +175,10 @@ SOURCE=.\src\sintab.h
# End Source File
# Begin Source File
SOURCE=.\src\sonic.h
# End Source File
# Begin Source File
SOURCE=.\src\speak_lib.h
# End Source File
# Begin Source File

+ 1
- 0
platforms/windows/windows_cmd/src/speech.h View File

@@ -33,6 +33,7 @@
#define NO_VARIADIC_MACROS
#define ESPEAK_API
#define INCLUDE_KLATT
#define INCLUDE_MBROLA
// will look for espeak_data directory here, and also in user's home directory
#define PATH_ESPEAK_DATA "/usr/share/espeak-data"

+ 8
- 0
platforms/windows/windows_dll/espeak.dsp View File

@@ -109,6 +109,10 @@ SOURCE=.\src\klatt.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sonic.cpp
# End Source File
# Begin Source File
SOURCE=.\src\numbers.cpp
# End Source File
# Begin Source File
@@ -174,6 +178,10 @@ SOURCE=.\src\klatt.h
# End Source File
# Begin Source File
SOURCE=.\src\sonic.h
# End Source File
# Begin Source File
SOURCE=.\src\phoneme.h
# End Source File
# Begin Source File

+ 66
- 57
platforms/windows/windows_dll/src/speak_lib.h View File

@@ -1,7 +1,7 @@
#ifndef SPEAK_LIB_H
#define SPEAK_LIB_H
/***************************************************************************
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
* Copyright (C) 2005 to 2010 by Jonathan Duddington *
* email: [email protected] *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -24,11 +24,11 @@
/* This is the header file for the library version of espeak */
/* */
/*************************************************************/
#define ESPEAK_API __declspec(dllexport)

#include <stdio.h>
#include <stddef.h>

#define ESPEAK_API_REVISION 5
#define ESPEAK_API_REVISION 6
/*
Revision 2
Added parameter "options" to eSpeakInitialize()
@@ -41,11 +41,19 @@ Revision 4

Revision 5
Added espeakCHARS_16BIT

Revision 6
Added macros: espeakRATE_MINIMUM, espeakRATE_MAXIMUM, espeakRATE_NORMAL
*/
/********************/
/* Initialization */
/********************/

// values for 'value' in espeak_SetParameter(espeakRATE, value, 0), nominally in words-per-minute
#define espeakRATE_MINIMUM 80
#define espeakRATE_MAXIMUM 450
#define espeakRATE_NORMAL 175


typedef enum {
espeakEVENT_LIST_TERMINATED = 0, // Retrieval mode: terminates the event list.
@@ -74,7 +82,7 @@ typedef struct {
const char *name; // used for MARK and PLAY events. UTF8 string
} id;
} espeak_EVENT;
/*
/*
When a message is supplied to espeak_synth, the request is buffered and espeak_synth returns. When the message is really processed, the callback function will be repetedly called.


@@ -82,16 +90,16 @@ typedef struct {

In PLAYBACK mode, the callback function is called as soon as an event happens.

For example suppose that the following message is supplied to espeak_Synth:
For example suppose that the following message is supplied to espeak_Synth:
"hello, hello."


* Once processed in RETRIEVAL mode, it could lead to 3 calls of the callback function :

** Block 1:
<audio data> +
<audio data> +
List of events: SENTENCE + WORD + LIST_TERMINATED
** Block 2:
<audio data> +
List of events: WORD + END + LIST_TERMINATED
@@ -128,11 +136,11 @@ typedef enum {

typedef enum {
/* PLAYBACK mode: plays the audio data, supplies events to the calling program*/
AUDIO_OUTPUT_PLAYBACK,
AUDIO_OUTPUT_PLAYBACK,

/* RETRIEVAL mode: supplies audio data and events to the calling program */
AUDIO_OUTPUT_RETRIEVAL,
/* SYNCHRONOUS mode: as RETRIEVAL but doesn't return until synthesis is completed */
AUDIO_OUTPUT_SYNCHRONOUS,

@@ -153,7 +161,7 @@ typedef enum {
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *path, int options);
int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *path, int options);
/* Must be called before any synthesis functions are called.
output: the audio data can either be played by eSpeak or passed back by the SynthCallback function.

@@ -172,10 +180,10 @@ typedef int (t_espeak_callback)(short*, int, espeak_EVENT*);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API void espeak_SetSynthCallback(t_espeak_callback* SynthCallback);
void espeak_SetSynthCallback(t_espeak_callback* SynthCallback);
/* Must be called before any synthesis functions are called.
This specifies a function in the calling program which is called when a buffer of
speech sound data has been produced.
speech sound data has been produced.


The callback function is of the form:
@@ -200,7 +208,7 @@ int SynthCallback(short *wav, int numsamples, espeak_EVENT *events);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API void espeak_SetUriCallback(int (*UriCallback)(int, const char*, const char*));
void espeak_SetUriCallback(int (*UriCallback)(int, const char*, const char*));
/* This function may be called before synthesis functions are used, in order to deal with
<audio> tags. It specifies a callback function which is called when an <audio> element is
encountered and allows the calling program to indicate whether the sound file which
@@ -241,7 +249,7 @@ int UriCallback(int type, const char *uri, const char *base);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Synth(const void *text,
espeak_ERROR espeak_Synth(const void *text,
size_t size,
unsigned int position,
espeak_POSITION_TYPE position_type,
@@ -264,7 +272,7 @@ ESPEAK_API espeak_ERROR espeak_Synth(const void *text,
start of the text.

position_type: Determines whether "position" is a number of characters, words, or sentences.
Values:
Values:

end_position: If set, this gives a character position at which speaking will stop. A value
of zero indicates no end position.
@@ -283,13 +291,13 @@ ESPEAK_API espeak_ERROR espeak_Synth(const void *text,
espeakENDPAUSE If set then a sentence pause is added at the end of the text. If not set then
this pause is suppressed.

unique_identifier: message identifier; helpful for identifying later
unique_identifier: message identifier; helpful for identifying later
data supplied to the callback.

user_data: pointer which will be passed to the callback function.

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -297,7 +305,7 @@ ESPEAK_API espeak_ERROR espeak_Synth(const void *text,
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text,
espeak_ERROR espeak_Synth_Mark(const void *text,
size_t size,
const char *index_mark,
unsigned int end_position,
@@ -312,8 +320,8 @@ ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text,

For the other parameters, see espeak_Synth()

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -321,13 +329,13 @@ ESPEAK_API espeak_ERROR espeak_Synth_Mark(const void *text,
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Key(const char *key_name);
espeak_ERROR espeak_Key(const char *key_name);
/* Speak the name of a keyboard key.
If key_name is a single character, it speaks the name of the character.
Otherwise, it speaks key_name as a text string.

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -335,11 +343,11 @@ ESPEAK_API espeak_ERROR espeak_Key(const char *key_name);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Char(wchar_t character);
/* Speak the name of the given character
espeak_ERROR espeak_Char(wchar_t character);
/* Speak the name of the given character

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -380,22 +388,23 @@ typedef enum {
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative);
espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int value, int relative);
/* Sets the value of the specified parameter.
relative=0 Sets the absolute value of the parameter.
relative=1 Sets a relative value of the parameter.

parameter:
espeakRATE: speaking speed in word per minute.
espeakRATE: speaking speed in word per minute. Values 80 to 450.

espeakVOLUME: volume in range 0-100 0=silence
espeakVOLUME: volume in range 0-200 or more.
0=silence, 100=normal full volume, greater values may produce amplitude compression or distortion

espeakPITCH: base pitch, range 0-100. 50=normal

espeakRANGE: pitch range, range 0-100. 0-monotone, 50=normal

espeakPUNCTUATION: which punctuation characters to announce:
value in espeak_PUNCT_TYPE (none, all, some),
value in espeak_PUNCT_TYPE (none, all, some),
see espeak_GetParameter() to specify which characters are announced.

espeakCAPITALS: announce capital letters by:
@@ -407,8 +416,8 @@ ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int valu

espeakWORDGAP: pause between words, units of 10mS (at the default speed)

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -416,7 +425,7 @@ ESPEAK_API espeak_ERROR espeak_SetParameter(espeak_PARAMETER parameter, int valu
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API int espeak_GetParameter(espeak_PARAMETER parameter, int current);
int espeak_GetParameter(espeak_PARAMETER parameter, int current);
/* current=0 Returns the default value of the specified parameter.
current=1 Returns the current value of the specified parameter, as set by SetParameter()
*/
@@ -424,14 +433,14 @@ ESPEAK_API int espeak_GetParameter(espeak_PARAMETER parameter, int current);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
/* Specified a list of punctuation characters whose names are to be spoken when the
value of the Punctuation parameter is set to "some".

punctlist: A list of character codes, terminated by a zero character.

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -439,11 +448,12 @@ ESPEAK_API espeak_ERROR espeak_SetPunctuationList(const wchar_t *punctlist);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream);
void espeak_SetPhonemeTrace(int value, FILE *stream);
/* Controls the output of phoneme symbols for the text
value=0 No phoneme output (default)
value=1 Output the translated phoneme symbols for the text
value=2 as (1), but also output a trace of how the translation was done (matching rules and list entries)
value=3 as (1), but produces IPA rather than ascii phoneme names

stream output stream for the phoneme symbols (and trace). If stream=NULL then it uses stdout.
*/
@@ -451,7 +461,7 @@ ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API void espeak_CompileDictionary(const char *path, FILE *log, int flags);
void espeak_CompileDictionary(const char *path, FILE *log, int flags);
/* Compile pronunciation dictionary for a language which corresponds to the currently
selected voice. The required voice should be selected before calling this function.

@@ -475,7 +485,7 @@ typedef struct {
unsigned char gender; // 0=none 1=male, 2=female,
unsigned char age; // 0=not specified, or age in years
unsigned char variant; // only used when passed as a parameter to espeak_SetVoiceByProperties
unsigned char xx1; // for internal use
unsigned char xx1; // for internal use
int score; // for internal use
void *spare; // for internal use
} espeak_VOICE;
@@ -504,24 +514,24 @@ typedef struct {
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec);
const espeak_VOICE **espeak_ListVoices(espeak_VOICE *voice_spec);
/* Reads the voice files from espeak-data/voices and creates an array of espeak_VOICE pointers.
The list is terminated by a NULL pointer

If voice_spec is NULL then all voices are listed.
If voice spec is give, then only the voices which are compatible with the voice_spec
If voice spec is given, then only the voices which are compatible with the voice_spec
are listed, and they are listed in preference order.
*/

#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name);
espeak_ERROR espeak_SetVoiceByName(const char *name);
/* Searches for a voice with a matching "name" field. Language is not considered.
"name" is a UTF8 string.

Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
Return: EE_OK: operation achieved
EE_BUFFER_FULL: the command can not be buffered;
you may try after a while to call the function again.
EE_INTERNAL_ERROR.
*/
@@ -529,7 +539,7 @@ ESPEAK_API espeak_ERROR espeak_SetVoiceByName(const char *name);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
/* An espeak_VOICE structure is used to pass criteria to select a voice. Any of the following
fields may be set:

@@ -549,7 +559,7 @@ ESPEAK_API espeak_ERROR espeak_SetVoiceByProperties(espeak_VOICE *voice_spec);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_VOICE *espeak_GetCurrentVoice(void);
espeak_VOICE *espeak_GetCurrentVoice(void);
/* Returns the espeak_VOICE data for the currently selected voice.
This is not affected by temporary voice changes caused by SSML elements such as <voice> and <s>
*/
@@ -557,12 +567,12 @@ ESPEAK_API espeak_VOICE *espeak_GetCurrentVoice(void);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Cancel(void);
espeak_ERROR espeak_Cancel(void);
/* Stop immediately synthesis and audio output of the current text. When this
function returns, the audio output is fully stopped and the synthesizer is ready to
synthesize a new message.

Return: EE_OK: operation achieved
Return: EE_OK: operation achieved
EE_INTERNAL_ERROR.
*/

@@ -570,25 +580,25 @@ ESPEAK_API espeak_ERROR espeak_Cancel(void);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API int espeak_IsPlaying(void);
int espeak_IsPlaying(void);
/* Returns 1 if audio is played, 0 otherwise.
*/

#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Synchronize(void);
espeak_ERROR espeak_Synchronize(void);
/* This function returns when all data have been spoken.
Return: EE_OK: operation achieved
Return: EE_OK: operation achieved
EE_INTERNAL_ERROR.
*/

#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API espeak_ERROR espeak_Terminate(void);
espeak_ERROR espeak_Terminate(void);
/* last function to be called.
Return: EE_OK: operation achieved
Return: EE_OK: operation achieved
EE_INTERNAL_ERROR.
*/

@@ -596,9 +606,8 @@ ESPEAK_API espeak_ERROR espeak_Terminate(void);
#ifdef __cplusplus
extern "C"
#endif
ESPEAK_API const char *espeak_Info(void* ptr);
const char *espeak_Info(void* ptr);
/* Returns the version number string.
The parameter is for future use, and should be set to NULL
*/
#endif


+ 1
- 0
platforms/windows/windows_dll/src/speech.h View File

@@ -34,6 +34,7 @@
#define ESPEAK_API __declspec(dllexport)
#define LIBRARY
#define INCLUDE_KLATT
#define INCLUDE_MBROLA

// will look for espeak_data directory here, and also in user's home directory
#define PATH_ESPEAK_DATA "/usr/share/espeak-data"

+ 1
- 0
platforms/windows/windows_sapi/src/speech.h View File

@@ -37,6 +37,7 @@
//#define USE_PORTAUDIO
//#define USE_NANOSLEEP
#define INCLUDE_KLATT
#define INCLUDE_MBROLA
// will look for espeak_data directory here, and also in user's home directory
#define PATH_ESPEAK_DATA "/usr/share/espeak-data"

+ 8
- 0
platforms/windows/windows_sapi/ttseng.dsp View File

@@ -144,6 +144,10 @@ SOURCE=.\src\setlengths.cpp
# End Source File
# Begin Source File
SOURCE=.\src\sonic.cpp
# End Source File
# Begin Source File
SOURCE=.\src\speak_lib.cpp
# End Source File
# Begin Source File
@@ -237,6 +241,10 @@ SOURCE=.\src\sintab.h
# End Source File
# Begin Source File
SOURCE=.\src\sonic.h
# End Source File
# Begin Source File
SOURCE=.\src\speak_lib.h
# End Source File
# Begin Source File

+ 2
- 2
platforms/windows/windows_sapi/ttsengobj.cpp View File

@@ -261,8 +261,8 @@ static int ConvertRate(int new_rate)
int rate;
static int rate_table[21] = {80,110,124,133,142,151,159,168,174,180,187,
196,208,220,240,270,300,335,369,390,450 };
static int rate_table[21] = {80,110,124,135,145,155,165,173,180,187,196,
208,220,245,270,300,335,370,410,450,500 };
rate = new_rate + master_rate;
if(rate < -10) rate = -10;

+ 5
- 4
src/Makefile View File

@@ -6,7 +6,7 @@ INCDIR=$(PREFIX)/include/espeak
LIBDIR=$(PREFIX)/lib
DATADIR=$(PREFIX)/share/espeak-data

RELEASE = 1.43
RELEASE = 1.44
BIN_NAME = speak
BIN2_NAME = espeak
LIB_NAME = libespeak.so
@@ -80,10 +80,10 @@ all: $(BIN_NAME) $(LIB_NAME) $(STATIC_LIB_NAME) $(BIN2_NAME)
$(CXX) $(CXXFLAGS) $(USE_AUDIO) -D PATH_ESPEAK_DATA=\"$(DATADIR)\" -Wall -pedantic -I. -c -fno-exceptions $<

$(BIN_NAME): $(OBJS1)
$(CXX) -o $@ $(OBJS1) $(LIBS1)
$(CXX) $(LDFLAGS) -o $@ $(OBJS1) $(LIBS1)

$(BIN2_NAME): $(OBJS3) $(LIB_NAME)
$(CXX) -o $@ $(OBJS3) $(LIBS3)
$(CXX) $(LDFLAGS) -o $@ $(OBJS3) $(LIBS3)



@@ -92,7 +92,8 @@ x_%.o: %.cpp
-I. -D LIBRARY -c -fno-exceptions $< -o x_$*.o

$(LIB_NAME): $(OBJS2)
$(CXX) -shared $(SONAME_OPT)$(LIB_NAME).$(LIB_VERSION) -o $@ $(OBJS2) $(LIBS2)
$(CXX) $(LDFLAGS) -shared $(SONAME_OPT)$(LIB_NAME).$(LIB_VERSION) -o $@ \
$(OBJS2) $(LIBS2)

$(STATIC_LIB_NAME): $(OBJS2)
$(AR) cqs $(STATIC_LIB_NAME) $(OBJS2)

+ 2
- 1
src/compiledata.cpp View File

@@ -140,6 +140,7 @@ static keywtab_t k_properties[] = {
{"isNotVowel", 0, i_isNotVowel},
{"isFinalVowel", 0, i_isFinalVowel},
{"isVoiced", 0, i_isVoiced}, // voiced consonant, or vowel
{"isFirstVowel", 0, i_isFirstVowel},

{NULL, 0, 0}
};
@@ -3259,7 +3260,7 @@ static void CompileEquivalents()
}
*p_equivalence++ = 0;

p_equivalence = (char *)((intptr_t)(p_equivalence + 3) & ~0x3); // align to word boundary
p_equivalence = (char *)((long int)(p_equivalence + 3) & ~0x3); // align to word boundary
n_bytes = p_equivalence - p_start;
p_start[1] = remove_stress;
n_bytes = n_bytes / 4;

+ 23
- 5
src/compiledict.cpp View File

@@ -208,14 +208,15 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
int flags;
int suffix_char;
int condition_num=0;
int at_start = 0;
const char *name;
char buf[60];
char buf_pre[60];
char suffix[20];
static char output[60];

static char symbols[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',
'@','&','%','+','#','S','D','Z','A','L','!',' ','?','?','J','N','K','V','?','T','X','?','W'};
static char symbols[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
'&','%','+','#','S','D','Z','A','L','!',' ','@','?','J','N','K','V','?','T','X','?','W'};

static char symbols_lg[] = {'A','B','C','H','F','G','Y'};

@@ -241,6 +242,8 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
case RULE_PHONEMES:
finished=1;
break;
case RULE_PRE_ATSTART:
at_start = 1; // drop through to next case
case RULE_PRE:
match_type = RULE_PRE;
*p = 0;
@@ -342,8 +345,10 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont
sprintf(p,"?%d ",condition_num);
p = &p[strlen(p)];
}
if((ix = strlen(buf_pre)) > 0)
if(((ix = strlen(buf_pre)) > 0) || at_start)
{
if(at_start)
*p++ = '_';
while(--ix >= 0)
*p++ = buf_pre[ix];
*p++ = ')';
@@ -1158,6 +1163,7 @@ static char *compile_rule(char *input)
char *prule;
int len;
int len_name;
int start;
int state=2;
int finish=0;
int pre_bracket=0;
@@ -1308,9 +1314,21 @@ static char *compile_rule(char *input)
}
if(rule_pre[0] != 0)
{
output[len++] = RULE_PRE;
start = 0;
if(rule_pre[0] == RULE_SPACE)
{
// omit '_' at the beginning of the pre-string and imply it by using RULE_PRE_ATSTART
c = RULE_PRE_ATSTART;
start = 1;
}
else
{
c = RULE_PRE;
}
output[len++] = c;

// output PRE string in reverse order
for(ix = strlen(rule_pre)-1; ix>=0; ix--)
for(ix = strlen(rule_pre)-1; ix>=start; ix--)
output[len++] = rule_pre[ix];
}


+ 53
- 26
src/dictionary.cpp View File

@@ -1090,6 +1090,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
int done;
int stressflags;
int dflags = 0;
int first_primary;

signed char vowel_stress[N_WORD_PHONEMES/2];
char syllable_weight[N_WORD_PHONEMES/2];
@@ -1433,6 +1434,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
}

done = 0;
first_primary = 0;
for(v=1; v<vowel_count; v++)
{
if(vowel_stress[v] < 0)
@@ -1469,6 +1471,18 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
stress = 3; /* use secondary stress for remaining syllables */
}
}

if(vowel_stress[v] >= 4)
{
if(first_primary == 0)
first_primary = v;
else
if(stressflags & S_FIRST_PRIMARY)
{
// reduce primary stresses after the first to secondary
vowel_stress[v] = 3;
}
}
}

if((unstressed_word) && (tonic < 0))
@@ -1737,7 +1751,6 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
int failed;
int unpron_ignore;
int consumed; /* number of letters consumed from input */
int count; /* count through rules in the group */
int syllable_count;
int vowel;
int letter_group;
@@ -1747,6 +1760,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
int n_bytes;
int add_points;
int command;
int check_atstart;

MatchRecord match;
static MatchRecord best;
@@ -1769,7 +1783,6 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_


total_consumed = 0;
count = 0;
common_phonemes = NULL;
match_type = 0;

@@ -1787,7 +1800,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
letter = 0;
distance_right= -6; /* used to reduce points for matches further away the current letter */
distance_left= -2;
count++;
check_atstart = 0;

match.points = 1;
match.end_type = 0;
@@ -1827,17 +1840,24 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
rule--; // so we are still pointing at the 0
failed=2; // matched OK
break;

case RULE_PRE_ATSTART: // pre rule with implied 'start of word'
check_atstart = 1;
unpron_ignore = 0;
match_type = RULE_PRE;
break;

case RULE_PRE:
match_type = RULE_PRE;
if(word_flags & FLAG_UNPRON_TEST)
{
// checking the start of the word for unpronouncable character sequences, only
// consider rules which explicitly match the start of a word
if(rule[0] != ' ')
failed = 1;
unpron_ignore = 0;
// Note: Those rules now use RULE_PRE_ATSTART
failed = 1;
}
break;

case RULE_POST:
match_type = RULE_POST;
break;
@@ -2306,31 +2326,34 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_
match.points += add_points;
}


if((failed == 2) && (unpron_ignore == 0))
{
/* matched OK, is this better than the last best match ? */

if(match.points >= best.points)
{
memcpy(&best,&match,sizeof(match));
total_consumed = consumed;
}

if((option_phonemes == 2) && (match.points > 0) && ((word_flags & FLAG_NO_TRACE) == 0))
// do we also need to check for 'start of word' ?
if((check_atstart==0) || (pre_ptr[-1] == ' '))
{
// show each rule that matches, and it's points score
int pts;
char decoded_phonemes[80];
if(check_atstart)
match.points += 4;

// note: 'count' contains the rule number, if we want to include it
pts = match.points;
if(group_length > 1)
pts += 35; // to account for an extra letter matching
DecodePhonemes(match.phonemes,decoded_phonemes);
fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group_chars, group_length, rule_start, word_flags), decoded_phonemes);
/* matched OK, is this better than the last best match ? */
if(match.points >= best.points)
{
memcpy(&best,&match,sizeof(match));
total_consumed = consumed;
}
if((option_phonemes == 2) && (match.points > 0) && ((word_flags & FLAG_NO_TRACE) == 0))
{
// show each rule that matches, and it's points score
int pts;
char decoded_phonemes[80];
pts = match.points;
if(group_length > 1)
pts += 35; // to account for an extra letter matching
DecodePhonemes(match.phonemes,decoded_phonemes);
fprintf(f_trans,"%3d\t%s [%s]\n",pts,DecodeRule(group_chars, group_length, rule_start, word_flags), decoded_phonemes);
}
}

}

/* skip phoneme string to reach start of next template */
@@ -3313,6 +3336,10 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f
fprintf(f_trans,"Replace: %s %s\n",word,*wordptr);
}
}
else
{
flags[0] &= ~FLAG_SKIPWORDS;
}

ph_out[0] = 0;
return(0);

+ 4
- 2
src/espeakedit.cpp View File

@@ -232,7 +232,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
EVT_MENU(MENU_LEXICON_BG, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_DE, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_IT, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_IT2, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_TEST, MyFrame::OnTools)
EVT_MENU(MENU_TO_UTF8, MyFrame::OnTools)
EVT_MENU(MENU_COUNT_WORDS, MyFrame::OnTools)
@@ -610,7 +609,6 @@ void MyFrame::OnTools(wxCommandEvent& event)
case MENU_LEXICON_BG:
case MENU_LEXICON_DE:
case MENU_LEXICON_IT:
case MENU_LEXICON_IT2:
case MENU_LEXICON_TEST:
CompareLexicon(event.GetId()); // Compare a lexicon with _rules translation
break;
@@ -699,6 +697,7 @@ void MyFrame::OnSpeak(wxCommandEvent& event)
break;

case MENU_SPEAK_FILE:
out_ptr = NULL;
transldlg->SpeakFile();
break;

@@ -707,11 +706,14 @@ void MyFrame::OnSpeak(wxCommandEvent& event)
break;

case MENU_SPEAK_PAUSE:
out_ptr = NULL;
SpeakNextClause(NULL,NULL,3);
if(SynthStatus() & 2)
speak_menu->SetLabel(MENU_SPEAK_PAUSE,_T("&Resume"));
else
{
speak_menu->SetLabel(MENU_SPEAK_PAUSE,_T("&Pause"));
}
break;

case MENU_SPEAK_VOICE:

+ 96
- 27
src/extras.cpp View File

@@ -289,11 +289,14 @@ static void DecodePhonemes2(const char *inptr, char *outptr)

void Lexicon_It(int pass)
{//======================
// Reads a lexicon of pairs of words: normal spelling and spelling with accents
// Creates file: dictsource/it_listx which includes corrections for stress position and [E]/[e] and [O]/[o] phonemes
// Words which are still in error are listed in file: it_compare (in the directory of the lexicon file).
int count=0;
int matched=0;
int ix;
int c;
char *p;
char *p, *p2;
int len;
int vowel_ix;
int stress_posn1;
@@ -305,8 +308,11 @@ void Lexicon_It(int pass)
FILE *f_out;
FILE *f_listx;
FILE *f_list_in = NULL;
int listx_count;
long int displ;
const char *alt_string;
wxString str;
static wxString fname_lex;
char buf[200];
char word[80];
char word1[80];
@@ -315,7 +321,10 @@ void Lexicon_It(int pass)
char temp[80];
char phonemes[80];
char phonemes2[80];
char buf_out[120];
char phonemes3[80];
char buf_out[200];
char buf_error[200];
char last_listx[200];
static const char *vowels1 = "aeiou";
static const char *vowels2 = "aeou";

@@ -333,31 +342,42 @@ void Lexicon_It(int pass)

static const char *exceptions[] = {ex1, ex2, ex3, ex4, ex5, ex6, ex7, ex8, ex9, ex10, NULL};

wxString fname = wxFileSelector(_T("Italian Lexicon"),path_dir1,_T(""),_T(""),_T("*"),wxOPEN);
if(pass == 1)
{
fname_lex = wxFileSelector(_T("Italian Lexicon"),path_dir1,_T(""),_T(""),_T("*"),wxOPEN);
}

strcpy(buf,fname.mb_str(wxConvLocal));
strcpy(buf,fname_lex.mb_str(wxConvLocal));
if((f_in = fopen(buf,"r")) == NULL)
{
wxLogError(_T("Can't read file ")+fname);
wxLogError(_T("Can't read file ")+fname_lex);
return;
}
path_dir1 = wxFileName(fname).GetPath();
path_dir1 = wxFileName(fname_lex).GetPath();
strcpy(buf_out, path_dir1.mb_str(wxConvLocal));
sprintf(buf, "%s/IT_errors", buf_out);
if((f_out = fopen("compare_it","w")) == NULL)
if((f_out = fopen(buf,"w")) == NULL)
{
wxLogError(_T("Can't write file: compare_it "));
str = wxString(buf, wxConvLocal);
wxLogError(_T("Can't write file: ") + str);
return;
}

listx_count = 0;
last_listx[0] = 0;

if(pass == 1)
{
sprintf(buf,"%s/it_listx",path_dsource);
remove(buf);
CompileDictionary(path_dsource,"it",NULL,NULL,0);
f_listx = fopen(buf,"w");
wxLogStatus(_T("Pass 1"));
}
else
{
CompileDictionary(path_dsource,"it",NULL,NULL,0);
sprintf(buf,"%s/it_listx2",path_dsource);
f_listx = fopen(buf,"w");
sprintf(buf,"%s/it_listx",path_dsource);
@@ -390,9 +410,9 @@ void Lexicon_It(int pass)
continue;

if(strlen(word) < 8)
sprintf(buf_out,"%s\t\t%s\t",word,temp);
sprintf(buf_error,"%s\t\t%s\t",word,temp);
else
sprintf(buf_out,"%s\t%s",word,temp);
sprintf(buf_error,"%s\t%s",word,temp);

sprintf(word1," %s ",word);

@@ -550,22 +570,37 @@ void Lexicon_It(int pass)
sscanf(buf, "%s", word1);
if(strcmp(word1, word_stem) < 0)
{
fprintf(f_listx,"%s",buf); // copy it_listx from pass 1 until we reach the matching word
sprintf(buf_out,"%s",buf); // copy it_listx from pass 1 until we reach the matching word
}
else
if(strcmp(word1, word_stem) == 0)
{
p = buf;
while((*p != '\n') && (*p != 0)) *p++;
*p = 0;
fprintf(f_listx,"%s %s\n",buf,alt_string); // add $alt or $alt2 to the entry
if(strcmp(word1, word_stem) == 0)
{
p = buf;
while((*p != '\n') && (*p != 0)) *p++;
*p = 0;
sprintf(buf_out,"%s %s\n",buf,alt_string); // add $alt or $alt2 to the entry
}
else
{
sprintf(buf_out,"%s %s\n", word_stem, alt_string); // add a new word with $alt or $alt2
fseek(f_list_in, displ, SEEK_SET);
}

if(strcmp(buf_out, last_listx) != 0)
{
fprintf(f_listx, "%s", buf_out);
listx_count++;
strcpy(last_listx, buf_out);
}
break;
}
else

if(strcmp(buf_out, last_listx) != 0)
{
fprintf(f_listx,"%s %s\n", word_stem, alt_string); // add a new word with $alt or $alt2
fseek(f_list_in, displ, SEEK_SET);
break;
fprintf(f_listx, "%s", buf_out);
listx_count++;
strcpy(last_listx, buf_out);
}
}
}
@@ -574,7 +609,26 @@ void Lexicon_It(int pass)
}
else
{
fprintf(f_out,"%s\t%s\t%s\n",buf_out,phonemes,phonemes2);
// allow if the only difference is no primary stress
p2 = phonemes2;
p = phonemes3;
while(*p2 != 0)
{
*p = *p2++;
if((*p2 == ':') && (strchr("aeiouEO", *p) != NULL)) p2++; // change lone vowels to short by removing ':'
if(*p == '\'') *p = ','; // change primary to secondary stress
p++;
}
*p = 0;
if(strcmp(phonemes, phonemes3) == 0)
{
matched++;
}
else
{
// still doesn't match, report this word
fprintf(f_out,"%s\t%s\t%s\n",buf_error,phonemes,phonemes2);
}
}
}

@@ -582,15 +636,32 @@ void Lexicon_It(int pass)
{
while(fgets(buf, sizeof(buf), f_list_in) != NULL)
{
fprintf(f_listx, "%s", buf); // copy the remaining entries from pass 1
if(strcmp(buf, last_listx) != 0) // check for duplicate entries
{
fprintf(f_listx, "%s", buf); // copy the remaining entries from pass 1
listx_count++;
strcpy(last_listx, buf);
}
}
fclose(f_list_in);
}
fclose(f_in);
fclose(f_out);
fclose(f_listx);
wxLogStatus(_T("Completed, equal=%d different=%d"),matched,count-matched);
}

if(pass == 2)
{
sprintf(buf,"%s/it_listx",path_dsource);
remove(buf);
sprintf(buf_out,"%s/it_listx2",path_dsource);
rename(buf_out, buf);
wxLogStatus(_T("Created file 'it_listx', entries=%d errors=%d total words=%d"),listx_count, count-matched, count);
}
else
{
wxLogStatus(_T("Pass 1, equal=%d different=%d"),matched,count-matched);
}
} // end of Lexicon_It


void Lexicon_De()
@@ -760,7 +831,7 @@ void Lexicon_De()
fclose(f_in);
fclose(f_out);
wxLogStatus(_T("Completed, equal=%d different=%d"),matched,count-matched);
}
} // end of Lexicon_De


extern int IsVowel(Translator *tr, int letter);
@@ -1340,8 +1411,6 @@ void CompareLexicon(int id)
break;
case MENU_LEXICON_IT:
Lexicon_It(1);
break;
case MENU_LEXICON_IT2:
Lexicon_It(2);
break;
case MENU_LEXICON_TEST:

+ 0
- 1
src/main.h View File

@@ -160,7 +160,6 @@ enum {
MENU_LEXICON_BG,
MENU_LEXICON_DE,
MENU_LEXICON_IT,
MENU_LEXICON_IT2,
MENU_LEXICON_TEST,
MENU_TO_UTF8,
MENU_COUNT_WORDS,

+ 0
- 1
src/menus.cpp View File

@@ -127,7 +127,6 @@ wxMenuBar *MakeMenu(int type, const char *dict_name)
lexicon_menu->Append(MENU_LEXICON_BG, _("Bulgarian"));
lexicon_menu->Append(MENU_LEXICON_DE, _("German"));
lexicon_menu->Append(MENU_LEXICON_IT, _("Italian"));
lexicon_menu->Append(MENU_LEXICON_IT2, _("Italian, pass 2"));
// lexicon_menu->Append(MENU_LEXICON_TEST, _("Test"));

tools_menu = new wxMenu;

+ 44
- 19
src/numbers.cpp View File

@@ -808,14 +808,18 @@ if((tr->prev_dict_flags & FLAG_ALT_TRANS) && ((c2 == 0) || (wtab[0].flags & FLAG
} // end of CheckDotOrdinal


static int hu_number_e(const char *word)
{//=====================================
static int hu_number_e(const char *word, int thousandplex, int value)
{//==================================================================
// lang-hu: variant form of numbers when followed by hyphen and a suffix starting with 'a' or 'e' (but not a, e, az, ez, azt, ezt, att. ett

if((word[0] == 'a') || (word[0] == 'e'))
{
if((word[1] == ' ') || (word[1] == 'z') || ((word[1] == 't') && (word[2] == 't')))
return(0);

if(((thousandplex==1) || ((value % 1000) == 0)) && (word[1] == 'l'))
return(0); // 1000-el

return(1);
}
return(0);
@@ -927,7 +931,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab)
{
if(!(wtab[0].flags & FLAG_ORDINAL))
{
if((wtab[0].flags & FLAG_HYPHEN_AFTER) && hu_number_e(word))
if((wtab[0].flags & FLAG_HYPHEN_AFTER) && hu_number_e(word, 0, acc))
{
// should use the 'e' form of the number
num_control |= 1;
@@ -1202,12 +1206,19 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
else
{
if((control & 1) && ((units == 0) || (tr->langopts.numbers & NUM_SWAP_TENS)))
if((control & 1) &&
((units == 0) || (tr->langopts.numbers & NUM_SWAP_TENS) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)))
{
sprintf(string,"_%dX%c", tens, ord_type);
if(Lookup(tr, string, ph_tens) != 0)
{
found_ordinal = 1;

if((units != 0) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL))
{
// Use the ordinal form of tens as well as units. Add the ordinal ending
strcat(ph_tens, ph_ordinal2);
}
}
}
if(found_ordinal == 0)
@@ -1290,6 +1301,10 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out)
if((tr->langopts.numbers & (NUM_SWAP_TENS | NUM_AND_UNITS)) && (ph_tens[0] != 0) && (ph_digits[0] != 0))
{
Lookup(tr, "_0and", ph_and);

if(tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)
ph_and[0] = 0;

if(tr->langopts.numbers & NUM_SWAP_TENS)
sprintf(ph_out,"%s%s%s%s",ph_digits, ph_and, ph_tens, ph_ordinal);
else
@@ -1355,7 +1370,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
char ph_thousands[50];
char ph_hundred_and[12];
char ph_thousand_and[12];
ordinal = control & 0x22;
hundreds = value / 100;
tensunits = value % 100;
@@ -1422,22 +1437,28 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null
suppress_null = 1;

found = 0;
if(tensunits == 0)
if((ordinal)
&& ((tensunits == 0) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)))
{
// is there a special pronunciation for exactly n00 ?
// ordinal number
sprintf(string, "_%dCo", hundreds);
found = Lookup(tr, string, ph_digits);

if(ordinal)
if((tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL) && (tensunits > 0))
{
// ordinal number
sprintf(string, "_%dCo", hundreds);
found = Lookup(tr, string, ph_digits);
}
if(!found)
{
sprintf(string,"_%dC0",hundreds);
found = Lookup(tr, string, ph_digits);
// Use ordinal form of hundreds, as well as for tens and units
// Add ordinal suffix to the hundreds
strcat(ph_digits, ph_ordinal2);
}
}

if((!found) && (tensunits == 0))
{
// is there a special pronunciation for exactly n00 ?
sprintf(string,"_%dC0",hundreds);
found = Lookup(tr, string, ph_digits);
}

if(!found)
{
sprintf(string,"_%dC",hundreds);
@@ -1536,6 +1557,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
int thousands_inc = 0;
int prev_thousands = 0;
int ordinal = 0;
int dot_ordinal;
int this_value;
int decimal_count;
int max_decimal_count;
@@ -1590,7 +1612,8 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
if(prev_thousands || (word[0] != '0'))
{
// don't check for ordinal if the number has a leading zero
ordinal = CheckDotOrdinal(tr, word, &word[ix], wtab, 0);
if((ordinal = CheckDotOrdinal(tr, word, &word[ix], wtab, 0)) != 0)
dot_ordinal = 1;
}

if((word[ix] == '.') && !isdigit(word[ix+1]) && !isdigit(word[ix+2]) && !(wtab[1].flags & FLAG_NOSPACE))
@@ -1709,7 +1732,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
if(tr->translator_name == L('h','u'))
{
// variant form of numbers when followed by hyphen and a suffix starting with 'a' or 'e' (but not a, e, az, ez, azt, ezt
if((wtab[thousandplex].flags & FLAG_HYPHEN_AFTER) && (thousands_exact==1) && hu_number_e(&word[suffix_ix]))
if((wtab[thousandplex].flags & FLAG_HYPHEN_AFTER) && (thousands_exact==1) && hu_number_e(&word[suffix_ix], thousandplex, value))
{
number_control |= 1; // use _1e variant of number
}
@@ -1769,9 +1792,11 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned
n_digit_lookup = 2;
}
}

// if((buf_digit_lookup[0] == 0) && (*p != '0') && (dot_ordinal==0))
if((buf_digit_lookup[0] == 0) && (*p != '0'))
{
// not found, lookup only the last digit
// not found, lookup only the last digit (?? but not if dot-ordinal has been found)
if(LookupDictList(tr, &p, buf_digit_lookup, flags, FLAG_SUFX, wtab)) // don't match '0', or entries with $only
{
n_digit_lookup = 1;

+ 14
- 12
src/setlengths.cpp View File

@@ -150,6 +150,20 @@ void SetSpeed(int control)
if(control == 2)
wpm = embedded_value[EMBED_S2];

// fast_settings[0] wpm where speedup starts
// fast_settings[1] wpm for maximum espeak speed
// fast_settings[2] maximum espeak speed

sonicSpeed = 1.0;
if(wpm > speed.fast_settings[0])
{
wpm2 = wpm;
wpm = speed.fast_settings[2];
// Maybe we can do better than a 10 wpm fudge factor?
sonicSpeed = ((double)wpm2 + 10)/wpm;
}


#ifdef TEST_SPEED
if(wpm > 1000)
{
@@ -262,18 +276,6 @@ void SetSpeed(int control)
if((speed.clause_pause_factor = speed.pause_factor) < 16)
speed.clause_pause_factor = 16;
}

if(wpm >= 370)
{
// TESTING
// use experimental fast settings if they have been specified in the Voice
if(speed.fast_settings[0] > 0)
speed.pause_factor = speed.fast_settings[0];
if(speed.fast_settings[1] > 0)
speed.wav_factor = speed.fast_settings[1];
if(speed.fast_settings[2] > 0)
speed.lenmod_factor = speed.lenmod2_factor = speed.fast_settings[2];
}
}

#ifdef TEST_SPEED

+ 967
- 0
src/sonic.cpp View File

@@ -0,0 +1,967 @@
/* Sonic library
Copyright 2010
Bill Cox
This file is part of the Sonic Library.

The Sonic Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

#include "StdAfx.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "sonic.h"

struct sonicStreamStruct {
short *inputBuffer;
short *outputBuffer;
short *pitchBuffer;
short *downSampleBuffer;
float speed;
float volume;
float pitch;
int numChannels;
int inputBufferSize;
int pitchBufferSize;
int outputBufferSize;
int numInputSamples;
int numOutputSamples;
int numPitchSamples;
int minPeriod;
int maxPeriod;
int maxRequired;
int remainingInputToCopy;
int sampleRate;
int prevPeriod;
int prevMaxDiff;
int prevMinDiff;
};

/* Just used for debugging */
void sonicMSG(char *format, ...)
{
char buffer[4096];
va_list ap;
FILE *file;

va_start(ap, format);
vsprintf((char *)buffer, (char *)format, ap);
va_end(ap);
file=fopen("/tmp/sonic.log", "a");
fprintf(file, "%s", buffer);
fclose(file);
}

/* Scale the samples by the factor. */
static void scaleSamples(
short *samples,
int numSamples,
float volume)
{
int fixedPointVolume = volume*4096.0f;
int value;

while(numSamples--) {
value = (*samples*fixedPointVolume) >> 12;
if(value > 32767) {
value = 32767;
} else if(value < -32767) {
value = -32767;
}
*samples++ = value;
}
}

/* Get the speed of the stream. */
float sonicGetSpeed(
sonicStream stream)
{
return stream->speed;
}

/* Set the speed of the stream. */
void sonicSetSpeed(
sonicStream stream,
float speed)
{
stream->speed = speed;
}

/* Get the pitch of the stream. */
float sonicGetPitch(
sonicStream stream)
{
return stream->pitch;
}

/* Set the pitch of the stream. */
void sonicSetPitch(
sonicStream stream,
float pitch)
{
stream->pitch = pitch;
}

/* Get the scaling factor of the stream. */
float sonicGetVolume(
sonicStream stream)
{
return stream->volume;
}

/* Set the scaling factor of the stream. */
void sonicSetVolume(
sonicStream stream,
float volume)
{
stream->volume = volume;
}

/* Get the sample rate of the stream. */
int sonicGetSampleRate(
sonicStream stream)
{
return stream->sampleRate;
}

/* Get the number of channels. */
int sonicGetNumChannels(
sonicStream stream)
{
return stream->numChannels;
}

/* Destroy the sonic stream. */
void sonicDestroyStream(
sonicStream stream)
{
if(stream->inputBuffer != NULL) {
free(stream->inputBuffer);
}
if(stream->outputBuffer != NULL) {
free(stream->outputBuffer);
}
if(stream->pitchBuffer != NULL) {
free(stream->pitchBuffer);
}
if(stream->downSampleBuffer != NULL) {
free(stream->downSampleBuffer);
}
free(stream);
}

/* Create a sonic stream. Return NULL only if we are out of memory and cannot
allocate the stream. */
sonicStream sonicCreateStream(
int sampleRate,
int numChannels)
{
sonicStream stream = (sonicStream)calloc(1, sizeof(struct sonicStreamStruct));
int minPeriod = sampleRate/SONIC_MAX_PITCH;
int maxPeriod = sampleRate/SONIC_MIN_PITCH;
int maxRequired = 2*maxPeriod;

if(stream == NULL) {
return NULL;
}
stream->inputBufferSize = maxRequired;
stream->inputBuffer = (short *)calloc(maxRequired, sizeof(short)*numChannels);
if(stream->inputBuffer == NULL) {
sonicDestroyStream(stream);
return NULL;
}
stream->outputBufferSize = maxRequired;
stream->outputBuffer = (short *)calloc(maxRequired, sizeof(short)*numChannels);
if(stream->outputBuffer == NULL) {
sonicDestroyStream(stream);
return NULL;
}
stream->pitchBufferSize = maxRequired;
stream->pitchBuffer = (short *)calloc(maxRequired, sizeof(short)*numChannels);
if(stream->pitchBuffer == NULL) {
sonicDestroyStream(stream);
return NULL;
}
stream->downSampleBuffer = (short *)calloc(maxRequired, sizeof(short));
stream->speed = 1.0f;
stream->pitch = 1.0f;
stream->volume = 1.0f;
stream->sampleRate = sampleRate;
stream->numChannels = numChannels;
stream->minPeriod = minPeriod;
stream->maxPeriod = maxPeriod;
stream->maxRequired = maxRequired;
return stream;
}

/* Enlarge the output buffer if needed. */
static int enlargeOutputBufferIfNeeded(
sonicStream stream,
int numSamples)
{
if(stream->numOutputSamples + numSamples > stream->outputBufferSize) {
stream->outputBufferSize += (stream->outputBufferSize >> 1) + numSamples;
stream->outputBuffer = (short *)realloc(stream->outputBuffer,
stream->outputBufferSize*sizeof(short)*stream->numChannels);
if(stream->outputBuffer == NULL) {
return 0;
}
}
return 1;
}

/* Enlarge the input buffer if needed. */
static int enlargeInputBufferIfNeeded(
sonicStream stream,
int numSamples)
{
if(stream->numInputSamples + numSamples > stream->inputBufferSize) {
stream->inputBufferSize += (stream->inputBufferSize >> 1) + numSamples;
stream->inputBuffer = (short *)realloc(stream->inputBuffer,
stream->inputBufferSize*sizeof(short)*stream->numChannels);
if(stream->inputBuffer == NULL) {
return 0;
}
}
return 1;
}

/* Add the input samples to the input buffer. */
static int addFloatSamplesToInputBuffer(
sonicStream stream,
float *samples,
int numSamples)
{
short *buffer;
int count = numSamples*stream->numChannels;

if(numSamples == 0) {
return 1;
}
if(!enlargeInputBufferIfNeeded(stream, numSamples)) {
return 0;
}
buffer = stream->inputBuffer + stream->numInputSamples*stream->numChannels;
while(count--) {
*buffer++ = (*samples++)*32767.0f;
}
stream->numInputSamples += numSamples;
return 1;
}

/* Add the input samples to the input buffer. */
static int addShortSamplesToInputBuffer(
sonicStream stream,
short *samples,
int numSamples)
{
if(numSamples == 0) {
return 1;
}
if(!enlargeInputBufferIfNeeded(stream, numSamples)) {
return 0;
}
memcpy(stream->inputBuffer + stream->numInputSamples*stream->numChannels, samples,
numSamples*sizeof(short)*stream->numChannels);
stream->numInputSamples += numSamples;
return 1;
}

/* Add the input samples to the input buffer. */
static int addUnsignedCharSamplesToInputBuffer(
sonicStream stream,
unsigned char *samples,
int numSamples)
{
short *buffer;
int count = numSamples*stream->numChannels;

if(numSamples == 0) {
return 1;
}
if(!enlargeInputBufferIfNeeded(stream, numSamples)) {
return 0;
}
buffer = stream->inputBuffer + stream->numInputSamples*stream->numChannels;
while(count--) {
*buffer++ = (*samples++ - 128) << 8;
}
stream->numInputSamples += numSamples;
return 1;
}

/* Remove input samples that we have already processed. */
static void removeInputSamples(
sonicStream stream,
int position)
{
int remainingSamples = stream->numInputSamples - position;

if(remainingSamples > 0) {
memmove(stream->inputBuffer, stream->inputBuffer + position*stream->numChannels,
remainingSamples*sizeof(short)*stream->numChannels);
}
stream->numInputSamples = remainingSamples;
}

/* Just copy from the array to the output buffer */
static int copyToOutput(
sonicStream stream,
short *samples,
int numSamples)
{
if(!enlargeOutputBufferIfNeeded(stream, numSamples)) {
return 0;
}
memcpy(stream->outputBuffer + stream->numOutputSamples*stream->numChannels,
samples, numSamples*sizeof(short)*stream->numChannels);
stream->numOutputSamples += numSamples;
return numSamples;
}

/* Just copy from the input buffer to the output buffer. Return 0 if we fail to
resize the output buffer. Otherwise, return numSamples */
static int copyInputToOutput(
sonicStream stream,
int position)
{
int numSamples = stream->remainingInputToCopy;

if(numSamples > stream->maxRequired) {
numSamples = stream->maxRequired;
}
if(!copyToOutput(stream, stream->inputBuffer + position*stream->numChannels,
numSamples)) {
return 0;
}
stream->remainingInputToCopy -= numSamples;
return numSamples;
}

/* Read data out of the stream. Sometimes no data will be available, and zero
is returned, which is not an error condition. */
int sonicReadFloatFromStream(
sonicStream stream,
float *samples,
int maxSamples)
{
int numSamples = stream->numOutputSamples;
int remainingSamples = 0;
short *buffer;
int count;

if(numSamples == 0) {
return 0;
}
if(numSamples > maxSamples) {
remainingSamples = numSamples - maxSamples;
numSamples = maxSamples;
}
buffer = stream->outputBuffer;
count = numSamples*stream->numChannels;
while(count--) {
*samples++ = (*buffer++)/32767.0f;
}
if(remainingSamples > 0) {
memmove(stream->outputBuffer, stream->outputBuffer + numSamples*stream->numChannels,
remainingSamples*sizeof(short)*stream->numChannels);
}
stream->numOutputSamples = remainingSamples;
return numSamples;
}

/* Read short data out of the stream. Sometimes no data will be available, and zero
is returned, which is not an error condition. */
int sonicReadShortFromStream(
sonicStream stream,
short *samples,
int maxSamples)
{
int numSamples = stream->numOutputSamples;
int remainingSamples = 0;

if(numSamples == 0) {
return 0;
}
if(numSamples > maxSamples) {
remainingSamples = numSamples - maxSamples;
numSamples = maxSamples;
}
memcpy(samples, stream->outputBuffer, numSamples*sizeof(short)*stream->numChannels);
if(remainingSamples > 0) {
memmove(stream->outputBuffer, stream->outputBuffer + numSamples*stream->numChannels,
remainingSamples*sizeof(short)*stream->numChannels);
}
stream->numOutputSamples = remainingSamples;
return numSamples;
}

/* Read unsigned char data out of the stream. Sometimes no data will be available, and zero
is returned, which is not an error condition. */
int sonicReadUnsignedCharFromStream(
sonicStream stream,
unsigned char *samples,
int maxSamples)
{
int numSamples = stream->numOutputSamples;
int remainingSamples = 0;
short *buffer;
int count;

if(numSamples == 0) {
return 0;
}
if(numSamples > maxSamples) {
remainingSamples = numSamples - maxSamples;
numSamples = maxSamples;
}
buffer = stream->outputBuffer;
count = numSamples*stream->numChannels;
while(count--) {
*samples++ = (char)((*buffer++) >> 8) + 128;
}
if(remainingSamples > 0) {
memmove(stream->outputBuffer, stream->outputBuffer + numSamples*stream->numChannels,
remainingSamples*sizeof(short)*stream->numChannels);
}
stream->numOutputSamples = remainingSamples;
return numSamples;
}

/* Force the sonic stream to generate output using whatever data it currently
has. No extra delay will be added to the output, but flushing in the middle of
words could introduce distortion. */
int sonicFlushStream(
sonicStream stream)
{
int maxRequired = stream->maxRequired;
int numSamples = stream->numInputSamples;
int remainingSpace, numOutputSamples, expectedSamples;

if(numSamples == 0) {
return 1;
}
if(numSamples >= maxRequired && !sonicWriteShortToStream(stream, NULL, 0)) {
return 0;
}
numSamples = stream->numInputSamples; /* Now numSamples < maxRequired */
if(numSamples == 0) {
return 1;
}
remainingSpace = maxRequired - numSamples;
memset(stream->inputBuffer + numSamples*stream->numChannels, 0,
remainingSpace*sizeof(short)*stream->numChannels);
stream->numInputSamples = maxRequired;
numOutputSamples = stream->numOutputSamples;
if(!sonicWriteShortToStream(stream, NULL, 0)) {
return 0;
}
/* Throw away any extra samples we generated due to the silence we added */
expectedSamples = (int)(numSamples*stream->speed + 0.5);
if(stream->numOutputSamples > numOutputSamples + expectedSamples) {
stream->numOutputSamples = numOutputSamples + expectedSamples;
}
return 1;
}

/* Return the number of samples in the output buffer */
int sonicSamplesAvailable(
sonicStream stream)
{
return stream->numOutputSamples;
}

/* If skip is greater than one, average skip samples togther and write them to
the down-sample buffer. If numChannels is greater than one, mix the channels
together as we down sample. */
static void downSampleInput(
sonicStream stream,
short *samples,
int skip)
{
int numSamples = stream->maxRequired/skip;
int samplesPerValue = stream->numChannels*skip;
int i, j;
int value;
short *downSamples = stream->downSampleBuffer;

for(i = 0; i < numSamples; i++) {
value = 0;
for(j = 0; j < samplesPerValue; j++) {
value += *samples++;
}
value /= samplesPerValue;
*downSamples++ = value;
}
}

/* Find the best frequency match in the range, and given a sample skip multiple.
For now, just find the pitch of the first channel. */
static int findPitchPeriodInRange(
short *samples,
int minPeriod,
int maxPeriod,
int *retMinDiff,
int *retMaxDiff)
{
int period, bestPeriod = 0;
short *s, *p, sVal, pVal;
unsigned long diff, minDiff = 1, maxDiff = 0;
int i;

for(period = minPeriod; period <= maxPeriod; period++) {
diff = 0;
s = samples;
p = samples + period;
for(i = 0; i < period; i++) {
sVal = *s++;
pVal = *p++;
diff += sVal >= pVal? (unsigned short)(sVal - pVal) :
(unsigned short)(pVal - sVal);
}
/* Note that the highest number of samples we add into diff will be less
than 256, since we skip samples. Thus, diff is a 24 bit number, and
we can safely multiply by numSamples without overflow */
if(diff*bestPeriod < minDiff*period) {
minDiff = diff;
bestPeriod = period;
}
if(diff*bestPeriod > maxDiff*period) {
maxDiff = diff;
}
}
*retMinDiff = minDiff;
*retMaxDiff = maxDiff;
return bestPeriod;
}

/* At abrupt ends of voiced words, we can have pitch periods that are better
aproximated by the previous pitch period estimate. Try to detect this case. */
static int prevPeriodBetter(
sonicStream stream,
int period,
int minDiff,
int maxDiff)
{
if(maxDiff*3/2 < stream->prevMaxDiff && (maxDiff*3.0f)*stream->prevMinDiff <
(float)stream->prevMaxDiff*minDiff*2) {
return 1;
}
return 0;
}

/* Find the pitch period. This is a critical step, and we may have to try
multiple ways to get a good answer. This version uses AMDF. To improve
speed, we down sample by an integer factor get in the 11KHz range, and then
do it again with a narrower frequency range without down sampling */
static int findPitchPeriod(
sonicStream stream,
short *samples)
{
int minPeriod = stream->minPeriod;
int maxPeriod = stream->maxPeriod;
int sampleRate = stream->sampleRate;
int minDiff, maxDiff, retPeriod;
int skip = 1;
int period;

if(sampleRate > SONIC_AMDF_FREQ) {
skip = sampleRate/SONIC_AMDF_FREQ;
}
if(stream->numChannels == 1 && skip == 1) {
period = findPitchPeriodInRange(samples, minPeriod, maxPeriod, &minDiff, &maxDiff);
} else {
downSampleInput(stream, samples, skip);
period = findPitchPeriodInRange(stream->downSampleBuffer, minPeriod/skip,
maxPeriod/skip, &minDiff, &maxDiff);
if(skip != 1) {
period *= skip;
minPeriod = period - (skip << 2);
maxPeriod = period + (skip << 2);
if(minPeriod < stream->minPeriod) {
minPeriod = stream->minPeriod;
}
if(maxPeriod > stream->maxPeriod) {
maxPeriod = stream->maxPeriod;
}
if(stream->numChannels == 1) {
period = findPitchPeriodInRange(samples, minPeriod, maxPeriod,
&minDiff, &maxDiff);
} else {
downSampleInput(stream, samples, 1);
period = findPitchPeriodInRange(stream->downSampleBuffer, minPeriod,
maxPeriod, &minDiff, &maxDiff);
}
}
}
if(prevPeriodBetter(stream, period, minDiff, maxDiff)) {
retPeriod = stream->prevPeriod;
} else {
retPeriod = period;
}
stream->prevMinDiff = minDiff;
stream->prevMaxDiff = maxDiff;
stream->prevPeriod = period;
return retPeriod;
}

/* Overlap two sound segments, ramp the volume of one down, while ramping the
other one from zero up, and add them, storing the result at the output. */
static void overlapAdd(
int numSamples,
int numChannels,
short *out,
short *rampDown,
short *rampUp)
{
short *o, *u, *d;
int i, t;

for(i = 0; i < numChannels; i++) {
o = out + i;
u = rampUp + i;
d = rampDown + i;
for(t = 0; t < numSamples; t++) {
*o = (*d*(numSamples - t) + *u*t)/numSamples;
o += numChannels;
d += numChannels;
u += numChannels;
}
}
}

/* Overlap two sound segments, ramp the volume of one down, while ramping the
other one from zero up, and add them, storing the result at the output. */
static void overlapAddWithSeparation(
int numSamples,
int numChannels,
int separation,
short *out,
short *rampDown,
short *rampUp)
{
short *o, *u, *d;
int i, t;

for(i = 0; i < numChannels; i++) {
o = out + i;
u = rampUp + i;
d = rampDown + i;
for(t = 0; t < numSamples + separation; t++) {
if(t < separation) {
*o = *d*(numSamples - t)/numSamples;
d += numChannels;
} else if(t < numSamples) {
*o = (*d*(numSamples - t) + *u*(t - separation))/numSamples;
d += numChannels;
u += numChannels;
} else {
*o = *u*(t - separation)/numSamples;
u += numChannels;
}
o += numChannels;
}
}
}

/* Just move the new samples in the output buffer to the pitch bufer */
static int moveNewSamplesToPitchBuffer(
sonicStream stream,
int originalNumOutputSamples)
{
int numSamples = stream->numOutputSamples - originalNumOutputSamples;
int numChannels = stream->numChannels;

if(stream->numPitchSamples + numSamples > stream->pitchBufferSize) {
stream->pitchBufferSize += (stream->pitchBufferSize >> 1) + numSamples;
stream->pitchBuffer = (short *)realloc(stream->pitchBuffer,
stream->pitchBufferSize*sizeof(short)*numChannels);
if(stream->pitchBuffer == NULL) {
return 0;
}
}
memcpy(stream->pitchBuffer + stream->numPitchSamples*numChannels,
stream->outputBuffer + originalNumOutputSamples*numChannels,
numSamples*sizeof(short)*numChannels);
stream->numOutputSamples = originalNumOutputSamples;
stream->numPitchSamples += numSamples;
return 1;
}

/* Remove processed samples from the pitch buffer. */
static void removePitchSamples(
sonicStream stream,
int numSamples)
{
int numChannels = stream->numChannels;
short *source = stream->pitchBuffer + numSamples*numChannels;

if(numSamples == 0) {
return;
}
if(numSamples != stream->numPitchSamples) {
memmove(stream->pitchBuffer, source, (stream->numPitchSamples -
numSamples)*sizeof(short)*numChannels);
}
stream->numPitchSamples -= numSamples;
}

/* Change the pitch. The latency this introduces could be reduced by looking at
past samples to determine pitch, rather than future. */
static int adjustPitch(
sonicStream stream,
int originalNumOutputSamples)
{
float pitch = stream->pitch;
int numChannels = stream->numChannels;
int period, newPeriod, separation;
int position = 0;
short *out, *rampDown, *rampUp;

if(stream->numOutputSamples == originalNumOutputSamples) {
return 1;
}
if(!moveNewSamplesToPitchBuffer(stream, originalNumOutputSamples)) {
return 0;
}
while(stream->numPitchSamples - position >= stream->maxRequired) {
period = findPitchPeriod(stream, stream->pitchBuffer + position*numChannels);
newPeriod = period/pitch;
if(!enlargeOutputBufferIfNeeded(stream, newPeriod)) {
return 0;
}
out = stream->outputBuffer + stream->numOutputSamples*numChannels;
if(pitch >= 1.0f) {
rampDown = stream->pitchBuffer + position*numChannels;
rampUp = stream->pitchBuffer + (position + period - newPeriod)*numChannels;
overlapAdd(newPeriod, numChannels, out, rampDown, rampUp);
} else {
rampDown = stream->pitchBuffer + position*numChannels;
rampUp = stream->pitchBuffer + position*numChannels;
separation = newPeriod - period;
overlapAddWithSeparation(period, numChannels, separation, out, rampDown, rampUp);
}
stream->numOutputSamples += newPeriod;
position += period;
}
removePitchSamples(stream, position);
return 1;
}

/* Skip over a pitch period, and copy period/speed samples to the output */
static int skipPitchPeriod(
sonicStream stream,
short *samples,
float speed,
int period)
{
long newSamples;
int numChannels = stream->numChannels;

if(speed >= 2.0f) {
newSamples = period/(speed - 1.0f);
} else if(speed > 1.0f) {
newSamples = period;
stream->remainingInputToCopy = period*(2.0f - speed)/(speed - 1.0f);
}
if(!enlargeOutputBufferIfNeeded(stream, newSamples)) {
return 0;
}
overlapAdd(newSamples, numChannels, stream->outputBuffer +
stream->numOutputSamples*numChannels, samples, samples + period*numChannels);
stream->numOutputSamples += newSamples;
return newSamples;
}

/* Insert a pitch period, and determine how much input to copy directly. */
static int insertPitchPeriod(
sonicStream stream,
short *samples,
float speed,
int period)
{
long newSamples;
short *out;
int numChannels = stream->numChannels;

if(speed < 0.5f) {
newSamples = period*speed/(1.0f - speed);
} else {
newSamples = period;
stream->remainingInputToCopy = period*(2.0f*speed - 1.0f)/(1.0f - speed);
}
if(!enlargeOutputBufferIfNeeded(stream, period + newSamples)) {
return 0;
}
out = stream->outputBuffer + stream->numOutputSamples*numChannels;
memcpy(out, samples, period*sizeof(short)*numChannels);
out = stream->outputBuffer + (stream->numOutputSamples + period)*numChannels;
overlapAdd(newSamples, numChannels, out, samples + period*numChannels, samples);
stream->numOutputSamples += period + newSamples;
return newSamples;
}

/* Resample as many pitch periods as we have buffered on the input. Return 0 if
we fail to resize an input or output buffer. Also scale the output by the volume. */
static int changeSpeed(
sonicStream stream,
float speed)
{
short *samples;
int numSamples = stream->numInputSamples;
int position = 0, period, newSamples;
int maxRequired = stream->maxRequired;

if(stream->numInputSamples < maxRequired) {
return 1;
}
do {
if(stream->remainingInputToCopy > 0) {
newSamples = copyInputToOutput(stream, position);
position += newSamples;
} else {
samples = stream->inputBuffer + position*stream->numChannels;
period = findPitchPeriod(stream, samples);
if(speed > 1.0) {
newSamples = skipPitchPeriod(stream, samples, speed, period);
position += period + newSamples;
} else {
newSamples = insertPitchPeriod(stream, samples, speed, period);
position += newSamples;
}
}
if(newSamples == 0) {
return 0; /* Failed to resize output buffer */
}
} while(position + maxRequired <= numSamples);
removeInputSamples(stream, position);
return 1;
}

/* Resample as many pitch periods as we have buffered on the input. Return 0 if
we fail to resize an input or output buffer. Also scale the output by the volume. */
static int processStreamInput(
sonicStream stream)
{
int originalNumOutputSamples = stream->numOutputSamples;
float speed = stream->speed/stream->pitch;

if(speed > 1.00001 || speed < 0.99999) {
changeSpeed(stream, speed);
} else {
if(!copyToOutput(stream, stream->inputBuffer, stream->numInputSamples)) {
return 0;
}
stream->numInputSamples = 0;
}
if(stream->pitch != 1.0f) {
if(!adjustPitch(stream, originalNumOutputSamples)) {
return 0;
}
}
if(stream->volume != 1.0f) {
/* Adjust output volume. */
scaleSamples(stream->outputBuffer + originalNumOutputSamples*stream->numChannels,
(stream->numOutputSamples - originalNumOutputSamples)*stream->numChannels,
stream->volume);
}
return 1;
}

/* Write floating point data to the input buffer and process it. */
int sonicWriteFloatToStream(
sonicStream stream,
float *samples,
int numSamples)
{
if(!addFloatSamplesToInputBuffer(stream, samples, numSamples)) {
return 0;
}
return processStreamInput(stream);
}

/* Simple wrapper around sonicWriteFloatToStream that does the short to float
conversion for you. */
int sonicWriteShortToStream(
sonicStream stream,
short *samples,
int numSamples)
{
if(!addShortSamplesToInputBuffer(stream, samples, numSamples)) {
return 0;
}
return processStreamInput(stream);
}

/* Simple wrapper around sonicWriteFloatToStream that does the unsigned char to float
conversion for you. */
int sonicWriteUnsignedCharToStream(
sonicStream stream,
unsigned char *samples,
int numSamples)
{
if(!addUnsignedCharSamplesToInputBuffer(stream, samples, numSamples)) {
return 0;
}
return processStreamInput(stream);
}

/* This is a non-stream oriented interface to just change the speed of a sound sample */
int sonicChangeFloatSpeed(
float *samples,
int numSamples,
float speed,
float pitch,
float volume,
int sampleRate,
int numChannels)
{
sonicStream stream = sonicCreateStream(sampleRate, numChannels);

sonicSetSpeed(stream, speed);
sonicSetPitch(stream, pitch);
sonicSetVolume(stream, volume);
sonicWriteFloatToStream(stream, samples, numSamples);
sonicFlushStream(stream);
numSamples = sonicSamplesAvailable(stream);
sonicReadFloatFromStream(stream, samples, numSamples);
sonicDestroyStream(stream);
return numSamples;
}

/* This is a non-stream oriented interface to just change the speed of a sound sample */
int sonicChangeShortSpeed(
short *samples,
int numSamples,
float speed,
float pitch,
float volume,
int sampleRate,
int numChannels)
{
sonicStream stream = sonicCreateStream(sampleRate, numChannels);

sonicSetSpeed(stream, speed);
sonicSetPitch(stream, pitch);
sonicSetVolume(stream, volume);
sonicWriteShortToStream(stream, samples, numSamples);
sonicFlushStream(stream);
numSamples = sonicSamplesAvailable(stream);
sonicReadShortFromStream(stream, samples, numSamples);
sonicDestroyStream(stream);
return numSamples;
}

+ 138
- 0
src/sonic.h View File

@@ -0,0 +1,138 @@
/* Sonic library
Copyright 2010
Bill Cox
This file is part of the Sonic Library.

The Sonic Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */

/*
The Sonic Library implements Pitch Based Resampling, which is a new algorithm
invented by Bill Cox for the specific purpose of speeding up speech by high
factors at high quality. It generates smooth speech at speed up factors as high
as 6X, possibly more. It is also capable of slowing down speech, and generates
high quality results regardless of the speed up or slow down factor. For
speeding up speech by 2X or more, the following equation is used:

newSamples = period/(speed - 1.0)
scale = 1.0/newSamples;

where period is the current pitch period, determined using AMDF or any other
pitch estimator, and speed is the speedup factor. If the current position in
the input stream is pointed to by "samples", and the current output stream
position is pointed to by "out", then newSamples number of samples can be
generated with:

out[t] = (samples[t]*(newSamples - t) + samples[t + period]*t)/newSamples;

where t = 0 to newSamples - 1.

For speed factors < 2X, an algorithm similar to PICOLA is used. The above
algorithm is first used to double the speed of one pitch period. Then, enough
input is directly copied from the input to the output to achieve the desired
speed up facter, where 1.0 < speed < 2.0. The amount of data copied is derived:

speed = (2*period + length)/(period + length)
speed*length + speed*period = 2*period + length
length(speed - 1) = 2*period - speed*period
length = period*(2 - speed)/(speed - 1)

For slowing down speech where 0.5 < speed < 1.0, a pitch period is inserted into
the output twice, and length of input is copied from the input to the output
until the output desired speed is reached. The length of data copied is:

length = period*(speed - 0.5)/(1 - speed)

For slow down factors between 0.5 and 0.5, no data is copied, and an algorithm
similar to high speed factors is used.
*/

#ifdef __cplusplus
extern "C" {
#endif

/* This specifies the range of voice pitches we try to match.
Note that if we go lower than 65, we could overflow in findPitchInRange */
#define SONIC_MIN_PITCH 65
#define SONIC_MAX_PITCH 400

/* These are used to down-sample some inputs to improve speed */
#define SONIC_AMDF_FREQ 4000

struct sonicStreamStruct;
typedef struct sonicStreamStruct *sonicStream;

/* For all of the following functions, numChannels is multiplied by numSamples
to determine the actual number of values read or returned. */

/* Create a sonic stream. Return NULL only if we are out of memory and cannot
allocate the stream. Set numChannels to 1 for mono, and 2 for stereo. */
sonicStream sonicCreateStream(int sampleRate, int numChannels);
/* Destroy the sonic stream. */
void sonicDestroyStream(sonicStream stream);
/* Use this to write floating point data to be speed up or down into the stream.
Values must be between -1 and 1. Return 0 if memory realloc failed, otherwise 1 */
int sonicWriteFloatToStream(sonicStream stream, float *samples, int numSamples);
/* Use this to write 16-bit data to be speed up or down into the stream.
Return 0 if memory realloc failed, otherwise 1 */
int sonicWriteShortToStream(sonicStream stream, short *samples, int numSamples);
/* Use this to write 8-bit unsigned data to be speed up or down into the stream.
Return 0 if memory realloc failed, otherwise 1 */
int sonicWriteUnsignedCharToStream(sonicStream stream, unsigned char *samples, int numSamples);
/* Use this to read floating point data out of the stream. Sometimes no data
will be available, and zero is returned, which is not an error condition. */
int sonicReadFloatFromStream(sonicStream stream, float *samples, int maxSamples);
/* Use this to read 16-bit data out of the stream. Sometimes no data will
be available, and zero is returned, which is not an error condition. */
int sonicReadShortFromStream(sonicStream stream, short *samples, int maxSamples);
/* Use this to read 8-bit unsigned data out of the stream. Sometimes no data will
be available, and zero is returned, which is not an error condition. */
int sonicReadUnsignedCharFromStream(sonicStream stream, unsigned char *samples, int maxSamples);
/* Force the sonic stream to generate output using whatever data it currently
has. No extra delay will be added to the output, but flushing in the middle of
words could introduce distortion. */
int sonicFlushStream(sonicStream stream);
/* Return the number of samples in the output buffer */
int sonicSamplesAvailable(sonicStream stream);
/* Get the speed of the stream. */
float sonicGetSpeed(sonicStream stream);
/* Set the speed of the stream. */
void sonicSetSpeed(sonicStream stream, float speed);
/* Get the pitch of the stream. */
float sonicGetPitch(sonicStream stream);
/* Set the pitch of the stream. */
void sonicSetPitch(sonicStream stream, float pitch);
/* Get the scaling factor of the stream. */
float sonicGetVolume(sonicStream stream);
/* Set the scaling factor of the stream. */
void sonicSetVolume(sonicStream stream, float volume);
/* Get the sample rate of the stream. */
int sonicGetSampleRate(sonicStream stream);
/* Get the number of channels. */
int sonicGetNumChannels(sonicStream stream);
/* This is a non-stream oriented interface to just change the speed of a sound
sample. It works in-place on the sample array, so there must be at least
speed*numSamples available space in the array. Returns the new number of samples. */
int sonicChangeFloatSpeed(float *samples, int numSamples, float speed, float pitch,
float volume, int sampleRate, int numChannels);
/* This is a non-stream oriented interface to just change the speed of a sound
sample. It works in-place on the sample array, so there must be at least
speed*numSamples available space in the array. Returns the new number of samples. */
int sonicChangeShortSpeed(short *samples, int numSamples, float speed, float pitch,
float volume, int sampleRate, int numChannels);

#ifdef __cplusplus
}
#endif

+ 1
- 1
src/speak.cpp View File

@@ -289,7 +289,7 @@ void MarkerEvent(int type, unsigned int char_position, int value, unsigned char
static int WavegenFile(void)
{//=========================
int finished;
unsigned char wav_outbuf[512];
unsigned char wav_outbuf[1024];
char fname[210];

out_ptr = out_start = wav_outbuf;

+ 2
- 2
src/speak_lib.cpp View File

@@ -528,8 +528,8 @@ static espeak_ERROR Synthesize(unsigned int unique_identifier, const void *text,
}
}
}
}
return(EE_OK);
}
return(EE_OK);
} // end of Synthesize

#ifdef DEBUG_ENABLED

+ 15
- 2
src/synthdata.cpp View File

@@ -35,8 +35,8 @@
#include "translate.h"
#include "wave.h"

const char *version_string = "1.44.04 14.Sep.10";
const int version_phdata = 0x014404;
const char *version_string = "1.44.18 03.Dec.10";
const int version_phdata = 0x014415;

int option_device_number = -1;
FILE *f_logespeak = NULL;
@@ -593,6 +593,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
int which;
unsigned int data;
int instn2;
int count;
PHONEME_TAB *ph;
PHONEME_LIST *plist_this;
static int ph_position[8] = {0, 1, 2, 3, 2, 0, 1, 3}; // prevPh, thisPh, nextPh, next2Ph, nextPhW, prevPhW, nextVowel, next2PhW
@@ -737,6 +738,18 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist,
case 12: // isVoiced
return((ph->type == phVOWEL) || (ph->type == phLIQUID) || (ph->phflags & phVOICED));
}

case 13: // isFirstVowel
count = 0;
for(;;)
{
if(plist->ph->type == phVOWEL)
count++;
if(plist->sourceix != 0)
break;
plist--;
}
return(count==1);
break;

}

+ 2
- 0
src/synthesize.h View File

@@ -326,6 +326,7 @@ typedef struct {
#define i_isNotVowel 0x8a
#define i_isFinalVowel 0x8b
#define i_isVoiced 0x8c
#define i_isFirstVowel 0x8d

// place of articulation
#define i_isVel 0x28
@@ -535,6 +536,7 @@ extern t_espeak_callback* synth_callback;
extern int option_log_frames;
extern const char *version_string;
extern const int version_phdata;
extern double sonicSpeed;

#define N_SOUNDICON_TAB 80 // total entries in soundicon_tab
#define N_SOUNDICON_SLOTS 4 // number of slots reserved for dynamic loading of audio files

+ 22
- 6
src/tr_languages.cpp View File

@@ -328,6 +328,9 @@ Translator *SelectTranslator(const char *name)
int name2 = 0;
Translator *tr;

static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 190, 240};
static const unsigned char stress_amps_fr[8] = {18,16, 18,18, 18,18, 18,18 };

static const unsigned char stress_amps_sk[8] = {17,17, 20,20, 20,22, 22,21 };
static const short stress_lengths_sk[8] = {190,190, 210,210, 0,0, 210,210};

@@ -355,6 +358,17 @@ Translator *SelectTranslator(const char *name)
}
break;

case L('a','m'): // Amharic, Ethiopia
{
SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
}
break;


case L('a','r'): // Arabic
tr->letter_bits_offset = OFFSET_ARABIC;
tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words
@@ -496,7 +510,7 @@ Translator *SelectTranslator(const char *name)
tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels

tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA;
tr->langopts.numbers2 = 0x2; // variant form of numbers before thousands
tr->langopts.numbers2 = 0x2 | NUM2_MULTIPLE_ORDINAL; // variant form of numbers before thousands

if(name2 == L_grc)
{
@@ -550,6 +564,7 @@ Translator *SelectTranslator(const char *name)
tr->langopts.param[LOPT_SONORANT_MIN] = 120; // limit the shortening of sonorants before short vowels

tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_AND_UNITS | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_ROMAN | NUM_ROMAN_AFTER;
tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL;

if(name2 == L('c','a'))
{
@@ -611,16 +626,12 @@ Translator *SelectTranslator(const char *name)

case L('f','r'): // french
{
static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 190, 240};
static const unsigned char stress_amps_fr[8] = {18,16, 20,20, 20,22, 18,18 };

SetupTranslator(tr,stress_lengths_fr,stress_amps_fr);
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables
tr->langopts.length_mods0 = tr->langopts.length_mods; // don't lengthen vowels in the last syllable
tr->langopts.accents = 2; // Say "Capital" after the letter.
tr->langopts.vowel_pause = 0;

tr->langopts.numbers = NUM_SINGLE_STRESS | NUM_DECIMAL_COMMA | NUM_ALLOW_SPACE | NUM_OMIT_1_HUNDRED | NUM_NOPAUSE | NUM_ROMAN | NUM_ROMAN_CAPITALS | NUM_ROMAN_AFTER | NUM_VIGESIMAL | NUM_DFRACTION_4;
SetLetterVowel(tr,'y');
@@ -685,7 +696,6 @@ Translator *SelectTranslator(const char *name)


case L('h','t'): // Haitian Creole
// static const short stress_lengths_fr[8] = {190, 170, 190, 200, 0, 0, 235, 240};
// memcpy(tr->stress_lengths,stress_lengths_fr,sizeof(tr->stress_lengths));
tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable
tr->langopts.stress_flags = 0x0024; // don't use secondary stress
@@ -905,6 +915,7 @@ SetLengthMods(tr,3); // all equal

tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_SWAP_TENS | NUM_OMIT_1_HUNDRED | NUM_ALLOW_SPACE | NUM_1900 | NUM_ORDINAL_DOT;
tr->langopts.ordinal_indicator = "e";
tr->langopts.stress_flags = S_FIRST_PRIMARY;
memcpy(tr->stress_lengths,stress_lengths_nl,sizeof(tr->stress_lengths));
}
break;
@@ -1201,6 +1212,11 @@ SetLengthMods(tr,3); // all equal
}
break;

case L('w','o'):
tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.numbers = NUM_AND_UNITS | NUM_HUNDRED_AND | NUM_OMIT_1_HUNDRED | NUM_OMIT_1_THOUSAND | NUM_SINGLE_STRESS;
break;

case L('z','h'):
case L_zhy:
{

+ 2
- 2
src/translate.cpp View File

@@ -2779,8 +2779,8 @@ if((c == '/') && (tr->langopts.testing & 2) && IsDigit09(next_in) && IsAlpha(pre
// dot after a word, with space following, probably an abbreviation
words[word_count-1].flags |= FLAG_HAS_DOT;

if(IsSpace(next_in))
c = ' '; // remove the dot if it's followed by a space, so that it's not pronounced
if(IsSpace(next_in) || (next_in == '-'))
c = ' '; // remove the dot if it's followed by a space or hyphen, so that it's not pronounced
}
}
else

+ 7
- 2
src/translate.h View File

@@ -145,10 +145,11 @@
#define RULE_CONDITION 5 // followed by condition number (byte)
#define RULE_GROUP_START 6
#define RULE_GROUP_END 7
#define RULE_LINENUM 8 // next 2 bytes give a line number, for debugging purposes
#define RULE_PRE_ATSTART 8 // as RULE_PRE but also match with 'start of word'
#define RULE_LINENUM 9 // next 2 bytes give a line number, for debugging purposes

#define RULE_SPACE 32 // ascii space
#define RULE_SYLLABLE 9 // @
#define RULE_SYLLABLE 21 // @
#define RULE_STRESSED 10 // &
#define RULE_DOUBLE 11 // %
#define RULE_INC_SCORE 12 // +
@@ -342,6 +343,7 @@ typedef struct {
#define S_FINAL_NO_2 0x10
#define S_NO_AUTO_2 0x20
#define S_2_TO_HEAVY 0x40
#define S_FIRST_PRIMARY 0x80
#define S_2_SYL_2 0x1000
#define S_INITIAL_2 0x2000
#define S_NO_AUTO_DIM 0x10000
@@ -353,6 +355,7 @@ typedef struct {
// bit4=don't allow secondary stress on last syllable
// bit5-don't use automatic secondary stress
// bit6=light syllable followed by heavy, move secondary stress to the heavy syllable. LANG=Finnish
// bit7=if more than one primary stress, make the subsequent primaries to secondary stress
// bit8=stress last syllable if it doesn't end in a vowel
// bit9=stress last syllable if it doesn't end in vowel or "s" or "n" LANG=Spanish
// bit12= In a 2-syllable word, if one has primary stress then give the other secondary stress
@@ -427,11 +430,13 @@ typedef struct {
// bit27= Roman numbers are ordinal numbers
int numbers;

#define NUM2_MULTIPLE_ORDINAL 0x1000
// bits 1-4 use variant form of numbers before thousands,millions,etc.
// bit6=(LANG=pl) two forms of plural, M or MA
// bit7=(LANG-ru) use MB for 1 thousand, million, etc
// bit8=(LANG=cs,sk) two forms of plural, M or MA
// bit9=(LANG=rw) say "thousand" and "million" before its number, not after
// bit12=(LANG=el,es) use ordinal form of hundreds and tens as well as units
int numbers2;

#define BREAK_THOUSANDS 0x49249248

+ 6
- 2
src/voices.cpp View File

@@ -152,7 +152,7 @@ static MNEM_TAB keyword_tab[] = {
{"mbrola", V_MBROLA},
{"consonants", V_CONSONANTS},
{"klatt", V_KLATT},
{"fast_test", V_FAST},
{"fast_test2", V_FAST},
{"speed", V_SPEED},

// these just set a value in langopts.param[]
@@ -410,7 +410,10 @@ void VoiceReset(int tone_only)
voice->consonant_ampv = 100;
voice->samplerate = 22050;
memset(voice->klattv,0,sizeof(voice->klattv));
memset(speed.fast_settings,0,sizeof(speed.fast_settings));

speed.fast_settings[0] = 350;
speed.fast_settings[1] = 800;
speed.fast_settings[2] = 175;

#ifdef PLATFORM_RISCOS
voice->roughness = 1;
@@ -509,6 +512,7 @@ static void PhonemeReplacement(int type, char *p)
static int Read8Numbers(char *data_in,int *data)
{//=============================================
// Read 8 integer numbers
memset(data, 0, 8+sizeof(int));
return(sscanf(data_in,"%d %d %d %d %d %d %d %d",
&data[0],&data[1],&data[2],&data[3],&data[4],&data[5],&data[6],&data[7]));
}

+ 119
- 20
src/wavegen.cpp View File

@@ -28,11 +28,13 @@
#include <math.h>



#include "speak_lib.h"
#include "speech.h"
#include "phoneme.h"
#include "synthesize.h"
#include "voice.h"
#include "sonic.h"

//#undef INCLUDE_KLATT

@@ -134,7 +136,7 @@ int wcmdq_tail=0;

// pitch,speed,
int embedded_default[N_EMBEDDED_VALUES] = {0, 50,175,100,50, 0, 0, 0,175,0,0,0,0,0,0};
static int embedded_max[N_EMBEDDED_VALUES] = {0,0x7fff,600,300,99,99,99, 0,600,0,0,0,0,4,0};
static int embedded_max[N_EMBEDDED_VALUES] = {0,0x7fff,750,300,99,99,99, 0,750,0,0,0,0,4,0};

#define N_CALLBACK_IX N_WAV_BUF-2 // adjust this delay to match display with the currently spoken word
int current_source_index=0;
@@ -148,7 +150,8 @@ static PortAudioStream *pa_stream=NULL;
static PaStream *pa_stream=NULL;
#endif


static sonicStream sonicSpeedupStream = NULL;
double sonicSpeed = 1.0;

// 1st index=roughness
// 2nd index=modulation_type
@@ -256,8 +259,6 @@ unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1] = {
217,220,223,226,229,232,236,239,
242,246,249,252, 254,255 };

int WavegenFill(int fill_zeros);


#ifdef LOG_FRAMES
static void LogMarker(int type, int value)
@@ -285,6 +286,11 @@ void WcmdqStop()
{//=============
wcmdq_head = 0;
wcmdq_tail = 0;
if(sonicSpeedupStream != NULL)
{
sonicDestroyStream(sonicSpeedupStream);
sonicSpeedupStream = NULL;
}
#ifdef USE_PORTAUDIO
Pa_AbortStream(pa_stream);
#endif
@@ -413,6 +419,10 @@ static int userdata[4];
static PaError pa_init_err=0;
static int out_channels=1;

unsigned char *outbuffer = NULL;
int outbuffer_size = 0;


#if USE_PORTAUDIO == 18
static int WaveCallback(void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, PaTimestamp outTime, void *userData )
@@ -425,9 +435,30 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,
int ix;
int result;
unsigned char *p;
unsigned char *out_buf;
unsigned char *out_end2;
int pa_size;

pa_size = framesPerBuffer*2;

out_ptr = out_start = (unsigned char *)outputBuffer;
out_end = out_ptr + framesPerBuffer*2;
// make a buffer 3x size of the portaudio output
ix = pa_size*3;
if(ix > outbuffer_size)
{
outbuffer = (unsigned char *)realloc(outbuffer, ix);
if(outbuffer == NULL)
{
fprintf(stderr, "espeak: out of memory\n");
}
outbuffer_size = ix;
out_ptr = NULL;
}
if(out_ptr == NULL)
{
out_ptr = out_start = outbuffer;
out_end = out_start + outbuffer_size;
}
out_end2 = &outbuffer[pa_size]; // top of data needed for the portaudio buffer

#ifdef LIBRARY
event_list_ix = 0;
@@ -435,6 +466,24 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,

result = WavegenFill(1);

// copy from the outbut buffer into the portaudio buffer
if(result && (out_ptr > out_end2))
{
result = 0; // don't end yet, there is more data in the buffer than can fit in portaudio
}

while(out_ptr < out_end2)
*out_ptr++ = 0; // fill with zeros up to the size of the portaudio buffer

memcpy(outputBuffer, outbuffer, pa_size);

// move the remaining contents of the start of the output buffer
for(p = out_end2; p < out_end; p++)
{
p[-pa_size] = p[0];
}
out_ptr -= pa_size;

#ifdef LIBRARY
count_samples += framesPerBuffer;
if(synth_callback)
@@ -455,14 +504,15 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,
{
// swap the order of bytes in each sound sample in the portaudio buffer
int c;
out_ptr = (unsigned char *)outputBuffer;
out_end = out_ptr + framesPerBuffer*2;
while(out_ptr < out_end)
unsigned char *buf_end;
out_buf = (unsigned char *)outputBuffer;
buf_end = out_buf + framesPerBuffer*2;
while(out_buf < buf_end)
{
c = out_ptr[0];
out_ptr[0] = out_ptr[1];
out_ptr[1] = c;
out_ptr += 2;
c = out_buf[0];
out_buf[0] = out_buf[1];
out_buf[1] = c;
out_buf += 2;
}
}
#endif
@@ -471,12 +521,12 @@ static int WaveCallback(const void *inputBuffer, void *outputBuffer,
{
// sound output can only do stereo, not mono. Duplicate each sound sample to
// produce 2 channels.
out_ptr = (unsigned char *)outputBuffer;
out_buf = (unsigned char *)outputBuffer;
for(ix=framesPerBuffer-1; ix>=0; ix--)
{
p = &out_ptr[ix*4];
p[3] = p[1] = out_ptr[ix*2 + 1];
p[2] = p[0] = out_ptr[ix*2];
p = &out_buf[ix*4];
p[3] = p[1] = out_buf[ix*2 + 1];
p[2] = p[0] = out_buf[ix*2];
}
}

@@ -1791,8 +1841,7 @@ void Write4Bytes(FILE *f, int value)




int WavegenFill(int fill_zeros)
int WavegenFill2(int fill_zeros)
{//============================
// Pick up next wavegen commands from the queue
// return: 0 output buffer has been filled
@@ -1930,6 +1979,56 @@ int WavegenFill(int fill_zeros)
}

return(0);
} // end of WavegenFill
} // end of WavegenFill2


/* Speed up the audio samples with libsonic. */
static int SpeedUp(short *outbuf, int length_in, int length_out, int end_of_text)
{//==============================================================================
if(length_in >0)
{
if(sonicSpeedupStream == NULL)
{
sonicSpeedupStream = sonicCreateStream(22050, 1);
}
if(sonicGetSpeed(sonicSpeedupStream) != sonicSpeed)
{
sonicSetSpeed(sonicSpeedupStream, sonicSpeed);
}
sonicWriteShortToStream(sonicSpeedupStream, outbuf, length_in);
}

if(end_of_text)
{
sonicFlushStream(sonicSpeedupStream);
}
return sonicReadShortFromStream(sonicSpeedupStream, outbuf, length_out);
} // end of SpeedUp


/* Call WavegenFill2, and then speed up the output samples. */
int WavegenFill(int fill_zeros)
{//============================
int finished;
unsigned char *p_start;
int length;
int max_length;

p_start = out_ptr;

// fill_zeros is ignored. It is now done in the portaudio callback
finished = WavegenFill2(0);

if(sonicSpeed > 1.0)
{
max_length = (out_end - p_start);
length = 2*SpeedUp((short *)p_start, (out_ptr-p_start)/2, max_length/2, finished);
out_ptr = p_start + length;

if(length >= max_length)
finished = 0; // there may be more data to flush
}
return finished;
} // end of WavegenFill


Loading…
Cancel
Save