Browse Source

Merge branch 'master' into build

Conflicts:
	src/Makefile.espeakedit
master
Reece Dunn 15 years ago
parent
commit
6798e206c3
92 changed files with 3438 additions and 2435 deletions
  1. 36
    32
      dictsource/da_list
  2. 618
    157
      dictsource/da_rules
  3. 1
    1
      dictsource/dict_phonemes
  4. 6
    0
      dictsource/en_list
  5. 3
    3
      dictsource/fr_list
  6. 1460
    1457
      dictsource/fr_rules
  7. 1
    3
      dictsource/pt_rules
  8. 3
    3
      dictsource/ta_rules
  9. BIN
      phsource/b/br
  10. BIN
      phsource/b/xbr
  11. 38
    34
      phsource/compile_report
  12. BIN
      phsource/d/xdr
  13. 11
    0
      phsource/envelope/i_risefall
  14. 6
    0
      phsource/envelope/i_risefall2
  15. BIN
      phsource/g/gr
  16. BIN
      phsource/g/xgr
  17. 124
    0
      phsource/intonation
  18. BIN
      phsource/klatt/b
  19. BIN
      phsource/klatt/bh
  20. BIN
      phsource/klatt/dz_pzd
  21. BIN
      phsource/klatt/dz_pzd_
  22. BIN
      phsource/klatt/m
  23. BIN
      phsource/klatt/m-syl
  24. BIN
      phsource/klatt/m_
  25. BIN
      phsource/klatt/n
  26. BIN
      phsource/klatt/n-syl
  27. BIN
      phsource/klatt/n^
  28. BIN
      phsource/klatt/n^@
  29. BIN
      phsource/klatt/nn
  30. BIN
      phsource/klatt/nr
  31. BIN
      phsource/klatt/qq
  32. BIN
      phsource/klatt/qqh
  33. BIN
      phsource/klatt/qqh_
  34. BIN
      phsource/klatt/tap2
  35. BIN
      phsource/klatt/v
  36. BIN
      phsource/klatt/v_
  37. BIN
      phsource/klatt/x_tap
  38. BIN
      phsource/klatt/zh
  39. BIN
      phsource/klatt/zh_
  40. BIN
      phsource/l/L2_oL
  41. BIN
      phsource/l/l_front
  42. BIN
      phsource/l/l_front_
  43. 7
    0
      phsource/ph_danish
  44. 2
    2
      phsource/ph_english
  45. 2
    2
      phsource/ph_english_n
  46. 2
    2
      phsource/ph_english_wm
  47. 19
    8
      phsource/ph_french
  48. 16
    0
      phsource/ph_nahuatl
  49. 4
    1
      phsource/ph_tamil
  50. 7
    2
      phsource/phonemes
  51. BIN
      phsource/r/@_
  52. BIN
      phsource/r/V_
  53. BIN
      phsource/r/V_2_
  54. BIN
      phsource/r/aa
  55. BIN
      phsource/r3/r_ru.wav
  56. BIN
      phsource/r3/r_ru2
  57. BIN
      phsource/ufric/l#.wav
  58. BIN
      phsource/ustop/t_short_.wav
  59. BIN
      phsource/vdiph/aau_6
  60. BIN
      phsource/vwl_de/uu_@
  61. BIN
      phsource/vwl_en_us/aU@
  62. BIN
      phsource/vwl_fr/br
  63. BIN
      phsource/vwl_fr/e_2r
  64. BIN
      phsource/vwl_fr/r
  65. BIN
      phsource/vwl_ru/ii-
  66. 2
    2
      src/Makefile
  67. 17
    10
      src/Makefile.espeakedit
  68. 4
    4
      src/compiledata.cpp
  69. 49
    28
      src/espeak.cpp
  70. 0
    2
      src/espeakedit.cpp
  71. 0
    205
      src/mbrolib.h
  72. 578
    0
      src/mbrowrap.cpp
  73. 108
    0
      src/mbrowrap.h
  74. 0
    41
      src/setlengths.cpp
  75. 12
    3
      src/speak.cpp
  76. 49
    10
      src/speak_lib.cpp
  77. 7
    6
      src/speak_lib.h
  78. 0
    1
      src/speech.h
  79. 103
    228
      src/synth_mbrola.cpp
  80. 1
    1
      src/synthdata.cpp
  81. 15
    57
      src/synthesize.cpp
  82. 7
    2
      src/synthesize.h
  83. 0
    21
      src/tr_english.cpp
  84. 0
    1
      src/tr_languages.cpp
  85. 1
    0
      src/translate.h
  86. 3
    0
      src/voice.h
  87. 2
    0
      src/voices.cpp
  88. 95
    93
      src/wave.cpp
  89. 1
    1
      src/wave.h
  90. 5
    4
      src/wave_pulse.cpp
  91. 5
    3
      src/wave_sada.cpp
  92. 8
    5
      src/wavegen.cpp

+ 36
- 32
dictsource/da_list View File

