@@ -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 |
@@ -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 |
@@ -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@ |
@@ -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_ |
@@ -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,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 | |||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 | |||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 _ | |||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 | |||
@@ -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 |
@@ -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); |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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" |
@@ -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 |
@@ -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 | |||
@@ -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" |
@@ -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" |
@@ -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 |
@@ -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; |
@@ -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) |
@@ -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; |
@@ -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]; | |||
} | |||
@@ -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); |
@@ -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: |
@@ -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: |
@@ -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, |
@@ -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; |
@@ -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; |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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; |
@@ -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 |
@@ -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; | |||
} |
@@ -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 |
@@ -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: | |||
{ |
@@ -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 |
@@ -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 |
@@ -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])); | |||
} |
@@ -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 | |||