mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-10-31 05:35:35 +00:00
Merge branch 'master' into build
Conflicts: src/Makefile.espeakedit
This commit is contained in:
+36
-32
@@ -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
|
||||
gelé sjel'e // PB gelé
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
@@ -24,7 +24,7 @@
|
||||
|
||||
// 2006-11-18 Gilles Casse <gcasse@oralux.org>
|
||||
//
|
||||
// Updated 2010-06-11 Michel Such <michel.such@free.fr>
|
||||
// Updated 2010-06-15 Michel Such <michel.such@free.fr>
|
||||
//
|
||||
// * 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
File diff suppressed because it is too large
Load Diff
+1
-3
@@ -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
@@ -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
|
||||
|
||||
Executable
BIN
Binary file not shown.
Binary file not shown.
+38
-34
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
ENVELOPE
|
||||
0 60
|
||||
5 63
|
||||
22 92
|
||||
31 100
|
||||
41 95
|
||||
85 12
|
||||
90 5
|
||||
100 0
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
ENVELOPE
|
||||
0 0
|
||||
45 95
|
||||
100 0
|
||||
|
||||
|
||||
Executable
BIN
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -1,7 +1,7 @@
|
||||
//====================================================
|
||||
// French
|
||||
//====================================================
|
||||
// Updated 2010-06-12 Michel Such <michel.such@free.fr>
|
||||
// Updated 2010-06-16 Michel Such <michel.such@free.fr>
|
||||
|
||||
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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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++;
|
||||
|
||||
-205
@@ -1,205 +0,0 @@
|
||||
#ifndef MBROLIB_H
|
||||
#define MBROLIB_H
|
||||
|
||||
/*
|
||||
* mbrolib: mbrola wrapper.
|
||||
*
|
||||
* Copyright (C) 2007 Gilles Casse <gcasse@oralux.org>
|
||||
*
|
||||
* 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
|
||||
@@ -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 <nico@fluxnic.net>
|
||||
*
|
||||
* 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,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 <nico@fluxnic.net>
|
||||
*
|
||||
* 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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
|
||||
#ifdef LIBRARY
|
||||
#define USE_ASYNC
|
||||
//#define USE_MBROLA_LIB
|
||||
#endif
|
||||
|
||||
#ifdef _ESPEAKEDIT
|
||||
|
||||
+104
-229
@@ -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();
|
||||
}
|
||||
|
||||
phix++;
|
||||
}
|
||||
|
||||
#ifdef USE_MBROLA_LIB
|
||||
MbrolaSynth(NULL);
|
||||
#endif
|
||||
if(!f_mbrola)
|
||||
{
|
||||
flush_MBR();
|
||||
|
||||
// flush the mbrola output buffer
|
||||
wcmdq[wcmdq_tail][0] = WCMD_MBROLA_DATA;
|
||||
wcmdq[wcmdq_tail][1] = 500;
|
||||
WcmdqInc();
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // end of MbrolaTranslate
|
||||
|
||||
|
||||
#ifdef TEST_MBROLA
|
||||
|
||||
static PHONEME_LIST mbrola_phlist;
|
||||
static int mbrola_n_ph;
|
||||
static int mbrola_phix;
|
||||
|
||||
|
||||
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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+93
-91
@@ -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)
|
||||
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
|
||||
else // myRead > aWrite
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user