@@ -111,9 +111,9 @@ _19 n'ed@-n
_2X t'y:w
_3X tR'&#Dv@ //PB [tR'ADv@] changed to [tR'&#Dv@]
_4X f'WRV //PB [f'W:*3] changed to [ f'WRV]
_5X hal't*es
_5X h&l't*es // PB [a] changed to [&]
_6X t*'es
_7X halfj'&rs
_7X h&lfj'&rs // PV a changed to &
_8X f'irs
_9X h&lf'Ems // PB a changed to &
_0C h'un*@:D
@@ -163,6 +163,8 @@ en e:n $u
et ed $u
her $u
kun $u
vel $u+
da $u

// conjunctions
og V $u+ $pause // and
@@ -187,6 +189,7 @@ med $u+ // with
af & // PB changed from [a?] to [&] - sound too short in a sentence
// Also removed $u from 'af' and other words. They disappeared.
ad &: // PB added 'ad'
ad &D $atend $sentence // PB "Det må ikke skille os ad."
at &: $u // PB changed from [at] to [&:]
hos // at - PB: removed [$u+]
som sVm // which / that - PB: removed [$u+]
@@ -257,7 +260,7 @@ f Ef
g ge:
h hO:
_i i:
j joD
j jVD // PB changed from [o]
k kO:
l El
m Em
@@ -316,7 +319,6 @@ interface _^_EN
image _^_EN
joke _^_EN
joystick _^_EN
junkie _^_EN
laptop _^_EN
level _^_EN
login _^_EN
@@ -335,13 +337,11 @@ password _^_EN
penthouse _^_EN
pickup _^_EN
pidgin _^_EN
producer _^_EN
ranger _^_EN
receiver _^_EN
research _^_EN
remake _^_EN
roadie _^_EN
roastbeef _^_EN
run _^_EN
scanner _^_EN
science _^_EN
@@ -356,7 +356,6 @@ small _^_EN
snob _^_EN
song _^_EN
source _^_EN
spam _^_EN
spirit _^_EN
squaw _^_EN
sweatshirt _^_EN
@@ -2344,7 +2343,7 @@ dessin des'EN $alt
dioxin $alt
disciplin $alt
doktrin $alt
(drive-in) drajv'in $alt
//(drive-in) drajv'in $alt
dusin $alt
endokrin $alt
endorfin $alt
@@ -2398,7 +2397,6 @@ lupin $alt
magasin $alt
mandarin $alt
mandolin $alt
mannequin m&n@k'EN $alt
margin $alt
marin $alt
marocain mAro'kEN $alt
@@ -5046,6 +5044,7 @@ adstringer $alt
adviser $alt
advoker $alt
afficer $alt
aflever $alt
afmarcher $alt
afrikaniser $alt
agere $alt
@@ -5154,7 +5153,7 @@ banaliser $alt
bandagere $alt
banderolere $alt
barbariser $alt
barber $alt
barbere $alt
barder $alt
barrier $alt
barrikader $alt
@@ -5179,7 +5178,7 @@ bonbonniere bVNbVNj'E:r $alt
boniter $alt
botaniser $alt
braiser $alt
briketter $alt
brikettere $alt
brillere $alt
brochere $alt
brodere $alt
@@ -5188,7 +5187,7 @@ bronzere $alt
brunere $alt
brutaliser $alt
bruyere bryj'E:r $alt
budgetter $alt
budgettere $alt
bugser $alt
bureaukratiser $alt
cadmier $alt
@@ -5274,7 +5273,7 @@ deputer $alt
dereguler $alt
deriver $alt
desarmer $alt
deserter $alt
desertere $alt
designere $alt
desinficer $alt
destiller $alt
@@ -5434,7 +5433,7 @@ farser $alt
fasciner $alt
favoriser $alt
feminiser $alt
ferier $alt
feriere $alt
fermenter $alt
ferniser $alt
fertiliser $alt
@@ -5550,7 +5549,7 @@ halver $alt
harceler $alt
harmoner $alt
harmoniser $alt
harpuner $alt
harpunere $alt
havarer $alt
hektografer $alt
herbariser $alt
@@ -5669,7 +5668,7 @@ intriger $alt
introducer $alt
intuber $alt
invader $alt
invalider $alt
invalidere $alt
inventer $alt
inverter $alt
invester $alt
@@ -5890,7 +5889,6 @@ laminer $alt
lancer $alt
lasere $alt
latiniser $alt
//lavere $alt
lavpasteuriser $alt
legaliser $alt
leger $alt
@@ -6119,7 +6117,7 @@ plakater $alt
planere $alt
plastificer $alt
platiner $alt
pletter $alt
plettere $alt
plisser $alt
plomber $alt
plæder $alt
@@ -6153,7 +6151,7 @@ privileger $alt
prober $alt
problematiser $alt
proceder $alt
producer $alt
producere $alt
profaner $alt
professionaliser $alt
profeter $alt
@@ -6190,7 +6188,7 @@ præferer $alt
præjudicer $alt
prækvalificer $alt
præluder $alt
præmier $alt
præmiere $alt
prænumerer $alt
præparer $alt
præsenter $alt
@@ -6218,7 +6216,7 @@ ramponer $alt
ranger $alt
rappeller $alt
rapportere $alt
raser $alt
rasere $alt
ratificer $alt
ratihaber $alt
rationaliser $alt
@@ -6256,7 +6254,7 @@ reimporter $alt
reinvester $alt
rejicer $alt
rekapituler $alt
reklamer $alt
reklamere $alt
rekognoscer $alt
rekommander $alt
rekompenser $alt
@@ -6418,7 +6416,7 @@ stabiliser $alt
staffer $alt
stagner $alt
standardiser $alt
stationer $alt
stationere $alt
statuere $alt
stenciler $alt
stenografer $alt
@@ -6492,9 +6490,9 @@ temperer $alt
tender $alt
teoretiser $alt
termografer $alt
terrasser $alt
terrassere $alt
terroriser $alt
testamenter $alt
testamentere $alt
testere $alt
tiere $alt
titrer $alt
@@ -6565,7 +6563,7 @@ verbaliser $alt
verificer $alt
verser $alt
versificer $alt
versioner $alt
versionere $alt
vibrer $alt
vidimer $alt
vikarier $alt
@@ -10300,23 +10298,24 @@ også Vs@ // also
idet id'e // in so far as
bleg blaj
blegrød blajrWD
blegrøde blajrWD@
//blege blaj@
blegemiddel bl&#j@mid@l
//blegansigt bl&#jansegt
slags sl'ags // sort, type
tre tr'e // the number 3
barber bab'er // PB barber
barbere bab'eV // PB barbere
barberer bab'eV // PB barberer
//barber bAb'er // PB barber
//barbere bab'eV // PB barbere
//barberer bab'eV // PB barberer
//barberes bab'eVs // PB barberes
barbererne bab'eVn@ // PB barberene
barberenes bab'eVn@s // PB barberenes
//barbererne bab'eVn@ // PB barberene
//barberenes bab'eVn@s // PB barberenes
rejicere rejis'eV // PB should not be pronounced [raje]
rejicerer rejis'eV // PB
rejiceres rejis'eVs // PB
rejicering rejis'eRiN // PB
gele sjel'e // PB gele
géle sjel'e // PB géle
ge sjel'e // PB ge
geleen sjel'e@-n // PB geleen
geleer sjel'e3 // PB geleer
geleens sjel'e@-ns // PB geleens
@@ -10361,6 +10360,7 @@ shampu Sjambo // PB Danish pronunciation - oo has been replaced b
(tour de force) tu:@d@||'fV:s // PB
(al qaeda) al||k'ajda // PB
(force majeure) fVrs||,ma'sjW:r // PB
(diner transportable) din'e|trANspVt'abl@ // PB
(quiche lorraine) kiS||lor'E:n:
(fait accompli) fEtakVmpl'i // PB
wien v'i:n // PB Wien - the town of Vienna
@@ -10406,6 +10406,8 @@ dna $abbrev
sos $abbrev // PB the SOS signal
pharm fA:rm? $hasdot // PB fx cand. pharm.
phil fil/3 $hasdot // PB fx cand. phil.
bh $abbrev
(bh'er) b,e:h'O:V

// Try to catch errors

@@ -10439,6 +10441,7 @@ sig si $capital //PB Sig = si with capital S - Sig det med blom
(vi steg) vi||st'e
(de steg) di||st'e
(alle steg) &l3||st'e
steg sdaj $atend $sentence
steget ste@d
// PB problem with noun "hav" = ocean and verb "hav(e)" = to have [hAu]/[h&v]
(et hav) ed||h'Au // PB "et hav" = an ocean - not "hav en god dag" - have a nice day
@@ -10472,6 +10475,7 @@ legenderne leg'EndVn3s
(så længe) sV||l'EN3
(så må) sV||m'O
(så har) sV||har
så sV $sentence $atstart
(virkede så) v'irkeD@||sV
(kom så) kVm||sV
(koste med) kosd@||mED

+ 618
- 157
dictsource/da_rules
File diff suppressed because it is too large
View File


+ 1
- 1
dictsource/dict_phonemes View File

@@ -62,7 +62,7 @@ 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
s S t T tS v w z


Dictionary hu_dict

+ 6
- 0
dictsource/en_list View File

@@ -792,6 +792,7 @@ chloroplast $1
chocolate tS0kl@t
cholera k0l@r@
cholesterol k@lEst@r0l
chorizo tSOr'i:zoU
chromosome kroUm@soUm
ciao tSaU
cigar sI2gA@
@@ -1003,6 +1004,7 @@ dose doUs
dosage doUsI2dZ
dramatic dr@matIk
drawer drO@
dreamt drEmpt
drier draI3
driest draI|@st
duet dju:'Et
@@ -1221,6 +1223,7 @@ havoc hav@k
hasty heIstI
hatred heItrI2d
hazardous haz3d@s
headfirst $2
heh hEh
hehe hi:h'i:
heifer hEf@
@@ -1492,6 +1495,7 @@ metaphor mEt@fO@
metallic mEt'alIk
miaou mi:'aU
miaow mi:'aU
mic maIk
mica maIk@
microorganism maIkroU'O@g@nIz@m
midday m,Idd'eI
@@ -1759,6 +1763,7 @@ preset pri:sEt
prestige prEst'i:Z
?3 pretense pri:tEns
pretext pri:tEkst
pretrial pri:tr'aI|@L
pretty prItI
privation praIv'eIS@n
privilege prIvI2lI2dZ
@@ -3096,6 +3101,7 @@ thy ,DaI
thine ,DaIn

me ,mi: $only
me mi: $atstart $atend
him ,hIm $only
us ,Vz $only
us $abbrev $allcaps

+ 3
- 3
dictsource/fr_list View File

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

// 2006-11-18 Gilles Casse <[email protected]>
//
// Updated 2010-06-11 Michel Such <[email protected]>
// Updated 2010-06-15 Michel Such <[email protected]>
//
// * Numbers, a few abbreviations and exceptions.
//
@@ -778,7 +778,7 @@ zut zyt
exocet E2gzosEt
fret fr'Et
budget bydZE2
hamlet hamlEt
hamlet _|amlEt
knesset knesEt
lazaret lazarE2
margaret margarEt
@@ -884,7 +884,7 @@ contentions kO~tA~tjO~z2
dations datjO~z2
désertions dezErtjO~z2 $verb
exploitions EksplwatjO~z2
heurtions hYrtjO~z2
heurtions _|WrtjO~z2
partions partjO~z2
rations ratjO~z2 $verb
tentions tA~tjO~z2

+ 1460
- 1457
dictsource/fr_rules
File diff suppressed because it is too large
View File


+ 1
- 3
dictsource/pt_rules View File

@@ -746,9 +746,7 @@
r) u (_A u
u (A_ 'u

ui 'uI
ui (_ uI
ui (s 'uI
ui uI
u (iu w
u (iCK u
uy uI

+ 3
- 3
dictsource/ta_rules View File

@@ -393,7 +393,7 @@
_) ட (வல t.V
_) ட (வர t.V
_) ட (ேப t.
_) ட (ாக்ஸி t.
_) டாக (்ஸி t.a:k

.group ண
ண n.V
@@ -597,6 +597,7 @@
_) த (ொம் d
_) த (ோசை d
_) த (ோஷ d
_) த (ுபாய d
//endsort

//sort
@@ -671,6 +672,7 @@ _பார்வ) த (ி t
ச) த (்ரு t
த) த (்ரூப t
பா) த (்ரூம t
_ப) த (ஞ்சலி tV
//endsort


@@ -989,13 +991,11 @@ _முகத்தின்_) ப (ாவ b
சிறு) ப (ிள்ளை p
ஆண்) ப (ிள்ளை p
பெண்) ப (ிள்ளை p
பூம்) ப (ுகார p
ம்) ப (ுரா b
இன்) ப (ுற b
_துன்) ப (ுற b
ப (ுறK p
மண்) ப (ுழு p
பூம்) ப (ுஹார p
ம்) ப (ூர b
ராம்) ப (ூர p
அ) ப (ூர்வ b

BIN
phsource/b/br View File


BIN
phsource/b/xbr View File


+ 38
- 34
phsource/compile_report View File

@@ -53,7 +53,7 @@ consonants 9 115
id 15 125
sq 33 126
hy 23 117
da 23 119
da 24 120
rw 15 130
ml 13 150
ne 18 156
@@ -82,6 +82,7 @@ b/bu [b] base
b/xb [b] base
[b] fr
[bh] hi
b/xbr [b] fr
d/d [d] base
[d[] base
[d] base2
@@ -139,6 +140,7 @@ d/xd [d] base
[d] sq
d/xd3 [dh] hi
d/xd_pzd [d;] pl
d/xdr [d] fr
d/xdz [dz] consonants
d/x_tap [t#] en
[*] pt
@@ -220,6 +222,7 @@ g/xg [g] base
[g] cy
[g] fr
[g] es
g/xgr [g] fr
h/h_ [h] base
[h] fi
[<h>] la
@@ -338,7 +341,7 @@ l/l_ [l/] base
l/l_@ [l/3] base
[l/] fr
l/l@ [l#] base
[ߵ ] base
[߸ ] base
[l] fr
[l/2] fr
l/L1_aL [l/] base
@@ -364,13 +367,13 @@ l/L2_uL [l/2] base
l/l_3 [l/] de
l/l_4 [ll] sq
l/la [l#] base
[ߵ ] base
[߸ ] base
[l] fr
[l/2] fr
l/l_a [l/3] base
[l/] fr
l/le [l#] base
[ߵ ] base
[߸ ] base
[l] fr
[l/2] fr
l/l_e [l/3] base
@@ -380,7 +383,7 @@ l/L_eL_af [&] af
l/l_front [L] sq
l/l_front_ [l/4] sq
l/li [l#] base
[ߵ ] base
[߸ ] base
[l] fr
[l/2] fr
[l] zh
@@ -392,14 +395,14 @@ ll/_ll [L] bg
l/l_long [l] base
[l] fr
l/lo [l#] base
[ߵ ] base
[߸ ] base
[l] fr
[l/2] fr
l/l_o [l/3] base
[l/] fr
l^/l_rfx [l.] base
l/lu [l#] base
[ߵ ] base
[߸ ] base
[l] fr
[l/2] fr
l/l_u [l/3] base
@@ -617,8 +620,8 @@ ufric/f [f] base
ufric/f_ [f] base
[f] fr
[f] pl
ufric/l# [l#] is
ufric/ll [l#] base
ufric/l# [l#] base
[l#] is
ufric/s [s] base
[s] fr
[z2] fr
@@ -923,6 +926,7 @@ vdiph/ai [aI] base2
[a:I] vi
[aI] id
[aI] hy
[aI] da
vdiph/ai_2 [aI] en
[aI] cy
[aY] cy
@@ -1939,51 +1943,51 @@ vwl_en_us/oor [0] en-us
vwl_en_us/or [o@] en-us
[O:] en-sc
vwl_en_us/ur [U@] en-us
vwl_fr/@2r [ߵ ] fr
vwl_fr/a2r [ߵ ] fr
vwl_fr/aa2r [ߵ ] fr
vwl_fr/@2r [߸ ] fr
vwl_fr/a2r [߸ ] fr
vwl_fr/aa2r [߸ ] fr
vwl_fr/br [r/2] fr
vwl_fr/e2r [ߵ ] fr
vwl_fr/e_2r [ߵ ] fr
vwl_fr/ee2r [ߵ ] fr
vwl_fr/i2r [ߵ ] fr
vwl_fr/e2r [߸ ] fr
vwl_fr/e_2r [߸ ] fr
vwl_fr/ee2r [߸ ] fr
vwl_fr/i2r [߸ ] fr
vwl_fr/j [j/] fr
vwl_fr/o2r [ߵ ] fr
vwl_fr/oo2r [ߵ ] fr
vwl_fr/o2r [߸ ] fr
vwl_fr/oo2r [߸ ] fr
vwl_fr/r [r] fr
[r/2] fr
vwl_fr/r_ [r/] fr
vwl_fr/r_@ [r/] fr
vwl_fr/r@ [ߵ ] fr
vwl_fr/r@ [߸ ] fr
vwl_fr/@R [x] pt-pt
vwl_fr/r@2 [ߵ ] fr
vwl_fr/r@2 [߸ ] fr
vwl_fr/@R2 [R] fr-ca
vwl_fr/ra [ߵ ] fr
vwl_fr/ra [߸ ] fr
vwl_fr/r_a [r/] fr
vwl_fr/raa [ߵ ] fr
vwl_fr/re [ߵ ] fr
vwl_fr/raa [߸ ] fr
vwl_fr/re [߸ ] fr
vwl_fr/r_e [r/] fr
vwl_fr/re2 [ߵ ] fr
vwl_fr/ree [ߵ ] fr
vwl_fr/ri [ߵ ] fr
vwl_fr/re2 [߸ ] fr
vwl_fr/ree [߸ ] fr
vwl_fr/ri [߸ ] fr
vwl_fr/r_i [r/] fr
vwl_fr/rj [ߵ ] fr
vwl_fr/rj [߸ ] fr
vwl_fr/r_n [r/] fr
vwl_fr/ro [ߵ ] fr
vwl_fr/ro [߸ ] fr
vwl_fr/r_o [r/] fr
vwl_fr/roo [ߵ ] fr
vwl_fr/roo [߸ ] fr
vwl_fr/rr [r/] fr
vwl_fr/ru [ߵ ] fr
vwl_fr/ru [߸ ] fr
vwl_fr/r_u [r/] fr
vwl_fr/rw [ߵ ] fr
vwl_fr/ry [ߵ ] fr
vwl_fr/rw [߸ ] fr
vwl_fr/ry [߸ ] fr
vwl_fr/r_y [r/] fr
vwl_fr/tr [r/2] fr
vwl_fr/trr [r/] fr
vwl_fr/u2r [ߵ ] fr
vwl_fr/u2r [߸ ] fr
vwl_fr/wa [w] fr
[w/] fr
vwl_fr/y2r [ߵ ] fr
vwl_fr/y2r [߸ ] fr
vwl_hi/l-voc [l-] base
[l-] sk
[l:] sk

BIN
phsource/d/xdr View File


+ 11
- 0
phsource/envelope/i_risefall View File

@@ -0,0 +1,11 @@
ENVELOPE
0 60
5 63
22 92
31 100
41 95
85 12
90 5
100 0



+ 6
- 0
phsource/envelope/i_risefall2 View File

@@ -0,0 +1,6 @@
ENVELOPE
0 0
45 95
100 0



BIN
phsource/g/gr View File


BIN
phsource/g/xgr View File


+ 124
- 0
phsource/intonation View File

@@ -0,0 +1,124 @@
tune s1
prehead 46 57
headenv fall 16
head 4 80 50 -8 -5
headextend 0 63 38 13 0
nucleus0 fall 64 8
nucleus fall 70 18 24 12
endtune

tune c1
prehead 46 57
headenv fall 16
head 4 80 46 -8 -5
headextend 0 63 38 13 0
nucleus0 fall-rise 80 18
nucleus fall-rise2 78 22 34 52
endtune

tune q1
prehead 46 57
headenv fall 16
head 4 75 43 -7 0
headextend 25 63 38 13 0
nucleus0 fall-rise 88 22
nucleus fall-rise2 82 22 34 66
endtune

tune e1
prehead 46 57
headenv fall 16
head 3 90 50 -9 0
headextend 16 82 50 32 16
nucleus0 fall 92 8
nucleus fall 92 80 76 8
endtune


// PB Tunes for the Danish intonation
// full-stop "." - punktum
tune s2
prehead 46 57
headenv fall 16
head 4 65 60 -8 -5
headextend 0 53 38 13 0
nucleus0 fall 44 28
nucleus fall 50 42 34 28 // sidste ord før punktu

onset 75 -5 -5
endtune

// comma "," - komma
tune c2
prehead 46 57
headenv fall 16
head 4 65 50 -8 -5
headextend 0 63 38 13 0
nucleus0 rise 60 42
nucleus rise 55 42 34 52 // sidste tal: slutniveau
endtune

// question mark "?" - spørgsmålste

tune q2
prehead 40 75
headenv fall 16
head 4 75 43 -7 0 //head 4 35 43 -7 0
headextend 25 63 38 13 0
nucleus0 rise 70 50 // første tal: slutniveaue

nucleus rise 35 45 60 70 // sidste tal: slutniveau
endtune

// exclamation mark "!" - udråbsteg

tune e2
prehead 46 57
headenv fall 16
head 3 90 50 -9 0
headextend 16 82 50 32 16
nucleus0 fall 92 8
nucleus fall 92 80 76 8
endtune



// Tunes for the French intonation
// full-stop "." - point
tune s3
prehead 46 57
headenv fall 16
head 4 80 50 -8 -5
headextend 0 63 38 13 0
nucleus0 fall 64 8
nucleus fall 70 18 24 12
endtune

// comma "," - virgule
tune c3
prehead 46 57
headenv fall 16
head 4 80 30 -5 -15
headextend 25 63 38 13 0
nucleus0 fall-rise 75 40
endtune

// question mark "?" - point d'interrogation
tune q3
prehead 46 57
headenv fall 16
head 4 75 43 -7 0
headextend 25 63 38 13 0
nucleus0 fall-rise 88 22
nucleus fall-rise2 82 22 34 66
endtune

// exclamation mark "!" - point d'exclamation
tune e3
prehead 46 57
headenv fall 16
head 3 90 50 -9 0
headextend 16 82 50 32 16
nucleus0 fall 92 8
nucleus fall 92 80 76 8
endtune

BIN
phsource/klatt/b View File


BIN
phsource/klatt/bh View File


BIN
phsource/klatt/dz_pzd View File


BIN
phsource/klatt/dz_pzd_ View File


BIN
phsource/klatt/m View File


BIN
phsource/klatt/m-syl View File


BIN
phsource/klatt/m_ View File


BIN
phsource/klatt/n View File


BIN
phsource/klatt/n-syl View File


BIN
phsource/klatt/n^ View File


BIN
phsource/klatt/n^@ View File


BIN
phsource/klatt/nn View File


BIN
phsource/klatt/nr View File


BIN
phsource/klatt/qq View File


BIN
phsource/klatt/qqh View File


BIN
phsource/klatt/qqh_ View File


BIN
phsource/klatt/tap2 View File


BIN
phsource/klatt/v View File


BIN
phsource/klatt/v_ View File


BIN
phsource/klatt/x_tap View File


BIN
phsource/klatt/zh View File


BIN
phsource/klatt/zh_ View File


BIN
phsource/l/L2_oL View File


BIN
phsource/l/l_front View File


BIN
phsource/l/l_front_ View File


+ 7
- 0
phsource/ph_danish View File

@@ -114,6 +114,13 @@ phoneme W#
FMT(vowel/V)
endphoneme

phoneme aI
vowel starttype #a endtype #i
length 250
FMT(vdiph/ai)
endphoneme


// CONSONANTS

// PB added l/3

+ 2
- 2
phsource/ph_english View File

@@ -383,7 +383,7 @@ endphoneme

phoneme aI@
vowel starttype #a endtype #@
length 270
length 280
IfNextVowelAppend(r-)
FMT(vwl_en/aI@)
endphoneme
@@ -391,7 +391,7 @@ endphoneme

phoneme aU@
vowel starttype #a endtype #@
length 270
length 280
IfNextVowelAppend(r-)
FMT(vwl_en/aU@)
endphoneme

+ 2
- 2
phsource/ph_english_n View File

@@ -239,7 +239,7 @@ endphoneme

phoneme aI@
vowel starttype #a endtype #@
length 270
length 280
IfNextVowelAppend(r-)
FMT(vwl_en/aI@)
endphoneme
@@ -247,7 +247,7 @@ endphoneme

phoneme aU@
vowel starttype #a endtype #@
length 270
length 280
IfNextVowelAppend(r-)
FMT(vwl_en/aU@)
endphoneme

+ 2
- 2
phsource/ph_english_wm View File

@@ -222,7 +222,7 @@ endphoneme

phoneme aI@
vowel starttype #a endtype #@
length 270
length 280
IfNextVowelAppend(r-)
FMT(vwl_en/ooi@)
endphoneme
@@ -230,7 +230,7 @@ endphoneme

phoneme aU@
vowel starttype #a endtype #@
length 270
length 280
IfNextVowelAppend(r-)
FMT(vwl_en/aU@)
endphoneme

+ 19
- 8
phsource/ph_french View File

@@ -1,7 +1,7 @@
//====================================================
// French
//====================================================
// Updated 2010-06-12 Michel Such <[email protected]>
// Updated 2010-06-16 Michel Such <[email protected]>

phoneme #l virtual
// Used for l and l/
@@ -80,8 +80,7 @@ phoneme r
vcd uvl frc nopause
rhotic
starttype #r endtype #r
Vowelin f1=1 f2=1600 -500 500 f3=-200 100 len=65
Vowelout f1=1 f2=1200 -400 800 f3=200 100 len=60
Vowelin f1=0 f2=1500 -400 400 f3=-400 80
lengthmod 7

IF nextPh(isNotVowel) THEN
@@ -148,7 +147,7 @@ endphoneme
phoneme r/2
liquid rhotic uvl nopause
starttype #r endtype #r
Vowelin f1=1 f2=1600 -500 500 f3=-200 100 len=65 amp=8
Vowelin f1=0 f2=1500 -400 400 f3=-400 80

CALL post_r
IF prevPhW(f) OR prevPhW(k) OR prevPhW(p) OR prevPhW(s) OR prevPhW(t) OR prevPhW(S) THEN
@@ -163,7 +162,7 @@ endphoneme


phoneme l
liquid nopause
liquid
starttype #l endtype #l
lengthmod 7

@@ -639,7 +638,11 @@ phoneme b
ENDIF

IF PreVoicing THEN
FMT(b/xb)
IF nextPhW(#r) THEN
FMT(b/xbr)
ELSE
FMT(b/xb)
ENDIF
ENDIF

IF nextPh(isPause2) OR nextPh(l) THEN
@@ -663,7 +666,11 @@ phoneme d
Vowelout f1=2 f2=1700 -300 300 f3=-100 80

IF PreVoicing THEN
FMT(d/xd)
IF nextPhW(#r) THEN
FMT(d/xdr)
ELSE
FMT(d/xd)
ENDIF
ENDIF

IF nextPh(isPause2) THEN
@@ -699,7 +706,11 @@ phoneme g
Vowelout f1=1 f2=2300 250 300 f3=-300 80 brk

IF PreVoicing THEN
FMT(g/xg)
IF nextPhW(#r) THEN
FMT(g/xgr)
ELSE
FMT(g/xg)
ENDIF
ENDIF

IF nextPh(isPause2) THEN

+ 16
- 0
phsource/ph_nahuatl View File

@@ -0,0 +1,16 @@
//====================================================
// Nahuatl (classical)
//====================================================
phoneme : // lengthens the previous vowel by 'length'
virtual
length 300
endphoneme
phoneme e
vowel starttype #e endtype #e
length 170
FMT(vowel/e_mid2)
endphoneme

+ 4
- 1
phsource/ph_tamil View File

@@ -80,7 +80,10 @@ endphoneme
phoneme u
vowel starttype #u endtype #u
length 110
ChangeIfNotStressed(U)
IF prevPhW(isVel) THEN
ELSE
ChangeIfNotStressed(U)
ENDIF
FMT(vowel/u_6)
endphoneme


+ 7
- 2
phsource/phonemes View File

@@ -1487,7 +1487,7 @@ phoneme l# // Lateral fricative (eg. Welsh "ll")
VowelEnding(l/xl, -40)
ENDIF

WAV(ufric/ll, 60)
WAV(ufric/l#, 60)
endphoneme


@@ -1720,6 +1720,12 @@ phonemetable da base
include ph_danish




// The following lines are experimental, for future additions.
// These langauges are not in a usable state.
// These lines can be deleted.

phonemetable rw base2
include ph_kinyarwanda

@@ -1738,7 +1744,6 @@ include ph_nepali
//phonemetable mr hi
//include ph_marathi


//phonemetable eu base2
//include ph_basque


BIN
phsource/r/@_ View File


BIN
phsource/r/V_ View File


BIN
phsource/r/V_2_ View File


BIN
phsource/r/aa View File


BIN
phsource/r3/r_ru.wav View File


BIN
phsource/r3/r_ru2 View File


BIN
phsource/ufric/l#.wav View File


BIN
phsource/ustop/t_short_.wav View File


BIN
phsource/vdiph/aau_6 View File


BIN
phsource/vwl_de/uu_@ View File


BIN
phsource/vwl_en_us/aU@ View File


BIN
phsource/vwl_fr/br View File


BIN
phsource/vwl_fr/e_2r View File


BIN
phsource/vwl_fr/r View File


BIN
phsource/vwl_ru/ii- View File


+ 2
- 2
src/Makefile View File

@@ -49,12 +49,12 @@ endif

speak_SOURCES = speak.cpp compiledict.cpp dictionary.cpp intonation.cpp \
readclause.cpp setlengths.cpp numbers.cpp synth_mbrola.cpp \
synthdata.cpp synthesize.cpp translate.cpp \
synthdata.cpp synthesize.cpp translate.cpp mbrowrap.cpp \
tr_languages.cpp voices.cpp wavegen.cpp phonemelist.cpp klatt.cpp

libespeak_SOURCES = speak_lib.cpp compiledict.cpp dictionary.cpp intonation.cpp \
readclause.cpp setlengths.cpp numbers.cpp synth_mbrola.cpp \
synthdata.cpp synthesize.cpp translate.cpp \
synthdata.cpp synthesize.cpp translate.cpp mbrowrap.cpp \
tr_languages.cpp voices.cpp wavegen.cpp phonemelist.cpp \
espeak_command.cpp event.cpp fifo.cpp $(WAVE) debug.cpp klatt.cpp


+ 17
- 10
src/Makefile.espeakedit View File

@@ -1,20 +1,27 @@
SRCS=\
compiledata.cpp compiledict.cpp debug.cpp dictionary.cpp espeak_command.cpp espeakedit.cpp \
event.cpp extras.cpp fifo.cpp formantdlg.cpp intonation.cpp klatt.cpp menus.cpp numbers.cpp \
options.cpp phonemelist.cpp prosodydisplay.cpp readclause.cpp setlengths.cpp speak_lib.cpp \
spect.cpp spectdisplay.cpp spectseq.cpp synthdata.cpp synthesize.cpp synth_mbrola.cpp \
translate.cpp transldlg.cpp tr_languages.cpp voicedlg.cpp voices.cpp vowelchart.cpp wave.cpp \
wavegen.cpp
# Makefile for 'espeakedit' program

SRCS= compiledata.cpp compiledict.cpp debug.cpp dictionary.cpp espeak_command.cpp \
espeakedit.cpp event.cpp extras.cpp fifo.cpp formantdlg.cpp intonation.cpp \
klatt.cpp mbrowrap.cpp menus.cpp numbers.cpp options.cpp phonemelist.cpp \
prosodydisplay.cpp readclause.cpp setlengths.cpp speak_lib.cpp spect.cpp \
spectdisplay.cpp spectseq.cpp synthdata.cpp synthesize.cpp synth_mbrola.cpp \
translate.cpp transldlg.cpp tr_languages.cpp voicedlg.cpp voices.cpp vowelchart.cpp \
wave.cpp wavegen.cpp

OBJS=$(patsubst %.cpp,%.o,$(SRCS))

WX_LIBS = -pthread -lwx_gtk2u_xrc-2.6 -lwx_gtk2u_qa-2.6 -lwx_gtk2u_html-2.6 -lwx_gtk2u_adv-2.6 -lwx_gtk2u_core-2.6 -lwx_baseu_xml-2.6 -lwx_baseu_net-2.6 -lwx_baseu-2.6
WX_LIBS = -pthread -lwx_gtk2u_xrc-2.6 -lwx_gtk2u_qa-2.6 -lwx_gtk2u_html-2.6 \
-lwx_gtk2u_adv-2.6 -lwx_gtk2u_core-2.6 -lwx_baseu_xml-2.6 -lwx_baseu_net-2.6 -lwx_baseu-2.6

LIBS=-lstdc++ -lportaudio

CPPFLAGS = -Wall -g -fexceptions -I/usr/lib/wx/include/gtk2-unicode-release-2.6 -I/usr/include/wx-2.6 -DGTK_NO_CHECK_CASTS -D__WXGTK__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D_LARGEFILE_SOURCE=1 -DNO_GCC_PRAGMA -D_ESPEAKEDIT
CPPFLAGS = -Wall -g -fexceptions -I/usr/lib/wx/include/gtk2-unicode-release-2.6
-I/usr/include/wx-2.6 \
-DGTK_NO_CHECK_CASTS -D__WXGTK__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES
-D_LARGEFILE_SOURCE=1 -DNO_GCC_PRAGMA -D_ESPEAKEDIT

CXXFLAGS = -O2 -g0 -Wall -g -fexceptions -I/usr/lib/wx/include/gtk2-unicode-release-2.6 -I/usr/include/wx-2.6 -DGTK_NO_CHECK_CASTS -D__WXGTK__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D_LARGEFILE_SOURCE=1 -DNO_GCC_PRAGMA -D_ESPEAKEDIT
CXXFLAGS = -O2 -g0 -Wall -g -fexceptions -I/usr/lib/wx/include/gtk2-unicode-release-2.6 -I/usr/include/wx-2.6 \
-DGTK_NO_CHECK_CASTS -D__WXGTK__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D_LARGEFILE_SOURCE=1 -DNO_GCC_PRAGMA -D_ESPEAKEDIT

all: espeakedit


+ 4
- 4
src/compiledata.cpp View File

@@ -1744,12 +1744,12 @@ static int LoadWavefile(FILE *f, const char *fname)
sr2 = Read4Bytes(f);
fseek(f,40,SEEK_SET);

if((sr1 != samplerate) || (sr2 != sr1*2))
if((sr1 != samplerate_native) || (sr2 != sr1*2))
{
#ifdef PLATFORM_WINDOWS
if(sr1 != samplerate)
if(sr1 != samplerate_native)
{
fprintf(f_errors,"Wrong samplerate %d, wants %d\n",sr1,samplerate);
fprintf(f_errors,"Wrong samplerate %d, wants %d\n",sr1,samplerate_native);
error("Wrong samplerate: %s",fname);
}
if(sr2 != sr1*2)
@@ -1764,7 +1764,7 @@ static int LoadWavefile(FILE *f, const char *fname)
if((fd_temp = mkstemp(fname_temp)) >= 0)
{
close(fd_temp);
sprintf(command,"sox \"%s%s.wav\" -r %d -c 1 -w %s polyphase\n",path_source,fname,samplerate,fname_temp);
sprintf(command,"sox \"%s%s.wav\" -r %d -c 1 -w %s polyphase\n",path_source,fname,samplerate_native,fname_temp);
if(system(command) < 0)
{
error("Failed to resample: %s",command);

+ 49
- 28
src/espeak.cpp View File

@@ -66,8 +66,10 @@ static const char *help_text =
"\t directory. <voice name> specifies the language\n"
"--path=\"<path>\"\n"
"\t Specifies the directory containing the espeak-data directory\n"
"--pho\n"
"\t Write mbrola phoneme data (.pho) to stdout, or to the file in --phonout\n"
"--phonout=\"<filename>\"\n"
"\t Write output from -x -X commands, and mbrola phoneme data, to this file\n"
"\t Write phoneme output from -x -X and --pho to this file\n"
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
@@ -87,6 +89,7 @@ int samplerate;
int quiet = 0;
unsigned int samples_total = 0;
unsigned int samples_split = 0;
unsigned int samples_split_seconds = 0;
unsigned int wavefile_count = 0;

FILE *f_wavfile = NULL;
@@ -218,15 +221,18 @@ int OpenWavFile(char *path, int rate)
else
f_wavfile = fopen(path,"wb");

if(f_wavfile != NULL)
if(f_wavfile == NULL)
{
fwrite(wave_hdr,1,24,f_wavfile);
Write4Bytes(f_wavfile,rate);
Write4Bytes(f_wavfile,rate * 2);
fwrite(&wave_hdr[32],1,12,f_wavfile);
return(0);
fprintf(stderr,"Can't write to: '%s'\n",path);
return(1);
}
return(1);


fwrite(wave_hdr,1,24,f_wavfile);
Write4Bytes(f_wavfile,rate);
Write4Bytes(f_wavfile,rate * 2);
fwrite(&wave_hdr[32],1,12,f_wavfile);
return(0);
} // end of OpenWavFile


@@ -266,25 +272,40 @@ static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events)
return(0);
}

if(samples_split > 0)
while(events->type != 0)
{
// start a new WAV file when this limit is reached, at the next sentence boundary
while(events->type != 0)
if(events->type == espeakEVENT_SAMPLERATE)
{
if((events->type == espeakEVENT_SENTENCE) && (samples_total > samples_split))
samplerate = events->id.number;
samples_split = samples_split_seconds * samplerate;
}
else
if(events->type == espeakEVENT_SENTENCE)
{
// start a new WAV file when the limit is reached, at this sentence boundary
if((samples_split > 0) && (samples_total > samples_split))
{
CloseWavFile();
samples_total = 0;
wavefile_count++;
}
events++;
}
events++;
}

if(f_wavfile == NULL)
{
sprintf(fname,"%s_%.2d%s",wavefile,++wavefile_count,filetype);
if(OpenWavFile(fname, samplerate) != 0)
return(1);
if(samples_split > 0)
{
sprintf(fname,"%s_%.2d%s",wavefile,wavefile_count+1,filetype);
if(OpenWavFile(fname, samplerate) != 0)
return(1);
}
else
{
if(OpenWavFile(wavefile, samplerate) != 0)
return(1);
}
}

if(numsamples > 0)
@@ -332,7 +353,8 @@ int main (int argc, char **argv)
{"stdout", no_argument, 0, 0x105},
{"split", optional_argument, 0, 0x106},
{"path", required_argument, 0, 0x107},
{"phonout", required_argument, 0, 0x108},
{"phonout", required_argument, 0, 0x108},
{"pho", no_argument, 0, 0x109},
{0, 0, 0, 0}
};

@@ -360,7 +382,8 @@ int main (int argc, char **argv)
int wordgap = -1;
int option_capitals = -1;
int option_punctuation = -1;
int option_phonemes = -1;
int option_phonemes = 0;
int option_mbrola_phonemes = 0;
int option_linelength = 0;
int option_waveout = 0;

@@ -550,9 +573,9 @@ int main (int argc, char **argv)

case 0x106: // -- split
if(optarg2 == NULL)
samples_split = 30; // default 30 minutes
samples_split = 30 * 60; // default 30 minutes
else
samples_split = atoi(optarg2);
samples_split = atoi(optarg2) * 60;
break;

case 0x107: // --path
@@ -566,6 +589,10 @@ int main (int argc, char **argv)
}
break;

case 0x109: // --pho
option_mbrola_phonemes = 8;
break;

default:
exit(0);
}
@@ -576,7 +603,7 @@ int main (int argc, char **argv)
{
// writing to a file (or no output), we can use synchronous mode
samplerate = espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,0,data_path,0);
samples_split = (samplerate * samples_split) * 60;
samples_split = samplerate * samples_split_seconds;

espeak_SetSynthCallback(SynthCallback);
if(samples_split)
@@ -589,12 +616,6 @@ int main (int argc, char **argv)
*extn = 0;
}
}
else
if(option_waveout)
{
if(OpenWavFile(wavefile,samplerate) != 0)
exit(4);
}
}
else
{
@@ -641,7 +662,7 @@ int main (int argc, char **argv)
espeak_SetParameter(espeakLINELENGTH,option_linelength,0);
if(option_punctuation == 2)
espeak_SetPunctuationList(option_punctlist);
espeak_SetPhonemeTrace(option_phonemes,f_phonemes_out);
espeak_SetPhonemeTrace(option_phonemes | option_mbrola_phonemes,f_phonemes_out);

if(filename[0]==0)
{

+ 0
- 2
src/espeakedit.cpp View File

@@ -129,8 +129,6 @@ char param[80];

if(argc > 1)
{
extern void VoiceReset(int control);

p = argv[1];
j = 0;
while((param[j] = p[j]) != 0) j++;

+ 0
- 205
src/mbrolib.h View File

@@ -1,205 +0,0 @@
#ifndef MBROLIB_H
#define MBROLIB_H

/*
* mbrolib: mbrola wrapper.
*
* Copyright (C) 2007 Gilles Casse <[email protected]>
*
* This 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 3 of the License, or (at your option) any later version.
*
* This 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 this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

#ifdef __cplusplus
extern "C" {
#endif

/* < types */

/** Parameters */

typedef struct {
int ignore_error; /* 1=Ignore any fatal error or unknown diphone */
char comment_char; /* Comment character */
float volume_ratio; /* Volume ratio */
float frequency_ratio; /* Applied to pitch points */
float time_ratio; /* Applied to phone durations */
} mbrolib_parameter;


/** Returned errors */

typedef enum {
MBROLIB_OK=0,
MBROLIB_DATABASE_NOT_INSTALLED,
MBROLIB_INVAL,
MBROLIB_OUT_OF_MEMORY,
MBROLIB_OUT_OF_RANGE,
MBROLIB_READ_ERROR,
MBROLIB_WRITE_ERROR
} MBROLIB_ERROR;



/** Gender */

typedef enum {
MBROLIB_FEMALE,
MBROLIB_MALE
} MBROLIB_GENDER;



/** Voice descriptor */

typedef struct {
char *name; /* name (for example: "en1") */
char *filename; /* database pathname (for example: "/usr/share/mbrola/voices/en1) */
int rate; /* database sample rate */
MBROLIB_GENDER gender;
const char *language; /* Language and optional dialect qualifier in ascii (e.g. en, fr_ca). */
} mbrolib_voice;

/* > */


/** Initialization, returns a new handle.
First function.

@param the_sample_rate: output rate in Hz (for example 22050). If 0, keep the original database rate.

@return handle (or NULL if error).
*/
void* mbrolib_init( int sample_rate);
typedef void* (t_mbrolib_init)(int);


/** Returns the list of the installed mbrola databases.
The databases are searched according to the MBROLA_PATH environment variable if set,
or under a default path otherwise (see MBROLA_PATH in mbrolib.c).
An array of voices is returned. The last item is set to NULL.
The caller must not free the returned items or the array.

@param the_handle previously given by mbrolib_init.

@return An array of voices.
*/
const mbrolib_voice ** mbrolib_list_voices( void* the_handle);
typedef const mbrolib_voice ** (t_mbrolib_list_voices)(void*);



/** Set voice

@param the_handle.

@param the_database (for example, "en1").

@return error code (MBROLIB_OK, MBROLIB_DATABASE_NOT_INSTALLED, MBROLIB_INVAL).

*/
MBROLIB_ERROR mbrolib_set_voice( void* the_handle, const char* the_name);
typedef MBROLIB_ERROR (t_mbrolib_set_voice)( void*, const char*);



/** Get the current database parameters.
The caller supplies a pointer to an already allocated structure.

@param the_handle previously given by mbrolib_init.

@param the_parameters: pointer to the structure.

@return error code (MBROLIB_OK, MBROLIB_INVAL).
*/
MBROLIB_ERROR mbrolib_get_parameter(void* the_handle, mbrolib_parameter* the_parameter);
typedef MBROLIB_ERROR (t_mbrolib_get_parameter)(void*, mbrolib_parameter*);



/** Set the database parameters using the supplied data.

@param the_handle previously given by mbrolib_init.

@param the_parameters: pointer to the wished parameters.

@return error code (MBROLIB_OK, MBROLIB_INVAL).
*/
MBROLIB_ERROR mbrolib_set_parameter(void* the_handle, const mbrolib_parameter* the_parameter);
typedef MBROLIB_ERROR (t_mbrolib_set_parameter)(void*, const mbrolib_parameter*);



/** Write the mbrola phonemes in the internal buffer.

@param the_handle.

@param the_mbrola_phonemes.

@param the_size in bytes.

@return error code (MBROLIB_OK, MBROLIB_INVAL, MBROLIB_WRITE_ERROR, MBROLIB_READ_ERROR).
*/
MBROLIB_ERROR mbrolib_write(void* the_handle, const char* the_mbrola_phonemes, size_t the_size);
typedef MBROLIB_ERROR (t_mbrolib_write)(void*, const char*, size_t);



/** Read n bytes of the output samples.

@param the_handle.

@param the_samples (raw audio data, 16bits, mono).

@param the_size max number of int16 to read.

@param the_size number of int16 read.

@return error code (MBROLIB_OK, MBROLIB_INVAL, MBROLIB_READ_ERROR).

*/
MBROLIB_ERROR mbrolib_read(void* the_handle, short* the_samples, int the_max_size, int* the_read_size);
typedef MBROLIB_ERROR (t_mbrolib_read)(void*, short*, int, int*);



/** Flush

@param the_handle.

*/
void mbrolib_flush(void* the_handle);
typedef void (t_mbrolib_flush)(void*);



/** Release the handle

@param the_handle.

@return error code (MBROLIB_OK, MBROLIB_INVAL).

*/
MBROLIB_ERROR mbrolib_terminate(void* the_handle);
typedef MBROLIB_ERROR (t_mbrolib_terminate)(void*);



#ifdef __cplusplus
}
#endif

#endif

+ 578
- 0
src/mbrowrap.cpp View File

@@ -0,0 +1,578 @@
/*
* mbrowrap -- A wrapper library around the mbrola binary
* providing a subset of the API from the Windows mbrola DLL.
*
* Copyright (C) 2010 by Nicolas Pitre <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*/

#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "mbrowrap.h"


/*
* mbrola instance parameters
*/

enum mbr_state {
MBR_INACTIVE = 0,
MBR_IDLE,
MBR_NEWDATA,
MBR_AUDIO,
MBR_WEDGED
};

static enum mbr_state mbr_state;

static char *mbr_voice_path;
static int mbr_cmd_fd, mbr_audio_fd, mbr_error_fd, mbr_proc_stat;
static pid_t mbr_pid;
static int mbr_samplerate;
static float mbr_volume = 1.0;
static char mbr_errorbuf[160];

struct datablock {
struct datablock *next;
int done;
int size;
char buffer[1]; /* 1 or more, dynamically allocated */
};

static struct datablock *mbr_pending_data_head, *mbr_pending_data_tail;

/*
* Private support code.
*/

static void log(const char *msg, ...)
{
va_list params;

va_start(params, msg);
vfprintf(stderr, msg, params);
fputc('\n', stderr);
va_end(params);
}

static void err(const char *err, ...)
{
va_list params;

va_start(params, err);
vsnprintf(mbr_errorbuf, sizeof(mbr_errorbuf), err, params);
va_end(params);
log("mbrola error: \"%s\"", mbr_errorbuf);
}

static int create_pipes(int p1[2], int p2[2], int p3[2])
{
int error=0;

if (pipe(p1) != -1) {
if (pipe(p2) != -1) {
if (pipe(p3) != -1) {
return 0;
} else
error = errno;
close(p2[0]);
close(p2[1]);
} else
error = errno;
close(p1[0]);
close(p1[1]);
}

err("pipe(): %s", strerror(error));
return -1;
}

static void close_pipes(int p1[2], int p2[2], int p3[2])
{
close(p1[0]);
close(p1[1]);
close(p2[0]);
close(p2[1]);
close(p3[0]);
close(p3[1]);
}

static int start_mbrola(const char *voice_path)
{
int error, p_stdin[2], p_stdout[2], p_stderr[2];
char charbuf[20];

if (mbr_state != MBR_INACTIVE) {
err("mbrola init request when already initialized");
return -1;
}

error = create_pipes(p_stdin, p_stdout, p_stderr);
if (error)
return -1;

mbr_pid = fork();

if (mbr_pid == -1) {
error = errno;
close_pipes(p_stdin, p_stdout, p_stderr);
err("fork(): %s", strerror(error));
return -1;
}

if (mbr_pid == 0) {
int i;

if (dup2(p_stdin[0], 0) == -1 ||
dup2(p_stdout[1], 1) == -1 ||
dup2(p_stderr[1], 2) == -1) {
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
"dup2(): %s\n", strerror(errno));
write(p_stderr[1], mbr_errorbuf, strlen(mbr_errorbuf));
_exit(1);
}

for (i = p_stderr[1]; i > 2; i--)
close(i);
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGTERM, SIG_IGN);

snprintf(charbuf, sizeof(charbuf), "%g", mbr_volume);
execlp("mbrola", "mbrola", "-e", "-v", charbuf,
voice_path, "-", "-.wav", (char *)NULL);
/* if execution reaches this point then the exec() failed */
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf),
"mbrola: %s\n", strerror(errno));
write(2, mbr_errorbuf, strlen(mbr_errorbuf));
_exit(1);
}

snprintf(charbuf, sizeof(charbuf), "/proc/%d/stat", mbr_pid);
mbr_proc_stat = open(charbuf, O_RDONLY);
if (mbr_proc_stat == -1) {
error = errno;
close_pipes(p_stdin, p_stdout, p_stderr);
waitpid(mbr_pid, NULL, 0);
mbr_pid = 0;
err("/proc is unaccessible: %s", strerror(error));
return -1;
}

signal(SIGPIPE, SIG_IGN);

if (fcntl(p_stdin[1], F_SETFL, O_NONBLOCK) == -1 ||
fcntl(p_stdout[0], F_SETFL, O_NONBLOCK) == -1 ||
fcntl(p_stderr[0], F_SETFL, O_NONBLOCK) == -1) {
error = errno;
close_pipes(p_stdin, p_stdout, p_stderr);
waitpid(mbr_pid, NULL, 0);
mbr_pid = 0;
err("fcntl(): %s", strerror(error));
return -1;
}

mbr_cmd_fd = p_stdin[1];
mbr_audio_fd = p_stdout[0];
mbr_error_fd = p_stderr[0];
close(p_stdin[0]);
close(p_stdout[1]);
close(p_stderr[1]);

mbr_state = MBR_IDLE;
return 0;
}

static void stop_mbrola(void)
{
if (mbr_state == MBR_INACTIVE)
return;
close(mbr_proc_stat);
close(mbr_cmd_fd);
close(mbr_audio_fd);
close(mbr_error_fd);
if (mbr_pid) {
kill(mbr_pid, SIGTERM);
waitpid(mbr_pid, NULL, 0);
mbr_pid = 0;
}
mbr_state = MBR_INACTIVE;
}

static void free_pending_data(void)
{
struct datablock *p, *head = mbr_pending_data_head;
while (head) {
p = head;
head = head->next;
free(p);
}
mbr_pending_data_head = NULL;
mbr_pending_data_tail = NULL;
}

static int mbrola_has_errors(void)
{
int result, error;

result = read(mbr_error_fd, mbr_errorbuf, sizeof(mbr_errorbuf)-1);

if (result == -1) {
if (errno == EAGAIN)
return 0;
err("read(error): %s", strerror(errno));
return -1;
}

if (result != 0) {
mbr_errorbuf[result] = 0;
if (mbr_errorbuf[result - 1] == '\n')
mbr_errorbuf[result - 1] = 0;
/* inhibit the reset signal message */
if (strncmp(mbr_errorbuf, "Got a reset signal", 18) == 0) {
mbr_errorbuf[0] = 0;
return 0;
}
/* don't consider this fatal at this point */
error = 0;
} else {
/* EOF on stderr, assume mbrola died. */
pid_t pid;
int status, len;
const char *msg;
char msgbuf[80];

pid = waitpid(mbr_pid, &status, WNOHANG);
if (!pid) {
msg = "mbrola closed stderr and did not exit";
} else {
mbr_pid = 0;
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
snprintf(msgbuf, sizeof(msgbuf),
"mbrola died by signal %d", sig);
msg = msgbuf;
} else if (WIFEXITED(status)) {
int exst = WEXITSTATUS(status);
snprintf(msgbuf, sizeof(msgbuf),
"mbrola exited with status %d", exst);
msg = msgbuf;
} else {
msg = "mbrola died and wait status is weird";
}
}
len = strlen(mbr_errorbuf);
if (!len)
snprintf(mbr_errorbuf, sizeof(mbr_errorbuf), "%s", msg);
else
snprintf(mbr_errorbuf+len, sizeof(mbr_errorbuf)-len,
", (%s)", msg);
error = -1;
}

log("mbrola error: \"%s\"", mbr_errorbuf);
return error;
}

static int send_to_mbrola(const char *cmd)
{
ssize_t result;
int len;
if (!mbr_pid)
return -1;

len = strlen(cmd);
result = write(mbr_cmd_fd, cmd, len);

if (result == -1) {
int error = errno;
if (error == EPIPE && mbrola_has_errors()) {
return -1;
} else if (error == EAGAIN) {
result = 0;
} else {
err("write(): %s", strerror(error));
return -1;
}
}
if (result != len) {
struct datablock *data;
data = (struct datablock *)malloc(sizeof(*data) + len - result);
if (data) {
data->next = NULL;
data->done = 0;
data->size = len - result;
memcpy(data->buffer, cmd + result, len - result);
result = len;
if (!mbr_pending_data_head)
mbr_pending_data_head = data;
else
mbr_pending_data_tail->next = data;
mbr_pending_data_tail = data;
}
}

return result;
}

static int mbrola_is_idle(void)
{
char *p;
char buffer[20]; /* looking for "12345 (mbrola) S" so 20 is plenty*/

/* look in /proc to determine if mbrola is still running or sleeping */
if (lseek(mbr_proc_stat, 0, SEEK_SET) != 0)
return 0;
if (read(mbr_proc_stat, buffer, sizeof(buffer)) != sizeof(buffer))
return 0;
p = (char *)memchr(buffer, ')', sizeof(buffer));
if (!p || (unsigned)(p - buffer) >= sizeof(buffer) - 2)
return 0;
return (p[1] == ' ' && p[2] == 'S');
}

static ssize_t receive_from_mbrola(void *buffer, size_t bufsize)
{
int result, wait = 1;
size_t cursize = 0;

if (!mbr_pid)
return -1;

do {
struct pollfd pollfd[3];
nfds_t nfds = 0;
int idle;

pollfd[0].fd = mbr_audio_fd;
pollfd[0].events = POLLIN;
nfds++;

pollfd[1].fd = mbr_error_fd;
pollfd[1].events = POLLIN;
nfds++;

if (mbr_pending_data_head) {
pollfd[2].fd = mbr_cmd_fd;
pollfd[2].events = POLLOUT;
nfds++;
}

idle = mbrola_is_idle();
result = poll(pollfd, nfds, idle ? 0 : wait);
if (result == -1) {
err("poll(): %s", strerror(errno));
return -1;
}
if (result == 0) {
if (idle) {
mbr_state = MBR_IDLE;
break;
} else {
if (wait >= 5000 * (4-1)/4) {
mbr_state = MBR_WEDGED;
err("mbrola process is stalled");
break;
} else {
wait *= 4;
continue;
}
}
}
wait = 1;

if (pollfd[1].revents && mbrola_has_errors())
return -1;

if (mbr_pending_data_head && pollfd[2].revents) {
struct datablock *head = mbr_pending_data_head;
char *data = head->buffer + head->done;
int left = head->size - head->done;
result = write(mbr_cmd_fd, data, left);
if (result == -1) {
int error = errno;
if (error == EPIPE && mbrola_has_errors())
return -1;
err("write(): %s", strerror(error));
return -1;
}
if (result != left) {
head->done += result;
} else {
mbr_pending_data_head = head->next;
free(head);
if (!mbr_pending_data_head)
mbr_pending_data_tail = NULL;
else
continue;
}
}

if (pollfd[0].revents) {
char *curpos = (char *)buffer + cursize;
size_t space = bufsize - cursize;
ssize_t obtained = read(mbr_audio_fd, curpos, space);
if (obtained == -1) {
err("read(): %s", strerror(errno));
return -1;
}
cursize += obtained;
mbr_state = MBR_AUDIO;
}
} while (cursize < bufsize);

return cursize;
}

/*
* API functions.
*/

int init_MBR(const char *voice_path)
{
int error, result;
unsigned char wavhdr[45];

error = start_mbrola(voice_path);
if (error)
return -1;

result = send_to_mbrola("#\n");
if (result != 2) {
stop_mbrola();
return -1;
}

/* we should actually be getting only 44 bytes */
result = receive_from_mbrola(wavhdr, 45);
if (result != 44) {
err("unable to get .wav header from mbrola");
stop_mbrola();
return -1;
}

/* parse wavhdr to get mbrola voice samplerate */
if (memcmp(wavhdr, "RIFF", 4) != 0 ||
memcmp(wavhdr+8, "WAVEfmt ", 8) != 0) {
err("mbrola did not return a .wav header");
stop_mbrola();
return -1;
}
mbr_samplerate = wavhdr[24] + (wavhdr[25]<<8) +
(wavhdr[26]<<16) + (wavhdr[27]<<24);
//log("mbrola: voice samplerate = %d", mbr_samplerate);

/* remember the voice path for setVolumeRatio_MBR() */
if (mbr_voice_path != voice_path) {
free(mbr_voice_path);
mbr_voice_path = strdup(voice_path);
}

return 0;
}

void close_MBR(void)
{
stop_mbrola();
free_pending_data();
free(mbr_voice_path);
mbr_voice_path = NULL;
mbr_volume = 1.0;
}

int reset_MBR()
{
int result, success = 1;
char dummybuf[4096];

if (mbr_state == MBR_IDLE)
return 1;
if (!mbr_pid)
return 0;
if (kill(mbr_pid, SIGUSR1) == -1)
success = 0;
free_pending_data();
result = write(mbr_cmd_fd, "\n#\n", 3);
if (result != 3)
success = 0;
do {
result = read(mbr_audio_fd, dummybuf, sizeof(dummybuf));
} while (result > 0);
if (result != -1 || errno != EAGAIN)
success = 0;
if (!mbrola_has_errors() && success)
mbr_state = MBR_IDLE;
return success;
}

int read_MBR(void *buffer, int nb_samples)
{
int result = receive_from_mbrola(buffer, nb_samples * 2);
if (result > 0)
result /= 2;
return result;
}

int write_MBR(const char *data)
{
mbr_state = MBR_NEWDATA;
return send_to_mbrola(data);
}

int flush_MBR(void)
{
return send_to_mbrola("\n#\n") == 3;
}

int getFreq_MBR(void)
{
return mbr_samplerate;
}

void setVolumeRatio_MBR(float value)
{
if (value == mbr_volume)
return;
mbr_volume = value;
if (mbr_state != MBR_IDLE)
return;
/*
* We have no choice but to kill and restart mbrola with
* the new argument here.
*/
stop_mbrola();
init_MBR(mbr_voice_path);
}

int lastErrorStr_MBR(char *buffer, int bufsize)
{
int result = snprintf(buffer, bufsize, "%s", mbr_errorbuf);
return result >= bufsize ? (bufsize - 1) : result;
}

void resetError_MBR(void)
{
mbr_errorbuf[0] = 0;
}

+ 108
- 0
src/mbrowrap.h View File

@@ -0,0 +1,108 @@
/*
* mbrowrap -- A wrapper library around the mbrola binary
* providing a subset of the API from the Windows mbrola DLL.
*
* Copyright (C) 2010 by Nicolas Pitre <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*/

#ifndef MBROWRAP_H
#define MBROWRAP_H

#ifdef __cplusplus
extern "C"
{
#endif

/*
* Initialize mbrola. The 'voice_path' argument must contain the
* path and file name to the mbrola voice database to be used. Returned
* value is 0 on success, or an error code otherwise (currently only -1
* is returned. If not successful, lastErrorStr_MBR() will provide the
* error reason. If this is successful, then close_MBR() must be called
* before init_MBR() can be called again.
*/
int init_MBR(const char *voice_path);

/*
* Stop mbrola and release any resources. It is necessary to call
* this after a successful call to init_MBR() before init_MBR() can be
* called again.
*/
void close_MBR(void);

/*
* Stop any ongoing processing and flush all buffers. After this call
* any synthesis request will start afresh. A non-zero value is returned
* on success, or 0 on failure. If not successful, lastErrorStr_MBR() will
* provide the error reason.
*/
int reset_MBR();

/*
* Return at most 'nb_samples' audio samples into 'buffer'. The returned
* value is the actual number of samples returned, or -1 on error.
* If not successful, lastErrorStr_MBR() will provide the error reason.
* Samples are always 16-bit little endian.
*/
int read_MBR(void *buffer, int nb_samples);

/*
* Write a NULL terminated string of phoneme in the input buffer.
* Return the number of chars actually written, or -1 on error.
* If not successful, lastErrorStr_MBR() will provide the error reason.
*/
int write_MBR(const char *data);

/*
* Send a flush command to the mbrola input stream.
* This is currently similar to write_MBR("#\n"). Return 1 on success
* or 0 on failure. If not successful, lastErrorStr_MBR() will provide
* the error reason.
*/
int flush_MBR(void);

/*
* Return the audio sample frequency of the used voice database.
*/
int getFreq_MBR(void);

/*
* Overall volume.
*/
void setVolumeRatio_MBR(float value);

/*
* Copy into 'buffer' at most 'bufsize' bytes from the latest error
* message. This may also contain non-fatal errors from mbrola. The
* returned value is the actual number of bytes copied. When no error
* message is pending then an empty string is returned. Consecutive
* calls to lastErrorStr_MBR() will return the same message unless it
* is explicitly cleared with resetError_MBR().
*/
int lastErrorStr_MBR(char *buffer, int bufsize);

/*
* Clear any pending error message.
*/
void resetError_MBR(void);

/*
* Tolerance to missing diphones (always active so this is ignored)
*/
static inline void setNoError_MBR(int no_error) { }

#ifdef __cplusplus
}
#endif

#endif

+ 0
- 41
src/setlengths.cpp View File

@@ -140,7 +140,6 @@ void SetSpeed(int control)
int s1;
int wpm;
int wpm2;
int test=0;

speed.loud_consonants = 0;
speed.min_sample_len = 450;
@@ -172,43 +171,6 @@ void SetSpeed(int control)
speed.loud_consonants = (wpm - 360) / 8;
}

#ifdef deleted
if(wpm >= 450)
{
// TEST
speed1 = 6;
speed2 = speed3 = 5;
speed.pause_factor = 12;
speed.clause_pause_factor = 15;
speed.wav_factor = 70;
speed.lenmod_factor = 53;
speed.min_sample_len = 400;
return;
}
if(wpm > 390)
{
// TEST
speed1 = 6;
speed2 = speed3 = 5;
speed.pause_factor = 13;
speed.clause_pause_factor = 15;

if(wpm >= 440)
{
speed.wav_factor = 72 - (wpm - 440)/4;
speed.lenmod_factor = 60 - (wpm - 440)/2;
speed.min_sample_len = 420 - (wpm - 440);
}
else
{
speed.wav_factor = 74;
speed.lenmod_factor = 65 - (wpm - 400)/10;
speed.min_sample_len = 450 - (wpm - 400)/2;
}
return;
}
#endif

wpm2 = wpm;
if(wpm > 359) wpm2 = 359;
if(wpm < 80) wpm2 = 80;
@@ -269,9 +231,6 @@ void SetSpeed(int control)
speed.min_sample_len = 420 - (wpm - 440);
}

if(test > 0)
speed.wav_factor = test;

speed.pause_factor = (256 * s1)/115; // full speed adjustment, used for pause length
speed.clause_pause_factor = 0;


+ 12
- 3
src/speak.cpp View File

@@ -98,8 +98,10 @@ static const char *help_text =
"\t directory. <voice name> specifies the language\n"
"--path=\"<path>\"\n"
"\t Specifies the directory containing the espeak-data directory\n"
"--pho\n"
"\t Write mbrola phoneme data (.pho) to stdout, or to the file in --phonout\n"
"--phonout=\"<filename>\"\n"
"\t Write output from -x -X commands, and mbrola phoneme data, to this file\n"
"\t Write phoneme output from -x -X and --pho to this file\n"
"--punct=\"<characters>\"\n"
"\t Speak the names of punctuation characters during speaking. If\n"
"\t =<characters> is omitted, all punctuation is spoken.\n"
@@ -214,7 +216,9 @@ void DisplayVoices(FILE *f_out, char *language)
} // end of DisplayVoices



void WVoiceChanged(voice_t *wvoice)
{
}

static int OpenWaveFile(const char *path, int rate)
//=================================================
@@ -472,7 +476,8 @@ int main (int argc, char **argv)
{"stdout", no_argument, 0, 0x105},
{"split", optional_argument, 0, 0x106},
{"path", required_argument, 0, 0x107},
{"phonout", required_argument, 0, 0x108},
{"phonout", required_argument, 0, 0x108},
{"pho", no_argument, 0, 0x109},
{0, 0, 0, 0}
};

@@ -702,6 +707,10 @@ int main (int argc, char **argv)
}
break;

case 0x109: // --pho
option_mbrola_phonemes = 8;
break;

default:
exit(0);
}

+ 49
- 10
src/speak_lib.cpp View File

@@ -59,6 +59,9 @@ static unsigned int my_unique_identifier=0;
static void* my_user_data=NULL;
static espeak_AUDIO_OUTPUT my_mode=AUDIO_OUTPUT_SYNCHRONOUS;
static int synchronous_mode = 1;
static int out_samplerate = 0;
static int voice_samplerate = 22050;

t_espeak_callback* synth_callback = NULL;
int (* uri_callback)(int, const char *, const char *) = NULL;
int (* phoneme_callback)(const char *) = NULL;
@@ -66,6 +69,13 @@ int (* phoneme_callback)(const char *) = NULL;
char path_home[N_PATH_HOME]; // this is the espeak-data directory


void WVoiceChanged(voice_t *wvoice)
{//=================================
// Voice change in wavegen
voice_samplerate = wvoice->samplerate;
}


#ifdef USE_ASYNC

static int dispatch_audio(short* outbuf, int length, espeak_EVENT* event)
@@ -85,6 +95,34 @@ static int dispatch_audio(short* outbuf, int length, espeak_EVENT* event)
{
case AUDIO_OUTPUT_PLAYBACK:
{
int event_type=0;
int event_data=0;
if(event)
{
event_type = event->type;
event_data = event->id.number;
}

if(event_type == espeakEVENT_SAMPLERATE)
{
voice_samplerate = event->id.number;

if(out_samplerate != voice_samplerate)
{
if(out_samplerate != 0)
{
// sound was previously open with a different sample rate
wave_close(my_audio);
sleep(1);
}
out_samplerate = voice_samplerate;
wave_init(voice_samplerate);
wave_set_callback_is_output_enabled( fifo_is_command_enabled);
my_audio = wave_open("alsa");
event_init();
}
}

if (outbuf && length && a_wave_can_be_played)
{
wave_write (my_audio, (char*)outbuf, 2*length);
@@ -220,17 +258,13 @@ static void select_output(espeak_AUDIO_OUTPUT output_type)
my_audio = NULL;
synchronous_mode = 1;
option_waveout = 1; // inhibit portaudio callback from wavegen.cpp
out_samplerate = 0;

switch(my_mode)
{
case AUDIO_OUTPUT_PLAYBACK:
// wave_init() is now called just before the first wave_write()
synchronous_mode = 0;
#ifdef USE_ASYNC
wave_init();
wave_set_callback_is_output_enabled( fifo_is_command_enabled);
my_audio = wave_open("alsa");
event_init();
#endif
break;

case AUDIO_OUTPUT_RETRIEVAL:
@@ -734,19 +768,21 @@ ENTER("espeak_Initialize");
return(EE_INTERNAL_ERROR);
option_phonemes = 0;
option_mbrola_phonemes = 0;
option_phoneme_events = (options & 1);

SetVoiceByName("default");
VoiceReset(0);
// SetVoiceByName("default");
for(param=0; param<N_SPEECH_PARAM; param++)
param_stack[0].parameter[param] = param_defaults[param];
SetParameter(espeakRATE,170,0);
SetParameter(espeakRATE,175,0);
SetParameter(espeakVOLUME,100,0);
SetParameter(espeakCAPITALS,option_capitals,0);
SetParameter(espeakPUNCTUATION,option_punctuation,0);
SetParameter(espeakWORDGAP,0,0);
DoVoiceChange(voice);
// DoVoiceChange(voice);
#ifdef USE_ASYNC
fifo_init();
@@ -1087,8 +1123,10 @@ ESPEAK_API void espeak_SetPhonemeTrace(int value, FILE *stream)
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)
bit 3: produce mbrola pho data
*/
option_phonemes = value;
option_phonemes = value & 3;
option_mbrola_phonemes = value & 8;
f_trans = stream;
if(stream == NULL)
f_trans = stderr;
@@ -1163,6 +1201,7 @@ ESPEAK_API espeak_ERROR espeak_Terminate(void)
{
wave_close(my_audio);
wave_terminate();
out_samplerate = 0;
}

#endif

+ 7
- 6
src/speak_lib.h View File

@@ -50,12 +50,13 @@ Revision 5
typedef enum {
espeakEVENT_LIST_TERMINATED = 0, // Retrieval mode: terminates the event list.
espeakEVENT_WORD = 1, // Start of word
espeakEVENT_SENTENCE, // Start of sentence
espeakEVENT_MARK, // Mark
espeakEVENT_PLAY, // Audio element
espeakEVENT_END, // End of sentence or clause
espeakEVENT_MSG_TERMINATED, // End of message
espeakEVENT_PHONEME // Phoneme, if enabled in espeak_Initialize()
espeakEVENT_SENTENCE = 2, // Start of sentence
espeakEVENT_MARK = 3, // Mark
espeakEVENT_PLAY = 4, // Audio element
espeakEVENT_END = 5, // End of sentence or clause
espeakEVENT_MSG_TERMINATED = 6, // End of message
espeakEVENT_PHONEME = 7, // Phoneme, if enabled in espeak_Initialize()
espeakEVENT_SAMPLERATE = 8 // internal use, set sample rate
} espeak_EVENT_TYPE;



+ 0
- 1
src/speech.h View File

@@ -44,7 +44,6 @@

#ifdef LIBRARY
#define USE_ASYNC
//#define USE_MBROLA_LIB
#endif

#ifdef _ESPEAKEDIT

+ 103
- 228
src/synth_mbrola.cpp View File

@@ -35,15 +35,11 @@

extern int Read4Bytes(FILE *f);
extern void SetPitch2(voice_t *voice, int pitch1, int pitch2, int *pitch_base, int *pitch_range);

#ifdef USE_MBROLA_LIB

extern unsigned char *outbuf;

#ifndef PLATFORM_WINDOWS

#include "mbrolib.h"
void * mb_handle;
#include "mbrowrap.h"

#else
#include <windows.h>
@@ -64,7 +60,7 @@ PROCVV reset_MBR;
PROCIV lastError_MBR;
PROCVCI lastErrorStr_MBR;
PROCVI setNoError_MBR;
PROCVI setFreq_MBR;
PROCIV getFreq_MBR;
PROCVF setVolumeRatio_MBR;


@@ -103,13 +99,11 @@ void unload_MBR()
}

#endif // windows
#endif // USE_MBROLA_LIB


static MBROLA_TAB *mbrola_tab = NULL;
static int mbrola_control = 0;


int option_mbrola_phonemes;


espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate)
@@ -133,37 +127,35 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
}

sprintf(path,"%s/mbrola/%s",path_home,mbrola_voice);
#ifdef USE_MBROLA_LIB
#ifdef PLATFORM_POSIX
if(GetFileLength(path) <= 0)
{
// mbrola voice file not found, look in /usr/share
sprintf(path,"/usr/share/mbrola/%s",mbrola_voice);
}
#endif
#ifdef PLATFORM_WINDOWS
if(load_MBR() == FALSE) // load mbrola.dll
return(EE_INTERNAL_ERROR);
#endif

if(init_MBR(path) != 0) // initialise the required mbrola voice
return(EE_NOT_FOUND);

setNoError_MBR(1); // don't stop on phoneme errors
#else
mb_handle = mbrolib_init(srate);
mbrolib_parameter m_parameters;

if(mb_handle == NULL)
return(EE_INTERNAL_ERROR);

MBROLIB_ERROR a_status = mbrolib_set_voice(mb_handle, mbrola_voice);
if(a_status != MBROLIB_OK)
return(EE_NOT_FOUND);
#endif // not windows
#endif // USE_MBROLA_LIB

// read eSpeak's mbrola phoneme translation data, eg. en1_phtrans
sprintf(path,"%s/mbrola_ph/%s",path_home,phtrans);
size = GetFileLength(path);
if((f_in = fopen(path,"r")) == NULL)
if((f_in = fopen(path,"r")) == NULL) {
close_MBR();
return(EE_NOT_FOUND);
}

if((mbrola_tab = (MBROLA_TAB *)realloc(mbrola_tab,size)) == NULL)
{
fclose(f_in);
close_MBR();
return(EE_INTERNAL_ERROR);
}

@@ -176,26 +168,16 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
fread(mbrola_tab,size,1,f_in);
fclose(f_in);


#ifdef USE_MBROLA_LIB
#ifdef PLATFORM_WINDOWS
setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0f);
#else
mbrolib_get_parameter(mb_handle,&m_parameters);
m_parameters.ignore_error = 1;
m_parameters.volume_ratio = (float)(mbrola_control & 0xff) /16.0;
mbrolib_set_parameter(mb_handle,&m_parameters);
#endif // not windows
#endif // USE_MBROLA_LIB

option_quiet = 1;
// srate = getFreq_MBR();
samplerate = srate;
if(srate == 22050)
SetParameter(espeakVOICETYPE,0,0);
else
SetParameter(espeakVOICETYPE,1,0);
strcpy(mbrola_name,mbrola_voice);
mbrola_delay = 3800; // improve synchronization of events
// mbrola_delay = 3800; // improve synchronization of events
mbrola_delay = 1000; // improve synchronization of events
return(EE_OK);
} // end of LoadMbrolaTable

@@ -383,155 +365,10 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final)
} // end of WritePitch


#ifdef USE_MBROLA_LIB

static void MbrolaMarker(int type, int char_posn, int length, int value)
{//=====================================================================

MarkerEvent(type,(char_posn & 0xffffff) | (length << 24),value,outbuf);

}


static void MbrolaEmbedded(int &embix, int sourceix)
{//=================================================
// There were embedded commands in the text at this point
unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command
unsigned int value;
int command;
int sign=0;

do {
word = embedded_list[embix++];
value = word >> 8;
command = word & 0x1f;

if((word & 0x60) == 0x60)
sign = -1;
else
if((word & 0x60) == 0x40)
sign = 1;

if(command < N_EMBEDDED_VALUES)
{
if(sign == 0)
embedded_value[command] = value;
else
embedded_value[command] += (value * sign);
}

switch(command & 0x1f)
{
case EMBED_M: // named marker
MbrolaMarker(espeakEVENT_MARK, (sourceix & 0x7ff) + clause_start_char, 0, value);
break;
}
} while ((word & 0x80) == 0);
}


#ifdef PLATFORM_WINDOWS
static int MbrolaSynth(char *p_mbrola)
{//===================================
// p_mbrola is a string of mbrola pho lines - Windows
int len;
int finished;
int result=0;

if(synth_callback == NULL)
return(1);

if(p_mbrola == NULL)
flush_MBR();
else
result = write_MBR(p_mbrola);


finished = 0;
while(!finished && ((len = read_MBR((short *)outbuf, outbuf_size/2)) > 0))
{
out_ptr = outbuf + len*2;

if(event_list)
{
event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
event_list[event_list_ix].user_data = 0;
}
count_samples += len;
finished = synth_callback((short *)outbuf, len, event_list);
event_list_ix=0;
}

if(finished)
{
// cancelled by user, discard any unused mbrola speech
flush_MBR();
while((len = read_MBR((short *)outbuf, outbuf_size/2)) > 0);
}
return(finished);
} // end of SynthMbrola
#else

static int MbrolaSynth(char *p_mbrola)
{//===================================
// p_mbrola is a string of mbrola pho lines - Linux

// This is wrong
// It must be called from WavegenFill()

int len;
int finished;
int result=0;

if(synth_callback == NULL)
return(1);

if(p_mbrola == NULL)
mbrolib_flush(mb_handle);
else
result = mbrolib_write(mb_handle,p_mbrola,strlen(p_mbrola));


finished = 0;
while(!finished && (mbrolib_read(mb_handle, (short *)out_ptr, (out_end - out_ptr)/2, &len) == MBROLIB_OK))
{
if(len == 0)
break;

out_ptr += (len*2);

if(event_list)
{
event_list[event_list_ix].type = espeakEVENT_LIST_TERMINATED; // indicates end of event list
event_list[event_list_ix].user_data = 0;
}
count_samples += len;
finished = synth_callback((short *)outbuf, len, event_list);
event_list_ix=0;
}

if(finished)
{
// cancelled by user, discard any unused mbrola speech
mbrolib_flush(mb_handle);
while(mbrolib_read(mb_handle, (short *)outbuf, outbuf_size/2, &len) == MBROLIB_OK)
{
if(len == 0)
break;
}
}
return(finished);
} // end of SynthMbrola
#endif // not windows
#endif // USE_MBROLA_LIB



void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
{//======================================================================
int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbrola)
{//=================================================================================
// Generate a mbrola pho file
unsigned int name;
int phix;
int len;
int len1;
PHONEME_TAB *ph;
@@ -552,21 +389,21 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
char buf[80];
char mbr_buf[120];

#ifdef USE_MBROLA_LIB
int embedded_ix=0;
int word_count=0;
static int phix;
static int embedded_ix;
static int word_count;

event_list_ix = 0;
out_ptr = outbuf;
#ifdef PLATFORM_WINDOWS
setNoError_MBR(1); // don't stop on phoneme errors
#endif
#else
// fprintf(f_mbrola,";; v=%.2f\n",(float)(mbrola_control & 0xff)/16.0); // ;; v= has no effect on mbrola
#endif
if (!resume) {
phix = 1;
embedded_ix = 0;
word_count = 0;
}

for(phix=1; phix < n_phonemes; phix++)
while (phix < n_phonemes)
{
if (WcmdqFree() < MIN_WCMDQ)
return 1;

mbr_buf[0] = 0;

p = &plist[phix];
@@ -576,24 +413,24 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
ph_prev = plist[phix-1].ph;
ph_next = plist[phix+1].ph;

#ifdef USE_MBROLA_LIB
if(p->synthflags & SFLAG_EMBEDDED)
{
MbrolaEmbedded(embedded_ix, p->sourceix);
DoEmbedded(embedded_ix, p->sourceix);
}
if(p->newword & 4)
MbrolaMarker(espeakEVENT_SENTENCE, (p->sourceix & 0x7ff) + clause_start_char, 0, count_sentences);

if(p->newword & 4)
DoMarker(espeakEVENT_SENTENCE, (p->sourceix & 0x7ff) + clause_start_char, 0, count_sentences);
if(p->newword & 1)
MbrolaMarker(espeakEVENT_WORD, (p->sourceix & 0x7ff) + clause_start_char, p->sourceix >> 11, clause_start_word + word_count++);
#endif
DoMarker(espeakEVENT_WORD, (p->sourceix & 0x7ff) + clause_start_char, p->sourceix >> 11, clause_start_word + word_count++);

name = GetMbrName(p,ph,ph_prev,ph_next,&name2,&len_percent,&control);
if(control & 1)
phix++;

if(name == 0)
if(name == 0) {
phix++;
continue; // ignore this phoneme
}

if((ph->type == phPAUSE) && (name == ph->mnemonic))
{
@@ -607,9 +444,7 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
else
len = (80 * speed.wav_factor)/256;

#ifdef USE_MBROLA_LIB
MbrolaMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, ph->mnemonic);
#endif
DoMarker(espeakEVENT_PHONEME, (p->sourceix & 0x7ff) + clause_start_char, 0, ph->mnemonic);

sprintf(buf,"%s\t",WordToString(name));
strcat(mbr_buf,buf);
@@ -720,6 +555,7 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)

if(pause)
{
len += PauseLength(pause,0);
sprintf(buf,"_ \t%d\n",PauseLength(pause,0));
strcat(mbr_buf,buf);
pause = 0;
@@ -731,39 +567,78 @@ void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola)
}
else
{
#ifdef USE_MBROLA_LIB
if(MbrolaSynth(mbr_buf) != 0)
return;
#endif
int res = write_MBR(mbr_buf);
if (res < 0)
return 0; /* don't get stuck on error */
if (res == 0)
return 1;
wcmdq[wcmdq_tail][0] = WCMD_MBROLA_DATA;
wcmdq[wcmdq_tail][1] = len;
WcmdqInc();
}
}

#ifdef USE_MBROLA_LIB
MbrolaSynth(NULL);
#endif
} // end of MbrolaTranslate

phix++;
}

