Browse Source

Fix samplerate for ufric/xx, ufric/sx_sv, x/g2.

Don't read all the voice files on start, wait until they are needed.
Added 'W' code to _rules files to mean: further letters follow while spelling a word.
Lang=fr replace [r] with [R],  shorten [R] slightly


git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@4 d46cf337-b52f-0410-862d-fd96e6ae7743
master
jonsd 18 years ago
parent
commit
9099061844

+ 3
- 0
dictsource/en_list View File

monsieur m@sj3: monsieur m@sj3:
?5 monsieur m@sjVR ?5 monsieur m@sjVR
mony mVnI2 // monies, monied mony mVnI2 // monies, monied
moped moUpEd
moraine m@reIn moraine m@reIn
morale m@ral morale m@ral
morass m0r'as morass m0r'as
morose m@r'oUs
mosquito m0sk'i:toU mosquito m0sk'i:toU
motel moUt'El motel moUt'El
motif moUt'i:f motif moUt'i:f
Altrincham O:ltrIN@m Altrincham O:ltrIN@m
Anglesey aNg@LsI2 Anglesey aNg@LsI2
Argyle A@g'aIl Argyle A@g'aIl
Argyll A@g;aIl
Bacup beIk@p Bacup beIk@p
Berwick bErIk Berwick bErIk
Betws bEtUs Betws bEtUs

+ 6
- 0
dictsource/en_rules View File

