diff --git a/dictsource/da_list b/dictsource/da_list index c7f5c752..eca6df58 100755 --- a/dictsource/da_list +++ b/dictsource/da_list @@ -1,4 +1,4 @@ -// PB = Peter Bjarkov - pbj1234@hotmail.com +// PB = Peter Bjarkov - pbj1234@hotmail.com // This file is UTF8 encoded // Spelling-to-phoneme words for Danish @@ -113,7 +113,7 @@ _3X tR'&#Dv@ //PB [tR'ADv@] changed to [tR'&#Dv@] _4X f'WRV //PB [f'W:*3] changed to [ f'WRV] _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 @@ -164,6 +164,7 @@ et ed $u her $u kun $u vel $u+ +da $u // conjunctions og V $u+ $pause // and @@ -204,7 +205,7 @@ dét de vi $u i _i $u+ mig maj $u // me -dig daj_| $u +dig daj $u dem $u ham $u hende $u @@ -259,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 @@ -318,7 +319,6 @@ interface _^_EN image _^_EN joke _^_EN joystick _^_EN -junkie _^_EN laptop _^_EN level _^_EN login _^_EN @@ -2343,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 @@ -5153,7 +5153,7 @@ banaliser $alt bandagere $alt banderolere $alt barbariser $alt -barber $alt +barbere $alt barder $alt barrier $alt barrikader $alt @@ -5178,7 +5178,7 @@ bonbonniere bVNbVNj'E:r $alt boniter $alt botaniser $alt braiser $alt -briketter $alt +brikettere $alt brillere $alt brochere $alt brodere $alt @@ -5549,7 +5549,7 @@ halver $alt harceler $alt harmoner $alt harmoniser $alt -harpuner $alt +harpunere $alt havarer $alt hektografer $alt herbariser $alt @@ -5668,7 +5668,7 @@ intriger $alt introducer $alt intuber $alt invader $alt -invalider $alt +invalidere $alt inventer $alt inverter $alt invester $alt @@ -6188,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 @@ -6490,7 +6490,7 @@ temperer $alt tender $alt teoretiser $alt termografer $alt -terrasser $alt +terrassere $alt terroriser $alt testamentere $alt testere $alt @@ -10298,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 @@ -10359,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 @@ -10404,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 @@ -10471,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 diff --git a/dictsource/da_rules b/dictsource/da_rules index 63cfc3bf..ee77a918 100755 --- a/dictsource/da_rules +++ b/dictsource/da_rules @@ -37,10 +37,12 @@ efter) a (b & // PB efterabe for) a (n & // foran for) a (nd A // PB forandre + for) a (nk A // PB forankre // PB general rule: [a] after r followed by sp/st/sk r) a (L08 a // PB rask // PB general rule: [&:] after m/n L09) a &: // mave + gn) av (pot Aw // PB gnavpotte torn) ad (o '&d // PB stressed kn) a (p A // PB manchetknap sn) a (p a // PB snappe @@ -51,9 +53,11 @@ // PB general rule: [a] after l before n l) a (n & // land l) an (ce AN // PB lancere + pl) an (ch AN // PB planche // PB words in da_list with final -ance &) ance ($p_alt 'ANs@ // balance, romance &) ance (+ ANs@ // PB unstressed after a syllable - ferieromance + &) ance (re$p_alt ANs'e // PB avancere // PB general rule: [a] after consonant before m C) a (m a // PB ham, gamle, lam C) a (mi & // PB vitamin @@ -160,6 +164,7 @@ C) a (vn A // favn, savn // PB general rule: [a] after kl before consonant kl) a (L06 a // PB klap + a (k a // akrobat a (ngC A // PB angst b) a (L06 A // PB baptist a (mp %A // PB ampul @@ -168,10 +173,12 @@ _okt) a (v '& // stressed _konk) a (v '& // stressed _det) a (lje '& // PB stressed + nev) a (da '& // PB _pol) a (k 'a // PB stressed polak _kos) a (k 'a // PB stressed - kosak _milli) a (r 'A // PB stressed - milliard _trilli) a (r 'A // PB stressed - trilliard + _sejl) a (ds '& // PB stressed L08) av (C Au // stavn st) av (nin &v // PB stavning h) av (_ & // PB hav - problem with the noun "hav" [hAu] @@ -179,15 +186,20 @@ _trilli) a (r 'A // PB stressed - trilliard h) av (C Au // PB havbund h) av (over Au // PB havoverfladen h) a (vn A // PB havn + h) ag (l Au // PB hav) a (nna '& // PB Havanna + h) a (ck & // PB hacke color) ado 'Ado // PB US state _) av (_ Au // PB av C) a (k a // PB makværk + C) a (x a // PB fax + st) a (ki & // PB stakit m) a (ka & // PN makaber C) a (ck a // PB tackle s) a (x a // PB saxofon l) a (kA & // PB lakune @l) a (g &j // PB nederlag + gr) ape Eb // PB grapefrugt // PB stressed a in final -al in $alt words in da_list &) al ($p_alt+ ''&l // the double '' enforces primary stress - fatal, monumental @@ -285,6 +297,8 @@ _vatik) a (n '& // PB Vatikanet al) a (sk '& // PB Alaska _radio) a (kti 'A // PB stressed - radioaktiv _impres) a (rio 'A // PB stressed + _rab) a (rber 'A // PB stressed + _ar) a (ber 'A // PB stressed bl) a (d & // PB blad h) a (n & // PB han j) a & // PB ja @@ -326,7 +340,9 @@ interf) a (ce ei // PB interface C) a (ft A // PB haft, saft sl) a (L06 a // PB slap ai (K aj + mount) ai (n e // PB mountain cockt) ail Ejl // PB + cont) ai (n 'Ej // PB container d) ay Ej // PB holyday, Holliday aise 'E:s@ // PB mayonnaise k) ai (n &|'i: // PB kokain @@ -339,7 +355,8 @@ interf) a (ce ei // PB interface p) a (pi & // PB papir L09) a (l &: // PB male L09) a (ld & // PB knald - _) a (ld a // PB aldrig, alder + _) a (ldr a // PB aldrig + a (ld & // PB alder b) a (lkan &: // PB Balkan over) a (lt '& // PB stressed a in 'overalt' s) a (m a // PB sammen @@ -366,6 +383,7 @@ interf) a (ce ei // PB interface an (cien aN L06) a (nd & // PB pande a (ndre A // PB andre + a (p a // PB apotek L06) a (nk a // PB banke @g) a (ng 'a // PB stressed a in words ending with -gang - engang, enegang h) a (nk a // PB hank @@ -375,9 +393,7 @@ restaur) ant 'AN // PB added stress t) a (nk A // PB tankstation t) a (x a // PB taxa kålr) a (bi 'A // PB kålrabi - stressed a - au (+ aw // PB auto, autoritet - e) au 'o // PB bureau, niveau - nive) au o + au (++ aw // PB auto, autoritet _biss) au 'a:w // PB Guinea-Bissau s) au (ce O: // PB sauce, bearnaisesauce ch) au (f o @@ -467,8 +483,10 @@ amsterd) a (m 'a // PB sl) ag (side Au // PB slagside sp) ag (ett &g' // PB spagetti sp) ag (hett &g' // PB spaghetti + sp) ag (num Au // PB r) ag (e+ Au // PB drage, rage C) age (+ &:j@ // PB tage, bage, kage + fl) ager (mus AuV // PB C) ager (_+ &:jV // PB tager, bager, kager l) agd (e &:j // PB lagde g) ager (e+ &S'e // PB gagere @@ -518,6 +536,7 @@ _trienn) ale '&:l@ b b bb b + ko) bb (er w // PB b (il 'b beagle bi:g@l //PB beagle - dog bloody blVdi // PB @@ -633,7 +652,7 @@ _trienn) ale '&:l@ cambridge kejmbRidZ // PB connecticut kVn'etikVd // PB carlisle kAlajl // PB - china tjajn& + china tjajn& // PB .group d @@ -641,14 +660,17 @@ _trienn) ale '&:l@ A) de (_ D3 A) d D // PB way too broad? + d (uk d // PB produkt a) d D // PB ad, udenad - dangerously broad a) de (Cr D3 // PB badedragt - not testet y) de D3 // PB brydehold Coe) de @-D // PB boede @) d (elt d // PB udelt, tildelt l) d // PB omit d after l - hold, skjold + l) d (et // PB spjældet d (ør d // PB bildør d (et d // PB metaldetektor + d (ing d // PB holdingfirma l) d (rig d // PB aldrig l) d (ig d // PB skyldig bal) de l3 // PB silent d - balde @@ -672,6 +694,7 @@ stikor) d // PB exception - silent d in 'stikord' A) d (C D A) dd D // PB hedder - "er" removed by &) er (_NS2 [V] A) d (s@ // PB fødsel - deleted 30+ rules, this one does the work + ræ) d (sel D // PB me) d (+ D // PB medspiller A) ds (_ s // PB silent d - palads, trods ø) d (L08+ D // PB nødstop @@ -707,7 +730,7 @@ stikor) d // PB exception - silent d in 'stikord' kla) dd (e D mi) dd (el D mu) dder DV - rø) dd (er D + rø) dder DV kry) dd (er D dd (et D bu) dd (ing D @@ -730,7 +753,7 @@ stikor) d // PB exception - silent d in 'stikord' gui) de (n de ver) d (en d vi) d (er D - gui) de (r de + gui) der dV lu) d (ere d A) d (es D ær) d (es d @@ -779,6 +802,8 @@ stikor) d // PB exception - silent d in 'stikord' _) doc (_ dVk // PB Doc - name dodge dVdZ // PB city daiquiri d&k@ri // PB drink + _) duke dZu:k // PB Duke - name + _) drive dRAjv // PB drive-in .group é // added by PB é 'e // idé, entré @@ -798,6 +823,8 @@ stikor) d // PB exception - silent d in 'stikord' _koll) e (ga 'e // PB stressed _koll) eg (e 'ej // PB stressed kolleger r) e E // PB general rule: [E] after r + klatr) e V // PB + gr) e (s & // PB kongres // dr) e (C@ @ // PP sladresøster - not tested r) e (vn &# // PB revne r) e (kto &# // PB rektor @@ -824,6 +851,7 @@ stikor) d // PB exception - silent d in 'stikord' rn) e (d+ e // PB derned an) e (r @ // PB anerkende L09) e (de E // nede, nederlag + mån) e (d @ // PB L09) e (t e // metal L09) e (l E // mellem _m) e (l_ e // PB @@ -841,6 +869,7 @@ stikor) d // PB exception - silent d in 'stikord' ri) e 3 // PB ferie _a) e (_ 3 // PB ae ød) e 3 // PB øde + god) e @ // PB pl) e (men 3 // PB supplement øbl) e (m 3 // PB møblement hvab) e (har_ 3 // PB hvabehar @@ -852,7 +881,7 @@ stikor) d // PB exception - silent d in 'stikord' en) e @ // PB ene, eneste en) e (rgi E // PB br) e (L09 & // PB bremse - sn) e (K e? // PB sne, snebold + sn) e (K e // PB sne, snebold sn) e (rp E // PB snerpet sn) ed (k e e // PB silent d - snedker _s) e (_ e? // PB se @@ -894,6 +923,7 @@ _kongr) e (s '& // PB kongres - stressed but not after a syllable _rødb) e (de 'e // PB stressed e in 'rødbede' _aller) e (de_ E // PB allerede - otherwise the E is changed by another rule _im) e (ns+ 'e // PB stressed + _magn) e (t 'e // PB stressed lar) e (do 'e // PB // PB final -em - stressed e @@ -912,13 +942,14 @@ _myxød) e (m 'e _syst) e (m 'e _teor) e (m 'e _ød) e (m 'e + el) e (ndig E // PB møgelendig - steressed with $alt rule leb) e (ndig 'E // PB steressed with $alt rule _ball) e (t@ 'E // PB balletdanser _en_ball) e (t 'E // PB lini) e @ // PB changed from [e] to [@] ft) e (r @ // PB oftere - r) e (nd a // PB rend + _r) e (nd+ a // PB rend @st) e (n+ e: // øjesten, skorstene h) e (n_+ e // hen carst) e (n @ @@ -986,7 +1017,8 @@ _intell) e (kt 'E _proj) e (kt 'E _prosp) e (kt 'E _præf) e (kt 'E - resp) e (kt 'E + _resp) e (kt 'E + resp) e (ktabel E _sociol) e (kt 'E _subj) e (kt 'E _susp) e (kt 'E @@ -1022,6 +1054,8 @@ _sakram) e (nte 'e k) ende (_ E-n@ // genkende, kende, anerkende sv) ende (_ E-n@ // PB not a -ende suffix - svende henv) ende (_ E-n@ // PB + anv) ende (_ E-n@ // PB + røvr) ende (_ a-n@ // PB røvrende L08) e (gt e // PB stegt L08) e (g a // PB steg, spegepølse @@ -1037,7 +1071,7 @@ _sakram) e (nte 'e r) eg (er Eg // PB e=> E eg (n aj // PB regn, tegning, lege underl) eg ej // PB underlegen - str) eg aj // PB stregen + str) eg (+ aj // PB stregen p) eg aj // PB pegefinger _) ege (_ e:j@ // PB added _ - ege(træer) _) ege (træ e:j@ // PB added _ - egetræe @@ -1072,6 +1106,7 @@ _offic) e (_ // office (officepakke) Ad) en (@ @-n // udenlandsk, udenad Ad) en (t en // PB identificere &) ene (_ @-n@ + gr) ene En@ // PB grene ucc) es 'e nog) et (_ D // PB noget ir) e (n 'e @@ -1083,6 +1118,8 @@ _offic) e (_ // office (officepakke) forur) e (ne 'e // PB stressed - forurene _terap) eut 'Wwd // PB stressed _torp) e (do 'e // PB stressed + _cel) e (ber 'e // PB stressed + // PB a few words with final -es - stressed e abc) e (s 'e cypr) e (s '& @@ -1093,6 +1130,7 @@ _terap) eut 'Wwd // PB stressed ompet) en (ce aN ress) en (timent aN // PB ressentiment m) edie 'edj3 // medie, kommedie + m) edier 'edjV // medier, kommedier inds) e e // PB indse inds) e (r_ e // PB indser etagere et&S'E:R // PB @@ -1102,10 +1140,12 @@ _terap) eut 'Wwd // PB stressed eyeliner ajlajnV // PB ey i // PB jockey eiffel ajf3l // PB Eiffeltårnet + ef) eu Vj // PB plant _) earl W:l/2 // PB Earl _) earp W:b // PB name _) east i:sd // PB Eastwood eu (rop Wu // PB Europa + eau 'o // PB bureau, niveau _t) e (_ e // PB te kin) e (s 'e // PB kineser @@ -1131,9 +1171,13 @@ _terap) eut 'Wwd // PB stressed &) el (l$p_alt ''E - modellen - only one l _) el el // elkedel +muskat) el ''El // PB el (sk+ el // PB naturelsker +intellektu) el el // // PB bestandd) el el // PB + halvd) el el // PB d) el (t+ el // PB tildelt + lob) el (ia 'el // PB d) el (A+ el // PB dele, omdele edd) el l/2 // PB seddel medd) el del // PB meddel @@ -1218,17 +1262,18 @@ reserved) el el sard) el 'el s) el (e el // sikkerhedssele sigtem) el el - skalp) el 'el +_skalp) el 'el sport) el 'el stikked) el el såv) el 'el - tab) el 'el + _tab) el 'el + tab) el el +respektab) el @l // PB tarant) el 'el univers) el 'el _frikad) el (l 'El // PB stressed - frikadelle frikad) el (l El // PB verdensd) el el -// t) el (+ el @) el (øs el // PB mageløs el (eg+ el // PB juleleg @@ -1245,6 +1290,7 @@ verdensd) el el &g) en (st en // PB genstand &g) en (kend en // PB genkende &g) enn (em en // ugennemskuelig +kuglep) en En // PB ord) en @n anci) enn EN // anciennitet retskaff) en @n @@ -1269,16 +1315,18 @@ _resid) en (s 'en // PB residens resid) en (s en // PB residens _acetyl) en 'en // PB _influ) en (za 'En // PB +skizofr) en 'En // PB + s) en (sib AN // PB sensibel _rev) en (che 'An // PB stressed rev) en (che 'An // PB not stressed after a syllable // PB $alt words with final -ent in da_list - stressed e - &) ent ($p_alt+ 'end // student - &) ent (&$p_alt+ 'end // student - &r) ent ($p_alt+ '&#nd // omtrent - &) ent (ur$p_alt+ end' // agentur - stressed u - &) ent (alsk$p_alt+ end' // + "alsk" - stressed a - orientalsk + &) ent ($p_alt+ 'ent // student + &) ent (&$p_alt+ 'ent // student + &r) ent ($p_alt+ '&#nt // omtrent + &) ent (ur$p_alt+ ent' // agentur - stressed u + &) ent (alsk$p_alt+ ent' // + "alsk" - stressed a - orientalsk // exceptions acc) ent (+ AN // PB ev) ent (A+ ent // PB eventyr, eventuel @@ -1289,6 +1337,7 @@ _influ) en (za 'En // PB // common affix -ender &) ender (_ EnV // anliggender, foretagender + &r) ender (_ anV // røvrender .group er // PB noun suffix -er (perler - pearls), -ers (perlers - pearls') -erne (perlerne - the pearls), -ernes (perlernes - the pearls') @@ -1299,9 +1348,9 @@ _influ) en (za 'En // PB &) ere (_ 3V // elskere &) eren (_ @r3n // elskeren &) erens (_ @r3ns // elskerens - &) ers (_S3 Vs // elskers + &) ers (_ Vs // elskers &) erne (_ Vn@ // elskerne - &) ernes (_S5 Vn@s // elskernes + &) ernes (_ Vn@s // elskernes &) erste (_ Vst@ //midterste &) ert (_ Vt // lummert @@ -1317,7 +1366,9 @@ _influ) en (za 'En // PB vurd) ere (_ er3 // overvurdere ng) er (_++ V // unger revolv) er V // PB + skid) er Vr // PB all) er V // PB allersidst + all) er (g er // PB allergisk j) er (n+ Er // jern j) er (ne++ Er // PB stjerne bunk) er V // PB not a -er suffix @@ -1362,6 +1413,8 @@ _perif) er 'er // PB stressed &) er ($p_alt++ ''er // PB stressed - repeter // exceptions fing) er (en VR // fingeren - clsashes with 'fing'ere' + _barb) er 'er // PB + lev) er (eg+ @r // PB leveregel // PB stressed e in words with -ering (1.100) in da_ list - likvidering &) ering ($p_alt ''ereN @@ -1389,6 +1442,8 @@ reserv) ert 'ert C) er (At V // PB probably way too broad - offeret c) er (e+ e // PB velkvalificeret + v) er (et er // PB kultiverret + t) er (et er // PB citeret bl) er (e er // PB genetablere desp) er (at 3R // PB desperat d) er (fra er // PB derfra @@ -1421,7 +1476,8 @@ reserv) ert 'ert _inf) er (no 'Er // PB inferno st) er (et r // PB orkesteret t) er (C V // PB lattermild - t) er (m Er // PB terminal + int) er (n+ 'Er // PB + t) er (min Er // PB terminal t) er (p Er // PB terpentin, terpe t) er (mo Er // PB termometer t) er (r E // PB terror @@ -1448,15 +1504,18 @@ L06L06) er V // PB klipper _l) er (_++ er // PB ler v) er (r_ er // PB levere th) er_ V // Luther + gt) er V // PB agter hj) er Er // PB hjerne stj) er+ Er // PB stjerne + øl) er V // PB brøler t) erræn &r'&#N // PB terræn _g) er (ne_+ Er // PB gerne j) er (g Er // PB bjerg @m) er (sk V // PB romersk ob) er (st V // PB + rooms) ervice Wvis // PB + d) erby A:bi // PB _all) erede (_ @reD@ -// &) eren (s_ 3r3n .group ed // PB verb suffix - ede (elskede - lovede) @@ -1473,6 +1532,7 @@ L06L06) er V // PB klipper _fr) ede (_+ ED@ // PB frede vr) ede (_+ ED@ // PB vrede ler) ede (_+ ED@ // PB fuglerede + b) ede (_+ eD@ // PB embede hindr) ede (_ 3D@ // PB forhindrede år) ede (_+ 3D@ // PB sårede odr) ede (_+ 3D@ // PB fodrede @@ -1490,9 +1550,13 @@ L06L06) er V // PB klipper // PB exceptions: not a 'et suffix _sk) et et // PB sket + el) et (+ et // PB pærelet + geb) et (+ 'et // PB s) et (_+ et // PB set it) et (_+ 'et // aktivitet _rak) et 'Et // PB raket + _brik) et 'Et // PB + brik) et Et // PB _toil) et 'Et // PB toilet, toilette _kok) et 'Et // PB stressed - koketteri, koket _kvint) et 'Et // PB @@ -1502,7 +1566,10 @@ _kvart) et 'Et // PB _tromp) et 'et // PB stressed tromp) et et // PB _klarin) et 'et // PB +_servi) et 'et // PB + servi) et et // PB klarin) et et // PB + _plan) et 'et // PB meg) et (+ et // PB not a suffix om) et (++ 'et // PB kilometer, kometer r) et (_++ &#t // ret @@ -1519,6 +1586,7 @@ klarin) et et // PB _bill) ett 'et // PB stressed - only one t _kask) et 'et // PB stressed _bajon) et 'Et // PB stressed +_tabur) et (+ '&#t // PB bajon) et Et // PB udsl) et et // PB udslet intern) et Et // PB @@ -1622,6 +1690,7 @@ _vinaigr) ette '&t@ g g gg (e g // lægge ru) g // PB rug, rugmel + fru) g (t g // PB æ) g (ernA j // PB lægerne o) g (ernA // PB nekrologerne sti) gmata gm'&:t& // PB stressed @@ -1639,6 +1708,7 @@ _vinaigr) ette '&t@ al) geriet Sj3r'i@d // PB Algeriet al) gerier Sj'iV // PB Algeriet al) gerisk Sj'i:rsg + guinea gin'e& // PB ødi) g (t_ // nødigt i) g (i g g (entl j // PB egentlig @@ -1667,6 +1737,8 @@ _vinaigr) ette '&t@ spur) gte t@ // PB silent g - spurgte n) gæ gE Co) g w // PB sprog, tog, toge + vo) g (t g // PB bevogtning + surro) g (at g // PB to) g (a g // PB exception toga to) g (o g // PB exception Togo to) g (t g // PB exception togt @@ -1676,6 +1748,7 @@ _vinaigr) ette '&t@ o) g (raf g // autograf o) g (n u // PB g => u - vogn, sogn r) g (_ w + ær) g w // PB bjærge r) g (er_ u // PB herberger u) g (e : u) g (ene S // PB ugenert @@ -1737,6 +1810,7 @@ _vinaigr) ette '&t@ å) g u // PB åg, åge ni) gger gV // PB nigger ne) g (_ j // PB neg, juleneg + ve) g (en j // PB undvegen ne) ger (++ V // PB neger te) g (ori g // kategori gear gir // PB gear, bakgear @@ -1751,6 +1825,7 @@ _vinaigr) ette '&t@ geneve Sen'E:v // PB genève Sen'E:v // PB _) gudskelov (_ gusg@lVu // PB + georgia dZV:dZj& .group ge @@ -1804,6 +1879,7 @@ _korte) ge =Se hitech hajtek // PB homer hom'er // PB Homer - Greek hawaii h&w'a:ji // PB + heather hEDV // PB .group i i i // PB i: => i - made a lot of rules redundant @@ -1841,12 +1917,17 @@ _princ) i (p 'i // PB stressed _alb) i (no 'i // PB stressed n) ij (megen aj // PB Nijmegen n) i (gg e // PB nigger + n) i (p e // PB nip, nippe n) i (ss e // PB nisse skr) i (pt 'e? // PB stressed - manuskript r) i (ft e // PB skrift, rift, drift v) i (ft e // PB vifte + d) i (sk e // PB købmandsdisk + d) i (skett i // PB diskette + d) i (sku i // PB diskutere kr) i (cket e // PB f) i (sk e // PB + gr) i (m e // PB l) i (lla e // PB kv) i (st e // PB @@ -1856,7 +1937,7 @@ _princ) i (p 'i // PB stressed // therefore u- is removed in group u before the word is translated // since the u+list words keep the stress. // Any other syllable before the word reverts to normal stress - &) ig ($p_alt+ =i // velærværdig, gudvelbehagelig + &) ig ($p_alt++ =i // velærværdig, gudvelbehagelig ige i:@ // PB deleted [(_] - pige, pigen, stige, sige iger i:V // PB piger @@ -1864,7 +1945,7 @@ _princ) i (p 'i // PB stressed kr) igen i:3n // PB krigen dil) igen (ce iS'AN // PB diligence kr) igs is - d) ige (r ig'e // PB redigere + ed) ige (r ig'e // PB redigere rr) ige (r ig'e // PB korrigere nav) ige (r ig'e // PB navigere dir) ige (r ig'e // PB dirigere @@ -1872,16 +1953,11 @@ intell) ige (n ig'e // PB intelligent fr) igea (r igi // PB frigear _) ige (n ig'E // PB igen rol) ige iE // PB rolige, beroligende + værd) ig i // PB silent g idel i:D@l // PB idel israel isrA:l // PB Israel vend) ige i:3 // PB nødvendige iew j'u -// i (nK i -// i (ng e // PB Inge, ingen -// sv) i (ng e // PB sving -// v) i (nk e // PB vinkel -// v) i (ng e // PB vinge -// s) i (nk e // PB sinke i (nL11 e //PB blinke, sinke, vinge, sving v) i (nkæld i // PB vinkælder s) i (d e // PB sidde @@ -1894,19 +1970,25 @@ intell) ige (n ig'e // PB intelligent dr) i (l e // PB drille br) i (lle e // PB briller i (dt e // PB midt, lidt + _sol) i (d 'i // PB solid b) i (dt i // PB bidt + b) i (tter e // PB sm) i (dt i // PB sk) i (dt i // PB skidt + sk) i (mm e // PB skimmel mask) i (n 'i // PB stressed - maskinskrive h) i (d i // PB hidtil b) i (lled e / PB billede kr) i (dt i // PB skridt, kridt v) i (dt i // PB vidt + v) i (sse e // PB visse, forvisse forv) i (s i // PB forvise l) i (st e // PB liste i (nd e // PB ind i (nt e // PB intakt f) i (nt_ i // PB + v) i (mp e // PB vimpel + h) i (m e // PB himmel am) i (go 'i // PB amigo magas) i 'i // PB magasin _kap) i (tel 'i // PB stressed @@ -1927,6 +2009,7 @@ intell) ige (n ig'e // PB intelligent // PB words with final -ik in da_list - stressed i &) ik ($p_alt ''ik // romantik + &) ik (er$p_alt =ik // romantiker &r) ik ($p_alt ''ek // fabrik &) ik (k$p_alt ''i // antikke - only one k &r) ik (k$p_alt ''e // fabrikker - only one k @@ -1971,14 +2054,16 @@ _konfl) i (kt 'i // PB stressed _just) i (ts 'i // PB _kul) i (ss 'i // PB kulisse i (nn e - i (mK e +// i (mK e l) i (m i // PB lim gl) i (m e // PB glimt, glimrende i (kK e // PB ikke, pik + lin) i (k i // PB klinik @t) i (k i // PB ferieromantik sk) i (k i // PB skikkelse _art) i (k 'i // PB stressed artikkel m) i (k i // PB mikroskop +gudhjælpem) ig aj // PB g) i (k+ i // PB begik i (x e // PB fixe m) i (ks e // PB mikse @@ -1987,10 +2072,11 @@ _konfl) i (kt 'i // PB stressed _g) i (k_ i // PB i (k@ i // PB antikvar v) i (k i // PB kvik - v) i (kl e // OB vikle + v) i (kl e // PB vikle k) i (kC+ i // PB kiks, kikkert l) i (kv i // PB likvid fl) i (C i // PB flid + fl) ig i // PB høflig r) ikk (+ ek // PB skiderikker t) i (me i: // PB time s) i (dA+ i: // PB siden @@ -2004,16 +2090,21 @@ _konfl) i (kt 'i // PB stressed st) i (k e // PB stik spl) i (t e // PB splitte d) i (gt e // PB heltedigt + sned) i (g i // PB ld) ig i // PB heldig l) i (p e // PB slippe r) i (k e // PB drik, skiderik - l) i (dt e // PB lidt + br) i (ke i // PB briket + _l) i (dt e // PB lidt + bl) i (dt i // PB L08) i (l_ e // PB spil, skil st) i (l_ i // PB stil + best) i (l e // PB L08) i (lt e // PB skilt, adskilt spl) i (n e // PB splint L08) i (ll e // PB spille - problem with the verb (ud)spile/(ud)spil[sbil] L08) i (ld i // PB spilde + L08) i (ls e // PB skilsmisse sk) i (ldr e // PB skildring m) i (dda e // PB middag m) i (ste e // PB miste @@ -2022,8 +2113,7 @@ _konfl) i (kt 'i // PB stressed L08) i (L06 i // PB skib tv) i (v i // PB tvivl v) i (gt e // PB vigtig - ev) i (g i // PB evigt, evindelig - værd) ig i // PB silent g + ev) ig i // PB evigt, evindelig v) i (l_+ e // PB vil hv) i (l+ i // PB hvil hv) i (lk+ e // PB hvilken @@ -2064,7 +2154,7 @@ revers) i (bel 'i // PB stressed suggest) i (bel 'i // PB stressed vis) i (bel 'i // PB stressed _medl) i (denhed 'i // PB medlidenhed - stressed - _omkr) i (ng 'e? // PB stressed e in 'omkring' + _omkr) i (ng 'e // PB stressed e in 'omkring' kn) i (p e? // PB knippel kn) i (v i // PB kniv _min) i (ster_ 'i // PB minister - stressed i @@ -2074,6 +2164,7 @@ suggest) i (bel 'i // PB stressed d) ie (sel i // PB dieselolie k) io (sk jV // PB kiosk tr) i (ck e // PB trick + r) i (bs e // PB _franc) i (sco 'i // PB // PB put stress on the syllable before final 'ium' - words in da_list @@ -2088,6 +2179,7 @@ _franc) i (sco 'i // PB // PB stressed i in words with final -mi in da_list &m) i ($p_alt ''i // økonomi + &m) i (sk$p_alt =i // stress on the previous syllable - økonomisk // PB stressed i in words with final -il in da_list &) il ($p_alt 'il // pædofil @@ -2107,6 +2199,7 @@ _rapsod) i 'i // PB rapsodi _abbed) i 'i // PB _ortopæd) i 'i // PB ortopædi swah) i (li 'i // PB stressed i +_hæmor) i (d 'i // PB hæmorider // stressed final i _akromegal) i 'i _anomal) i 'i @@ -2151,6 +2244,7 @@ _terap) i 'i &s) i ($p_alt 'i // fantasi, afasi v) i (sk e // PB viskelæder + v) i (sne e // PB l) i (e j r) i (gt e // PB rigtigt l) ig (g+ e // PB ligge - only one g @@ -2178,6 +2272,7 @@ _terap) i 'i .group is // PB words ending with -ist in da_list with $alt - stressed i &) ist ($p_alt ''ist // bassist + &) ist (ik$p_altS4 ist''ik // journalistik .group it // PB words with final -it - stressed i @@ -2222,8 +2317,10 @@ _sport) iv 'iw j (ohn dZ joe dZOu jackie dZ&ki // PB + junkie dZVnki // PB jo (ckey dZV // PB _) j (im_ dZ // PB + jimmy dZemi // PB _) j (eff dZ // PB j (azz dZ // PB je (t dZE // PB jetfly @@ -2259,6 +2356,7 @@ _sport) iv 'iw kk k kanterel kant@r'&#l // PB kumquat kVmkwVd // PB + kakerlak kak@l'ak // PB &) kvarter kvarter // PB kommandokvarter s) k g _spe) k (takk ' // silent k, stresssed a - spektakkel @@ -2288,6 +2386,7 @@ _sport) iv 'iw f) l l/2 // PB add a bit more to l after f b) l l/2 // PB add a bit more to l after b &) ld (er l // PB silent d - anmelder + sø) lv l // PB silent v se) lv l // PB selv, selvfølgelig, selvhjælp se) lv (e lv // PB selve, selvet bo) ld ld @@ -2298,7 +2397,7 @@ _sport) iv 'iw lotion l3uSjn // PB håndlotion lorraine loRE:n // PB name he) lg (e lj // PB Helge, helgen - levere lev'eV // PB +// levere lev'eV // PB _) lee (_ li: // PB the name Lee @) levere leveV // PB ley li // PB volley @@ -2314,6 +2413,7 @@ _sport) iv 'iw _) mere (_ mer // PB mere matine m&tin'e // PB _) meget (_ ma:j@D // PB meget + _) megen (_ ma:j@n // PB megen _) medea med'E:& // PB Medea montgomery mVndg'Vmri // PB mareridt mA:@rit // PB @@ -2330,6 +2430,7 @@ _sport) iv 'iw madero _^_ES // PB money mVni // PB makeup mEjk'Vb // PB + madagaskar m&d&g'&sk& // PB .group me // PB General rule for words with -ment @@ -2411,6 +2512,7 @@ _bombarde) ment m'AN // PB bombardement // PB words with final -ni in da_list - stressed i &) ni ($p_alt+ 'ni // ironi &) ni (sk$p_alt+ =ni // ironisk - stress on pervious syllable before sk +_harmo) nika =nik& // PB stressed o // PB nouns with final -ner ("er" has been removed) in da_list // stressed previous syllable @@ -2433,6 +2535,7 @@ _bombarde) ment m'AN // PB bombardement _) naiv n&'iv // PB naiv @) naiv n&iv // PB bundnaiv _) new (_ %nju // PB + newzealand njus'el&n // PB .group nd // PB general rule: nd = [n] after a vowel @@ -2442,11 +2545,16 @@ _bombarde) ment m'AN // PB bombardement A) nd (el nd // PB andel, ejendel e) nd (elig n // PB endelig ve) ndig ndi // PB udvendig + å) nd (eli n // PB åndelig ha) nd (el n // PB + y) ndig ndi // PB ke) nd (el nd // PB kendelse + spe) nd (er nd // PB spendere + svi) nd (el n // PB nd (om nd // PB ejendom nd (ød nd // PB stendød bi) nd (e n // PB forbindelse + mi) nd (e n // PB mindelund u) nde (l n // PB silent de - misundelig ble) nd (e nd // PB blender ba) nd (it nd // PB bandit @@ -2541,19 +2649,24 @@ elektr) o (de 'o peri) o (de 'o oo u: //PB English words like 'pool' + h) ood u:d // PB Robin Hood + r) o (bin V // PB k) oor (d oV:? // PB koordinat _biot) o (p 'o // PB stressed _isot) o (p 'o // PB stressed o (L06 V // PN op, opdrage, obstruere + o (pi o // PB opium + _t) o (bak o' // PB tobak vide) o o // PB videobånd gl) o o // PB global - kn) o (b o // PB - br) o (ccoli V // PB + kn) o (L06 o // PB knob, knop + h) o (lding Ou // PB holdingselskab + br) occ (oli Vk // PB helik) o (pt 'V // PB stressed - helikopter p) o (pu o // PB populær p) o (t V // PB potte d) o (nald V // PB name - p) o (tA o // PB potage + p) o (tag o // PB potage o (per o // PB opera sk) o o // PB skopudser _sk) o (d V // PB skod @@ -2570,7 +2683,9 @@ elektr) o (de 'o r) o (L06 o // PB problem pr) o (p V // PB blodprop kr) o (p V // PB - gr) o (g V // PB groggy + gr) ogg Vg // PB groggy + gr) og Vg // PB grog + k) og (t Vg // PB hvalr) o (s V // PB _eur) o (pa 'o // PB stressed dr) o (p V // PB droppe @@ -2581,6 +2696,7 @@ elektr) o (de 'o Ca) o (s V // PB kaos Laos r) o (ma o // PB romantik org (+ V:w // PB sorg, morgen, Norge + ge) org (ine og // PB o (rga+ V // PB organ r) or (g oR // PB rorgænger kont) o (r 'o // PB kontor - stressed @@ -2588,6 +2704,7 @@ korrid) o (r 'o // PB labrad) o (r 'V // PB mete) o (r 'o // PB matad) o (r 'o // PN + sam) o (a 'o // PB katastr) o (fe 'o: // PB katastrofe lit) o (te 'o: // PB stressed en) o (rm 'V // PB stressed @@ -2613,13 +2730,17 @@ _horis) o (n 'V // PB horisont kan) o (n o // PB not stressed after a syllable o (dds V: // PB odds o (sse V // PB tosse, nosse + m) o (sset o // PB j) o (b V // PB job mon) o (k 'V // PB monokel - stressed ov (e+ Vu // PB over, oven + t) ov (er ov // PB tatovere k) ov (end ov // PB kovending ov (ærn+ ov // autoværn h) ov (+ Vu // hov, sove ov (+ Vw // PB sjov, lov, skov + o (vi+ o // PB pseudovidenskabelig + tr) o (v o // PB troværdig sk) ov (tur Vw // PB l) ov (_mig_ ow // PB from the verb "at love" ov (s_+ Vw // PB sjovs, lovs, skovs @@ -2629,8 +2750,10 @@ _horis) o (n 'V // PB horisont ov (p Vw // PB lovprise v) ov (e Ov // PB vove o (fC V // PB ofte + skiz) o (fren o // PB n) ov (++ ov // PB nova, november _C) o (k 'V // PB beginning with 1 consonant followed by o and k: sok, nok, kok + k) o (kos o // PB p) o (ka o // PB pokal p) o (ker o // PB bet) on VN // PB betonen @@ -2641,6 +2764,8 @@ _horis) o (n 'V // PB horisont o (mf V // PB omformulere _m) o (rt V // PB mortadel o (k V // PB okker, lok + kr) o (k o // PB krokus + v) o (ke o // PB provokere r) o (ke o // PB neurokemi o (ktob %o // PB stressed next syllable - oktober fr) o o // PB frokost @@ -2648,6 +2773,7 @@ _horis) o (n 'V // PB horisont f) o (kA o // PB fokus, fokal o (ka o // PB lokal, polal o (rk V // PB orke orkester + f) o (s V // PB fosfat g) o (dt V // PB godt, godte k) or (p V: // PB korps k) or (pi or // PB korpige @@ -2678,6 +2804,7 @@ _horis) o (n 'V // PB horisont k) ors V:s // PB kors, korsage c) o (rs V // PB corsage k) o (lL06 V // PB kolbe + k) o (gl V // PB kogle bistr) o 'o // PB stressed o in 'bistro' er) o (b 'o // PB erobre - stressed o _er) o (t 'o // PB erot - stressed o @@ -2687,7 +2814,7 @@ _horis) o (n 'V // PB horisont _metad) o (n 'o PB stressed ang) o (la 'o // PB stressed L09) o (va o // PB nova, renovation - pr) o (vA+ ov // PB provokere + pr) o (vA+ o // PB provokere h) oved o:@D // PB hoved tr) o o // PB tro kn) o (tt V // PB knotten @@ -2699,9 +2826,12 @@ _metad) o (n 'o PB stressed p) olish VliS // PB møbelpolish tr) o (kl V // PB trokle tr) o (p V // PB trop + tr) o (po o // PB antropolog tr) o (pi o // PB tropisk tr) o (pe o // PB troperne t) or V // PB faktor + t) or (n or // PB + t) or (ny V // PB tornyster t) or (e o // PB faktorer t) or (en V // PB faktoren, doktoren oy (+ 'Vj // PB destroyer, royal, loyal @@ -2710,6 +2840,7 @@ _metad) o (n 'o PB stressed st) o (r+ o // PB stor p) o (r O // PB porno _m) o (C o // PB m + o + consonant: mor, mord, + m) ontana Vnt'&n& // PB m) o (ms V // PB m) o (kk V // PB mokke, mokka m) o (nitor V // PB @@ -2743,6 +2874,8 @@ _metad) o (n 'o PB stressed Xl) o (m V // PB lom, lomme, blomst pl) o (m o // PB exception from the rule above (Xl) o (m) - plombe o (m V // PB om, ensom VERY BROAD + kr) o (m o // PB krom + o (mi o // PB sodomi f) o (m o // PB nymfoman fot) o o // PB r) o (mA o // PB romer @@ -2768,15 +2901,20 @@ _metad) o (n 'o PB stressed o (se o: // PB rose, skose, pose h) o (spice V // PB hospice C) o (st V // PB post, moster + komp) o (st 'V // PB stressed r) o (st o // PB rost + pr) o (sta V // PB prostata fr) o (st V // PB - f) oged o:@D // PB silent g + f) oged o:@D // PB silent g k) o (sC V // PB kosmisk + kok) o (s o // PB kokosnød k) o (st o // PB kost (broom) Problem with kost = food k) o (ste V // PB verb - koste = brooms will be mispronounced + k) o (stbar V // PB + bek) o (st V // OB bekostning frok) o (st V // PB omk) o (st V // PB omkostninger - pr) o (s o // PB prostitueret + pr) o (sti o // PB prostitueret st) o (mi o // PB stomi h) o (st o // PB host Cl) o (t V // PB flot @@ -2849,6 +2987,8 @@ _filos) o (fisk 'o //PB tr) o (ld V // PB trold kn) o (ld V // PB knold sn) o (t V // PB snot + h) otdog VtdVg // PB + _h) o (t_ V // PB or (l O: // PB orlov oscar VskA // PB @@ -2903,7 +3043,7 @@ _maked) on 'on // PB makedoner enf) or 'V // PB k) or (t V:? // PB kort m) orge V:3 // PB morgen - dek) or 'V:r // PB dekor + dek) or (_ 'V:r // PB dekor rapp) or (t 'V: // PB rapport f) or (t V:? // PB fort m) or (f V: // PB morfar @@ -2914,7 +3054,7 @@ _maked) on 'on // PB makedoner _) or V // PB orientere orm orm // PB n) or (m O // PB - st) or (m O:? // PB + st) or (m O: // PB b) or (t Vr // PB bortforklare or (al oR // PB oral _esk) or (te 'V: // PB eskorte @@ -2955,6 +3095,7 @@ _success) or =V f) ord (æ Vd' // PB fordærve f) ord (ø Vd' // PB fordømme ord (en+ Vrd // PB orden, ordensmagt + t) ord (en ord // PB j) ord (en oV // PB fjorden jorden ord (entlig+ 'Vrd // PB overordentlig - stressed ord (ne+ Vrd // PB ordne @@ -3085,7 +3226,7 @@ _success) or =V _f) or (mand 'V // PB formand, formandsskifte _f) or (mbar 'V // PB formbar _f) or (mbrød 'V // PB formbrød - _f) or (me 'V // PB forme + _f) or (me+ 'V // PB forme _f) or (melig 'V // PB formelig _f) ormer (_ 'VrmV // PB former - problem with "formér" _f) or (mfast 'Vr // PB formfast @@ -3221,6 +3362,7 @@ _success) or =V _) på (ske p'O // PB not a prefix - påske &) p (_ p // PB hjælp p (syk // psykolog [s,ykol'o] + sym) p (tom // PB silent p pipeline pajplajn // PB pitchpine peTSpa:jn // pb praline pRAlin'e // PB @@ -3230,6 +3372,7 @@ _success) or =V protegé prod@S'e // PB protegé _) passager p&s&sj'er // PB passager peanut pi:nVd // PB + pseu sWw // PB pseudo .group ph @@ -3248,10 +3391,12 @@ _success) or =V rr R rickshaw rekSV: // PB rickshaw rickshawer rekSV:V // PB rickshawer + _) reservoir resErvo'a: // PB + reservoir resErvoa: // PB recut rikVd // PB - reggae REgEj - rioja ri'Vk& - ramirez _^_ES + reggae REgEj // PB + rioja ri'Vk& // PB wine + ramirez _^_ES // PB name reece ri:s // PB name r (K r // not followed by a vowel hve) r r // PB hver @@ -3291,6 +3436,7 @@ transpo) r (t //PB transport s s ss s sc s // PB scene + me) sc (al sk // PB sco (t skV // PB Scotland Yard // PB/JD s suffix - $alt words in da_list // 2-3.000 words end with s, so this cannot be a general suffix. @@ -3376,6 +3522,8 @@ franci) sc (o sk // PB Francisco for_) sig (_ saj // PB se noget for sig fra_) sig (_ saj // PB slå fra sig stå_) sig (_ saj // PB stå sig godt med + slå_) sig (_ saj // PB + slår_) sig (_ saj // PB _) sig (_alene saj // PB klare sig alene vende_) sig (_ saj // PB erklære_) sig (_ saj // PB @@ -3387,6 +3535,7 @@ hygge_) sig (_ saj // PB _) sig (_ud_ saj // PB rode sig ud i _) sig (_af_ saj // PB tage sig af ak_) sig (_ saj // PB drak sig fuld + gik_) sig (_ saj // PB gik sig en tur s) s // PB use [sV] instead pf [sO] @@ -3613,6 +3762,8 @@ meningi) ti (s =ti u (nK u u (nL08 O // PB kunst br) unch VnS // PB + ketch) u (p V // PB + s) ui (te wi // PB st) u (nt V // PB stuntman b) urg (er Wg // PB u (ng O // PB ung @@ -3627,13 +3778,21 @@ meningi) ti (s =ti _glas) u (r 'u // PB stressed _abs) u (rd 'u // PB stressed _fig) u (r 'u // PB stressed + _harp) u (n 'u // PB stressed l) u (f 0 // PB luft +// l) u (gt 0 // PB +// b) u (gt 0 // PB +// fr) u (gt 0 // PB +// f) u (gt 0 // PB fugt + m) u (L11 0 // PB mug + C) u (gt 0 // frugt, fugt, lugt + sl) u (gt u // PB + b) u (gta u // PB bugtasler l) u (n_ u // PB lun l) u (ne u // PB lune l) u (nte 0 // PB lunte l) u (ka u // Lukas h) u (nd u // PB hund - u (gt 0 // PB fugt r) u (s u r) u (st O // PB udrustning ue (_ u: // PB due, vindue, statue @@ -3666,6 +3825,7 @@ centrif) u (g 'u // PB stressed hovedk) u (ls u // PB k) u (ld u // PB kulde omk) u (ld 'u // PB + imp) u (ls 'u // PB stressed k) u (le u // PB kule sk) u (ll+ u // PB skulle k) u (lt u // PB kultur @@ -3680,6 +3840,7 @@ hovedk) u (ls u // PB sn) u (L06 0 // PB snup s) u (L06 0 // PB suppe u (nk 0 // PB sunket + h) u (n u // PB hunkøn s) u (per u // PB s) u (k 0 // PB suk, sukker sk) u (f 0 // PB skuffe @@ -3694,6 +3855,7 @@ hovedk) u (ls u // PB d) u (ft 0 // PB duft f) u (n+ 0 // PB funktion, karpunkel p) u (k 0 // PB pukle + p) u (lv 0 // PB pulver _r) u (b_ O // PB rub n) u (l 0 // PB nul _r) u (bbe O // PB rubbe, rubbet @@ -3710,6 +3872,7 @@ hovedk) u (ls u // PB _der) u (d 'u // PB stressed - derud r) u u r) u (p O // PB korrupt + gr) u (p u // PB gruppe r) u (m O s) u (cc y b) u (dget y @@ -3809,6 +3972,7 @@ proven) u y sm) y (k W // PB smykke lib) y i // // PB Libyen l) y (st @ // PB problem with lyst = blond, light coloured + l) y (stre Y // PB lystre _l) y (ste_ y // PB &l) y (st y // PB åbenlyst fl) y y // PB flystøtte @@ -3834,7 +3998,7 @@ _molek) y (le 'y // PB stressed k) yss Ws // PB kysse k) y (se y: // PB kyse y (nK W // PB changed from Y to W - synge, ynde - s) y (nsk y // PB + s) y (ns y // PB s) y (nl y // PB synlig s) y (nkr y // PB synkron s) y (nt y // PB syntes @@ -3855,8 +4019,12 @@ _molek) y (le 'y // PB stressed yacht jagd // PB lystyacht york JV:k // PB yankee j&nki // PB + bill) y i // PB luc) y i // PB ken) y (a j // PB + kan) y (le 'Y // PB stressed + _kab) y (s 'Y // PB stressed + _kah) y (t 'Y // PB stressed d) y (_ i b) y (A y n) y (A y @@ -3875,7 +4043,7 @@ _molek) y (le 'y // PB stressed &) ær ($p_alt 'Er // elementær // æ (CK E - r) æ (d a // PB forræder + r) æ (dd a // PB forræder pr) ædi ED // PB prædiken æ (bK E // PB dræb, slæb æ (bt &# // PB dræbt @@ -3883,11 +4051,13 @@ _molek) y (le 'y // PB stressed tr) æ (d+ E // PB træde tr) æ (n &# // PB trænge tr) æ (ne E // PB træne - kr) æ (f &# // PB kræfter - kr) æ (m &# // PB skræmme, kræmmer - r) æ (n &# // PB changed from [Aj] - rænke - r) æ (k &# // PB række - r) æ (t &# // PB åndedræt + dr) æ (n E // PB dræne +// kr) æ (f &# // PB kræfter +// kr) æ (m &# // PB skræmme, kræmmer +// r) æ (n &# // PB changed from [Aj] - rænke +// r) æ (k &# // PB række +// r) æ (t &# // PB åndedræt + r) æ (C &# // PB rædsel pr) æ (k E // PB præke bl) ære EV // PB blærerøv gr) æ (ken E // Grækenland @@ -3934,6 +4104,7 @@ majest) æ (t 'E // PB stressed æ øjer W#jV // PB bøjer ø (jn W# // PB øjne l) øg 'Vj // løgn, løg + g) øg (l Vj // PB gøgler l) ø (s W C) ø (j W# // PB søjle, bøjle L09) ø (g V // PB m => L09 (m + n) - møg @@ -3954,7 +4125,7 @@ majest) æ (t 'E // PB stressed æ ø (re_ W: // PB køre r) ø (ver W# // PB røver r) ø (v W# // PB røv - k) ø (d W // PB skød, kød + k) ød WD // PB skød, kød _) øg (_ Wj // PB 'øg' noun and verb d) øg (n Vj øj+ V:j // PB changet from [Oj] @@ -3974,7 +4145,7 @@ majest) æ (t 'E // PB stressed æ ovenp) å (_ 'O // PB stressed r) å (d+ O: // PB råd r) å (dn+ V // PB rådne - r) å (dd V // PB rådden + r) å (dd+ V // PB rådden tr) å (dt V // PB overtrådt r) å (dg+ V // PB rådgive ård O:? // PB gårdmand, bondegård - silent d @@ -3993,6 +4164,7 @@ uimodst) å (elig 'O // PB stressed forh) åbentlig 'ObEntli // PB stressed h) år V:? // PB hår, hård bl) å (@ V // PB blåbær, blågrå + bl) å (t V // PB å (nd V // PB hånd, ånd, bånd l) å (r V p) å (s V // PB påstand @@ -4010,6 +4182,7 @@ uimodst) å (elig 'O // PB stressed r) å (bt V // PB råbte år V: // PB år, står åre V3 // PB tåre + å (lti V // PB måltid .group $ dVlV // PB changed from [dVlar] @@ -4017,4 +4190,5 @@ uimodst) å (elig 'O // PB stressed ï i: // PB Thaïs 'er (_ %V // PB 60'er 'erne (_ %Vn@ // PB 60'erne + 'ernes (_ %Vn@s // PB 60'ernes 'en (_S3 %@n // PB EMP'en - doesn't work diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index 9bc2b941..e4ed037f 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -3,207 +3,626 @@ Phonemes which are used in the *_rules and *_list files Dictionary af_dict +& &: 3: @ @- @L @U a +A: aI AI aU A~ E e: e@ +eI e~ i I iu O O: o@ +OI oI o~ u uI W y Y@ +Yy + +- : ; ? b c d dZ +f g h j k l l# m +n N n^ p r s S t +T tS v w x x2 z Z Dictionary ca_dict +@ a a# aI e E E2 i +o O u U + +* ** : ; b B d D +dZ; f g j J J^ k l +l^ m n N n^ p Q R +R2 s S; t T ts tS; v +v# w z Z Z; Dictionary cs_dict +@- a a: aU e e: eI eU +i i: l- o o: oU r- u +u: + +* ; b c d dZ dz f +g h j J k l l^ m +n N n^ p r R R^ R^/ +s S t tS ts v x z +Z Dictionary cy_dict +@ @- @I @Y a A: aI aU +AY aY E e: eU I i: Iu +O o: OI OY U u: uY V +Y y: Yu + +: b C d D dZ f g +h j k l l# m n N +p r s S t T v w +x z Dictionary da_dict +& &# 0 3 @ @- a A +e E i o O u V W +W# y Y + +* - : ? b B d D +dZ f g h j J k l +l/2 l/3 m n N p r R +s S t T tS v w z Dictionary hu_dict +A a: E e: i i: o o: +u u: Y y y: Y: + +- : b c d dZ dz f +g h j J k l m n +n^ p r R R2 s S s2 +t tS ts v z Z Dictionary de_dict +3 3: @ @- a A A: aI +aU E E2 E: e: EI I i2 +i: n- O o: OY U u: W +y y: Y: + +* : ; b C d D dZ +f g g# h j k l m +n N p pF r s S t +tS ts v w x z Z Dictionary el_dict +@ @- a aI e i o oI +u + +* ; b c C d D f +g j k l l^ m n N +n^ p Q r R s s; t +T ts v x z z; Dictionary en_dict +0 3 3: @ @- @2 @5 @L +a a# A: A@ aa aI aI@ aU +aU@ A~ E e: e@ eI i I +I2 i: i@ i@3 IR O O: o: +O@ o@ OI oU O~ U u: U@ +V VR + +: ; ? b C d D dZ +f g g- h j k l l# +m n N n^ p Q r r- +s S t T t2 tS v w +x z Z Dictionary eo_dict +@- a aI aU e eI eU i +o oI u uI + +* - b d dZ f g h +j k l m n p r R +s S t T tS ts v w +x z Z Dictionary es_dict +a aI aU e E eI eU i +o O oI u + +* ** : b B d D f +g j J J^ k l m n +N n^ p Q R R2 s t +T tS v v# w x z Dictionary fi_dict +& &i &y a a2 ai au e +ei eu ey i I ie iu iy +o oi ou u ui uo Y y +Yi yi Yy yY + +: b d f g h j k +l m n N p r s S +s2 t v w Z Dictionary fr_dict +@ @- a A~ e E E2 E: +E~ i I o O o2 o3 O~ +u u: w W W~ y Y + +- : b d dZ f g h +j k l m n N n2 n^ +p p2 r r2 s S t t2 +t3 tS v z Z z2 z3 Dictionary grc_dict +a aI aU e E EI eU EU +i o O oI OI OU u y +yI + +: b d f g h j k +l m n N p R s t +T v x z Dictionary hbs_dict +& @ @2 a A a: aI aU +e E e: i I i: l- o +O o: oU r* r- u U u: + +* ; b d dZ dz dZ; f +g h j k l l^ m n +N n^ p r R R2 s S +t tS ts tS; v x z Z Dictionary hi_dict +@ @- @2 @3 a a: aI aU +e E e: E: E~ i I i: +l- o O o: O: O~ o~ r- +U u: u~ V + +- : b bh c ch d d. +dh dh. f g gh h H j +J Jh k kh l l. m n +N n. n^ p ph Q q r +r. s S s. t T t. th +th. v w x z Dictionary ta_dict +a a: aI aU e E e: i +I i: o o: u U u: U: +V V# + +: ; b C d d. dZ f +g h H j k l l. m +n N n. n^ p Q r R +s S s. t T t. th tS +v w z z. Dictionary hy_dict +@ a aI e eI i i@ o +u W y + +** b c d dZ dz f g +h j k k# l m n p +p# r R r" s S t t# +tS ts ts# v X z Z Dictionary id_dict +@ a aI aU e E E2 i +o O u + +: ? b d dZ f g h +j k l m n N n^ p +r R R2 s S t tS v +w x z Dictionary is_dict +@- a a: aI aI: aU aU: E +E: eI eI: i I i: I: O +O: OI oU oU: u u: W W: +y y: yI Yy Yy: + +* ** : ; b c C d +D f g h j J k l +l# m m# n N n# N# n^ +n^# p Q r R r# R2 s +S s2 t T tl# v x z Dictionary it_dict +@- a a/ aI aU e E eI +i I o O u + +* : ; b d dZ f g +h j k l l^ m n N +n^ p r R s S t tS +ts v w w2 z Dictionary jbo_dict +@ a aI aU e eI i l- +n- o oI r- u + +b d dZ f g h j k +l m n N p R s S +t tS v w x z Z Dictionary ku_dict +8 a e E E# eI eU i +I o u U y + +* : b c d dZ f g +h j J k l m n p +q r R s S t tS v +w x z Z Dictionary la_dict +@- a a: aI aU E e: EU +I i: O o: OI U u: y +y: + +* : ; ? b d f +g h j k l m n N +p r R s t w z Dictionary lv_dict +a a: ai au e e: ei i +i: ie iu o o: u u: ui +uo + +: b c d dZ f g h +j J k l l^ m n N +n^ p r R R2 s S t +tS ts v z Z Dictionary mk_dict +& @ @- @2 a A a: e +E e: i I i: l- o o: +oU r- u u: + +* b d dZ dz dZ; f g +h j k k^ l l^ m n +N n^ p r R s S t +tS ts tS; v x z Z Dictionary nci_dict +a e i o O + +: ? b c d f g j +k l m n p R s S +t tS v w x Dictionary nl_dict +8 @ @- A a: A~ E e: +EI eU i I O O: o: u +VU Wy y Y: yU + +* : ; b d f g h +j k l m n N n^ p +Q r s S t tS v v# +w x z Dictionary no_dict +@ @2 a A a: A: AI aI +aU E E: e: I i: O o: +OI U u- u-: u-I u: W y +y: Y: Yy + +: ; b d f g h j +k l m n N p r R +s S s; t v w x z Dictionary pap_dict +a a/ aI e E eI i o +O u y Y + +: ? b d dZ f g h +j k l m n N n^ p +R s S t tS v w x +z Z Dictionary pl_dict +a E E# E~ i O O~ u +y + +: ; b c C d d; dZ +dz f g h j k l m +n N n^ p r R s S +s; S; t t; tS ts tS; v +w x z Z Z; Dictionary pt_dict +& &/ &U~ &~ @ @- a A +aI aU e E eI EI eU EU +i I i/ iU o O oI OI +o~ u U uI u~ y + +* : ; b C d dZ f +g h j k l l^ m n +N n^ p Q r R r- s +S s# s; t T tS ts v +w x z Z Dictionary ro_dict +@ @- @I @U a aI aU e +ea eI eo eU i i/ I^ iI +iU o O Oa oI oU u uI +y Y yI yU + +* *; b b; c C d d; +dZ f f; g h j k l +l; m m; n N n; p p; +r s S S; t t; tS ts +ts; v v; w w2 x z Z +z; Z; Dictionary ru_dict +8 @- a A e E E# E2 +E3 i I I# I2 I3 I^ ja +ju o O u u" u# V V# +y Y + +* ; b d d; dZ; f g +j k l l^ m m; n n^ +p r R s S s; S; t +t; ts tS; v x z Z z; +Z; Dictionary sk_dict +& @- a a: e e: i i: +l- l: o o: oU r- r: u +u: + +* ; b d d; dZ dz f +g h j k l l^ m n +N n^ p r R R^ R^/ s +S t t; tS ts v x z +Z Dictionary sq_dict +@ @/ a A a/ aI e E +eI i I I# O OI u V +y yE + +** : ; b c d D dZ +dz dZ; f g h j k l +L ll m n n^ p r R +R2 s S t T tS ts v +w z Z Dictionary sv_dict +8 @ a A: E E- e: E: +I i: O o: U u- u: W +y y: Y: + +: ; b d f g h j +k l m n N p R s +S s. S; sx t v w z Dictionary sw_dict +@- a a/ e i m- n- N- +o u + +* : b d D f g h +j J k l m n N n^ +p Q R s S t T tS +v w x z Dictionary sl_dict +& @ a e E i o O +u y + +: b d dZ dz f g h +j k l l^ m n N n^ +p R R^ s S t tS ts +v w x z Z Dictionary tr_dict +@ a e E i I o O +u U W y Y + +* : b c d dZ f g +G h j J k l m n +p Q r R s S t tS +v w z Z Dictionary vi_dict +@ @: @:I @:U @I @U a a: +a:I a:U aI aU e E eU EU +i i@ iU o O OI oI u +u@ uI y y@ yI + +b c d D f g h j +J k kh l m n N n^ +p Q r s s. t t[ tS; +v w x z Z z. Dictionary zh_dict +@ @r a A ai Au E ei +i i. i[ iA iE io iou N- +o o- ong ou u u@ ua uai +uei uo y y& y@ yE yi yu + +; C f h j k kh l +l# m n N p ph Q q +Q" Q^ r R r" R2 R3 s +s. S; t th ts ts. ts. tS; +tS; tsh v w x X z. Dictionary zhy_dict +a aa aai aan aau ai au e +ei eo eoi eu i iu o oe +oi ong ou u ui yu + +b c d f g h j k +l m n N p r s t +tS v w z Dictionary am_dict +@ a e i o u y + +b d h l m q R s +S t tS Dictionary ml_dict +a a: aI aU e E e: i +I i: o o: r- u u: V +y + +: b bh c ch d d. dh +dh. dZ f g gh h j J +Jh k kh l l. m n N +n. n^ p ph R R2 s s. +S; t t. th th. tS v w +z z. Dictionary ne_dict +@ @/ @2 @3 a aI aU a~ +e E eI eU e~ E~ i I +i~ l- o O o: oI oU O~ +o~ r- u uI u~ V VI VU +V~ + +- : b bh c ch d d. +dh f g gh h H j J +Jh k kh l l. m n N +n. n^ p ph Q q r r. +s S s. t T t. th v +w x z z. Dictionary pa_dict +@ a a~ e E e~ E~ i +I i~ I~ o O O~ o~ r- +u U U~ u~ V V~ + +: ; b bh c ch d d. +dh dh. f g gh h H j +J Jh k kh l l. m n +N n. n^ p ph Q R R2 +s S t t. th th. v x +z Dictionary prs_dict +@ A E eI i o u + +: b d dZ f g h j +k l m n p r R s +S t tS v w X z Z Dictionary rw_dict +a e i o u + +* : b B c d dZ f +g h j J k l m n +N n^ p q R s S S; +t tS v w x z Dictionary ur_dict +@ a a: aI aU E e: i +I i: O o: U u: + +: b bh c ch d D d. +dh dh. dZ f g gh H j +J Jh k kh l m n N +p ph Q q R r. s S +s. t T t. th th. v x +z Z z. Dictionary bg_dict +@ a e i o u + +; b C d d; dZ dz f +g j k l L l^ m n +n^ p r s S s; t t; +tS ts v x z Z z; Dictionary nso_dict +@ a e i m- n- N- o +u + +- : b d D dZ f g +h j J k l l# m n +N n^ p Q r R R3 s +S t T tS v w x z diff --git a/dictsource/en_list b/dictsource/en_list index 8a2ca729..cf40be9e 100644 --- a/dictsource/en_list +++ b/dictsource/en_list @@ -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@ @@ -1494,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 diff --git a/dictsource/pt_rules b/dictsource/pt_rules index 742387dd..cdb2f7a3 100755 --- a/dictsource/pt_rules +++ b/dictsource/pt_rules @@ -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 diff --git a/dictsource/ta_rules b/dictsource/ta_rules index 9e1459a7..b0ddd3fc 100644 --- a/dictsource/ta_rules +++ b/dictsource/ta_rules @@ -991,13 +991,11 @@ _முகத்தின்_) ப (ாவ b சிறு) ப (ிள்ளை p ஆண்) ப (ிள்ளை p பெண்) ப (ிள்ளை p - பூம்) ப (ுகார p ம்) ப (ுரா b இன்) ப (ுற b _துன்) ப (ுற b ப (ுறK p மண்) ப (ுழு p - பூம்) ப (ுஹார p ம்) ப (ூர b ராம்) ப (ூர p அ) ப (ூர்வ b diff --git a/phsource/compile_report b/phsource/compile_report index 907ed558..71bfc9d3 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -341,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 @@ -367,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 @@ -383,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 @@ -395,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 @@ -620,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 @@ -1943,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 diff --git a/phsource/l/L2_oL b/phsource/l/L2_oL index 583e4133..1f66489e 100644 Binary files a/phsource/l/L2_oL and b/phsource/l/L2_oL differ diff --git a/src/Makefile b/src/Makefile index 13177231..d760954f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,3 @@ -# Makefile for 'espeak', 'speak', and 'libespeak' - # remove -fno-exceptions if it causes problems with stdio library on some platforms (ARM) PREFIX=/usr @@ -51,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 diff --git a/src/Makefile.espeakedit b/src/Makefile.espeakedit index ca60e3c4..861676bd 100644 --- a/src/Makefile.espeakedit +++ b/src/Makefile.espeakedit @@ -2,10 +2,10 @@ 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 \ + 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)) diff --git a/src/compiledata.cpp b/src/compiledata.cpp index d05bff6b..09d462c2 100644 --- a/src/compiledata.cpp +++ b/src/compiledata.cpp @@ -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); diff --git a/src/espeak.cpp b/src/espeak.cpp index 205a25d5..37e601a3 100644 --- a/src/espeak.cpp +++ b/src/espeak.cpp @@ -66,8 +66,10 @@ static const char *help_text = "\t directory. specifies the language\n" "--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=\"\"\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=\"\"\n" "\t Speak the names of punctuation characters during speaking. If\n" "\t = 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) { diff --git a/src/espeakedit.cpp b/src/espeakedit.cpp index b84d0b1b..788927a2 100644 --- a/src/espeakedit.cpp +++ b/src/espeakedit.cpp @@ -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++; diff --git a/src/mbrolib.h b/src/mbrolib.h deleted file mode 100644 index 0616b464..00000000 --- a/src/mbrolib.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef MBROLIB_H -#define MBROLIB_H - -/* - * mbrolib: mbrola wrapper. - * - * Copyright (C) 2007 Gilles Casse - * - * 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 diff --git a/src/mbrowrap.cpp b/src/mbrowrap.cpp new file mode 100644 index 00000000..e7673127 --- /dev/null +++ b/src/mbrowrap.cpp @@ -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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/src/mbrowrap.h b/src/mbrowrap.h new file mode 100644 index 00000000..0409507c --- /dev/null +++ b/src/mbrowrap.h @@ -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 + * + * 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 diff --git a/src/setlengths.cpp b/src/setlengths.cpp index 8261813b..43bd3c7c 100644 --- a/src/setlengths.cpp +++ b/src/setlengths.cpp @@ -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; diff --git a/src/speak.cpp b/src/speak.cpp index 7f100867..144aeb5f 100644 --- a/src/speak.cpp +++ b/src/speak.cpp @@ -98,8 +98,10 @@ static const char *help_text = "\t directory. specifies the language\n" "--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=\"\"\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=\"\"\n" "\t Speak the names of punctuation characters during speaking. If\n" "\t = 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); } diff --git a/src/speak_lib.cpp b/src/speak_lib.cpp index 77428ad6..9683f3f1 100644 --- a/src/speak_lib.cpp +++ b/src/speak_lib.cpp @@ -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 @@ -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 diff --git a/src/synthdata.cpp b/src/synthdata.cpp index da4f5b20..5334e5a9 100644 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -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; diff --git a/src/synthesize.cpp b/src/synthesize.cpp index ed05b3e7..7f739401 100644 --- a/src/synthesize.cpp +++ b/src/synthesize.cpp @@ -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 @@ -1172,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; @@ -1182,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) @@ -1198,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; @@ -1279,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; @@ -1873,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(); diff --git a/src/synthesize.h b/src/synthesize.h index e87178c2..29438122 100644 --- a/src/synthesize.h +++ b/src/synthesize.h @@ -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); diff --git a/src/translate.h b/src/translate.h index b4f0b1d3..f3bbd0e9 100644 --- a/src/translate.h +++ b/src/translate.h @@ -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; diff --git a/src/voice.h b/src/voice.h index 3f842c38..75c9337a 100644 --- a/src/voice.h +++ b/src/voice.h @@ -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); diff --git a/src/voices.cpp b/src/voices.cpp index 5e519f15..40200de2 100644 --- a/src/voices.cpp +++ b/src/voices.cpp @@ -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; diff --git a/src/wave.cpp b/src/wave.cpp index 0cef7467..56602be3 100644 --- a/src/wave.cpp +++ b/src/wave.cpp @@ -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) @@ -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) // //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)