#ifdef TEST_MBROLA
if(!f_mbrola)
{
flush_MBR();

static PHONEME_LIST mbrola_phlist;
static int mbrola_n_ph;
static int mbrola_phix;
// flush the mbrola output buffer
wcmdq[wcmdq_tail][0] = WCMD_MBROLA_DATA;
wcmdq[wcmdq_tail][1] = 500;
WcmdqInc();
}

return 0;
} // end of MbrolaTranslate

int MbrolaFill(int fill_zeros)
{//===========================
}

int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
{//==================================================================
if(resume == 0)
FILE *f_mbrola = NULL;

if(*n_ph == 0)
return(0);

if(option_mbrola_phonemes)
{
mbrola_phlist = phoneme_list;
mbrola_n_ph = n_ph;
mbrola_phix = 0;
// send mbrola data to a file, not to the mbrola library
f_mbrola = f_trans;
}

resume(0); // finished phoneme list
int again = MbrolaTranslate(phoneme_list, *n_ph, resume, f_mbrola);
if (!again)
*n_ph = 0;
return again;
}


int MbrolaFill(int length, int resume)
{//===================================
// Read audio data from Mbrola (length is in milisecs)

static int n_samples;
int req_samples, result;

if (!resume)
n_samples = samplerate * length / 1000;

req_samples = (out_end - out_ptr)/2;
if (req_samples > n_samples)
req_samples = n_samples;
result = read_MBR((short *)out_ptr, req_samples);
if (result <= 0)
return 0;
out_ptr += result*2;
n_samples -= result;
return n_samples ? 1 : 0;
}