ch (ord k ch (ord k
an) ch (or k an) ch (or k
o) ch (_ k o) ch (_ k
oo) ch (_ tS
_ta) ch k _ta) ch k
ta) ch tS ta) ch tS
sta) ch S sta) ch S
acB) e (_ I2 acB) e (_ I2
e (Cic_ E e (Cic_ E
e (Cical 'E e (Cical 'E
e (Cium i:
t) ech (_ Ek t) ech (_ Ek
m) e (chanic I m) e (chanic I
@@) eble (_ @b@L @@) eble (_ @b@L
eir e@ eir e@
w) eir i@ w) eir i@
l) ei (s E l) ei (s E
th) ei (sC i:I
_s) eis (m aIz _s) eis (m aIz
f) ei (t_ I f) ei (t_ I
ei (th aI ei (th aI
_) mobile moUbaIl _) mobile moUbaIl
im) mobile moUbaIl im) mobile moUbaIl
mobile m@bi:l mobile m@bi:l
mono (ga m@n'0
mo (noto m@ mo (noto m@
_) mono m0noU _) mono m0noU
mon (opol m@n mon (opol m@n
_id) ol (a 0l _id) ol (a 0l
petr) ol (_ @L petr) ol (_ @L
s) ol (em 0l s) ol (em 0l
s) ol (ic @l
s) ol (il @l
t) ol (er 0l t) ol (er 0l
m) ol (ec @l m) ol (ec @l
m) ol (ecule 0l m) ol (ecule 0l

+ 133
- 136
dictsource/fr_list View File

// "letter" name, then include the letter name here, with the letter // "letter" name, then include the letter name here, with the letter
// prefixed by a _ character. // prefixed by a _ character.


_à a:aksA~grav
â a:aksA~sirkO~flEks
ä a:trema
_à a:aksA~gRav
â a:aksA~siRkO~flEks
ä a:tRema
ç sesedij ç sesedij
ë @:trema
ë @:tRema
é @:aksA~Egy é @:aksA~Egy
è @:aksA~grav
ê @:aksA~sirkO~flEks
ï i:trema
ë @:trema
è @:aksA~gRav
ê @:aksA~siRkO~flEks
ï i:tRema
ë @:tRema
ñ Entilde ñ Entilde
ô o:aksA~sirkO~flEks
ö o:trema
ù u:aksA~grav
û u:aksA~sirkO~flEks
ü u:trema
_y i:gr'Ek
ô o:aksA~siRkO~flEks
ö o:tRema
ù u:aksA~gRav
û u:aksA~siRkO~flEks
ü u:tRema
_y i:gR'Ek






! Eksklamassj'O~ ! Eksklamassj'O~
_" gijm'E _" gijm'E
_# dj'Ez _# dj'Ez
_$ dOl'ar
_% purs'A~
_$ dOl'aR
_% puRs'A~
_& e _& e
_' apOstr'Of
_( 'uvr@-parA~t'Ez
_) f'Erm parA~t'Ez
_* astErisk:
_' apOstR'Of
_( 'uvR@-paRA~t'Ez
_) f'ERm paRA~t'Ez
_* astERisk:
_+ plys _+ plys
_, virg'yl
_- tir'E
_, viRg'yl
_- tiR'E
_. pw'E~ _. pw'E~
_/ sl'aS _/ sl'aS
_: d'Ypw'E~ _: d'Ypw'E~
_; pw'E~virg'yl
_< E~ferj'Wr
_; pw'E~viRg'yl
_< E~feRj'WR
_= eg'al _= eg'al
_> syperj'Wr
_> sypeRj'WR
_? kEstj'O~ _? kEstj'O~
_@ at _@ at
_[ uvr@-_kroS'E
_[ uvR@-_kRoS'E
_\ b'aksl'aS _\ b'aksl'aS
_] f'Erm_kroS'E
_^ sirkOnfl'Eks
_] f'ERm_kRoS'E
_^ siRkOnfl'Eks
__ sulin^'e __ sulin^'e
_` aks'A~_gr'av
_{ uvr_akOl'ad
_| b'ar
_} f'Erm_akOl'ad
_` aks'A~_gR'av
_{ uvR_akOl'ad
_| b'aR
_} f'ERm_akOl'ad
_~ tild'e _~ tild'e
_¢ sEnt _¢ sEnt
_¥ i;'En _¥ i;'En
_£ l'ivr
_° d@gr'e
_£ l'ivR
_° d@gR'e
_± pl'yz_'u_mw'E~ _± pl'yz_'u_mw'E~
_× myltip@-lj'e_p'ar
_÷ diviz'e_p'ar
_¼ W~_k'ar
_× myltip@-lj'e_p'aR
_÷ diviz'e_p'aR
_¼ W~_k'aR
_½ W~_d@m'i _½ W~_d@m'i
_¾ trw'a k'ar
_© _^_k'0pIr,aIt_^_
r@Zistr'@d_m'ark
_¾ tRw'a k'aR
_© _^_k'0pIR,aIt_^_
R@ZistR'@d_m'aRk






// numeric // numeric


_0 zer'o
_0 zeR'o
_1 W~ _1 W~
_2 d'Y _2 d'Y
_3 trw'a
_4 k'atr
_3 tRw'a
_4 k'atR
_5 s'E~c _5 s'E~c
_6 s'is _6 s'is
six siz2 six siz2
dix diz2 dix diz2
_11 O~z _11 O~z
_12 d'uz _12 d'uz
_13 tr'Ez
_14 kat'Orz
_13 tR'Ez
_14 kat'ORz
_15 k'E~z _15 k'E~z
_16 s'Ez _16 s'Ez
_17 d'is:'Et _17 d'is:'Et
_20 v'E~ _20 v'E~
_21 v'E~te:E~ _21 v'E~te:E~
_22 v'E~td'Y _22 v'E~td'Y
_23 v'E~t:trw'a
_24 v'E~tk'atr
_23 v'E~t:tRw'a
_24 v'E~tk'atR
_25 v'E~ts'E~c _25 v'E~ts'E~c
_26 v'E~ts'is _26 v'E~ts'is
_27 v'E~ts'Et _27 v'E~ts'Et
_28 v'E~tw^it _28 v'E~tw^it
_29 v'E~tn'@f _29 v'E~tn'@f
_3X tr'A~t
_31 tr'A~te:E~
_4X kar'A~t
_41 kar'A~te:E~
_3X tR'A~t
_31 tR'A~te:E~
_4X kaR'A~t
_41 kaR'A~te:E~
_5X sE~k'A~t _5X sE~k'A~t
_51 sE~k'A~te:E~ _51 sE~k'A~te:E~
_6X swas'A~t _6X swas'A~t
_7X swas'A~t:d'is _7X swas'A~t:d'is
_71 swas'A~te:O~z _71 swas'A~te:O~z
_72 swas'A~t:d'uz _72 swas'A~t:d'uz
_73 swas'A~t:tr'Ez
_74 swas'A~t:kat'Orz
_73 swas'A~t:tR'Ez
_74 swas'A~t:kat'ORz
_75 swas'A~t:k'E~z _75 swas'A~t:k'E~z
_76 swas'A~t:s'Ez _76 swas'A~t:s'Ez
_77 swas'A~t:d'is:'Et _77 swas'A~t:d'is:'Et
_78 swas'A~t:d'is:'w^it _78 swas'A~t:d'is:'w^it
_79 swas'A~t:d'is:n'@f _79 swas'A~t:d'is:n'@f
_8X k'atr@v'E~
_80 k'atr@v'E~z2
_9X k'atr@v'E~d'is
_91 k'atr@v'E~:O~z
_92 k'atr@v'E~:d'uz
_93 k'atr@v'E~:tr'Ez
_94 k'atr@v'E~:kat'Orz
_95 k'atr@v'E~:k'E~z
_96 k'atr@v'E~:s'Ez
_97 k'atr@v'E~:d'is:'Et
_98 k'atr@v'E~:d'is:'w^it
_99 k'atr@v'E~:d'is:n'@f
_8X k'atR@v'E~
_80 k'atR@v'E~z2
_9X k'atR@v'E~d'is
_91 k'atR@v'E~:O~z
_92 k'atR@v'E~:d'uz
_93 k'atR@v'E~:tR'Ez
_94 k'atR@v'E~:kat'ORz
_95 k'atR@v'E~:k'E~z
_96 k'atR@v'E~:s'Ez
_97 k'atR@v'E~:d'is:'Et
_98 k'atR@v'E~:d'is:'w^it
_99 k'atR@v'E~:d'is:n'@f
_0C s'A~ _0C s'A~
_1C0 s'A~t2 _1C0 s'A~t2
_0M1 m'il _0M1 m'il
_1M1 m'il _1M1 m'il
_0M2 milj'O~ _0M2 milj'O~
_0M3 milj'ar
_0M3 milj'aR
_0and e _0and e
_dpt pw'E~ _dpt pw'E~


ac 'a s'e ac 'a s'e
api 'a p'e 'i api 'a p'e 'i
cio s'e'i;'o cio s'e'i;'o
ctrl kO~tr'ol
dept depart@m'A~
etc etseter'a
ctrl kO~tR'ol
dept depaRt@m'A~
etc etseteR'a
hmm h@m hmm h@m
ibm 'i:b'e:'Em ibm 'i:b'e:'Em
ip 'i:p'e ip 'i:p'e
mlle mad@mwaz'El mlle mad@mwaz'El
mme mad'am mme mad'am
mr m@sj'Y mr m@sj'Y
p.s pOstkript'Om
ratp 'Er:'a:t'e:p'e
p.s pOstkRipt'Om
ratp 'ER:'a:t'e:p'e
s.t.p s'il:t'@:pl'E s.t.p s'il:t'@:pl'E
s.v.p s'il:v'u:pl'E s.v.p s'il:v'u:pl'E
st s'E~ st s'E~
ste s'E~t ste s'E~t
stp s'il:t'@:pl'E stp s'il:t'@:pl'E
svp s'il:v'u:pl'E svp s'il:v'u:pl'E
url 'y:'Er:'El
url 'y:'ER:'El
usb 'y:'Es:'be usb 'y:'Es:'be
utf y:te:Ef utf y:te:Ef
xfce iksEfse@ xfce iksEfse@
xy 'iks:igr'Ek
xy 'iks:igR'Ek


ii d'Y $abbrev // roman numerals ii d'Y $abbrev // roman numerals
iii trw'a $abbrev
iv k'atr $abbrev
iii tRw'a $abbrev
iv k'atR $abbrev




dr dOkt'Wr $dot $capital
dr dOkt'WR $dot $capital
prof $dot prof $dot






// numbers


// articles // articles
le $u $nounf le $u $nounf


// Letters which can be words // Letters which can be words
//=========================== //===========================
à a:aksA~grav $atend
y i:gr'Ek $atend
à a:aksA~gRav $atend
y i:gR'Ek $atend








scient si scient si
bénéficient benefisi $verb bénéficient benefisi $verb
président prezidA~t2
président prezidt2 $verb
président pRezidA~t2
président pRezidt2 $verb




// MAIN WORD DICTIONARY // MAIN WORD DICTIONARY
//********************* //*********************


monsieur m@sjY // monsieur
montréal mO~real // Montréal
monsieur m@sjY
montréal mO~Real
(il y a) ili;a $u (il y a) ili;a $u
(il y) ili $u (il y) ili $u
(n'est ce pas) nEspa (n'est ce pas) nEspa
bus bys bus bys
echo Eko echo Eko
fils fis fils fis
mars mars
mars maRs
pays pEi pays pEi
sens sA~s sens sA~s
c'est sEt2 $u c'est sEt2 $u
espeak ispik espeak ispik
nvda $abbrev nvda $abbrev
outlook autluk outlook autluk
reader Rid'Wr
potentiomètre pOtA~sjOmEtr
reader Rid'WR
potentiomètre pOtA~sjOmEtR


processus pROsEsys processus pROsEsys


// ut (t is said) // ut (t is said)
août ut août ut
azimut azim'yt azimut azim'yt
brut br'yt
brut bR'yt
but by $verb but by $verb
but byt but byt
connecticut kOnEktikyt connecticut kOnEktikyt
helmut Elmut helmut Elmut
mazout mazut mazout mazut
out aut out aut
rut ryt
scorbut skOrbyt
rut Ryt
scorbut skORbyt
scout skut scout skut
scouts skut scouts skut
stout staut stout staut
uppercut ypErkyt
uppercut ypERkyt
ut yt ut yt
zut syt zut syt




// et (t is said) // et (t is said)


//Downing_street
//Dun_and_Bradstreet
bridget bRidZEt bridget bRidZEt
exocet EgzOsEt exocet EgzOsEt
fret fR'Et fret fR'Et
gadget gadZEt gadget gadZEt
hamlet amlEt hamlet amlEt
internet E~tErnEt
internet E~tERnEt
jacket ZakEt jacket ZakEt
knesset knEsEt knesset knEsEt
lazaret lazarEt
margaret margarEt
lazaret lazaREt
margaret maRgaREt
net nEt net nEt
offset OfsEt offset OfsEt
pickpocket pikpOkEt pickpocket pikpOkEt
// ct (ct are not said) // ct (ct are not said)
aspect aspE aspect aspE
aspects aspE aspects aspE
circonspect circO~spE
irrespect irEspE
prospect prOspE
respect rEspE
circonspect ciRcO~spE
irrespect iREspE
prospect pROspE
respect REspE
suspect syspE suspect syspE


// st (t is not said) // st (t is not said)
prévost prevo
prévost pRevo


// urt (t is said) // urt (t is said)
kurt kurt
yaourt jaurt
yoghourt yogurt
yogourt yogurt
kurt kuRt
yaourt jauRt
yoghourt yoguRt
yogourt yoguRt


// ort (t said) // ort (t said)
short SOrt
short SORt


// art (t said) // art (t said)
stewart stiwart
steward stiwart
stuttgart Stutgart
hart art
kart kart
smart smart
stewart stiwaRt
steward stiwaRt
stuttgart StutgaRt
hart aRt
kart kaRt
smart smaRt


// irt // irt
flirt fl@rt
(sweat shirt) swEtS@rt
tee-shirt tiS@rt
flirt fl@Rt
(sweat shirt) swEtS@Rt
tee-shirt tiS@Rt


parfum parfW~
parfum paRfW~
forum fOR@m forum fOR@m


// words from other languages // words from other languages
// tions (tjO~ instead of sjO~) // tions (tjO~ instead of sjO~)
achetions aS@tjO~z2 achetions aS@tjO~z2
ajoutions aZutjO~z2 ajoutions aZutjO~z2
apportions apOrtjO~z2
apprêtions aprEtjO~z2
arrêtions arEtjO~z2
apportions apORtjO~z2
apprêtions apREtjO~z2
arrêtions aREtjO~z2
assistions asistjO~ assistions asistjO~
bastions bastjO~z2 bastions bastjO~z2
battions batjO~z2 battions batjO~z2
discutions diskytjO~z2 discutions diskytjO~z2
doutions dutjO~z2 doutions dutjO~z2
débutions debytjO~z2 débutions debytjO~z2
désertions dezErtjO~z2
désertions dezERtjO~z2
détentions detA~tjO~z2 détentions detA~tjO~z2
escomptions EskO~tjO~z2 escomptions EskO~tjO~z2
existions EgzistjO~z2 existions EgzistjO~z2
exploitions EksplwatjO~z2 exploitions EksplwatjO~z2
exportions EkspOrtjO~z2
exportions EkspORtjO~z2
gestions ZEstjO~z2 gestions ZEstjO~z2
habitions abitjO~z2 habitions abitjO~z2
heurtions @rtjO~z2
heurtions @RtjO~z2
indigestions E~diZEstjO~z2 indigestions E~diZEstjO~z2
insistions E~sistjO~z2 insistions E~sistjO~z2
jetions Z@tjO~z2 jetions Z@tjO~z2
limitions limitjO~z2 limitions limitjO~z2
manifestions manifEstjO~z2 manifestions manifEstjO~z2
méritions meritjO~z2
partions partjO~z2
pressentions prEsA~tjO~z2
présentions prezA~tjO~z2
prêtions prEtjO~z2
méritions meRitjO~z2
partions paRtjO~z2
pressentions pREsA~tjO~z2
présentions pRezA~tjO~z2
prêtions pREtjO~z2
quittions kitjO~z2 quittions kitjO~z2
rations ratjO~z2
redoutions r@dutjO~z2
regrettions r@grEtjO~z2
représentions r@prezA~tjO~z2
respections rEspEktjO~z2
ressentions r@sA~tjO~z2
restions rEstjO~z2
répétions repetjO~z2
rations RatjO~z2
redoutions R@dutjO~z2
regrettions R@gREtjO~z2
représentions R@pRezA~tjO~z2
respections REspEktjO~z2
ressentions R@sA~tjO~z2
restions REstjO~z2
répétions RepetjO~z2
sentions sA~tjO~z2 sentions sA~tjO~z2
sortions sOrtjO~z2
sortions sORtjO~z2
souhaitions suEtjO~z2 souhaitions suEtjO~z2
soumettions sumEtjO~z2 soumettions sumEtjO~z2
supportions sypOrtjO~z2
supportions sypORtjO~z2
tentions tA~tjO~z2 tentions tA~tjO~z2
traitions tREtjO~z2 traitions tREtjO~z2
votions vOtjO~z2 $u votions vOtjO~z2 $u

+ 4
- 4
dictsource/fr_rules View File

_r) e (stru @ // restructurer _r) e (stru @ // restructurer
-) est (_ Est // -est -) est (_ Est // -est


Cr) es (_C @
rC) es (_C @ // fortes dames
@Cr) es (_C =@
rC) es (_C =@ // fortes dames


') eu (_ y // eu ') eu (_ y // eu
eu (r_ W // peur eu (r_ W // peur
_CC) e (_ @ _CC) e (_ @
_qu) e (_ @ // que _qu) e (_ @ // que


Cr) e (_C @ // quatre pattes
rC) e (_C @
@Cr) e (_C =@ // quatre pattes
rC) e (_C =@


e (_ // montre e (_ // montre



+ 45
- 20
dictsource/pt_list View File



_. p'oNtu _. p'oNtu
_! ,eskl&mas'&U~ _! ,eskl&mas'&U~
_" 'asp&s
_# k,ardZin'aU
?1 _" 'asp&S
?2 _" 'asp&s
?1 _# k,ardin'al
?2 _# k,ardZin'aU
_$ s,if@-*'&U~ _$ s,if@-*'&U~
_% pors'eINtu _% pors'eINtu
_& 'e _& 'e
_' ap'Ost@-*,ofu
?1 _' ap'Ost@-*,ofy
?2 _' ap'Ost@-*,ofu
_( ,ab@-*ipa*'eINtezi _( ,ab@-*ipa*'eINtezi
_) f,ES&pa*'eINtezi _) f,ES&pa*'eINtezi
_* ,aste*'isku _* ,aste*'isku
_+ m'aIs
?1 _+ m'aIS
?2 _+ m'aIs
_, v'irgul& _, v'irgul&
_- 'ifeIN _- 'ifeIN
_/ b'aQ& _/ b'aQ&
_: d,oIsp'oNtus _: d,oIsp'oNtus
_; p,oNtu_iv'irgul& _; p,oNtu_iv'irgul&
_< men'Or _< men'Or
_= igw'aU
?1 _= igw'al
?2 _= igw'aU
_> maI'Or _> maI'Or
_? ,iNtex,ogas'&U~ _? ,iNtex,ogas'&U~
_@ ax'ob& _@ ax'ob&
__ s,ublin^'adu __ s,ublin^'adu
_` g@-*'avi _` g@-*'avi
_{ ,ab@-*iS'avi _{ ,ab@-*iS'avi
_| b,ax&v,ertSik'aU
?1 _| b,ax&v,ertSik'al
?2 _| b,ax&v,ertSik'aU
_} f,ES&S'avi _} f,ES&S'avi
_~ tS'iU
?1 _~ t'il
?2 _~ tS'iU
_¡ ,eskl&mas,&U~,iNvertS'id& _¡ ,eskl&mas,&U~,iNvertS'id&
_¿ ,iNtex,ogas,&U~,iNvertS'id& _¿ ,iNtex,ogas,&U~,iNvertS'id&
_" 'ab@-*i;'asp&z d'upl&s
?1 _" 'ab@-*i;'asp&S d'upl&S
?2 _" 'ab@-*i;'asp&z d'upl&s




// numeric // numeric


// ABBREVIATIONS // ABBREVIATIONS
//************** //**************
(http ://) ag,atete'pe_
a.c ,as'e
abadv $abbrev
a.c 'as'e
adsl $abbrev
apedv $abbrev
?1 apedv ,a,pe,,E,de've
bios b'i,OS
d.c d,es'e d.c d,es'e
etc ,ets'Ete*&
cpu $abbrev
//?1 cpu ,se,pe'u
?1 cpuc ,se,pe,u'se
edp $abbrev
?1 etc ,ets'Et:r&
?2 etc ,ets'Ete*&
?2 (http ://) ag,atete'pe_
nvda $abbrev
unts $abbrev
unts $abbrev
?1 usb ,u,Esy'be
?2 usb $abbrev




// articles // articles
abacaxi abakaSi abacaxi abakaSi
axé aSE axé aSE
elixir eliSir elixir eliSir
?1fixe fiSe
?1 fixe fiSe
lixo l'iSu lixo l'iSu
roxo x'oSu roxo x'oSu


?1 alt 'alt ?1 alt 'alt
?1 bacalhau b,&k&lj'aU ?1 bacalhau b,&k&lj'aU
?1 caps k'aps ?1 caps k'aps
?1 ctrl k'oNt:r'Ol
ctrl k'oNt:r,Ol
?1 delete dil'i:t ?1 delete dil'i:t
?1 design diz'aIn //? In Brasilian Portuguese
?1 design diz'aIn
?1 down d'aUn ?1 down d'aUn
?1 download d'aUnloUd ?1 download d'aUnloUd
?1 escape Sk'eIpy ?1 escape Sk'eIpy
?1 mail meIl ?1 mail meIl
?2 mail m'eja ?2 mail m'eja
?1 menu mEnU ?1 menu mEnU
?1 num _^_EN
?1 ok Ok'eI
ok Ok'eI
?1 pause p'au:z ?1 pause p'au:z
?1 page p'eIdZ ?1 page p'eIdZ
?1 scroll _^_EN ?1 scroll _^_EN
?1 access 'aksEs ?1 access 'aksEs
debian d'Ebj&~N debian d'Ebj&~N
espeak isp'i:k espeak isp'i:k
speak spi:k
espeakedit isp'i:k,Ed,it
firefox f'ai@foks firefox f'ai@foks
?1 hal hal ?1 hal hal
?1 jaws dZ'au:z ?1 jaws dZ'au:z
?1 linux l'inUks
?1 linux l,in'uks
?2 linux l'inuks ?2 linux l'inuks
openoffice 'opeIN|'Ofis openoffice 'opeIN|'Ofis
?1 reader r'i:d&@
?1 reader _^_EN
slackware sl'akwe@ slackware sl'akwe@
speak spi:k
suse z'u:ts@ suse z'u:ts@
ubuntu ub'untu ubuntu ub'untu
unix j'u:niks
?1 unix ,u:n'iks
?2 unix j'u:niks
?1 windows _^_EN ?1 windows _^_EN




vogel f'o:g@l vogel f'o:g@l
volkmann f'Olkman volkmann f'Olkman




+ 78
- 72
dictsource/pt_rules View File



.group a .group a
_) a (_ a _) a (_ a
_) a (_W 'a // in an acronym
a a a a
&) a (_ =& // in final unstressed syllable &) a (_ =& // in final unstressed syllable
&) a (s_ =& &) a (s_ =&


a (C_ & a (C_ &
a (r_ 'a a (r_ 'a
?1 p) a (d_ =E
?1 p) a (d_ =E
a (CC_ & a (CC_ &
?1 al (_ 'al // eg: Portugal, capital, etc. ?1 al (_ 'al // eg: Portugal, capital, etc.
?2 al (K aU ?2 al (K aU
an (K &~N an (K &~N
a (nhA &~ a (nhA &~
am (_ =&U~ am (_ =&U~
?1 a (z_ 'a //eg: paz, rapaz, capaz, etc...


ai aI ai aI
ai (s aI ai (s aI
?2 el (K EU ?2 el (K EU
?2 elh elj ?2 elh elj


?1 e (rtA_ 'E // Eg: Alberto, aberta, etc...
?1 e (rtA_ 'E // Eg: Alberto, aberta, etc...
em (C eIm em (C eIm
en (K eIN en (K eIN
enh en^ enh en^
eu (s eU eu (s eU
e (uCK e e (uCK e


?1 _) es (C@@ S // drop initial "e".
?1 _) e (f i // efectuar, etc.
?1 C) e (cC 'E // eg: seleccionar, efectuar, selecção, etc...
?1 C) e (ã i // leão, panteão, etc.
?1 C) e (a i // oceano, etc.
?1 _C) e (CACA =y //definições.
?1 _C) e (CCACAr =y // desligar.
?1 _C) e (CKAr =y // fechar
?1 _C) e (CCACAr =y // terminar.
?1 _C) e (CACC =y // recicla, reciclagem, etc...
?1 _f) e (rrament =y // ferramenta, ferramentas.
?1 hip) e (r ,E // eg: hiper
?1 sup) e (r ,E // super
?1 int) e (rC 'E // Interno
?1 int) e (rr E // Interno
?1 n) e (t ,E // eg: net

?1 e (l_ ,E
?1 _) es (C@@ S // drop initial "e".
?1 _) e (f i // efectuar, etc.
?1 _n) e (nhu i // eg: nenhum, nenhuma, nenhuns, nenhumas.
?1 C) e (cC ,E // eg: seleccionar, efectuar, etc...
?1 C) ecç 'E's // eg: selecção, etc...
?1 C) e (ã i // leão, panteão, etc.
?1 C) e (a i // oceano, etc.
?1 _C) e (CACA y //definições.
?1 _C) e (CCACAr y // desligar.
?1 C) e (CCAC y // eg: deslocamento, etc...
?1 _C) e (CKAr y // fechar
?1 _C) e (CCACAr y // terminar.
?1 _C) e (CACC y // recicla, reciclagem, etc...
?1 _f) e (rrament y // ferramenta, ferramentas.
?1 hip) e (r ,E // eg: hiper
?1 sup) e (r ,E // super
?1 int) e (rC 'E // Interno
?1 int) e (rr E // eg: Enterra
?1 n) e (t ,E // eg: net
?1 e (l_ ,E // eg: possível, manuel, etc...




.group é .group é




.group f .group f
?1 _) f (_ Ef; // individual letter
?1 _) f (__ Ef // individual letter at end-of-word
?1 _) f (_W Ef; // within an acronym
?1 _) f (_ Ef // individual letter or end-of-acronym
_) f (_ 'Efe _) f (_ 'Efe
f f f f
f (f f (f


.group g .group g
?1 _) g (_ ge ?1 _) g (_ ge
?1 _) g (_W Ze // within an acronym
_) g (_ Ze _) g (_ Ze
g g g g
g (g g (g




.group h .group h
_) h (_ ag'a
?1 _) h (_ &g'a
?2 _) h (_ ag'a
h // silent h // silent




úC) i (A_ j úC) i (A_ j
úCC) i (A_ j úCC) i (A_ j


?1 @) ing (_ _^_EN
?1 @) ings (_ _^_EN
?1 @) ing (_ _^_EN
?1 @) ings (_ _^_EN




.group í .group í


.group k .group k
?1 _) k (_ k'ap& ?1 _) k (_ k'ap&
?2 _) k (_ ka
?2 _) k (_ ka
k k k k
k (k k (k




.group l .group l
?1 _) l (_ El; // individual letter
?1 _) l (__ El // individual letter at end-of-word
?1 _) l (_W El; // within an acronym
?1 _) l (_ El
_) l (_ 'Ele _) l (_ 'Ele
l l l l
l (l l (l




.group m .group m
?1 _) m (_ Em;
?1 _) m (__ Em
?1 _) m (_W 'Em;
?1 _) m (_ Em
_) m (_ 'eme _) m (_ 'eme
m m m m
m (m m (m




.group n .group n
?1 _) n (_ En;
?1 _) n (__ En
?1 _) n (_W 'En
?1 _) n (_ En
_) n (_ 'ene _) n (_ 'ene
n n n n
n (n n (n
oi (s oI oi (s oI
o (iCK o o (iCK o
oo u oo u
?1 v) oo (_ ow
?1 C) oo (_ ow // eg: voo, enjoo, etc...
oy OI oy OI


o (Ca_ O o (Ca_ O
?1 o (Cá_ 'O
?1 o (Cé_ 'O
?1 o (Cí_ 'O
?1 o (Có_ 'O
?1 o (Cú_ 'O
?1 ol (_ Ol ?1 ol (_ Ol
?2 ol (K Ow ?2 ol (K Ow
?2 olh olj ?2 olh olj


?1 om (_ 'om
?2 om (_ oN
?1 om (_ 'om
?2 om (_ oN
o (ma_ o o (ma_ o
?1 om (C 'om
?2 om (C om
?1 om (C 'om
?2 om (C om
on (K oN on (K oN
o (na_ o o (na_ o
onh on^ onh on^
o (rmA_ O o (rmA_ O
o (rmAC O o (rmAC O


?1 oz (_ OS
?2 oz (_ Oz
?1 oz (_ OS
?2 oz (_ Oz
o (zes_ O o (zes_ O
o (ra_ O o (ra_ O
o (ras_ O o (ras_ O
?1 _C) o (CACACC =u // Documento, documentação, etc.
?1 _C) o (CCAC =u // formatar, formato.
?1 _) o (C O // eg: olá, orla, opção, etc...
?1 _C) o (CACACC u // Documento, documentação, etc.
?1 C) o (CCAC u // formatar, formato.




.group ô .group ô


.group r .group r
?1 _) r (_ 'Err; // individual letter
?1 _) r (__ 'Err // individual letter at end-of-word
?1 _) r (_W 'Err; // within an acronym
?1 _) r (_ 'Err
_) r (_ 'Exe _) r (_ 'Exe
_) r (_\$ xe'aU // currency _) r (_\$ xe'aU // currency
r r r r
?1 A) r (A :r
?2 A) r (A *
?1 A) r (_A :r
?2 A) r (_A *
?1 A) r (A :r
?2 A) r (A *
?1 A) r (_A :r
?2 A) r (_A *
rr x rr x
?1 C) r (A :r
?2 C) r (A @-*
?1 C) r (A :r
?2 C) r (A @-*
_) r x _) r x
l) r x l) r x
n) r x n) r x




.group s .group s
?1 _) s (_ 'Ess|; [s]+[;] not [s;] phoneme
?1 _) s (__ 'Ess
_) s (_ 'Ese
?1 _) s (_W 'Es|; within an acronym [s]+[;] not [s;] phoneme
?1 _) s (_ 'Es
?2 _) s (_ 'Ese
s s s s
ss s ss s
sc (Y s sc (Y s
sç s sç s
A) s (A z A) s (A z
?1 s (_ S
?2 s (_ s
s (_A z // next word starts with vowel
s (_G z // next word starts with voiced consonant
?1 @) s (_ S
?2 @) s (_ s
@) s (_A z // next word starts with vowel
@) s (_G z // next word starts with voiced consonant


A) s (_S1 s A) s (_S1 s
A) s (_AS1 z // next word starts with vowel A) s (_AS1 z // next word starts with vowel
?2 t (i tS ?2 t (i tS
?2 t (í tS ?2 t (í tS
?2 t (e_ tS ?2 t (e_ tS
?1 th _^_EN
?1 tion (_ _^_EN
?1 th _^_EN
?1 tion (_ _^_EN




.group u .group u




.group w .group w
_) w (_ d'ablju
?1 _) w (_ d'&bl,iu
?2 _) w (_ d'ablju
w w w w
?1 w (_ _^_EN
?1 w (_ _^_EN




.group x .group x
?1 _) x (_ SiS
?2 _) x (_ Sis
?1 _) x (_ SiS
?2 _) x (_ Sis
x (A S x (A S
A) x (A ks A) x (A ks
e) x (A z e) x (A z




.group y .group y
_) y (_ 'ipsiloN
?1 _) y (_ 'ipsil,ON
?2 _) y (_ 'ipsiloN
y i y i
y (A j y (A j


_) z (_ ze _) z (_ ze
z z z z
z (z z (z
?1 z (_ S
?2 z (_ s
z (_A z
z (_G z
?1 @) z (_ S
?2 @) z (_ s
@) z (_A z
@) z (_G z


?1 A) z (C S ?1 A) z (C S
?1 A) z (G+ Z ?1 A) z (G+ Z
?1 A) z (_C S ?1 A) z (_C S
?1 A) z (_G+ Z ?1 A) z (_G+ Z



.group .group
ç s ç s
_) ç (_ s'esed'il^& _) ç (_ s'esed'il^&








BIN
phsource/ufric/sx_sv.wav View File


BIN
phsource/ufric/xx.wav View File


BIN
phsource/vnasal/o_n3 View File


BIN
phsource/vnasal/vowelchart.png View File


BIN
phsource/vwl_fr/@R View File


BIN
phsource/vwl_fr/@R2 View File


BIN
phsource/x/g2.wav View File


+ 3
- 0
src/compiledict.cpp View File

case 'T': case 'T':
c = RULE_ALT1; c = RULE_ALT1;
break; break;
case 'W':
c = 0x31;
break;
case 'L': case 'L':
// expect two digits // expect two digits
c = *p++ - '0'; c = *p++ - '0';

+ 6
- 1
src/numbers.cpp View File

int n_bytes; int n_bytes;
int letter; int letter;
int len; int len;
int next;
unsigned char *p; unsigned char *p;
char ph_stress[2]; char ph_stress[2];
char capital[20]; char capital[20];


len = utf8_out(letter,&single_letter[2]); len = utf8_out(letter,&single_letter[2]);
single_letter[2+len] = ' '; single_letter[2+len] = ' ';
memcpy(&single_letter[3+len],&word[n_bytes],3); // include the next letter, after a space, in case it affects the translation rules

next = 0x31;
if(word[n_bytes] == ' ')
next = ' ';
single_letter[3+len] = next; // follow by space-space if the end of the word, or space-0x31


single_letter[1] = '_'; single_letter[1] = '_';
if(Lookup(&single_letter[1],ph_buf) == 0) if(Lookup(&single_letter[1],ph_buf) == 0)

+ 2
- 2
src/readclause.cpp View File

{ {
sp = &ssml_stack[ix]; sp = &ssml_stack[ix];


if(sp->voice_name[0] != 0)
strcpy(voice_name, sp->voice_name);
// if(sp->voice_name[0] != 0)
strcpy(voice_name, sp->voice_name); // don't inherit name from previous levels ??
if(sp->language[0] != 0) if(sp->language[0] != 0)
strcpy(language, sp->language); strcpy(language, sp->language);
if(sp->voice_gender != 0) if(sp->voice_gender != 0)

+ 1
- 1
src/synthdata.cpp View File

#include "translate.h" #include "translate.h"
#include "wave.h" #include "wave.h"


const char *version_string = "1.24.02 04.May.07";
const char *version_string = "1.24.03 06.May.07";
const int version_phdata = 0x012201; const int version_phdata = 0x012201;


int option_device_number = -1; int option_device_number = -1;

+ 1
- 1
src/translate.h View File



#define FLAG_CAPITAL 0x8000 /* pronunciation if initial letter is upper case */ #define FLAG_CAPITAL 0x8000 /* pronunciation if initial letter is upper case */
#define FLAG_DOT 0x10000 /* ignore '.' after word (abbreviation) */ #define FLAG_DOT 0x10000 /* ignore '.' after word (abbreviation) */
#define FLAG_ABBREV 0x20000 /* use this pronunciation rather than split into letters */
#define FLAG_ABBREV 0x20000 // spell as letters, even with a vowel, OR use specified pronunciation rather than split into letters
#define FLAG_STEM 0x40000 // must have a suffix #define FLAG_STEM 0x40000 // must have a suffix


#define FLAG_DOUBLING 0x80000 // doubles the following consonant #define FLAG_DOUBLING 0x80000 // doubles the following consonant

+ 173
- 145
src/voices.cpp View File

static int len_path_voices; static int len_path_voices;


espeak_VOICE *voice_selected = NULL; espeak_VOICE *voice_selected = NULL;
espeak_VOICE *first_voice = NULL;
char voice_name[40]; char voice_name[40];




} }






static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*leafname)
{//===================================================================================
// Read a Voice file, allocate a VOICE_DATA and set data from the
// file's language, gender, name lines

char linebuf[120];
char vname[80];
char vgender[80];
char vlanguage[80];
char languages[300]; // allow space for several alternate language names and priorities


unsigned int len;
int langix = 0;
int n_languages = 0;
char *p;
espeak_VOICE *voice_data;
int priority;
int age;
int n_variants = 3; // default, number of variants of this voice before using another voice
int gender;

#ifdef PLATFORM_WINDOWS
if(memcmp(leafname,"mb-",3) == 0)
{
// check whether the mbrola speech data is present for this voice
memcpy(vname,&leafname[3],3);
vname[3] = 0;
sprintf(linebuf,"%s/mbrola/%s",path_home,vname);

if(GetFileLength(linebuf) <= 0)
return(0);
}
#endif

vname[0] = 0;
vgender[0] = 0;
age = 0;

while(fgets(linebuf,sizeof(linebuf),f_in) != NULL)
{
linebuf[strlen(linebuf)-1] = 0;

if(memcmp(linebuf,"name",4)==0)
{
p = &linebuf[4];
while(isspace(*p)) p++;
strncpy0(vname,p,sizeof(vname));
}
else
if(memcmp(linebuf,"language",8)==0)
{
priority = DEFAULT_LANGUAGE_PRIORITY;
vlanguage[0] = 0;

sscanf(&linebuf[8],"%s %d",vlanguage,&priority);
len = strlen(vlanguage) + 2;
// check for space in languages[]
if(len < (sizeof(languages)-langix-1))
{
languages[langix] = priority;

strcpy(&languages[langix+1],vlanguage);
langix += len;
n_languages++;
}
}
else
if(memcmp(linebuf,"gender",6)==0)
{
sscanf(&linebuf[6],"%s %d",vgender,&age);
}
else
if(memcmp(linebuf,"variants",8)==0)
{
sscanf(&linebuf[8],"%d",&n_variants);
}
}
languages[langix++] = 0;

gender = LookupMnem(genders,vgender);

if(n_languages == 0)
{
#ifdef deleted
// Read voice variant files
// Don't use this, instead preset the variants_* arrays

// no language is specified, this voice file only affects the voice characteristics
if(memcmp(leafname,"!variant",8)==0)
{
if(((variant = atoi(&leafname[8])) > 0) && (strlen(variants_either) < N_VOICE_VARIANTS))
{
char string[2];
string[0] = variant;
string[1] = 0;
strcat(variants_either,string);
if(gender == 1)
strcat(variants_male,string);
if(gender == 2)
strcat(variants_female,string);
}
}
#endif
return(NULL); // no language lines in the voice file
}

p = (char *)calloc(sizeof(espeak_VOICE) + langix + strlen(fname) + strlen(vname) + 3, 1);
voice_data = (espeak_VOICE *)p;
p = &p[sizeof(espeak_VOICE)];

memcpy(p,languages,langix);
voice_data->languages = p;

strcpy(&p[langix],fname);
voice_data->identifier = &p[langix];
voice_data->name = &p[langix];

if(vname[0] != 0)
{
langix += strlen(fname)+1;
strcpy(&p[langix],vname);
voice_data->name = &p[langix];
}

voice_data->age = age;
voice_data->gender = gender;
voice_data->variant = 0;
voice_data->xx1 = n_variants;
return(voice_data);
} // end of ReadVoiceFile




void VoiceReset(int tone_only) void VoiceReset(int tone_only)
{//=========================== {//===========================
// Set voice to the default values // Set voice to the default values
char phonemes_name[40]; char phonemes_name[40];
char *language_type; char *language_type;
char buf[200]; char buf[200];
char path_voices[140];
char langname[4]; char langname[4];


int stress_amps[8]; int stress_amps[8];
if(voicename[0]==0) if(voicename[0]==0)
strcpy(voicename,"default"); strcpy(voicename,"default");


sprintf(buf,"%s%cvoices%c%s",path_home,PATHSEP,PATHSEP,voicename);
sprintf(path_voices,"%s%cvoices%c",path_home,PATHSEP,PATHSEP);
sprintf(buf,"%s%s",path_voices,voicename);


if(GetFileLength(buf) <= 0) if(GetFileLength(buf) <= 0)
{ {
langname[0] = voicename[0]; langname[0] = voicename[0];
langname[1] = voicename[1]; langname[1] = voicename[1];
langname[2] = 0; langname[2] = 0;
sprintf(buf,"%s%cvoices%c%s%c%s",path_home,PATHSEP,PATHSEP,langname,PATHSEP,voicename);
sprintf(buf,"%s%s%c%s",path_voices,langname,PATHSEP,voicename);
} }


f_voice = fopen(buf,"r"); f_voice = fopen(buf,"r");
if(first_voice == NULL)
{
first_voice = ReadVoiceFile(f_voice,buf+len_path_voices,voicename);
rewind(f_voice);
}


language_type = "en"; // default language_type = "en"; // default
if(f_voice == NULL) if(f_voice == NULL)


p = voice->languages; // list of languages+dialects for which this voice is suitable p = voice->languages; // list of languages+dialects for which this voice is suitable


if(voice_spec->languages == NULL)
if(spec_n_parts == 0)
{ {
score = 100; score = 100;
} }
if(score == 0) if(score == 0)
return(0); return(0);


if((voice_spec->name != NULL) && (strcmp(voice_spec->name,voice->name)==0))
if(voice_spec->name != NULL)
{ {
// match on voice name
score += 400;
if(strcmp(voice_spec->name,voice->name)==0)
{
// match on voice name
score += 500;
}
else
if(strcmp(voice_spec->name,voice->identifier)==0)
{
score += 400;
}
} }


if(((voice_spec->gender == 1) || (voice_spec->gender == 2)) && if(((voice_spec->gender == 1) || (voice_spec->gender == 2)) &&
int ix; int ix;
int score; int score;
int nv; // number of candidates int nv; // number of candidates
int n_parts=1;
int n_parts=0;
int lang_len=0; int lang_len=0;
char *p; char *p;
espeak_VOICE *vp; espeak_VOICE *vp;


// count number of parts in the specified language // count number of parts in the specified language
if(voice_select->languages != NULL)
if((voice_select->languages != NULL) && (voice_select->languages[0] != 0))
{ {
n_parts = 1;
lang_len = strlen(voice_select->languages); lang_len = strlen(voice_select->languages);
for(p = voice_select->languages; *p != 0; p++) for(p = voice_select->languages; *p != 0; p++)
{ {
n_parts++; n_parts++;
} }
} }

// select those voices which match the specified language // select those voices which match the specified language
nv = 0; nv = 0;
for(ix=0; ix<n_voices_list; ix++) for(ix=0; ix<n_voices_list; ix++)






static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*leafname)
{//===================================================================================
// Read a Voice file, allocate a VOICE_DATA and set data from the
// file's language, gender, name lines

char linebuf[120];
char vname[80];
char vgender[80];
char vlanguage[80];
char languages[300]; // allow space for several alternate language names and priorities


unsigned int len;
int langix = 0;
int n_languages = 0;
char *p;
espeak_VOICE *voice_data;
int priority;
int age;
int n_variants = 3; // default, number of variants of this voice before using another voice
int gender;

#ifdef PLATFORM_WINDOWS
if(memcmp(leafname,"mb-",3) == 0)
{
// check whether the mbrola speech data is present for this voice
memcpy(vname,&leafname[3],3);
vname[3] = 0;
sprintf(linebuf,"%s/mbrola/%s",path_home,vname);

if(GetFileLength(linebuf) <= 0)
return(0);
}
#endif

vname[0] = 0;
vgender[0] = 0;
age = 0;

while(fgets(linebuf,sizeof(linebuf),f_in) != NULL)
{
linebuf[strlen(linebuf)-1] = 0;

if(memcmp(linebuf,"name",4)==0)
{
p = &linebuf[4];
while(isspace(*p)) p++;
strncpy0(vname,p,sizeof(vname));
}
else
if(memcmp(linebuf,"language",8)==0)
{
priority = DEFAULT_LANGUAGE_PRIORITY;
vlanguage[0] = 0;

sscanf(&linebuf[8],"%s %d",vlanguage,&priority);
len = strlen(vlanguage) + 2;
// check for space in languages[]
if(len < (sizeof(languages)-langix-1))
{
languages[langix] = priority;

strcpy(&languages[langix+1],vlanguage);
langix += len;
n_languages++;
}
}
else
if(memcmp(linebuf,"gender",6)==0)
{
sscanf(&linebuf[6],"%s %d",vgender,&age);
}
else
if(memcmp(linebuf,"variants",8)==0)
{
sscanf(&linebuf[8],"%d",&n_variants);
}
}
languages[langix++] = 0;

gender = LookupMnem(genders,vgender);

if(n_languages == 0)
{
#ifdef deleted
// Read voice variant files
// Don't use this, instead preset the variants_* arrays

// no language is specified, this voice file only affects the voice characteristics
if(memcmp(leafname,"!variant",8)==0)
{
if(((variant = atoi(&leafname[8])) > 0) && (strlen(variants_either) < N_VOICE_VARIANTS))
{
char string[2];
string[0] = variant;
string[1] = 0;
strcat(variants_either,string);
if(gender == 1)
strcat(variants_male,string);
if(gender == 2)
strcat(variants_female,string);
}
}
#endif
return(NULL); // no language lines in the voice file
}

p = (char *)calloc(sizeof(espeak_VOICE) + langix + strlen(fname) + strlen(vname) + 3, 1);
voice_data = (espeak_VOICE *)p;
p = &p[sizeof(espeak_VOICE)];

memcpy(p,languages,langix);
voice_data->languages = p;

strcpy(&p[langix],fname);
voice_data->identifier = &p[langix];
voice_data->name = &p[langix];

if(vname[0] != 0)
{
langix += strlen(fname)+1;
strcpy(&p[langix],vname);
voice_data->name = &p[langix];
}

voice_data->age = age;
voice_data->gender = gender;
voice_data->variant = 0;
voice_data->xx1 = n_variants;
return(voice_data);
} // end of ReadVoiceFile


static espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name) static espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name)
{//============================================================================ {//============================================================================
int ix; int ix;
FILE *f_voice; FILE *f_voice;
espeak_VOICE *voice_data; espeak_VOICE *voice_data;
int ftype; int ftype;
char fname[80];
char fname[140];


#ifdef PLATFORM_RISCOS #ifdef PLATFORM_RISCOS
#else #else
espeak_VOICE *v; espeak_VOICE *v;
int variant=0; int variant=0;
char *p; char *p;
char buf[80];
static char buf[60];


strncpy0(buf,name,sizeof(buf)); strncpy0(buf,name,sizeof(buf));
if((p = strchr(buf,'+')) != NULL) if((p = strchr(buf,'+')) != NULL)
variant = atoi(p+1); variant = atoi(p+1);
} }


// first check for a voice with this filename
if(LoadVoice(buf,1) != NULL)
{
voice_selected = first_voice;
WavegenSetVoice(voice);
return(EE_OK);
}

if(n_voices_list == 0) if(n_voices_list == 0)
espeak_ListVoices(NULL); // create the voices list espeak_ListVoices(NULL); // create the voices list


int ix; int ix;
static espeak_VOICE *voices[N_VOICES_LIST]; static espeak_VOICE *voices[N_VOICES_LIST];
char selected_voice_id[80]; char selected_voice_id[80];
char path_voices[80];
char path_voices[130];


// free previous voice list data // free previous voice list data
if((voice_selected != NULL) && (voice_selected->identifier != NULL)) if((voice_selected != NULL) && (voice_selected->identifier != NULL))

Loading…
Cancel
Save