git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@237 d46cf337-b52f-0410-862d-fd96e6ae7743master
@@ -497,7 +497,7 @@ word _^_EN | |||
abort ab'O*t | |||
absentier apzEnt'i:* | |||
abstinent $3 | |||
achsig 'aksIC2 | |||
achsig 'aksIg# | |||
akazie $alt | |||
allein $2 | |||
andre and@-*@ // andere | |||
@@ -703,7 +703,7 @@ vielbesprochen $3 | |||
vielleicht $2 | |||
vorbei fo:*b'aI | |||
vorher fo:*h'e:* | |||
vorherig fo:*h'e:*IC | |||
vorherig fo:*h'e:*Ig# | |||
vorig fo:*Ig | |||
//wahrscheinlich $2 |
@@ -550,24 +550,8 @@ | |||
@) i (at_ I | |||
i (d_ 'i: | |||
i (erin =i: | |||
ig (C IC | |||
ig (m Ig | |||
ig (n Ig | |||
ig (l Ig | |||
ig (r Ig | |||
ig (ung Ig | |||
ig (end_ Ig | |||
ig Ig# // [ig] or [iC] | |||
igh aI | |||
igtet Ikt@t | |||
igtest Ikt@st | |||
&) ig (_N IC | |||
&) ig (_ Ig // -ig + inflexions | |||
@) igst (_ ICst | |||
@) igste (_ ICst@ | |||
@) igstem (_ ICst@m | |||
@) igsten (_ ICst@n | |||
@) igster (_ ICst3 | |||
@) igstes (_ ICst@s | |||
i (i i:_! | |||
@@ -15,22 +15,6 @@ n N n^ p r s S t | |||
T tS v w x x2 z Z | |||
Dictionary ne_dict | |||
@ @/ @2 @3 a aI aU a~ | |||
e E eI eU e~ E~ i I | |||
i~ l- o O o: oI oU O~ | |||
o~ r- u uI u~ V VI VU | |||
V~ | |||
- : b bh c ch d d. | |||
dh f g gh h H j J | |||
Jh k kh l l. m n N | |||
n. n^ p ph Q q r r. | |||
s S s. t T t. th v | |||
w x z z. | |||
Dictionary ca_dict | |||
@ a a# aI e E E2 i | |||
@@ -88,8 +72,8 @@ E E2 E: e: EI I i2 i: | |||
O o: OY U u: W y y: | |||
Y: | |||
* : ; b C C2 d D | |||
dZ f g h j k l m | |||
* : ; b C d D dZ | |||
f g g# h j k l m | |||
n N p pF r s S t | |||
tS ts v w x z Z | |||
@@ -143,17 +127,6 @@ N n^ p Q R R2 s t | |||
T tS v v# w x z | |||
Dictionary hu_dict | |||
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 | |||
Dictionary fi_dict | |||
& &i &y a a2 ai au e | |||
@@ -217,12 +190,15 @@ r. s S s. t T t. th | |||
th. v w x z | |||
Dictionary am_dict | |||
Dictionary hu_dict | |||
@ a e i o u y | |||
A a: E e: i i: o o: | |||
u u: Y y y: Y: | |||
b d h l m q R s | |||
S t tS | |||
- : 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 | |||
Dictionary hy_dict | |||
@@ -281,21 +257,6 @@ k l m n N p R s | |||
S t tS v w x z Z | |||
Dictionary ro_dict | |||
@ @- @I @U a aI aU e | |||
ea eI eo eU i i/ I^ iI | |||
iU o O Oa oI oU u uI | |||
y Y yI yU | |||
* *; b b; c C d d; | |||
dZ f f; g h j k l | |||
l; m m; n N n; p p; | |||
r s S S; t t; tS ts | |||
ts; v v; w w2 x z Z | |||
z; Z; | |||
Dictionary ku_dict | |||
8 a e E E# eI eU i | |||
@@ -342,20 +303,6 @@ N n^ p r R s S t | |||
tS ts tS; v x z Z | |||
Dictionary ml_dict | |||
a a: aI aU e E e: i | |||
I i: o o: r- u u: V | |||
y | |||
: b bh c ch d d. dh | |||
dh. dZ f g gh h j J | |||
Jh k kh l l. m n N | |||
n. n^ p ph R R2 s s. | |||
S; t t. th th. tS v w | |||
z z. | |||
Dictionary nci_dict | |||
a e i o O | |||
@@ -400,20 +347,6 @@ R s S t tS v w x | |||
z Z | |||
Dictionary pa_dict | |||
@ a a~ e E e~ E~ i | |||
I i~ I~ o O O~ o~ r- | |||
U u U~ u~ V V~ | |||
: ; b bh c ch d d. | |||
dh dh. f g gh h H j | |||
J Jh k kh l l. m n | |||
N n. n^ p ph Q R R2 | |||
s S t t. th th. v x | |||
z | |||
Dictionary pl_dict | |||
a E E# E~ i O O~ u | |||
@@ -426,15 +359,6 @@ s; S; t t; tS ts tS; v | |||
w x z Z Z; | |||
Dictionary prs_dict | |||
@ A E eI i o u | |||
: b d dZ f g h j | |||
k l m n p r R s | |||
S t tS v w X z Z | |||
Dictionary pt_dict | |||
& &/ &U~ &~ @ @- a A | |||
@@ -449,6 +373,21 @@ S s# s; t T tS ts v | |||
w x z Z | |||
Dictionary ro_dict | |||
@ @- @I @U a aI aU e | |||
ea eI eo eU i i/ I^ iI | |||
iU o O Oa oI oU u uI | |||
y Y yI yU | |||
* *; b b; c C d d; | |||
dZ f f; g h j k l | |||
l; m m; n N n; p p; | |||
r s S S; t t; tS ts | |||
ts; v v; w w2 x z Z | |||
z; Z; | |||
Dictionary ru_dict | |||
8 @- a A e E E# E2 | |||
@@ -463,16 +402,6 @@ t; ts tS; v x z Z z; | |||
Z; | |||
Dictionary rw_dict | |||
a e i o u | |||
* : b B c d dZ f | |||
g h j J k l m n | |||
N n^ p q R s S S; | |||
t tS v w x z | |||
Dictionary sk_dict | |||
& @- a a: e e: i i: | |||
@@ -579,16 +508,3 @@ oi ong ou u ui yu | |||
b c d f g h j k | |||
l m n N p r s t | |||
tS v w z | |||
Dictionary ur_dict | |||
@ a a: aI aU E e: i | |||
I i: O o: U u: | |||
: b bh c ch d D d. | |||
dh dh. dZ f g gh H j | |||
J Jh k kh l m n N | |||
p ph Q q R r. s S | |||
s. t T t. th th. v x | |||
z Z z. |
@@ -992,6 +992,7 @@ dogged d0gI2d | |||
domino $1 | |||
donor doUn3 | |||
dont doUnt $only | |||
donut doUnVt | |||
dose doUs | |||
dosage doUsI2dZ | |||
dramatic dr@matIk | |||
@@ -1025,7 +1026,6 @@ electron I2lEktr0n | |||
elicit I2lIsI2t | |||
eligible ElI2dZ@b@L | |||
élite Il'i:t | |||
email i:meIl | |||
embed Emb'Ed | |||
ember Emb3 | |||
empire $1 | |||
@@ -2634,7 +2634,7 @@ Graeme greI@m | |||
Graham greI@m | |||
Hadrian heIdri:@n | |||
Harriet hari@t | |||
Heidi haIdI | |||
Heidi haIdi | |||
Huw hju: | |||
Iain i:@n | |||
Ian i:@n |
@@ -197,6 +197,7 @@ _#-át a:t $alt2 | |||
(00-ig) nul:Anul:a:ig //special exception | |||
(0-ban) nul:a:bAn | |||
(0-ba) nul:a:bA | |||
(00-s) nul:Anul:a:S | |||
(1-gyet) EJ:Et | |||
(1-gyes) EJ:ES | |||
(2-őt) kEt:Y:t |
@@ -163,7 +163,8 @@ menetren) dsz (erű d|s | |||
bri) ddzs (el dZ: | |||
rekor) d (sebesség | |||
hol) d (sü d | |||
árpá) d (sáv d | |||
árpá) d (sáv d | |||
ötö) dsz (ör ts: | |||
.group dz | |||
fogó) dz (kod ts | |||
@@ -319,8 +320,8 @@ _minde) gy (ik J | |||
tizene) gy (edszer J: | |||
tizene) gy (es J: | |||
ú) gy (sincs J | |||
e) gy (ért J: | |||
a) gy (sérül J | |||
e) gy (ért J: | |||
a) gy (sérül J | |||
@@ -425,7 +426,7 @@ keresztü) l (j l | |||
mosquito moskito: | |||
mosquitó moskito: | |||
messerschmitt mEs:ER2Smit: | |||
?!2 hi) mm (ler m | |||
?!2 hi) mm (ler m | |||
.group n | |||
@@ -521,7 +522,7 @@ tulajdo) n (jog n | |||
_) richá (rd R2iCa: | |||
reichsmarschall R2EjsmAR2SAl: | |||
?!2 _) roose (velt R2u:z | |||
?!2 _) reichs R2Ejs | |||
?!2 _) reichs R2Ejs | |||
.group s | |||
s S | |||
@@ -568,13 +569,13 @@ juventu) ssz s: //a radio station name | |||
ejtőernyő) ssz S|s | |||
farka) ssz (em Ss | |||
villamo) ssz (ék Ss | |||
titko) ssz ( olgál Ss | |||
titko) ssz (olgál Ss | |||
karo) ssz (ék Ss | |||
hú) ssz (elet Ss | |||
vörö) ssz (em Ss | |||
dőlé) ssz (ög Ss | |||
vonó) ssz (erenád Ss | |||
maro) ssz ( Ss | |||
maro) ssz Ss | |||
szepe) ssz (ombat Ss | |||
ko) ssz (arv Ss | |||
kaka) ssz (ék Ss | |||
@@ -594,7 +595,7 @@ zuhaná) ssz (erű Ss | |||
kéke) ssz (ürke Ss | |||
éde) ssz (áj Ss | |||
égé) ssz (abály Ss | |||
egyene) ssz ( Ss | |||
egyene) ssz Ss | |||
má) ssz (or Ss | |||
éke) ssz (ól Ss | |||
éle) ssz (em Ss | |||
@@ -628,17 +629,17 @@ hivatá) ssz (erű Ss | |||
hú) ssz (ekrény Ss | |||
írá) ssz (akér Ss | |||
jelené) ssz (erű Ss | |||
kampó) ssz ( Ss | |||
kampó) ssz Ss | |||
ka) ssz (ék Ss | |||
katalógu) ssz (ám Ss | |||
kattogá) ssz ( Ss | |||
kattogá) ssz Ss | |||
ki) ssz (ám Ss | |||
ki) ssz (erű Ss | |||
ki) ssz (ob Ss | |||
ki) ssz (ék Ss | |||
ki) ssz (ótár Ss | |||
könyve) ssz (ek Ss | |||
köté) ssz ( Ss | |||
köté) ssz Ss | |||
laká) ssz (en Ss | |||
lapo) ssz (ár Ss | |||
látomá) ssz (erű Ss | |||
@@ -647,7 +648,7 @@ látomá) ssz (erű Ss | |||
lépé) ssz (ám Ss | |||
nyomá) ssz (erű Ss | |||
löké) ssz (erű Ss | |||
luxu) ssz ( Ss | |||
luxu) ssz Ss | |||
mágne) ssz (alag Ss | |||
megállapodá) ssz (erű Ss | |||
meglepeté) ssz (erű Ss | |||
@@ -669,10 +670,10 @@ pikkelye) ssz (árny Ss | |||
rajtaüté) ssz (er Ss | |||
karo) ssz (ériájú Ss | |||
ruhá) ssz (ekrény Ss | |||
sárgá) ssz ( Ss | |||
sárgá) ssz Ss | |||
sa) ssz (em Ss | |||
serté) ssz ( Ss | |||
sonká) ssz ( Ss | |||
serté) ssz Ss | |||
sonká) ssz Ss | |||
sor) ssz (erű Ss | |||
töré) ssz (ög Ss | |||
uta) ssz (ál Ss | |||
@@ -912,8 +913,8 @@ terüle) t (cél t | |||
tesz) t (cél t | |||
dró) t (sövény t | |||
dró) t (sövénny t | |||
a) th (én t | |||
a) th (én t | |||
huncu) t (ság t | |||
.group ts | |||
ts (_S2 tS //general rule with word end of ts letters | |||
@@ -990,7 +991,7 @@ indula) tsz (ó t|s | |||
me) tsz (ik ts: | |||
me) tsz (e ts: | |||
hű) ts tS: | |||
huncu) ts (ág tS: | |||
.group u | |||
@@ -1104,6 +1105,7 @@ találko) z (t s | |||
gő) z (síp z | |||
matró) z (sapka z | |||
nehé) z (súly z | |||
tör) zsz (ászló Z|z | |||
zsz z|s //general exception. Need difference first z and second sz phoneme. For example, rajzszög, rajzszeg, mézszín words. | |||
pén) z (t s | |||
rende) z (ked s | |||
@@ -1124,9 +1126,11 @@ tájéko) z (tass s | |||
tű) zsz (eréssz s: | |||
búcsú) z (ko s | |||
nyújtó) z (ko s | |||
ő) z (sörét z | |||
.group | |||
$ dolla:R2 | |||
ä E | |||
æ E |
@@ -28,12 +28,12 @@ g g@ | |||
_i ibu | |||
j Z@ | |||
k k@ | |||
_l l@ | |||
_m m@ | |||
_n n@ | |||
l l@ | |||
m m@ // should "words" l,m,n,r say the syllable consonant? | |||
n n@ | |||
_o obu | |||
p p@ | |||
_r R@ | |||
r R@ | |||
s s@ | |||
t t@ | |||
_u ubu | |||
@@ -42,9 +42,9 @@ x x@ | |||
y '@bu | |||
z z@ | |||
h @h@bu | |||
q k@bu | |||
w v@bu | |||
h @h'@bu | |||
q k'@bu | |||
w v'@bu | |||
// stressed cmavo |
@@ -231,6 +231,7 @@ tamil தமிழ் $text | |||
பாக்கிப் $alt | |||
பாக்கித் $alt | |||
பாக்கிச் $alt | |||
பர்மிய $alt | |||
(பி . ஏ) bije: | |||
@@ -329,3 +330,4 @@ tamil தமிழ் $text | |||
பைக்கில் baIkkIl | |||
தாங்ஸ் Ta:Nks // thanks | |||
டிபுடி d.EpjUt.i // deputy | |||
டிபன் t.ifVn |
@@ -13,17 +13,15 @@ | |||
<hr> | |||
A phoneme table defines all the phonemes which are used by a language, together with their properties and the data for their production as sounds. | |||
<p> | |||
Generally each language has its own phoneme table, although additional phoneme tables can be used for different voices within the language. These alternatives are referenced from Voices files. | |||
Generally each language has its own phoneme table, although additional phoneme tables can be used for different voices within the language. These alternatives are referenced from Voice files. | |||
<p> | |||
A phoneme table does not need to define all the phonemes used by a language. Instead it can reference a previously defined phoneme table, whose phonemes it inherits. These can then be used as they are, or overridden by new definitions, or new phonemes added. For example, a phoneme table may redefine (or add) some of the vowels that it uses, but inherit most of its consonants from a standard set. | |||
A phoneme table does not need to define all the phonemes used by a language. It can inherit the phonemes from a previously defined phoneme table. For example, a phoneme table may redefine (or add) some of the vowels that it uses, but inherit most of its consonants from a standard set. | |||
<p> | |||
<blockquote>Note: This specification is not yet complete and does not include the definitions of the formant sequence specifications. | |||
<br> | |||
The source files for the phoneme data is in the "phsource" directory in the espeakedit download package. | |||
The source files for the phoneme data are in the "phsource" directory in the espeakedit download package. "Vowel files", which are referenced in FMT(), VowelStart(), and VowelEnding() instructions are made using the espeakedit program. | |||
</blockquote> | |||
<p> <hr> | |||
<h3>Phoneme files</h3> | |||
The phoneme tables are defined in a master phoneme file, named <strong>phonemes</strong>. This starts with the <strong>base</strong> phoneme table followed by other phoneme tables for languages and voices which inherit phonemes from the <strong>base</strong> table or from each other. | |||
The phoneme tables are defined in a master phoneme file, named <strong>phonemes</strong>. This starts with the <strong>base</strong> phoneme table followed by phoneme tables for other languages and voices. These inherit phonemes from the <strong>base</strong> table or previously defined tables. | |||
<p> | |||
In addition to phoneme definitions, the phoneme file can contain the following: | |||
<dl> | |||
@@ -32,37 +30,54 @@ In addition to phoneme definitions, the phoneme file can contain the following: | |||
<p> | |||
<dt><strong>phonemetable</strong> <name> <parent> | |||
<dd>Starts a new phoneme table, and ends the previous table.<br> | |||
<name> Is the name of this phoneme table. This name is used in Voices files.<br> | |||
<name> Is the name of this phoneme table. This name is used in Voice files.<br> | |||
<parent> Is the name of a previously defined phoneme table whose phoneme definitions are inherited by this one. The name <strong>base</strong> indicates the first (base) phoneme table. | |||
<p> | |||
<dt><strong>phonemenumber</strong> <integer> | |||
<dd>This statement is used at the start of the master <strong>phonemes</strong> file to define some specific code numbers for various phonemes which are used directly within the <strong>speak</strong> program. | |||
</dl> | |||
<p> <hr> | |||
<h3>Phoneme definitions</h3> | |||
A phoneme table contains a list of phoneme definitions. Each starts with the keyword <strong>phoneme</strong> and the phoneme name (this is the name used in the pronunciation rules), and ends with the keyword <strong>endphoneme</strong>. For example: | |||
Note: These new Phoneme definitions apply to eSpeak version 1.42.20 and later. | |||
<p> | |||
A phoneme table contains a list of phoneme definitions. Each starts with the keyword <strong>phoneme</strong> and the phoneme name (this is the name used in the pronunciation rules in a language's *_rules and *_list files), and ends with the keyword <strong>endphoneme</strong>. For example: | |||
<pre> phoneme aI | |||
vowel | |||
starttype #a endtype #i | |||
length 230 | |||
formants vowels/ai | |||
starttype (a) endtype (I) | |||
FMT(vowels/ai) | |||
endphoneme | |||
phoneme s | |||
vls alv frc sibilant | |||
vowelin f1=0 f2=1700 -300 300 f3=-100 100 | |||
vowelout f1=0 f2=1700 -300 250 f3=-100 100 rms=20 | |||
voicingswitch z | |||
lengthmod 3 | |||
wave unvoc/s | |||
before _ unvoc/s_ | |||
before p unvoc/s! | |||
before t unvoc/s! | |||
before k unvoc/s! | |||
switchvoicing z | |||
Vowelin f1=0 f2=1700 -300 300 f3=-100 80 | |||
Vowelout f1=0 f2=1700 -300 250 f3=-100 80 rms=20 | |||
IF nextPh(isPause) THEN | |||
WAV(ufric/s_) | |||
ELIF nextPh(p) OR nextPh(t) OR nextPh(k) THEN | |||
WAV(ufric/s!) | |||
ENDIF | |||
WAV(ufric/s) | |||
endphoneme | |||
</pre> | |||
<p> | |||
A phoneme definition contains both static properties and executed instructions. The instructions may contain conditional statements, so that the effect of the phoneme may be different depending on adjacent phonemes, whether the syllable is stressed, etc. | |||
<p> | |||
The instructions of a phoneme are interpreted in two different phases. In the first phase, the instructions may change the phoneme and replace it by a different phoneme. In the second phase, instructions are used to produce the sound for the phoneme. | |||
<p> | |||
The <strong>import_phoneme</strong> statement can be used to copy a previously defined phoneme from a specified phoneme table. For example: | |||
<pre> | |||
phoneme t | |||
import_phoneme base/t[ | |||
endphoneme | |||
</pre> | |||
means: <code>phoneme t</code> in this phoneme table is a copy of <code>phoneme t[</code> from phoneme table "base". A <strong>length</strong> instruction can be used after <strong>import_phoneme</strong> to vary the length from the original. | |||
<p> <hr> | |||
<h3>Phoneme Properties</h3> | |||
Within the phoneme definition the following lines may occur: ( (V) indicates only for vowels, (C) only for consonants) | |||
<p> | |||
<ul> | |||
@@ -75,8 +90,8 @@ Within the phoneme definition the following lines may occur: ( (V) indicates on | |||
<tr><TD><b>frc</b></TD><td>fricative eg: <code> f, v, T, D, s, z, S, Z, C, x</code></td></tr> | |||
<tr><TD><b>afr</b></TD><td>affricate eg: <code> tS, dZ</code></td></tr> | |||
<tr><TD><b>pause</b></TD><td></td></tr> | |||
<tr><TD><b>stress</b></TD><td>stress symbols, eg: ' , = %</td></tr> | |||
<tr><TD><b>virtual</b></TD><td>Used to represent a class of phonemes. See section ("Phoneme Pairs", below)</td></tr> | |||
<tr><TD><b>stress</b></TD><td>used for stress symbols, eg: ' , = %</td></tr> | |||
<tr><TD><b>virtual</b></TD><td>Used to represent a class of phonemes.</td></tr> | |||
</table> | |||
</dl> | |||
<dl><dt>Properties: | |||
@@ -85,6 +100,7 @@ Within the phoneme definition the following lines may occur: ( (V) indicates on | |||
<tr><TD><b>vcd</b></TD><td>(C) voiced eg. <code> b, d, g, v, z</code></td></tr> | |||
<tr><TD><b>sibilant</b></TD><td>(C) eg: <code> s, z, S, Z, tS, dZ</code></td></tr> | |||
<tr><TD><b>palatal</b></TD><td>(C) A palatal or palatalized consonant.</td></tr> | |||
<tr><TD><b>rhotic</b></TD><td>(C) An "r" type consonant.</td></tr> | |||
<tr><TD><b>unstressed</b></TD><td>(V) This vowel is always unstressed, unless explicitly marked otherwise.</td></tr> | |||
<tr><TD><b>nolink</b></TD><td>Prevent any linking from the previous phoneme.</td></tr> | |||
<tr><TD><b>trill</b></TD><td>(C) Apply trill to the voicing.</td></tr> | |||
@@ -109,75 +125,208 @@ Within the phoneme definition the following lines may occur: ( (V) indicates on | |||
<TD><b>glt</b></TD><td>glottal</TD></tr> | |||
</table> | |||
<p> | |||
<dt><strong>starttype</strong> <phoneme> | |||
<dd>Allocates this phoneme to a group so that conditions such as nextPh(#e) can test for any of a group of phonemes. Pre-defined groups for use for vowels are: #@ #a #e #i #o #u. Additional groups can be defined as phonemes with type "virtual". | |||
<p> | |||
<dt><strong>endtype</strong> <phoneme> | |||
<dd>Allocates this phoneme to a group so that conditions such as prevPh(#e) can test for any of a group of phonemes. Pre-defined groups for use for vowels are: #@ #a #e #i #o #u. Additional groups can be defined as phonemes with type "virtual". | |||
<p> | |||
<dt><strong>lengthmod</strong> <integer> | |||
<dd>(C) Determines how this consonant affects the length of the previous vowel. This value is used as index into the <code>length_mods</code> table in the <code>CalcLengths()</code> function in the eSpeak program. | |||
<p> | |||
<dt><strong>voicingswitch</strong> <phoneme> | |||
<dd>This is used for some languages to change between voiced and unvoiced phonemes. | |||
</dl> | |||
</ul> | |||
<p> <hr> | |||
<h3>Phoneme Instructions</h3> | |||
Phoneme Instructions may be included within conditional statements. | |||
<p> | |||
During the first phase of phoneme interpretation, an instruction which causes a change to a different phoneme will terminate the instructions. During the second phase, FMT() and WAV() instructions will terminate the instructions. | |||
<ul> | |||
<dl> | |||
<dt><strong>length</strong> | |||
<dd>(V) The relative length of the phoneme, typically about 140 for a short vowel and from 200 to 250 for a long vowel or diphong. Currently used only for vowels. | |||
<dt><strong>length</strong> <length> | |||
<dd>The relative length of the phoneme, typically about 140 for a short vowel and from 200 to 300 for a long vowel or diphong. A length() instruction is needed for vowels. It is optional for consonants. | |||
<p> | |||
<dt><strong>formants</strong> <sound spec> | |||
<dd><sound spece> is a relative path to a file which defines how to generate the sound (a vowel or voiced consonant) from a sequence of formant values. (see **) | |||
<dt><strong>WAV</strong>(<wav file>, <amplitude>) | |||
<dd> <wav file> is a path to a WAV file (22 kHz, 16 bits, mono) within <code>phsource/</code> which will be played to produce the sound. This method is used for unvoiced consonants. <wavefile> does not include a .WAV filename extension, although the file to which it refers may or may not have one.<br> | |||
<amplitude> is optional. It is a percentage change to the amplitude of the WAV file. So, <code>WAV(ufric/s, 50)</code> means: play file 'ufric/s.wav' at 50% amplitude. | |||
<p> | |||
<dt><strong>wave</strong> <wavefile> | |||
<dd>(C) This is an alternative to <strong>formants</strong>. <wavefile> is a relative path to a WAV file (22 kHz, 16 bits) which will be played to produce the sound. This method is used for unvoiced consonants. <wavefile> does not include a .WAV filename extension, although the file to which it refers may or may not have one. | |||
<dt><strong>FMT</strong>(<vowel file>) | |||
<dd><vowel file> is a path to a file (within <code>phsource/</code>) which defines how to generate the sound (a vowel or voiced consonant) from a sequence of formant values. Vowel files are made using the espeakedit program. | |||
<p> | |||
<dt><strong>before</strong> <phoneme> <sound spec> | |||
<dd>This specifies an alternative realization when the phoneme followed by another specified phoneme. <strong>before</strong> may be followed by several <phoneme> <sound seq> pairs. | |||
<dt><strong>FMT</strong>(<vowel file>) <strong>addWav</strong>(<wav file>, <amplitude>) | |||
<dd>For voiced consonants, a FMT() instruction may be followed by an addWav() instruction. addWav() has the same format as a WAV() instruction, but the WAV file is mixed with the sound which is synthesized from the FMT() instruction. | |||
<p> | |||
<dt><strong>after</strong> <phoneme> <sound spec> | |||
<dd>This specifies an alternative realization when the phoneme follows another specified phoneme. Vowels are considered as two parts, start and end, so both a <strong>before</strong> and an <strong>after</strong> condition may apply to the same vowel. | |||
<dt><strong>VowelStart</strong>(<vowel file>, <length adjust>) | |||
<dd>This is used to modify the start of a vowel when it follows a sonorant consonant (such as [l] or [j]). It replaces the first frame of the <vowel file> which is specified in a FMT() instruction by this <vowel file>, and adjusts the length of the original by a signed value <length adjust>. The VowelStart() instruction may be specified either in the phoneme definition of the vowel, or in the phoneme definition of the sonorant consonant which precedes the vowel. The former takes precedence. | |||
<p> | |||
<dt><strong>starttype</strong> <phoneme> | |||
<dd>Allocates this phoneme to a category for the purposes of choosing the variant of a phoneme that precedes it. See section "Phoneme Pairs" below. | |||
<dt><strong>VowelEnding</strong>(<vowel file>, <length adjust>) | |||
<dd>This is used to modify the end of a vowel when it is followed by a sonorant consonant (such as [l] or [j]). It is appended to the <vowel file> which is specified in a FMT() instruction by this <vowel file>, and adjusts the length of the original by a signed value <length adjust>. The VowelEnding() instruction may be specified either in the phoneme definition of the vowel, or in the phoneme definition of the sonorant consonant which follows the vowel. The former takes precedence. | |||
<p> | |||
<dt><strong>endtype</strong> <phoneme> | |||
<dd>Allocates this phoneme to a category for the purposes of choosing the variant of a phoneme that follows it. See section "Phoneme Pairs" below. | |||
<dt><strong>Vowelin</strong> <vowel transition data> | |||
<dd>(C) Specifies the effects of this consonant on the formants of a following vowel. See "vowel transitions", below. | |||
<p> | |||
<dt><strong>reduceto</strong> <phoneme> <level> | |||
<dd>(V) Change to the specified phoneme (such as schwa, @) if this syllable has a stress level less than that specified by <level> | |||
<dt><strong>Vowelout</strong> <vowel transition data> | |||
<dd>(C) Specifies the effects of this consonant on the formants of a preceding vowel. See "vowel transitions", below. | |||
<p> | |||
<dt><strong>linkout</strong> <phoneme> | |||
<dd>If the following phoneme is a vowel then this additional phoneme will be inserted before it. | |||
<dt><strong>ChangePhoneme(</strong><phoneme>) | |||
<dd>Change to the specified phoneme. | |||
<p> | |||
<dt><strong>beforevowel</strong> <phoneme> | |||
<dd>The phoneme changes to this one if the next phoneme is a vowel. | |||
<dt><strong>ChangeIfDiminished(</strong><phoneme>) | |||
<dd>Change to the specified phoneme (such as schwa, @) if this syllable has "diminished" stress. | |||
<p> | |||
<dt><strong>beforevowelpause</strong> <phoneme> | |||
<dd>Change to this if the next phoneme is a vowel or pause. | |||
<dt><strong>ChangeIfUnstressed(</strong><phoneme>) | |||
<dd>Change to the specified phoneme if this syllable has "diminished" or "unstressed" stress. | |||
<p> | |||
<dt><strong>beforenotvowel</strong> <phoneme> | |||
<dd>Change to this if the next phoneme is <strong>not</strong> a vowel. | |||
<dt><strong>ChangeIfNotStressed(</strong><phoneme>) | |||
<dd>Change to the specified phoneme if this syllable does not have "primary" stress. | |||
<p> | |||
<dt><strong>lengthmod</strong> <integer> | |||
<dd>(C) Determines how this consonant affects the length of the previous vowel. This value is used as index into the <code>length_mods</code> table in the <code>CalcLengths()</code> function in the speak program. | |||
<dt><strong>ChangeIfStressed(</strong><phoneme>) | |||
<dd>Change to the specified phoneme if this syllable has "primary" stress. | |||
<p> | |||
<dt><strong>vowelin</strong> <vowel transition data> | |||
<dd>(C) Specifies the effects of this consonant on the formants of a following vowel. See "vowel transitions", below. | |||
<dt><strong>IfNextVowelAppend(</strong><phoneme>) | |||
<dd>If the following phoneme is a vowel then this additional phoneme will be inserted before it. | |||
<p> | |||
<dt><strong>vowelout</strong> <vowel transition data> | |||
<dd>(C) Specifies the effects of this consonant on the formants of a preceding vowel. See "vowel transitions", below. | |||
<dt><strong>RETURN</strong> | |||
<dd>Ends executions of instructions. | |||
<p> | |||
<dt><strong>CALL</strong> <phoneme table>/<phoneme> | |||
<dd>Executes the instructions of the specified phoneme. | |||
</dl> | |||
</ul> | |||
<p> <hr> | |||
<h3>Phoneme Pairs</h3> | |||
The pronunciation of a phoneme can depend on the phonemes before and after it. Some of this modification is done automatically - the program automatically adjusts the beginning and end of a vowel to match its adjacent sounds. You can also specify variant pronunciations in the phoneme table. | |||
<h3>Conditional Statements</h3> | |||
Phoneme definitions can contain conditional statements such as: | |||
<pre> | |||
IF <condition> THEN | |||
<statements> | |||
ENDIF | |||
</pre> | |||
or more generally: | |||
<pre> | |||
IF <condition> THEN | |||
<statements> | |||
ELIF <condition> THEN | |||
<statements> | |||
... | |||
ELSE | |||
<statements> | |||
ENDIF | |||
</pre> | |||
where the <code>ELSE</code> and multiple <code>ELSE</code> parts are optional. | |||
<p> | |||
The <strong>before</strong> and <strong>after</strong> statements can specify different sound variants to be used when the phoneme is before or is after another specified phoneme. The adjacent phoneme that's specified in a <strong>before</strong> or <strong>after</strong> statement may refer not just to one, but to other phonemes too. For example:<pre> before ; unvoc/s;</pre>means that the sound <code>unvoc/s;</code> is used (rather than <code>unvoc/s</code> if the following phoneme is <code>[;]</code>. But this rule also applies if the next phoneme is another type of pause, <code>[_]</code> or <code>[;;]</code>. This is because these two include a line<pre> starttype ;</pre>in their phoneme specifications. This means that they look like a <code>[;]</code> to a preceding phoneme. | |||
Multiple conditions may be joined with <code>AND</code> or <code>OR</code>, but not a mixture of <code>AND</code>s and <code>OR</code>s. | |||
<p> | |||
When looking for a matching <strong>before</strong> or <strong>after</strong> rule, if an exact match is not found, then a match is looked for by replacing either or both of the two phonemes by their <strong>starttype</strong> and <strong>endtype</strong> groups as appropriate. | |||
<strong>Condition</strong> | |||
Can be: | |||
<ul> | |||
<dl> | |||
<dt>prevPh(<attribute>) | |||
<dd>Test the previous phoneme | |||
<p> | |||
<dt>prevPhW(<attribute>) | |||
<dd>Test the previous phoneme, but only within the same word. Returns false if there is no previous phoneme in the word. | |||
<p> | |||
<dt>thisPh(<attribute>) | |||
<dd>Test this current phoneme | |||
<p> | |||
<dt>nextPh(<attribute>) | |||
<dd>Test the following phoneme | |||
<p> | |||
<dt>nextPhW(<attribute>) | |||
<dd>Test the following phoneme, but only within the same word. Returns false if there is no following phoneme in the word. | |||
<p> | |||
<dt>next2Ph(<attribute>) | |||
<dd>Test the phoneme after the next phoneme. | |||
<p> | |||
<dt>nextVowel(<attribute>) | |||
<dd>Test the next vowel after the current phoneme, but only within the same word. Returns false if there is none. | |||
<p> | |||
<dt>PreVoicing() | |||
<dd>This is used as part of the instructions for voiced stop consonants (eg. [d] [g]). If true then produce a voiced murmer before the stop. | |||
<p> | |||
<dt>KlattSynth() | |||
<dd>Returns true if the voice is using the Klatt synthesizer rather than the eSpeak synthesizer. | |||
</dl> | |||
</ul> | |||
<strong>Attributes</strong> | |||
<ul> | |||
Note: Additional attributes could be added to eSpeak if needed. | |||
<dl> | |||
<dt><phoneme name> | |||
<dd>True if the phoneme has this phoneme name. | |||
<p> | |||
<dt><phoneme group> | |||
<dd>True if the phoneme has this starttype (or if it has this endtype if it's used in prevPh() ). The pre-defined phoneme groups are #@, #a, #e, #i, #o, #u. | |||
<p> | |||
<dt>isPause | |||
<dd>True if the phoneme is a pause. | |||
<p> | |||
<dt>isPause2 | |||
<dd><code>nextPh(isPause2)</code> is used to test whether the next phoneme is not a vowel or liquid consonant within the same word. | |||
<p> | |||
<strong>virtual</strong> phonemes can be defined for use in <strong>starttype</strong> and <strong>endtype</strong> statements. For example, a virtual phoneme <code>[ (i) ]</code> is used to represent vowels which start with and end with an <code>[i]</code> type sound. So <code>[i:]</code> and <code>[I]</code> have <code> starttype (i) </code> and those, plus diphthongs such as <code>[aI] [eI] [OI]</code> have <code> endtype (i) </code>. By convension, names of virtual phonemes include a pair of round brackets. | |||
<dt>isVowel | |||
<dt>isNotVowel | |||
<dt>isLiquid | |||
<dt>isNasal | |||
<dt>isVFricative | |||
<dd>These test the phoneme type. | |||
<p> | |||
<dt>isPalatal | |||
<dt>isRhotic | |||
<dd>These test whether the phoneme has this property. | |||
<p> | |||
<dt>isWordStart | |||
<dt>notWordStart | |||
<dd>These text whether this is the first phoneme in a word. | |||
<p> | |||
<dt>isWordEnd | |||
<dd>True if this is the final phoneme in a word. | |||
<p> | |||
<dt>isFinalVowel | |||
<dd>True if this is the last vowel in a word. | |||
<p> | |||
<dt>isAfterStress | |||
<dd>True if this phoneme is after the stressed vowel in a word. | |||
<p> | |||
<dt>isVoiced | |||
<dd>True if this phoneme is a vowel or a voiced consonant. | |||
<p> | |||
<dt>isDiminished | |||
<dd>True if the syllable stress is "diminished" | |||
<p> | |||
<dt>isUnstressed | |||
<dd>True if the syllable stress is "diminished" or "unstressed" | |||
<p> | |||
<dt>isNotStressed | |||
<dd>True if the syllable stress is not "primary stress". | |||
<p> | |||
<dt>isStressed | |||
<dd>True if the syllable stress is "primary stress". | |||
<p> | |||
<dt>isMaxStress | |||
<dd>True if this is the highest stressed syllable in the word. | |||
<p> | |||
<dt> | |||
<dd> | |||
</dl> | |||
</ul> | |||
<p> <hr> | |||
<h3>Sound Specifications</h3> | |||
There are three ways to produce sounds: | |||
<ul> | |||
<li>Playing a WAV file. This is used for unvoiced consonants such as <code> [p] [t] [s]</code>. | |||
<li>Generating a wave from a sequence of formant parameters. This is used for vowels and also for sonorants such as <code> [l] [j] [n]</code>. | |||
<li>A mixture of these. A stored WAV file is mixed with a wave generated from formant parameters. This is used for voiced stops and fricatives such as <code> [b] [g] [v] [z]</code>. | |||
<li>Playing a WAV file, by using a WAV() instruction. This is used for unvoiced consonants such as <code> [p] [t] [s]</code>. | |||
<li>Generating a wave from a sequence of formant parameters, by using a FMT() instruction.This is used for vowels and also for sonorants such as <code> [l] [j] [n]</code>. | |||
<li>A mixture of these. A stored WAV file is mixed with a wave generated from formant parameters. Use a FMT() instruction followed by addWav(). This is used for voiced stops and fricatives such as <code> [b] [g] [v] [z]</code>. | |||
</ul> | |||
A <em><sound spec></em> in the phoneme table can refer to a WAV file, a formant sequence, or a mixture of both. It can also include a numeric value to adjust the length of the sound. | |||
<p> <hr> | |||
<h3>Vowel Transitions</h3> | |||
These specify how a consonant affects an adjacent vowel. A consonant may cause a transition in the vowel's formants as the mouth changes shape between the consonant and the vowel. The following attributes may be specified. Note that the maximum rate of change of formant frequencies is limited by the speak program.<p> |
@@ -321,8 +321,8 @@ l/l_@ [l/3] base | |||
[W] fr | |||
[Y] fr | |||
[l/] fr | |||
l/l@ [] base | |||
[L] base | |||
l/l@ [L] base | |||
[¼ØÛ] base | |||
[W] fr | |||
[Y] fr | |||
[l] fr | |||
@@ -348,15 +348,15 @@ l/L2_oL [l/2] base | |||
l/L2_uL [l/2] base | |||
l/l_3 [l/] de | |||
l/l_4 [ll] sq | |||
l/la [] base | |||
[L] base | |||
l/la [L] base | |||
[¼ØÛ] base | |||
[a] fr | |||
[l] fr | |||
l/l_a [l/3] base | |||
[l/] fr | |||
[wA] fr | |||
l/le [] base | |||
[L] base | |||
l/le [L] base | |||
[¼ØÛ] base | |||
[l] fr | |||
l/l_e [l/3] base | |||
[l/] fr | |||
@@ -364,8 +364,8 @@ l/L_eL_af [&] af | |||
[&:] af | |||
l/l_front [L] sq | |||
l/l_front_ [l/4] sq | |||
l/li [] base | |||
[L] base | |||
l/li [L] base | |||
[¼ØÛ] base | |||
[l] fr | |||
[l] zh | |||
l/l_i [l/3] base | |||
@@ -373,15 +373,15 @@ l/l_i [l/3] base | |||
[i] sq | |||
l/l_long [l] base | |||
[l] fr | |||
l/lo [] base | |||
[L] base | |||
l/lo [L] base | |||
[¼ØÛ] base | |||
[l] fr | |||
l/l_o [l/3] base | |||
[l/] fr | |||
[o2] fr | |||
l^/l_rfx [l.] base | |||
l/lu [] base | |||
[L] base | |||
l/lu [L] base | |||
[¼ØÛ] base | |||
[l] fr | |||
[w^i] fr | |||
l/l_u [l/3] base | |||
@@ -1503,8 +1503,7 @@ vowel/i_en [i:] en | |||
vowel/i_fnt [i:] en_wi | |||
[i:] hi | |||
[i] pa | |||
vowel/ii [I] en | |||
[I] en_n | |||
vowel/ii [I] en_n | |||
[I2] en_n | |||
[I] en_rp | |||
[I2] en_rp | |||
@@ -1875,8 +1874,8 @@ vwl_fr/_r2 [r] fr | |||
vwl_fr/@R2 [R] fr_ca | |||
vwl_fr/ra [a] fr | |||
vwl_fr/r_a [r/2] fr | |||
vwl_fr/r_a~ [A~] fr | |||
vwl_fr/rA~ [A~] fr | |||
vwl_fr/raa [A~] fr | |||
vwl_fr/r_an [A~] fr | |||
vwl_fr/re [r] fr | |||
vwl_fr/r_e [r/2] fr | |||
vwl_fr/ri [r] fr |
@@ -164,9 +164,6 @@ phoneme I | |||
vowel starttype #i endtype #i | |||
length 130 | |||
IfNextVowelAppend(;) | |||
IF nextPhW(isVel) THEN | |||
FMT(vowel/ii) | |||
ENDIF | |||
FMT(vowel/ii_2) | |||
endphoneme | |||
@@ -306,7 +303,7 @@ endphoneme | |||
phoneme aI | |||
vowel starttype #a endtype #i | |||
length 230 | |||
length 240 | |||
FMT(vdiph/ai_2) | |||
endphoneme | |||
@@ -1,7 +1,7 @@ | |||
//==================================================== | |||
// French | |||
//==================================================== | |||
// Updated 2010-02-09 Michel Such <[email protected]> | |||
// Updated 2010-02-13 Michel Such <[email protected]> | |||
phoneme #l virtual | |||
// Used for l and l/ | |||
@@ -411,10 +411,10 @@ phoneme A~ | |||
vowel starttype #a endtype #a | |||
length 190 | |||
IF nextPh(r/2) THEN | |||
VowelEnding(vwl_fr/r_a~) | |||
VowelEnding(vwl_fr/r_an) | |||
ENDIF | |||
IF prevPh(#r) THEN | |||
VowelStart(vwl_fr/rA~) | |||
VowelStart(vwl_fr/raa) | |||
ENDIF | |||
FMT(vnasal/aa_n4) |
@@ -259,16 +259,19 @@ phoneme pF | |||
endphoneme | |||
phoneme C2 // for "ig" -> [IC] or [Ig] | |||
phoneme g# // for "ig" -> [IC] or [Ig] | |||
vls pal frc palatal | |||
lengthmod 3 | |||
IF nextPh(isVowel) THEN | |||
IF nextPhW(isVoiced) THEN | |||
ChangePhoneme(g) | |||
ELSE | |||
ChangePhoneme(C) | |||
ENDIF | |||
CALL C | |||
endphoneme | |||
phoneme l/ // used for [l] when not before a vowel | |||
liquid | |||
lengthmod 7 | |||
@@ -317,8 +320,6 @@ phoneme j | |||
endphoneme | |||
// This is actually the ENGLISH "rolling r". For german, we now use * in the dictionary, | |||
// so this phoneme will only be used in english words in german texts. | |||
phoneme r |
@@ -71,10 +71,7 @@ endphoneme | |||
phoneme u | |||
vowel starttype #u endtype #u | |||
length 110 | |||
IF prevPhW(isVel) THEN | |||
ELSE | |||
ChangeIfNotStressed(U) | |||
ENDIF | |||
ChangeIfNotStressed(U) | |||
FMT(vowel/u_6) | |||
endphoneme | |||
@@ -1,10 +1,7 @@ | |||
// 13.02.10 JSD: Changed for eSpeak version 1.43 | |||
// 13.02.10 jonsd: Changed for eSpeak version 1.43 | |||
#include <stdio.h> |
@@ -132,6 +132,7 @@ static keywtab_t k_properties[] = { | |||
{"isAfterStress",0, i_isAfterStress}, | |||
{"isNotVowel", 0, i_isNotVowel}, | |||
{"isFinalVowel", 0, i_isFinalVowel}, | |||
{"isVoiced", 0, i_isVoiced}, // voiced consonant, or vowel | |||
{NULL, 0, 0} | |||
}; |
@@ -1127,8 +1127,8 @@ static char *compile_rule(char *input) | |||
} // end of compile_rule | |||
static int __cdecl string_sorter(char **a, char **b) | |||
{//================================================= | |||
int __cdecl string_sorter(char **a, char **b) | |||
{//=========================================== | |||
char *pa, *pb; | |||
int ix; | |||
@@ -1,5 +1,5 @@ | |||
/*************************************************************************** | |||
* 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 * | |||
@@ -59,7 +59,8 @@ const char *path_data; | |||
extern void TestTest(int control); | |||
extern void CompareLexicon(int); | |||
extern void ConvertToUtf8(); | |||
extern void FormatDictionary(const char *dictname); | |||
extern void DictionaryFormat(const char *dictname); | |||
extern void DictionarySort(const char *dictname); | |||
extern void init_z(); | |||
extern void CompilePhonemeData(void); | |||
@@ -200,6 +201,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame) | |||
EVT_MENU(MENU_COMPILE_DICT, MyFrame::OnTools) | |||
EVT_MENU(MENU_COMPILE_DICT_DEBUG, MyFrame::OnTools) | |||
EVT_MENU(MENU_FORMAT_DICTIONARY, MyFrame::OnTools) | |||
EVT_MENU(MENU_SORT_DICTIONARY, MyFrame::OnTools) | |||
EVT_MENU(MENU_COMPILE_MBROLA, MyFrame::OnTools) | |||
EVT_MENU(MENU_CLOSE_ALL, MyFrame::OnQuit) | |||
EVT_MENU(MENU_QUIT, MyFrame::OnQuit) | |||
@@ -592,7 +594,11 @@ void MyFrame::OnTools(wxCommandEvent& event) | |||
break; | |||
case MENU_FORMAT_DICTIONARY: | |||
FormatDictionary(dictionary_name); | |||
DictionaryFormat(dictionary_name); | |||
break; | |||
case MENU_SORT_DICTIONARY: | |||
DictionarySort(dictionary_name); | |||
break; | |||
case MENU_VOWELCHART1: |
@@ -1,5 +1,5 @@ | |||
/*************************************************************************** | |||
* Copyright (C) 2006 to 2007 by Jonathan Duddington * | |||
* Copyright (C) 2006 to 2010 by Jonathan Duddington * | |||
* email: [email protected] * | |||
* * | |||
* This program is free software; you can redistribute it and/or modify * | |||
@@ -36,6 +36,7 @@ | |||
#include "options.h" | |||
extern char word_phonemes[N_WORD_PHONEMES]; // a word translated into phoneme codes | |||
extern int __cdecl string_sorter(char **a, char **b); | |||
//****************************************************************************************************** | |||
@@ -1312,7 +1313,156 @@ void ConvertToUtf8() | |||
//****************************************************************************************************** | |||
void FormatDictionary(const char *dictname) | |||
#define N_SORT_LIST 10000 | |||
void DictionarySort(const char *dictname) | |||
{//====================================== | |||
// Sort rules in *_rules file between lines which begin with //sort and //endsort | |||
FILE *f_in; | |||
FILE *f_out; | |||
int ix; | |||
char *p; | |||
char *p_end; | |||
char *p_pre; | |||
int sorting; | |||
int sort_ix=0; | |||
int sort_count=0; | |||
int line_len; | |||
int key_len; | |||
char buf[200]; | |||
char key[200]; | |||
char fname_in[200]; | |||
char fname_out[200]; | |||
char *sort_list[N_SORT_LIST]; | |||
wxLogMessage(_T("Sorts the *_rules file, between lines which begin with\n//sort\n and\n//endsort")); | |||
// try with and without '.txt' extension | |||
sprintf(fname_in,"%s%s_rules.txt",path_dsource,dictname); | |||
if((f_in = fopen(fname_in,"r")) == NULL) | |||
{ | |||
sprintf(fname_in,"%s%s_rules",path_dsource,dictname); | |||
if((f_in = fopen(fname_in,"r")) == NULL) | |||
{ | |||
wxLogError(_T("Can't open rules file: ") + wxString(fname_in,wxConvLocal)); | |||
return; | |||
} | |||
} | |||
sprintf(fname_out,"%s%s_rules_sorted",path_dsource,dictname); | |||
if((f_out = fopen(fname_out,"w")) == NULL) | |||
{ | |||
wxLogError(_T("Can't write to file: ") + wxString(fname_out,wxConvLocal)); | |||
fclose(f_in); | |||
return; | |||
} | |||
sorting = 0; | |||
while(fgets(buf, sizeof(buf)-1, f_in) != NULL) | |||
{ | |||
buf[sizeof(buf)-1] = 0; // ensure zero byte terminator | |||
line_len = strlen(buf); | |||
if(memcmp(buf,"//endsort",9)==0) | |||
{ | |||
sort_count++; | |||
sorting = 0; | |||
qsort((void *)sort_list, sort_ix, sizeof(char *), (int(*)(const void *, const void *))string_sorter); | |||
// write out the sorted lines | |||
for(ix=0; ix<sort_ix; ix++) | |||
{ | |||
key_len = strlen(sort_list[ix]); | |||
p = &sort_list[ix][key_len+1]; // the original line is after the key | |||
fprintf(f_out,"%s",p); | |||
free(sort_list[ix]); | |||
} | |||
} | |||
if(sorting == 0) | |||
{ | |||
if(memcmp(buf,"//sort",6)==0) | |||
{ | |||
sorting = 1; | |||
sort_ix = 0; | |||
} | |||
fwrite(buf, line_len, 1, f_out); | |||
continue; | |||
} | |||
p_end = strstr(buf,"//"); | |||
if(p_end == NULL) | |||
p_end = &buf[line_len]; | |||
// add to the list of lines to be sorted | |||
p = buf; | |||
while((*p==' ') || (*p == '\t')) p++; // skip leading spaces | |||
if(*p == '?') | |||
{ | |||
// conditional rule, skip the condition | |||
while(!isspace(*p) && (*p != 0)) p++; | |||
} | |||
// skip any pre -condition | |||
p_pre = p; | |||
while(p < p_end) | |||
{ | |||
if(*p == ')') | |||
{ | |||
p_pre = p+1; | |||
break; | |||
} | |||
p++; | |||
} | |||
p = p_pre; | |||
while((*p==' ') || (*p == '\t')) p++; // skip spaces | |||
ix = 0; | |||
while(!isspace(*p) && (*p != 0)) | |||
{ | |||
key[ix++] = *p++; | |||
} | |||
while((*p==' ') || (*p == '\t')) p++; // skip spaces | |||
if(*p == '(') | |||
{ | |||
// post-condition | |||
p++; // skip '(' | |||
while(!isspace(*p) && (*p != 0) && (p < p_end)) | |||
{ | |||
key[ix++] = *p++; | |||
} | |||
} | |||
key[ix] = 0; | |||
key_len = strlen(key); | |||
p = (char *)malloc(key_len + line_len + 8); | |||
sprintf(p,"%s%6d",key,sort_ix); // include the line number (within the sort section) in case the keys are otherwise equal | |||
strcpy(p, key); | |||
strcpy(&p[key_len+1], buf); | |||
sort_list[sort_ix++] = p; | |||
if(sort_ix >= N_SORT_LIST) | |||
{ | |||
wxLogError(_T("Too many lines to sort, > %d"), N_SORT_LIST); | |||
break; | |||
} | |||
} | |||
fclose(f_in); | |||
fclose(f_out); | |||
if(sorting != 0) | |||
{ | |||
wxLogError(_T("Missing //$endsort")); | |||
} | |||
wxLogStatus(_T("Sorted %d sections. Written to file: ") + wxString(fname_out,wxConvLocal),sort_count); | |||
} // end of DictionarySort | |||
void DictionaryFormat(const char *dictname) | |||
{//======================================== | |||
// Format the *_rules file for the current voice | |||
@@ -1345,10 +1495,10 @@ void FormatDictionary(const char *dictname) | |||
const int tab3 = 28; | |||
// try with and without '.txt' extension | |||
sprintf(fname_in,"%s/%s_rules.txt",path_dsource,dictname); | |||
sprintf(fname_in,"%s%s_rules.txt",path_dsource,dictname); | |||
if((f_in = fopen(fname_in,"r")) == NULL) | |||
{ | |||
sprintf(fname_in,"%s/%s_rules",path_dsource,dictname); | |||
sprintf(fname_in,"%s%s_rules",path_dsource,dictname); | |||
if((f_in = fopen(fname_in,"r")) == NULL) | |||
{ | |||
wxLogError(_T("Can't open rules file: ") + wxString(fname_in,wxConvLocal)); | |||
@@ -1356,7 +1506,7 @@ void FormatDictionary(const char *dictname) | |||
} | |||
} | |||
sprintf(fname_out,"%s/%s_rules_formatted",path_dsource,dictname); | |||
sprintf(fname_out,"%s%s_rules_formatted",path_dsource,dictname); | |||
if((f_out = fopen(fname_out,"w")) == NULL) | |||
{ | |||
wxLogError(_T("Can't write to file: ") + wxString(fname_out,wxConvLocal)); | |||
@@ -1569,8 +1719,13 @@ void FormatDictionary(const char *dictname) | |||
fclose(f_in); | |||
fclose(f_out); | |||
wxLogStatus(_("Written to file: ") + wxString(fname_out,wxConvLocal)); | |||
} // end of FormatDictionary | |||
remove(fname_in); | |||
if(rename(fname_out, fname_in) == 0) | |||
wxLogStatus(_("Written to file: ") + wxString(fname_in,wxConvLocal)); | |||
else | |||
wxLogStatus(_("Failed to rename: ") + wxString(fname_out,wxConvLocal)); | |||
} // end of DictionaryFormat | |||
//****************************************************************************************************** |
@@ -136,6 +136,7 @@ enum { | |||
MENU_COMPILE_DICT, | |||
MENU_COMPILE_DICT_DEBUG, | |||
MENU_FORMAT_DICTIONARY, | |||
MENU_SORT_DICTIONARY, | |||
MENU_COMPILE_MBROLA, | |||
MENU_SPEAK_TRANSLATE, |
@@ -1,5 +1,5 @@ | |||
/*************************************************************************** | |||
* 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 * | |||
@@ -90,7 +90,8 @@ wxMenuBar *MakeMenu(int type) | |||
data_menu->Append(MENU_COMPILE_MBROLA, _("Compile &mbrola phonemes list...")); | |||
data_menu->AppendSeparator(); | |||
data_menu->Append(MENU_FORMAT_DICTIONARY, _("&Layout *_rules file")); | |||
data_menu->Append(MENU_SORT_DICTIONARY, _("&Sort *_rules file")); | |||
// OPTIONS MENU | |||
paths_menu = new wxMenu; | |||
paths_menu->Append(MENU_PATH0, _("Master phonemes file...")); |
@@ -970,10 +970,11 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output | |||
#define SSML_BREAK 13 | |||
#define SSML_IGNORE_TEXT 14 | |||
#define HTML_BREAK 15 | |||
#define SSML_CLOSE 0x10 // for a closing tag, OR this with the tag type | |||
#define HTML_NOSPACE 16 // don't insert a space for this element, so it doesn't break a word | |||
#define SSML_CLOSE 0x20 // for a closing tag, OR this with the tag type | |||
// these tags have no effect if they are self-closing, eg. <voice /> | |||
static char ignore_if_self_closing[] = {0,1,1,1,1,0,0,0,0,1,1,0,1,0,1,0,0}; | |||
static char ignore_if_self_closing[] = {0,1,1,1,1,0,0,0,0,1,1,0,1,0,1,0,0,0,0}; | |||
static MNEM_TAB ssmltags[] = { | |||
@@ -994,6 +995,7 @@ static MNEM_TAB ssmltags[] = { | |||
{"br", HTML_BREAK}, | |||
{"li", HTML_BREAK}, | |||
{"dd", HTML_BREAK}, | |||
{"img", HTML_BREAK}, | |||
{"td", HTML_BREAK}, | |||
{"h1", SSML_PARAGRAPH}, | |||
@@ -1003,6 +1005,12 @@ static MNEM_TAB ssmltags[] = { | |||
{"hr", SSML_PARAGRAPH}, | |||
{"script", SSML_IGNORE_TEXT}, | |||
{"style", SSML_IGNORE_TEXT}, | |||
{"font", HTML_NOSPACE}, | |||
{"b", HTML_NOSPACE}, | |||
{"i", HTML_NOSPACE}, | |||
{"strong", HTML_NOSPACE}, | |||
{"em", HTML_NOSPACE}, | |||
{"code", HTML_NOSPACE}, | |||
{NULL,0}}; | |||
@@ -1637,7 +1645,7 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb | |||
if(tag_name[0] == '/') | |||
{ | |||
// closing tag | |||
if((tag_type = LookupMnem(ssmltags,&tag_name[1])) != 0) | |||
if((tag_type = LookupMnem(ssmltags,&tag_name[1])) != HTML_NOSPACE) | |||
{ | |||
outbuf[outix++] = ' '; | |||
} | |||
@@ -1645,9 +1653,9 @@ static int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int &outix, int n_outb | |||
} | |||
else | |||
{ | |||
if((tag_type = LookupMnem(ssmltags,tag_name)) != 0) | |||
if((tag_type = LookupMnem(ssmltags,tag_name)) != HTML_NOSPACE) | |||
{ | |||
// separate SSML tags from the previous word (but not unknown HMTL tags such as <b> <font> which can occur inside a word) | |||
// separate SSML tags from the previous word (but not HMTL tags such as <b> <font> which can occur inside a word) | |||
outbuf[outix++] = ' '; | |||
} | |||
@@ -35,7 +35,7 @@ | |||
#include "translate.h" | |||
#include "wave.h" | |||
const char *version_string = "1.42.42 12.Feb.10"; | |||
const char *version_string = "1.43 17.Feb.10"; | |||
const int version_phdata = 0x014220; | |||
int option_device_number = -1; | |||
@@ -706,6 +706,9 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, | |||
return(false); | |||
} | |||
break; | |||
case 12: // isVoiced | |||
return((ph->type == phVOWEL) || (ph->phflags & phVOICED)); | |||
} | |||
break; | |||
@@ -343,11 +343,13 @@ typedef struct { | |||
#define i_isAfterStress 0x89 | |||
#define i_isNotVowel 0x8a | |||
#define i_isFinalVowel 0x8b | |||
#define i_isVoiced 0x8c | |||
#define i_isPalatal 0x49 // bit 9 in phflags | |||
#define i_isRhotic 0x56 // bit 22 in phflags | |||
#define i_StressLevel 0x800 | |||
@@ -377,6 +377,7 @@ void VoiceReset(int tone_only) | |||
// default is: pitch 80,118 | |||
voice->pitch_base = 0x47000; | |||
voice->pitch_range = 4104; | |||
// default is: pitch 80,117 | |||
// voice->pitch_base = 0x47000; | |||
// voice->pitch_range = 3996; | |||
@@ -571,8 +572,14 @@ voice_t *LoadVoice(const char *vname, int control) | |||
if(GetFileLength(buf) <= 0) | |||
{ | |||
// look in "test" sub-directory | |||
sprintf(buf,"%stest%c%s",path_voices,PATHSEP,voicename); | |||
// look in "extra" sub-directory | |||
sprintf(buf,"%sextra%c%s",path_voices,PATHSEP,voicename); | |||
if(GetFileLength(buf) <= 0) | |||
{ | |||
// look in "test" sub-directory | |||
sprintf(buf,"%stest%c%s",path_voices,PATHSEP,voicename); | |||
} | |||
} | |||
} | |||
} |