void MbrolaReset(void)
{//===================
// Reset the Mbrola engine and flush the pending audio

reset_MBR();
}
#endif

+ 1
- 1
src/synthdata.cpp View File

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

const char *version_string = "1.43.46 20.Jun.10";
const char *version_string = "1.43.48 28.Jun.10";
const int version_phdata = 0x014342;

int option_device_number = -1;

+ 15
- 57
src/synthesize.cpp View File

@@ -135,7 +135,7 @@ static void EndPitch(int voice_break)
syllable_centre = -1;
memset(vowel_transition,0,sizeof(vowel_transition));
}
} // end of Synthesize::EndPitch
} // end of EndPitch



@@ -152,7 +152,7 @@ static void DoAmplitude(int amp, unsigned char *amp_env)
q[2] = (long)amp_env;
q[3] = amp;
WcmdqInc();
} // end of Synthesize::DoAmplitude
} // end of DoAmplitude



@@ -181,7 +181,7 @@ static void DoPitch(unsigned char *env, int pitch1, int pitch2)
q[2] = (long)env;
q[3] = (pitch1 << 16) + pitch2;
WcmdqInc();
} // end of Synthesize::DoPitch
} // end of DoPitch



@@ -223,7 +223,7 @@ static void DoPause(int length, int control)
wcmdq[wcmdq_tail][1] = len;
WcmdqInc();
last_frame = NULL;
} // end of Synthesize::DoPause
} // end of DoPause


extern int seq_len_adjust; // temporary fix to advance the start point for playing the wav sample
@@ -253,9 +253,9 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
else
{
// increase consonant amplitude at high speeds, depending on the peak consonant amplitude
x = ((35 - wav_scale) * speed.loud_consonants);
if(x < 0) x = 0;
wav_scale = (wav_scale * (x+256))/256;
// x = ((35 - wav_scale) * speed.loud_consonants);
// if(x < 0) x = 0;
// wav_scale = (wav_scale * (x+256))/256;
}

if(std_length > 0)
@@ -383,32 +383,6 @@ static int DoSample2(int index, int which, int std_length, int control, int leng
} // end of DoSample2


#ifdef deleted
int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int amp)
{//====================== ==========================================================
int index;
int match_level;
int amp2;
int result;

EndPitch(1);
index = LookupSound(ph1,ph2,which & 0xff,&match_level,0);
if((index & 0x800000) == 0)
return(0); // not wavefile data

amp2 = wavefile_amp;
if(amp != 0)
amp2 = (amp * wavefile_amp)/20;

if(amp == -1)
amp2 = amp;

result = DoSample2(index,which,length_mod,0,amp2);
last_frame = NULL;
return(result);
} // end of DoSample
#endif


int DoSample3(PHONEME_DATA *phdata, int length_mod, int amp)
{//=========================================================
@@ -1198,8 +1172,8 @@ if(which==1)



static void DoMarker(int type, int char_posn, int length, int value)
{//=================================================================
void DoMarker(int type, int char_posn, int length, int value)
{//==========================================================
// This could be used to return an index to the word currently being spoken
// Type 1=word, 2=sentence, 3=named marker, 4=play audio, 5=end
wcmdq[wcmdq_tail][0] = WCMD_MARKER;
@@ -1208,7 +1182,7 @@ static void DoMarker(int type, int char_posn, int length, int value)
wcmdq[wcmdq_tail][3] = value;
WcmdqInc();

} // end of Synthesize::DoMarker
} // end of DoMarker


void DoVoiceChange(voice_t *v)
@@ -1224,8 +1198,8 @@ void DoVoiceChange(voice_t *v)
}


static void DoEmbedded(int &embix, int sourceix)
{//=============================================
void DoEmbedded(int &embix, int sourceix)
{//======================================
// There were embedded commands in the text at this point
unsigned int word; // bit 7=last command for this word, bits 5,6 sign, bits 0-4 command
unsigned int value;
@@ -1305,14 +1279,12 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume)
PHONEME_DATA phdata_tone;
FMT_PARAMS fmtp;

#ifdef TEST_MBROLA
if(mbrola_name[0] != 0)
return(MbrolaGenerate(phoneme_list,n_ph,resume));
#endif

if(option_quiet)
return(0);

if(mbrola_name[0] != 0)
return(MbrolaGenerate(phoneme_list,n_ph,resume));

if(resume == 0)
{
ix = 1;
@@ -1899,20 +1871,6 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control)
return(1);
}

if(mbrola_name[0] != 0)
{
#ifdef USE_MBROLA_LIB
MbrolaTranslate(phoneme_list,n_phoneme_list,NULL);
#else
{
FILE *f_mbrola;
if((f_mbrola = f_trans) == stderr)
f_mbrola = stdout;
MbrolaTranslate(phoneme_list,n_phoneme_list,f_mbrola);
}
#endif
}

Generate(phoneme_list,&n_phoneme_list,0);
WavegenOpenSound();


+ 7
- 2
src/synthesize.h View File

@@ -462,6 +462,7 @@ extern unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1];
#define WCMD_MARKER 10
#define WCMD_VOICE 11
#define WCMD_EMBEDDED 12
#define WCMD_MBROLA_DATA 13


#define N_WCMDQ 160
@@ -557,8 +558,12 @@ espeak_ERROR SetVoiceByName(const char *name);
espeak_ERROR SetVoiceByProperties(espeak_VOICE *voice_selector);
espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate);
void SetParameter(int parameter, int value, int relative);
void MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, FILE *f_mbrola);
//int MbrolaSynth(char *p_mbrola);
int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbrola);
int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume);
int MbrolaFill(int length, int resume);
void MbrolaReset(void);
void DoEmbedded(int &embix, int sourceix);
void DoMarker(int type, int char_posn, int length, int value);
//int DoSample(PHONEME_TAB *ph1, PHONEME_TAB *ph2, int which, int length_mod, int amp);
int DoSample3(PHONEME_DATA *phdata, int length_mod, int amp);
int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_LIST *plist, int modulation);

+ 0
- 21
src/tr_english.cpp View File

@@ -1,21 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
* email: [email protected] *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* <http://www.gnu.org/licenses/>. *
***************************************************************************/

#include "StdAfx.h"


+ 0
- 1
src/tr_languages.cpp View File

@@ -881,7 +881,6 @@ SetLengthMods(tr,3); // all equal
static const short stress_lengths_nl[8] = {160,135, 210,210, 0, 0, 260,280};

tr->langopts.stress_rule = STRESSPOSN_1L;
tr->langopts.vowel_pause = 1;
tr->langopts.vowel_pause = 0x30; // ??
tr->langopts.param[LOPT_DIERESES] = 1;
tr->langopts.param[LOPT_PREFIXES] = 1;

+ 1
- 0
src/translate.h View File

@@ -545,6 +545,7 @@ extern int option_tone_flags;
extern int option_waveout;
extern int option_quiet;
extern int option_phonemes;
extern int option_mbrola_phonemes;
extern int option_phoneme_events;
extern int option_linelength; // treat lines shorter than this as end-of-clause
extern int option_multibyte;

+ 3
- 0
src/voice.h View File

@@ -41,6 +41,7 @@ typedef struct {
int formant_factor; // adjust nominal formant frequencies by this because of the voice's pitch (256ths)
int consonant_amp; // amplitude of unvoiced consonants
int consonant_ampv; // amplitude of the noise component of voiced consonants
int samplerate;
int klattv[8];

// parameters used by Wavegen
@@ -77,6 +78,8 @@ espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name);
voice_t *LoadVoice(const char *voice_name, int control);
voice_t *LoadVoiceVariant(const char *voice_name, int variant);
void DoVoiceChange(voice_t *v);
void WVoiceChanged(voice_t *wvoice);
void WavegenSetVoice(voice_t *v);
void ReadTonePoints(char *string, int *tone_pts);
void VoiceReset(int control);


+ 2
- 0
src/voices.cpp View File

@@ -408,6 +408,7 @@ void VoiceReset(int tone_only)
voice->voicing = 64;
voice->consonant_amp = 100;
voice->consonant_ampv = 100;
voice->samplerate = 22050;
memset(voice->klattv,0,sizeof(voice->klattv));
memset(speed.fast_settings,0,sizeof(speed.fast_settings));

@@ -921,6 +922,7 @@ voice_t *LoadVoice(const char *vname, int control)
phtrans[0] = 0;
sscanf(p,"%s %s %d",name,phtrans,&srate);
LoadMbrolaTable(name,phtrans,srate);
voice->samplerate = srate;
}
break;


+ 95
- 93
src/wave.cpp View File

@@ -56,15 +56,16 @@ enum {ONE_BILLION=1000000000};
static t_wave_callback* my_callback_is_output_enabled=NULL;

#define N_WAV_BUF 10
#define SAMPLE_RATE 22050
#define MAX_SAMPLE_RATE 22050
#define FRAMES_PER_BUFFER 512
#define BUFFER_LENGTH (SAMPLE_RATE*2*sizeof(uint16_t))
#define THRESHOLD (BUFFER_LENGTH/5)
#define BUFFER_LENGTH (MAX_SAMPLE_RATE*2*sizeof(uint16_t))
//#define THRESHOLD (BUFFER_LENGTH/5)
static char myBuffer[BUFFER_LENGTH];
static char* myRead=NULL;
static char* myWrite=NULL;
static int out_channels=1;
static int my_stream_could_start=0;
static int wave_samplerate;

static int mInCallbackFinishedState = false;
#if (USE_PORTAUDIO == 18)
@@ -168,89 +169,89 @@ static int pa_callback(void *inputBuffer, void *outputBuffer,
PaStreamCallbackFlags flags, void *userData )
#endif
{
int aResult=0; // paContinue
char* aWrite = myWrite;
size_t n = out_channels*sizeof(uint16_t)*framesPerBuffer;
int aResult=0; // paContinue
char* aWrite = myWrite;
size_t n = out_channels*sizeof(uint16_t)*framesPerBuffer;

myReadPosition += framesPerBuffer;
SHOW("pa_callback > myReadPosition=%u, framesPerBuffer=%lu (n=0x%x) \n",(int)myReadPosition, framesPerBuffer, n);
myReadPosition += framesPerBuffer;
SHOW("pa_callback > myReadPosition=%u, framesPerBuffer=%lu (n=0x%x) \n",(int)myReadPosition, framesPerBuffer, n);

if (aWrite >= myRead)
{
if((size_t)(aWrite - myRead) >= n)
{
memcpy(outputBuffer, myRead, n);
myRead += n;
}
else
{
SHOW_TIME("pa_callback > underflow");
aResult=1; // paComplete;
mInCallbackFinishedState = true;
size_t aUsedMem=0;
aUsedMem = (size_t)(aWrite - myRead);
if (aUsedMem)
{
memcpy(outputBuffer, myRead, aUsedMem);
}
char* p = (char*)outputBuffer + aUsedMem;
memset(p, 0, n - aUsedMem);
// myReadPosition += aUsedMem/(out_channels*sizeof(uint16_t));
myRead = aWrite;
}
}
else // myRead > aWrite
{
if ((size_t)(myBuffer + BUFFER_LENGTH - myRead) >= n)
if (aWrite >= myRead)
{
memcpy(outputBuffer, myRead, n);
myRead += n;
if((size_t)(aWrite - myRead) >= n)
{
memcpy(outputBuffer, myRead, n);
myRead += n;
}
else
{
SHOW_TIME("pa_callback > underflow");
aResult=1; // paComplete;
mInCallbackFinishedState = true;
size_t aUsedMem=0;
aUsedMem = (size_t)(aWrite - myRead);
if (aUsedMem)
{
memcpy(outputBuffer, myRead, aUsedMem);
}
char* p = (char*)outputBuffer + aUsedMem;
memset(p, 0, n - aUsedMem);
// myReadPosition += aUsedMem/(out_channels*sizeof(uint16_t));
myRead = aWrite;
}
}
else if ((size_t)(aWrite + BUFFER_LENGTH - myRead) >= n)
else // myRead > aWrite
{
int aTopMem = myBuffer + BUFFER_LENGTH - myRead;
if (aTopMem)
{
SHOW("pa_callback > myRead=0x%x, aTopMem=0x%x\n",(int)myRead, (int)aTopMem);
memcpy(outputBuffer, myRead, aTopMem);
}
int aRest = n - aTopMem;
if (aRest)
{
SHOW("pa_callback > myRead=0x%x, aRest=0x%x\n",(int)myRead, (int)aRest);
char* p = (char*)outputBuffer + aTopMem;
memcpy(p, myBuffer, aRest);
}
myRead = myBuffer + aRest;
}
else
{
SHOW_TIME("pa_callback > underflow");
aResult=1; // paComplete;

int aTopMem = myBuffer + BUFFER_LENGTH - myRead;
if (aTopMem)
{
SHOW("pa_callback > myRead=0x%x, aTopMem=0x%x\n",(int)myRead, (int)aTopMem);
memcpy(outputBuffer, myRead, aTopMem);
}
int aRest = aWrite - myBuffer;
if (aRest)
{
SHOW("pa_callback > myRead=0x%x, aRest=0x%x\n",(int)myRead, (int)aRest);
char* p = (char*)outputBuffer + aTopMem;
memcpy(p, myBuffer, aRest);
}

size_t aUsedMem = aTopMem + aRest;
char* p = (char*)outputBuffer + aUsedMem;
memset(p, 0, n - aUsedMem);
// myReadPosition += aUsedMem/(out_channels*sizeof(uint16_t));
myRead = aWrite;
if ((size_t)(myBuffer + BUFFER_LENGTH - myRead) >= n)
{
memcpy(outputBuffer, myRead, n);
myRead += n;
}
else if ((size_t)(aWrite + BUFFER_LENGTH - myRead) >= n)
{
int aTopMem = myBuffer + BUFFER_LENGTH - myRead;
if (aTopMem)
{
SHOW("pa_callback > myRead=0x%x, aTopMem=0x%x\n",(int)myRead, (int)aTopMem);
memcpy(outputBuffer, myRead, aTopMem);
}
int aRest = n - aTopMem;
if (aRest)
{
SHOW("pa_callback > myRead=0x%x, aRest=0x%x\n",(int)myRead, (int)aRest);
char* p = (char*)outputBuffer + aTopMem;
memcpy(p, myBuffer, aRest);
}
myRead = myBuffer + aRest;
}
else
{
SHOW_TIME("pa_callback > underflow");
aResult=1; // paComplete;

int aTopMem = myBuffer + BUFFER_LENGTH - myRead;
if (aTopMem)
{
SHOW("pa_callback > myRead=0x%x, aTopMem=0x%x\n",(int)myRead, (int)aTopMem);
memcpy(outputBuffer, myRead, aTopMem);
}
int aRest = aWrite - myBuffer;
if (aRest)
{
SHOW("pa_callback > myRead=0x%x, aRest=0x%x\n",(int)myRead, (int)aRest);
char* p = (char*)outputBuffer + aTopMem;
memcpy(p, myBuffer, aRest);
}

size_t aUsedMem = aTopMem + aRest;
char* p = (char*)outputBuffer + aUsedMem;
memset(p, 0, n - aUsedMem);
// myReadPosition += aUsedMem/(out_channels*sizeof(uint16_t));
myRead = aWrite;
}
}
}

SHOW("pa_callback > myRead=%x\n",(int)myRead);
SHOW("pa_callback > myRead=%x\n",(int)myRead);


// #if USE_PORTAUDIO == 18
@@ -288,7 +289,7 @@ static int pa_callback(void *inputBuffer, void *outputBuffer,
#endif


return(aResult);
return(aResult);
//#endif

} // end of WaveCallBack
@@ -335,7 +336,7 @@ static int wave_open_sound()
out_channels = 1;

#if USE_PORTAUDIO == 18
// err = Pa_OpenDefaultStream(&pa_stream,0,1,paInt16,SAMPLE_RATE,FRAMES_PER_BUFFER,N_WAV_BUF,pa_callback,(void *)userdata);
// err = Pa_OpenDefaultStream(&pa_stream,0,1,paInt16,wave_samplerate,FRAMES_PER_BUFFER,N_WAV_BUF,pa_callback,(void *)userdata);

PaDeviceID playbackDevice = Pa_GetDefaultOutputDeviceID();

@@ -351,7 +352,7 @@ static int wave_open_sound()
paInt16,
NULL,
/* general parameters */
SAMPLE_RATE, FRAMES_PER_BUFFER, 0,
wave_samplerate, FRAMES_PER_BUFFER, 0,
//paClipOff | paDitherOff,
paNoFlag,
pa_callback, (void *)userdata);
@@ -376,12 +377,12 @@ static int wave_open_sound()
paInt16,
NULL,
/* general parameters */
SAMPLE_RATE, FRAMES_PER_BUFFER, 0,
wave_samplerate, FRAMES_PER_BUFFER, 0,
//paClipOff | paDitherOff,
paNoFlag,
pa_callback, (void *)userdata);
// err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,
// SAMPLE_RATE,
// wave_samplerate,
// FRAMES_PER_BUFFER,
// N_WAV_BUF,pa_callback,(void *)userdata);
SHOW("wave_open_sound > Pa_OpenDefaultStream(2): err=%d (%s)\n",err, Pa_GetErrorText(err));
@@ -395,7 +396,7 @@ static int wave_open_sound()
&pa_stream,
NULL, /* no input */
&myOutputParameters,
SAMPLE_RATE,
wave_samplerate,
framesPerBuffer,
paNoFlag,
// paClipOff | paDitherOff,
@@ -410,7 +411,7 @@ static int wave_open_sound()
&pa_stream,
NULL, /* no input */
&myOutputParameters,
SAMPLE_RATE,
wave_samplerate,
framesPerBuffer,
paNoFlag,
// paClipOff | paDitherOff,
@@ -427,14 +428,14 @@ static int wave_open_sound()
&pa_stream,
NULL, /* no input */
&myOutputParameters,
SAMPLE_RATE,
wave_samplerate,
framesPerBuffer,
paNoFlag,
// paClipOff | paDitherOff,
pa_callback,
(void *)userdata);

// err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,(double)SAMPLE_RATE,FRAMES_PER_BUFFER,pa_callback,(void *)userdata);
// err = Pa_OpenDefaultStream(&pa_stream,0,2,paInt16,(double)wave_samplerate,FRAMES_PER_BUFFER,pa_callback,(void *)userdata);
}
mInCallbackFinishedState = false;
#endif
@@ -526,7 +527,7 @@ static void select_device(const char* the_api)
defaultAlsaIndex = hostInfo->defaultOutputDevice;
const PaDeviceInfo *deviceInfo = Pa_GetDeviceInfo( defaultAlsaIndex );
update_output_parameters(defaultAlsaIndex, deviceInfo);
if (Pa_IsFormatSupported(NULL, &myOutputParameters, SAMPLE_RATE) == 0)
if (Pa_IsFormatSupported(NULL, &myOutputParameters, wave_samplerate) == 0)
{
SHOW( "select_device > ALSA (default), name=%s (#%d)\n", deviceInfo->name, defaultAlsaIndex);
selectedIndex = defaultAlsaIndex;
@@ -541,7 +542,7 @@ static void select_device(const char* the_api)
update_output_parameters(i, deviceInfo);
if (Pa_IsFormatSupported(NULL, &myOutputParameters, SAMPLE_RATE) == 0)
if (Pa_IsFormatSupported(NULL, &myOutputParameters, wave_samplerate) == 0)
{
SHOW( "select_device > ALSA, name=%s (#%d)\n", deviceInfo->name, i);
@@ -613,12 +614,13 @@ void wave_set_callback_is_output_enabled(t_wave_callback* cb)
//<wave_init

// TBD: the arg could be "alsa", "oss",...
void wave_init()
void wave_init(int srate)
{
ENTER("wave_init");
PaError err;

pa_stream = NULL;
wave_samplerate = srate;
mInCallbackFinishedState = false;
init_buffer();

@@ -1023,7 +1025,7 @@ int wave_get_remaining_time(uint32_t sample, uint32_t* time)
{
// TBD: take in account time suplied by portaudio V18 API
a_time = sample - myReadPosition;
a_time = 0.5 + (a_time * 1000.0) / SAMPLE_RATE;
a_time = 0.5 + (a_time * 1000.0) / wave_samplerate;
}
else
{
@@ -1050,7 +1052,7 @@ void *wave_test_get_write_buffer()
// notdef USE_PORTAUDIO


void wave_init() {}
void wave_init(int srate) {}
void* wave_open(const char* the_api) {return (void *)1;}
size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize) {return theSize;}
int wave_close(void* theHandler) {return 0;}

+ 1
- 1
src/wave.h View File

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

extern int option_device_number;

extern void wave_init();
extern void wave_init(int samplerate);
// TBD: the arg could be "alsa", "oss",...
extern void* wave_open(const char* the_api);


+ 5
- 4
src/wave_pulse.cpp View File

@@ -65,7 +65,6 @@ enum {

static t_wave_callback* my_callback_is_output_enabled=NULL;

#define SAMPLE_RATE 22050
#define ESPEAK_FORMAT PA_SAMPLE_S16LE
#define ESPEAK_CHANNEL 1

@@ -90,6 +89,7 @@ static int time_offset_msec = 0;
static int just_flushed = 0;

static int connected = 0;
static int wave_samplerate;

#define CHECK_DEAD_GOTO(label, warn) do { \
if (!mainloop || \
@@ -475,7 +475,7 @@ static int pulse_open()
pthread_mutex_init( &pulse_mutex, (const pthread_mutexattr_t *)NULL);

ss.format = ESPEAK_FORMAT;
ss.rate = SAMPLE_RATE;
ss.rate = wave_samplerate;
ss.channels = ESPEAK_CHANNEL;

if (!pa_sample_spec_valid(&ss))
@@ -677,11 +677,12 @@ void wave_set_callback_is_output_enabled(t_wave_callback* cb)
//>
//<wave_init

void wave_init()
void wave_init(int srate)
{
ENTER("wave_init");

stream = NULL;
wave_samplerate = srate;

pulse_open();
}
@@ -846,7 +847,7 @@ int wave_get_remaining_time(uint32_t sample, uint32_t* time)
{
// TBD: take in account time suplied by portaudio V18 API
a_time = sample - a_timing_info.read_index;
a_time = 0.5 + (a_time * 1000.0) / SAMPLE_RATE;
a_time = 0.5 + (a_time * 1000.0) / wave_samplerate;
}
else
{

+ 5
- 3
src/wave_sada.cpp View File

@@ -77,12 +77,14 @@ static uint32_t last_play_position=0;
//
//<wave_init

void wave_init() {
void wave_init(int srate) {
ENTER("wave_init");

audio_info_t ainfo;
char *audio_device = NULL;

wave_samplerate = srate;

audio_device = getenv("AUDIODEV");
if (audio_device != NULL) {
if ((sun_audio_fd = open(audio_device, O_WRONLY)) < 0) {
@@ -108,7 +110,7 @@ void wave_init() {
SHOW("wave_init() play buffer size: %d\n", ainfo.play.buffer_size);
ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
ainfo.play.channels = 1;
ainfo.play.sample_rate = SAMPLE_RATE;
ainfo.play.sample_rate = wave_samplerate;
ainfo.play.precision = SAMPLE_SIZE;

if (ioctl(sun_audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
@@ -520,7 +522,7 @@ int wave_get_remaining_time(uint32_t sample, uint32_t* time)
(actual_index <= ainfo.play.samples)) {
*time = 0;
} else {
a_time = ((actual_index - ainfo.play.samples) * 1000) / SAMPLE_RATE;
a_time = ((actual_index - ainfo.play.samples) * 1000) / wave_samplerate;
*time = (uint32_t) a_time;
}
SHOW("wave_get_remaining_time for %d: %d\n", sample, *time);

+ 8
- 5
src/wavegen.cpp View File

@@ -288,6 +288,8 @@ void WcmdqStop()
#ifdef USE_PORTAUDIO
Pa_AbortStream(pa_stream);
#endif
if(mbrola_name[0] != 0)
MbrolaReset();
}


@@ -1563,6 +1565,8 @@ void WavegenSetVoice(voice_t *v)
option_harmonic1 = 6;
}
WavegenSetEcho();
MarkerEvent(espeakEVENT_SAMPLERATE,0,wvoice->samplerate,out_ptr);
// WVoiceChanged(wvoice);
}


@@ -1797,11 +1801,6 @@ int WavegenFill(int fill_zeros)
static int resume=0;
static int echo_complete=0;

#ifdef TEST_MBROLA
if(mbrola_name[0] != 0)
return(MbrolaFill(fill_zeros));
#endif

while(out_ptr < out_end)
{
if(WcmdqUsed() <= 0)
@@ -1904,6 +1903,10 @@ int WavegenFill(int fill_zeros)
case WCMD_EMBEDDED:
SetEmbedded(q[1],q[2]);
break;

case WCMD_MBROLA_DATA:
result = MbrolaFill(length, resume);
break;
}

if(result==0)

Loading…
Cancel
Save