From 2a5c9b674802623a43f547b63aee147b3b0ce60c Mon Sep 17 00:00:00 2001 From: jonsd Date: Tue, 8 May 2007 08:02:15 +0000 Subject: [PATCH] Lang=fr change to phonemes [o] [O] [A~] [O~] [R] Added new phonemes [s.] and [z.] (as common phonemes), use in Lang=ru, Lang=sv, Lang=hi Remake WAV files for [s;] and [z;] phonemes. espeak_Terminate(), set pointers to NULL after free(). espeak_Initialize(), returns EE_INTERNAL_ERROR (-1) if fails to allocate memory. Change to the default tone setting (array: tone_points in voices.cpp). git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@5 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/hi_list | 2 +- dictsource/hi_rules | 6 +- dictsource/ru_list | 10 +- dictsource/ru_rules | 94 +-- dictsource/sv_rules | 6 +- dictsource/vi_rules | 4 +- phsource/compile_report | 93 +-- phsource/ph_french | 12 +- phsource/ph_russian | 6 + phsource/phonemes | 31 +- phsource/ufric/s_pzd.wav | Bin 6326 -> 4756 bytes phsource/ufric/s_pzd_.wav | Bin 0 -> 5674 bytes phsource/ufric/sh_rfx.wav | Bin 0 -> 4956 bytes phsource/vnasal/o_n3 | Bin 7280 -> 7276 bytes phsource/vnasal/oo_n | Bin 1573 -> 7276 bytes phsource/vnasal/vowelchart.png | Bin 20108 -> 20115 bytes phsource/vowel/V | Bin 951 -> 951 bytes phsource/vowel/V_2 | Bin 6237 -> 6239 bytes phsource/vwl_fr/@R | Bin 1318 -> 1318 bytes src/dictionary.cpp | 4 +- src/intonation.cpp | 2 +- src/readclause.cpp | 7 +- src/speak_lib.cpp | 8 +- src/speak_lib.h | 2 +- src/speak_riscos.cpp | 1234 ++++++++++++++++++++++++++++++++ src/synthdata.cpp | 2 +- src/tr_languages.cpp | 4 +- src/translate.h | 2 +- src/voices.cpp | 16 +- 29 files changed, 1413 insertions(+), 132 deletions(-) create mode 100644 phsource/ufric/s_pzd_.wav create mode 100644 phsource/ufric/sh_rfx.wav create mode 100644 src/speak_riscos.cpp diff --git a/dictsource/hi_list b/dictsource/hi_list index 52330a0a..ab3e5b47 100755 --- a/dictsource/hi_list +++ b/dictsource/hi_list @@ -156,7 +156,7 @@ _dpt _d@s@ml'o:_ // ?? what is Hi for "." ? ऱ r@ व v@ श S@ -ष S@ // should be retroflex [S] +ष s.@ // should be retroflex [S] स s@ ह H@ क़ q@ diff --git a/dictsource/hi_rules b/dictsource/hi_rules index 81ec0dec..7c916eb7 100755 --- a/dictsource/hi_rules +++ b/dictsource/hi_rules @@ -347,9 +347,9 @@ ?1 श (_ S .group ष - ष SV //?? or retroflex [S] - ष (B S //?? -?1 ष (_ S //?? + ष s.V //?? or retroflex [S] + ष (B s. //?? +?1 ष (_ s. //?? .group स स sV diff --git a/dictsource/ru_list b/dictsource/ru_list index 00391980..8e7d8a83 100644 --- a/dictsource/ru_list +++ b/dictsource/ru_list @@ -18,7 +18,7 @@ _2 dv'A _3 t;r'i _4 ts;It'yr;I _5 p;'jat; -_6 S'Es;t; +_6 s.'Es;t; _7 s;'em _8 v'os;E2m _9 d;'ev;It; @@ -28,7 +28,7 @@ _12 dv;In'AttsVt; _13 tr;In'AttsVt; _14 ts;It'y@-*nVttsVt; _15 p;Itn'AttsVt; -_16 SE#stn'AttsVt; +_16 s.E#stn'AttsVt; _17 s;Imn'AttsVt; _18 vOs;Imn'AttsVt; _19 d;E2v;Itn'AttsVt; @@ -36,7 +36,7 @@ _2X dv'AttsVt; _3X tr;'ittsVt; _4X s'o@-*Ok _5X p;Id;d;Is;'jat -_6X SE2z;d;d;Is;'jat +_6X s.E2z;d;d;Is;'jat _7X s;'emd;E2s;It _8X v'os;E2md;E2s;It _9X d;E2v;In'ostO @@ -45,7 +45,7 @@ _2C dv;'es;t;I _3C tr;'ista _4C ts;It'yr;E2sta _5C p;,It;s'ot -_6C S,E#s;t;s'ot +_6C s.,E#s;t;s'ot _7C s;,Ims'ot _8C vOs;Ims'ot _9C d;E2v;It;s'ot @@ -82,7 +82,7 @@ _dpt2 _d;Is;'atYx // end of decimal fraction // questions -что Sto $u $pause // what, that +что s.to $u $pause // what, that // misc. diff --git a/dictsource/ru_rules b/dictsource/ru_rules index 62ce34b2..1fb01063 100755 --- a/dictsource/ru_rules +++ b/dictsource/ru_rules @@ -177,25 +177,25 @@ .group ж - _) ж (_ ZE - ж (кY S - ж (кь S - ж (пY S - ж (пь S - ж (сь S - ж (сY S - ж (ть S - ж (тY S - ж (фь S - ж (фY S - ж (ффь S - ж (ффY S - ж (хь S - ж (хY S - ж (хкY S - ж (хкь S + _) ж (_ z.E + ж (кY s. + ж (кь s. + ж (пY s. + ж (пь s. + ж (сь s. + ж (сY s. + ж (ть s. + ж (тY s. + ж (фь s. + ж (фY s. + ж (ффь s. + ж (ффY s. + ж (хь s. + ж (хY s. + ж (хкY s. + ж (хкь s. - ж Z + ж z. .group з _) з (_ zE @@ -243,8 +243,8 @@ з (сь s; з (сY s; - з (ж Z - з (ш S + з (ж z. + з (ш s. з (щ s;s; з (ч s;s; з z @@ -329,6 +329,10 @@ .group о о o + о (B oj + о (Cь oj + о (FY oj + .group п _) п (_ pE @@ -396,10 +400,10 @@ с (дY z; с (дB z; - с (ж Z - с (ш S - с (щ s;s; - с (ч s;s; + с (ж z. + с (ш s. + с (щ s; + с (ч s; с s @@ -430,7 +434,7 @@ т (ж d - т t + т t .group у _) у (_ u @@ -546,27 +550,27 @@ .group ш - _) ш (_ SA - ш (б Z - ш (бь Z - ш (бY Z - ш (бмь Z - ш (бмY Z - ш (бвь Z - ш (бвY Z - ш (г Z - ш (гь Z - ш (гY Z - ш (д Z - ш (дь Z - ш (дY Z - ш (дB Z - ш (ж Z - ш (з Z - ш (зь Z - ш (зY Z + _) ш (_ s.A + ш (б z. + ш (бь z. + ш (бY z. + ш (бмь z. + ш (бмY z. + ш (бвь z. + ш (бвY z. + ш (г z. + ш (гь z. + ш (гY z. + ш (д z. + ш (дь z. + ш (дY z. + ш (дB z. + ш (ж z. + ш (з z. + ш (зь z. + ш (зY z. - ш S + ш s. .group щ _) щ (_ S;ja diff --git a/dictsource/sv_rules b/dictsource/sv_rules index dcd3ffa3..bf9a6c8c 100755 --- a/dictsource/sv_rules +++ b/dictsource/sv_rules @@ -243,11 +243,11 @@ espeak _^_EN .group r r r r) r - rs S + rs s. rsi (o rsx' - rsk Sk + rsk s.k rsk (i rsx - rss S + rss s. rg (_ rj radera rad'e:ra diff --git a/dictsource/vi_rules b/dictsource/vi_rules index 503d5755..9fdbda1c 100644 --- a/dictsource/vi_rules +++ b/dictsource/vi_rules @@ -1,4 +1,4 @@ - + .group a a a: ai a:I @@ -387,7 +387,7 @@ qu kw .group r - r D + r z; .group s s s diff --git a/phsource/compile_report b/phsource/compile_report index 63f9ad28..d9e64da9 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,38 +1,38 @@ 33 phoneme tables new total - base 89 89 - en 52 136 - en_n 29 136 - en_us 36 136 - en_sc 39 138 - en_rp 34 136 - en_wm 30 136 - af 37 120 - cy 30 115 - de 28 112 - eo 15 101 - fi 40 120 - fr 32 113 - fr_ca 11 113 - hi 50 125 - hu 24 106 - nl 25 109 - pl 17 100 - sk 22 115 - cs 6 116 - hr 15 119 - ru 35 116 - it 28 109 - es 7 109 - pt 25 124 - pt_pt 17 124 - ro 36 133 - el 7 109 - sv 25 111 - no 29 115 - vi 41 126 - zh_yue 32 117 - sw 14 98 + base 91 91 + en 52 138 + en_n 29 138 + en_us 36 138 + en_sc 39 140 + en_rp 34 138 + en_wm 30 138 + af 37 122 + cy 30 117 + de 28 114 + eo 15 103 + fi 40 122 + fr 32 115 + fr_ca 11 115 + hi 50 127 + hu 24 108 + nl 25 111 + pl 17 102 + sk 22 117 + cs 6 118 + hr 15 121 + ru 36 119 + it 28 111 + es 7 111 + pt 25 126 + pt_pt 17 126 + ro 36 135 + el 7 111 + sv 25 113 + no 29 117 + vi 41 128 + zh_yue 32 119 + sw 14 100 3 b/b base hi ro 2 b/b_ base hi @@ -216,7 +216,9 @@ 1 ufric/sh_ base 2 ufric/sh_pzd base ro 3 ufric/sh_pzd_ base - 5 ufric/s_pzd base ro + 2 ufric/sh_rfx base + 3 ufric/s_pzd base ro + 2 ufric/s_pzd_ base 1 ufric/sx_sv sv 1 ufric/th base 1 ufric/th_ base @@ -343,8 +345,8 @@ 1 vdiph/y#y fi 2 vdiph/y#y_2 af zh_yue 1 vdiph/y#y_3 nl - 2 vnasal/aa_n en fr - 1 vnasal/aa_n3 af + 1 vnasal/aa_n en + 2 vnasal/aa_n3 af fr 2 vnasal/ee_n en fr_ca 3 vnasal/ee_n2 hi pl pt_pt 2 vnasal/e_n af pt @@ -356,7 +358,8 @@ 1 vnasal/oi_n pt 2 vnasal/o_n hi pt 1 vnasal/o_n2 af - 2 vnasal/oo_n en fr + 1 vnasal/o_n3 fr + 1 vnasal/oo_n en 2 vnasal/oo_n2 hi pl 1 vnasal/&u_n pt 1 vnasal/u_n pt @@ -375,18 +378,18 @@ 1 vocw/Q2 nl 6 vocw/v base ro 4 vocw/zh base ro - 1 vocw/zh_rfx cs + 3 vocw/zh_rfx base cs 3 voc/z base fr ro 3 voc/z_ base fr ro - 2 voc/zh base ro - 2 voc/zh_ base ro + 3 voc/zh base ro + 3 voc/zh_ base ro 1 voc/zh_2 cs 2 voc/z_pzd base 2 voc/z_pzd_ base 14 vowel/@ base en en_us en_rp cy hi hr 1 vowel/@- base 4 vowel/& en_rp fi hi sv - 5 vowel/0 en fr hi it pt + 4 vowel/0 en hi it pt 4 vowel/0_2 en_n en_wm pt_pt sw 5 vowel/0_3 en_us en_sc en_rp hu 1 vowel/@_2 fr @@ -402,7 +405,7 @@ 5 vowel/a_2 eo it pt_pt ro vi 3 vowel/a#_2 hr sv sw 5 vowel/a_3 en_sc cs - 11 vowel/a#_3 en en_n en_us en_wm de hi pt_pt vi zh_yue + 12 vowel/a#_3 en en_n en_us en_wm de hi ru pt_pt vi zh_yue 4 vowel/a_4 en_wm el vi 2 vowel/a_5 sv sw 7 vowel/aa en_us fi fr_ca no zh_yue @@ -445,13 +448,13 @@ 2 vowel/ii_4 en_rp 6 vowel/ii_en en en_n 5 vowel/@_low hi ro no - 9 vowel/o en en_wm de fr hi it pt_pt sv + 8 vowel/o en en_wm de hi it pt_pt sv 4 vowel/o_2 cy hi hu no 2 vowel/o-_2 en_n en_wm 2 vowel/o_3 en_sc 1 vowel/o-_3 en_rp - 1 vowel/o_4 en_n - 1 vowel/o_6 nl + 2 vowel/o_4 en_n fr + 2 vowel/o_6 fr nl 4 vowel/oe en af de fr 1 vowel/oe_2 no 1 vowel/oe_4 sv diff --git a/phsource/ph_french b/phsource/ph_french index 01b0c75a..d3c3405d 100644 --- a/phsource/ph_french +++ b/phsource/ph_french @@ -50,14 +50,14 @@ endphoneme phoneme o vowel starttype (o) endtype (o) length 166 - formants vowel/o + formants vowel/o_4 endphoneme phoneme O vowel starttype (o) endtype (o) length 190 - formants vowel/0 + formants vowel/o_6 endphoneme @@ -102,7 +102,7 @@ endphoneme phoneme A~ vowel starttype (a) endtype (a) length 222 - formants vnasal/aa_n + formants vnasal/aa_n3 endphoneme @@ -116,7 +116,7 @@ endphoneme phoneme O~ vowel starttype (o) endtype (o) length 222 - formants vnasal/oo_n + formants vnasal/o_n3 endphoneme @@ -188,7 +188,6 @@ phoneme R length 100 lengthmod 7 beforenotvowel r/ - trill formants vwl_fr/@R+r3/rx%80 endphoneme @@ -240,7 +239,7 @@ endphoneme phoneme z2 // silent unless followed by vowel beforenotvowel NULL vcd alv frc sibilant - vowelout f1=0 f2=1700 -300 300 f3=-100 60 len=50 + vowelout f1=0 f2=1700 -300 300 f3=-100 60 len=50 formants voc/z+ufric/s_ before _ voc/z_+ufric/s_ lengthmod 6 @@ -277,3 +276,4 @@ endphoneme + diff --git a/phsource/ph_russian b/phsource/ph_russian index 4d3c1679..4a68780c 100755 --- a/phsource/ph_russian +++ b/phsource/ph_russian @@ -278,4 +278,10 @@ phoneme a length 100 endphoneme +phoneme a# + vowel starttype (a) endtype (a) + formants vowel/a#_3 + length 100 +endphoneme + diff --git a/phsource/phonemes b/phsource/phonemes index 99e0262c..75341000 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -774,12 +774,23 @@ phoneme Z endphoneme +phoneme z. + vcd pla frc sibilant + vowelin f1=0 f2=1800 -100 300 f3=-300 80 + vowelout f1=2 f2=1800 -100 300 f3=-300 80 brk + formants voc/zh+vocw/zh_rfx + before _ voc/zh_+vocw/zh_rfx + lengthmod 6 + switchvoicing s. +endphoneme + + phoneme z; vcd pal frc sibilant palatal vowelin f1=2 f2=2700 400 600 f3=300 80 rate len=70 vowelout f1=2 f2=2300 250 300 f3=-300 80 brk - formants voc/z_pzd+ufric/s_pzd%40 - before _ voc/z_pzd_+ufric/s_pzd%40 + formants voc/z_pzd+ufric/s_pzd%80 + before _ voc/z_pzd_+ufric/s_pzd_%80 lengthmod 6 switchvoicing s; endphoneme @@ -994,12 +1005,24 @@ phoneme s; vowelout f1=1 f2=2700 400 600 f3=200 70 rate len=70 length 100 lengthmod 3 - wave ufric/s_pzd%50 - before _ ufric/s_pzd%50 + wave ufric/s_pzd + before _ ufric/s_pzd_ switchvoicing z; endphoneme +phoneme s. + vls pla frc sibilant + vowelin f1=0 f2=1800 -100 300 f3=-300 80 + vowelout f1=0 f2=1800 -100 300 f3=-300 80 + length 100 + lengthmod 3 + wave ufric/sh_rfx%80 + before _ ufric/sh_rfx%60 + switchvoicing z. +endphoneme + + phoneme S; vls pal frc sibilant palatal vowelin f1=1 f2=2700 400 600 f3=200 70 rate len=70 diff --git a/phsource/ufric/s_pzd.wav b/phsource/ufric/s_pzd.wav index 775aa16c12e0cee5002907f28ae08140149aa4ff..6be18370f874a40a616945ecf5700dc069d898e6 100644 GIT binary patch literal 4756 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 H_TK1!-rwLg literal 6326 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 diff --git a/phsource/ufric/s_pzd_.wav b/phsource/ufric/s_pzd_.wav new file mode 100644 index 0000000000000000000000000000000000000000..2ca263d7b171b84faf2f3167fea42f1ba3ff4d04 GIT binary patch literal 5674 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 z zj2!5DVsC(OFH`o=3e#Pss8F*^OtOVP)`xgkS9SUaIy#9ulETRLRS4N;pAadWtI7u+ zIMI3;AH+YoIlPpE<#MjemARTerf2h5EH0ba`Rvaz)|u{J6{EZg-ee;?m@Cc)avluU zo3N%G<+~*p=+}V^ccptzf5g*3`q(~<*?dlq)N{>d)snX3Z4oXf+gEUiPWN1^kXwq& z$!z*tLv;uS0ryRd0ssq+M0SgS+=&xRlwE8Ulh?d_-#jWN0=uoCvq5JRzxd>a(SdI|G zZ$uX z9W>$8jN@ff@vR8*O%j*%`hd?(5U*quH1||k&lTlQn4)T^Q|h@I&&}<7A#>%;z*c>k zHkbZ{n(&c<<2!E6uAa<7O+{$w%N%j!-rQ?!)>aEeC-@2f+)4UDn|_%GVA z^fE9suuB&-OY~NmZZEP@aI{&4Q$)Cl&T*Z4aEdZH4~L4*SOV8_MT`YjKbRn@sX=s(UKG%_X$8s)em#bk1yS#6=G|
    |=76ylZc=hU-BA5!e&>P#rRHVyzV#{3{Lnu|M9?$(&lG@tFaU-+^;IXB04;qzg3pSA=7bul!qk6; zMAzWX_Mg0mW~=7vJ1^}A@G9u)?H#4*TlY<1w_3|5MV@`%AFw8>_UgRH9S12tCRkb6 zn5OexC?QXa4Z_eGZh-yWw}J660WVs$d^LmC`MYrK-0r#C^NQ*50>lu}I%Hb#dXY-& z+|xO|b20+=bvrA{e<;|>pDirs@#_M)Wz{N=c8bXeUuAnOzUw9NmOwdo2+iSI*j5&_ z%6Q%W*t*8wnG2rFH#Gmi8~A~0@eA?09nI&}Qtkn_yxe@3(pk$D*cO1ZIYZ1BkN8KZ zit9`ZbwWSzc7mU*ZlWse;S~H8`Y9(b;M{V%z0JVGoe4cp}`RD}gP6dbG+!m?yHk|GvG_lyZYSFRP0mS`)<%?#&JL0hL5u zu(WuI>%}@l`Vk6V!Czo~aS=a(>oi*R)K6s}d6jSDK^YE3bS7s(KJ&GFA^tU6^hwi( z%i%6;PpMw2egy;gG3|gSW}27%9XSp9d)wr2dq!}7TokCQGpq{~<2=<0!(?xdtIuFd z(Fh-@33?68grz2qf_W6qu-3`bc#8%(C%t_ymeZl1JqE|ABBH6R>veof^{rmX&BP;* zp0Dczx)d+Pl2&a|1ZKb;eM_Zr3Z;7;zSGO!PasHq%tPo$PvZ+*l5b$V*X7qWa~Z5E z4qE9vQ72GIj-VNOImcTU#3g(weiC_7z|C7*84dDcVnIi zz%b7AQmDBJEFJ~V#TD_Vr{^fB#VrH#b1ixyi&~xSTmE=C z&`orn=GAty_!-sb`}U_n8^jp1K>6JjflFpOydo0CLptOuCl{KX>fqa?*A1Pz0(>L< zUH!eR%aEui1qSDpr=Pw5c32d{5jdUBP^7BjH1KAiV(@DD8ArQuZmRo}{tXU^nj%!T zv(`f)eb;TLzoGT|W2o=zW`&6a8161`&Nv;^6_3?NU=cANJ6VZhCS|$NZicz86Je46 zvA>Nkgw(2i$l*V;8dz!6scDazvWBtXt!1E1$KA-=heug!yQZdT2W04>FHG z<$B_G=z}llrgP2>=>K@PXpNPv_4Z5HrR(Zgvx|n)IC?AMt&*~nIAtd5txyIc^=Z8e zN?vG;cf(`_yi2MPd%OHAh{fkzAICL7e>E8X_EAVZ96GbQj(TqhK#yg>*P9 z-?5TJMLf)l%`-C&Zo$7COY`&rs)1P;CAM>z=D)Z+l;UrQU?obA_y*Dg?W!kcu;)A> zP(&1!g?Y8wtq&QX3lt5{aGaOoCD`V0zCxwBFk6s^Pq8N4;Yh57GrSwh$9&xL*ROaR U&4hPFbuk&Hc^9Y>Fo-4p51>BRwg3PC literal 0 HcmV?d00001 diff --git a/phsource/vnasal/o_n3 b/phsource/vnasal/o_n3 index 96c431e5166ac8af83afacc8fa3ea58e6a7b7953..844461017e2760f7890b1e25c16ab2b1cf6d4af7 100644 GIT binary patch delta 117 zcmexh@y0?nIKb68B-k~Og@J(~KR(Zxogog$f`W~T94st98r649)@9LWYT(=)$8w#S z H!Oj8z!U-gM delta 121 zcmaE3@xekdIKb68B-k~OgMopexF9vTq^LBPogp5`V_>lVc~Ef8Mp+IPmR}8*j!f2M z(Pv`d+8o7lotfp=f)`GcO*y~Ut2au RiU1Ay-Cww3bE*V83jlzlDUARC diff --git a/phsource/vnasal/oo_n b/phsource/vnasal/oo_n index e94b5b37c3f623fca3ab3075911d7214b3ce3370..3b2ddc9ca69d836ff54bbac29600b575c53978bc 100644 GIT binary patch literal 7276 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 GyM6;LVaFi= diff --git a/phsource/vnasal/vowelchart.png b/phsource/vnasal/vowelchart.png index 84f36af1c2a903fb380f9927d2ccc1fb2be0edd1..9f4bb568844a321c8a05c2ad2e70ecc3fbc2c8d8 100644 GIT binary patch literal 20115 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

    X_v?ep2Vy{LfQQU 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 literal 20108 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

    DAtYU^={*HQX)xzYt%wUy^QXP) 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 delta 29 kcmca_aMyr0IKb68B-k~Ok%56BaU;JE2V=_S7!GCu0ED6kmjD0& diff --git a/phsource/vwl_fr/@R b/phsource/vwl_fr/@R index 02d86667e085cc1ada6d7228326a50782f80445a..5bf76ffb77413f160a6d5e0624d4f62d474e1b12 100644 GIT binary patch delta 26 icmZ3+wTx?m4&#H3y1I;v3pPhHIx;fe-#nM8lL-KLhzPj= delta 26 icmZ3+wTx?m4&#T7y1I;vTQ)~CIx;f8-#nM8lL-KO90=_I diff --git a/src/dictionary.cpp b/src/dictionary.cpp index 4263d3ce..69316c35 100755 --- a/src/dictionary.cpp +++ b/src/dictionary.cpp @@ -1098,9 +1098,9 @@ void Translator::SetWordStress(char *output, unsigned int dictionary_flags, int if((langopts.stress_flags & 0x1000) && (vowel_stress[1] == 0)) { - if((vowel_count == 3) && (vowel_stress[2] >= 4)) + // If there is only one syllable before the primary stress, give it a secondary stress + if((vowel_count > 2) && (vowel_stress[2] >= 4)) { - // 2-syllable word, put a secondary stress on the initial syllable vowel_stress[1] = 3; } } diff --git a/src/intonation.cpp b/src/intonation.cpp index d9b8d511..e0526418 100755 --- a/src/intonation.cpp +++ b/src/intonation.cpp @@ -267,7 +267,7 @@ static TONE_TABLE tone_table[N_TONE_TABLE] = { {PITCHfrise, 38,10, PITCHfrise2, 36,10, // comma, or question 20, 25, 34, 20, drops_0, 3, 3, 15, 25, 0}, - {PITCHdrop, 40, 2, PITCHdrop, 42,25, // exclamation + {PITCHdrop, 38, 1, PITCHdrop, 42,25, // exclamation 20, 25, 34, 22, drops_0, 3, 3, 12, 8, 0}, diff --git a/src/readclause.cpp b/src/readclause.cpp index ce9343d1..32010b97 100644 --- a/src/readclause.cpp +++ b/src/readclause.cpp @@ -1841,8 +1841,11 @@ void InitText2(void) ssml_sp->voice_variant = 0; ssml_sp->voice_gender = 0; ssml_sp->voice_age = 0; - strncpy0(ssml_sp->voice_name,pvoice->name,sizeof(ssml_sp->voice_name)); - strncpy0(ssml_sp->language,&pvoice->languages[1],sizeof(ssml_sp->language)); + if(pvoice != NULL) + { + strncpy0(ssml_sp->voice_name,pvoice->name,sizeof(ssml_sp->voice_name)); + strncpy0(ssml_sp->language,&pvoice->languages[1],sizeof(ssml_sp->language)); + } current_voice_id[0] = 0; n_param_stack = 1; diff --git a/src/speak_lib.cpp b/src/speak_lib.cpp index 173c822a..8b8f83d7 100644 --- a/src/speak_lib.cpp +++ b/src/speak_lib.cpp @@ -646,11 +646,13 @@ ESPEAK_API int espeak_Initialize(espeak_AUDIO_OUTPUT output_type, int buf_length buf_length = 200; outbuf_size = (buf_length * samplerate)/500; outbuf = (unsigned char*)realloc(outbuf,outbuf_size); - out_start = outbuf; + if((out_start = outbuf) == NULL) + return(EE_INTERNAL_ERROR); // allocate space for event list. Allow 500 events per minute n_event_list = (buf_length*500)/1000; - event_list = (espeak_EVENT *)realloc(event_list,sizeof(espeak_EVENT) * n_event_list); + if((event_list = (espeak_EVENT *)realloc(event_list,sizeof(espeak_EVENT) * n_event_list)) == NULL) + return(EE_INTERNAL_ERROR); option_phonemes = 0; @@ -1050,7 +1052,9 @@ ESPEAK_API espeak_ERROR espeak_Terminate(void) #endif Free(event_list); + event_list = NULL; Free(outbuf); + outbuf = NULL; FreePhData(); return EE_OK; diff --git a/src/speak_lib.h b/src/speak_lib.h index 1c20a706..c85008bd 100644 --- a/src/speak_lib.h +++ b/src/speak_lib.h @@ -145,7 +145,7 @@ int espeak_Initialize(espeak_AUDIO_OUTPUT output, int buflength, const char *pat path: The directory which contains the espeak-data directory, or NULL for the default location. - Returns: sample rate in Hz + Returns: sample rate in Hz, or -1 (EE_INTERNAL_ERROR). */ typedef int (t_espeak_callback)(short*, int, espeak_EVENT*); diff --git a/src/speak_riscos.cpp b/src/speak_riscos.cpp new file mode 100644 index 00000000..507fe513 --- /dev/null +++ b/src/speak_riscos.cpp @@ -0,0 +1,1234 @@ + +/************************************************************************** +* Copyright (C) 2005,2006 by Jonathan Duddington * +* jonsd@users.sourceforge.net * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU General Public License * +* along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ + +#define USE_MODULE + +#include +#include +#include +#include +#include +#include "kernel.h" + +#include "speech.h" +#include "speak_lib.h" +#include "voice.h" +#include "phoneme.h" +#include "synthesize.h" +#include "translate.h" + +#define os_X 0x20000 + +// interface to the assembler section +extern "C" { +extern void DMA_Handler(void); + + +// used from the cmhgfile +extern _kernel_oserror *user_init(char *cmd_fail, int podule_base, void *pw); +extern _kernel_oserror *swi_handler(int swi_no, int *r, void *pw); +extern _kernel_oserror *command_handler(char *arg_string, int argc, int cmd_no, void *pw); +extern int callback_handler(_kernel_swi_regs *r, void *pw); +extern int callback_entry(_kernel_swi_regs *r, void *pw); +extern int sound_handler(_kernel_swi_regs *r, void *pw); +extern int sound_entry(_kernel_swi_regs *r, void *pw); + +} + +extern int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume); +extern void RiscosOpenSound(); +extern int WcmdqUsed(); +extern void FreePhData(); +extern void FreeDictionary(); + +extern int wcmdq_head; +extern int wcmdq_tail; +extern int current_source_index; + +FILE *f_text; +int (* uri_callback)(int, const char *, const char *) = NULL; + +int amp = 8; // default + +char path_home[80] = ""; +char wavefile[120]; +char textbuffile[L_tmpnam]; +int sample_rate_index; // current value +int current_voice_num=0; +int n_voice_files = 0; + +// output sound buffer, 2 bytes per sample +static unsigned short SoundBuf[4096]; +static void *module_data; +static int callback_inhibit = 0; +static int more_text=0; + +#define N_VOICE_NAMES 40 +static char *voice_names[40]; + +#define N_STATIC_BUF 8000 +static char static_buf[N_STATIC_BUF]; +static _kernel_oserror errblk; + + + +USHORT voice_pcnt[N_PEAKS+1][3]; +voice_t voice_data; +voice_t *voice; + +static const char *help_text = +"\nspeak [options] [\"\"]\n\n" +"-f Text file to speak\n" +"--stdin Read text input from stdin instead of a file\n\n" +"If neither -f nor --stdin, are spoken, or if none then text is\n" +"spoken from stdin, each line separately.\n\n" +"-a \n" +"\t Amplitude, 0 to 200, default is 100\n" +"-l \n" +"\t Line length. If not zero (which is the default), consider\n" +"\t lines less than this length as end-of-clause\n" +"-p \n" +"\t Pitch adjustment, 0 to 99, default is 50\n" +"-s \n" +"\t Speed in words per minute 80 to 370, default is 170\n" +"-v \n" +"\t Use voice file of this name from espeak-data/voices\n" +"-w \n" +"\t Write output to this WAV file, rather than speaking it directly\n" +"-b\t Input text is 8-bit encoding\n" +"-m\t Interpret SSML markup, and ignore other < > tags\n" +"-q\t Quiet, don't produce any speech (may be useful with -x)\n" +"-x\t Write phoneme mnemonics to stdout\n" +"-X\t Write phonemes mnemonics and translation trace to stdout\n" +"--stdout Write speech output to stdout\n" +"--compile=\n" +"\t Compile the pronunciation rules and dictionary in the current\n" +"\t directory. = is optional and specifies which language\n" +"--punct=\"\"\n" +"\t Speak the names of punctuation characters during speaking. If\n" +"\t = is omitted, all punctuation is spoken.\n" +"--voices=\n" +"\t List the available voices for the specified language.\n" +"\t If is omitted, then list all voices.\n"; + + +// additional Latin characters beyond the Latin1 character set +#define MAX_WALPHA 0x233 +// indexed by character - 0x100 +// 0=not alphabetic, 0xff=lower case, other=value to add to upper case to convert to lower case +static unsigned char walpha_tab[MAX_WALPHA-0xff] = { + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 100 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 110 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 120 + 0xff,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, 1, // 130 + 0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, // 140 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 150 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 160 + 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, // 170 + 0xff, 210, 1,0xff, 1,0xff, 206, 1,0xff, 205, 205, 1,0xff,0xff, 79, 202, // 180 + 203, 1,0xff, 205, 207,0xff, 211, 209, 1,0xff,0xff,0xff, 211, 213,0xff, 214, // 190 + 1,0xff, 1,0xff, 1,0xff, 218, 1,0xff, 218,0xff,0xff, 1,0xff, 218, 1, // 1a0 + 0xff, 217, 217, 1,0xff, 1,0xff, 219, 1,0xff,0xff,0xff, 1,0xff,0xff,0xff, // 1b0 + 0xff,0xff,0xff,0xff, 2, 1,0xff, 2, 1,0xff, 2, 1,0xff, 1,0xff, 1, // 1c0 + 0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff,0xff, 1,0xff, // 1d0 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 1e0 + 0xff, 2, 1,0xff, 1,0xff,0xff,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 1f0 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 200 + 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 210 + 0xff, 0, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, 1,0xff, // 220 + 1,0xff, 1,0xff }; // 230 + +// use ctype.h functions for Latin1 (character < 0x100) +int iswalpha(int c) +{ + if(c < 0x100) + return(isalpha(c)); + if(c > MAX_WALPHA) + return(0); + return(walpha_tab[c-0x100]); +} + +int iswdigit(int c) +{ + if(c < 0x100) + return(isdigit(c)); + return(0); +} + +int iswalnum(int c) +{ + if(iswdigit(c)) + return(1); + return(iswalpha(c)); +} + +int towlower(int c) +{ + int x; + if(c < 0x100) + return(tolower(c)); + if((c > MAX_WALPHA) || ((x = walpha_tab[c-0x100])==0xff)) + return(c); // already lower case + return(c + x); // convert to lower case +} + +int iswupper(int c) +{ + int x; + if(c < 0x100) + return(isupper(c)); + if(((c > MAX_WALPHA) || (x = walpha_tab[c-0x100])==0) || (x == 0xff)) + return(0); + return(1); +} + +int iswlower(int c) +{ + if(c < 0x100) + return(islower(c)); + if((c > MAX_WALPHA) || (walpha_tab[c-0x100] != 0xff)) + return(0); + return(1); +} + +int iswspace(int c) +{ + if(c < 0x100) + return(isspace(c)); + return(0); +} + +int iswpunct(int c) +{ + if(c < 0x100) + return(ispunct(c)); + return(0); +} + +const wchar_t *wcschr(const wchar_t *str, int c) +{ + while(*str != 0) + { + if(*str == c) + return(str); + str++; + } + return(NULL); +} + +const int wcslen(const wchar_t *str) +{ + int ix=0; + + while(*str != 0) + { + ix++; + } + return(ix); +} + + +int GetFileLength(const char *filename) +{//==================================== + int length=0; + int type; + _kernel_swi_regs regs; + _kernel_oserror *error; + + regs.r[0] = 5; + regs.r[1] = (int)filename; + regs.r[2] = 0; + regs.r[3] = 0; + regs.r[4] = 0; + regs.r[5] = 0; + + error = _kernel_swi(0x20008,®s,®s); + if(error) + return(0); + + type = regs.r[0]; + length = regs.r[4]; + + if(type==2) + return(-2); // a directory + if((type!=1) && (type!=3)) + return(0); /* not a file */ + + return(length); +} /* end of GetFileLength */ + + + +void ReadVoiceNames2(char *directory) +{//================================== + int len; + int *type; + char *p; + _kernel_swi_regs regs; + _kernel_oserror *error; + char buf[80]; + char directory2[80]; + + regs.r[0] = 10; + regs.r[1] = (int)directory; + regs.r[2] = (int)buf; + regs.r[3] = 1; + regs.r[4] = 0; + regs.r[5] = sizeof(buf); + regs.r[6] = 0; + + while(regs.r[3] > 0) + { + error = _kernel_swi(0x0c+os_X,®s,®s); /* OS_GBPB 10, read directory entries */ + if((error != NULL) || (regs.r[3] == 0)) + { + break; + } + type = (int *)(&buf[16]); + len = strlen(&buf[20]); + + if(*type == 2) + { + // a sub-directory + sprintf(directory2,"%s.%s",directory,&buf[20]); + ReadVoiceNames2(directory2); + } + else + { + p = Alloc(len+1); + strcpy(p,&buf[20]); + voice_names[n_voice_files++] = p; + if(n_voice_files >= (N_VOICE_NAMES-1)) + break; + } + } +} + + +void ReadVoiceNames() +{//=================== + char directory[80]; + + for(n_voice_files=0; n_voice_files sizeof(SoundBuf)) + size = sizeof(SoundBuf); + + out_ptr = (unsigned char *)(&SoundBuf[0]); + out_end = (unsigned char *)(&SoundBuf[size]); + WavegenFill(1); +} + + + +int initialise(void) +{//================= + sprintf(path_home,"%s.espeak-data",""); + if(GetFileLength(path_home) != -2) + { + // not found, try the 10 character version of the directory name + sprintf(path_home,"%s.espeak-dat",""); + } + if(GetFileLength(path_home) != -2) + { + // still can't find data directory + sprintf(errblk.errmess,"Speak: Can't find data directory: '%s'\n",path_home); + return(-1); + } + + WavegenInit(22050,0); + LoadPhData(); + SynthesizeInit(); + return(0); +} + + + +void speak_text_string(char *data, int terminator, int len, int wait, int voice_num) +/**********************************************************************************/ +/* 'wait' indictes wait until speaking is finished before returning */ +{ + int c; + int ix; + static static_length=0; + static int user_token=0; /* increment for each call of translate() */ + _kernel_swi_regs regs; + + regs.r[0] = (int)callback_entry; + regs.r[1] = (int)module_data; + _kernel_swi(0x5f, ®s, ®s); + + + if((voice_num >= 0) && (voice_num != current_voice_num) && (voice_num < N_VOICE_NAMES)) + { + SetVoiceByName(voice_names[voice_num]); + WavegenSetVoice(voice); + } + current_voice_num = voice_num; + + /* don't count CR as terminator if length is specified */ + if(len > 0) terminator = 0; + + ix = 0; + if(more_text == 0) + static_length = 0; + else + { + strcat(&static_buf[static_length]," : "); + static_length+=3; + } + + if(terminator == 0) + { + while(((c = data[ix++]) != 0) && (static_length < N_STATIC_BUF-4)) + { + static_buf[static_length++] = c; + if(ix == len) + break; + } + } + else + { + while(((c = data[ix++]) != '\r') && (c != '\n') && (c != 0) && (static_length < N_STATIC_BUF-3)) + { + static_buf[static_length++] = c; + if(ix == len) + break; + } + } + static_buf[static_length] = 0; + + if(option_waveout==0) + { + if(more_text == 0) + { + InitText(0); + RiscosOpenSound(); + more_text = SpeakNextClause(NULL,(void *)static_buf,0); + } + + while(wait) + { + if((more_text==0) && (wcmdq_head == wcmdq_tail)) + break; + + //we need to block to allow the callback handler to run + regs.r[0] = 129; // wait for key press + regs.r[1] = 10; + regs.r[2] = 0; + _kernel_swi(0x06, ®s, ®s); // OS_Byte + } + } + else + { + more_text = 0; + SpeakNextClause(NULL,(void *)static_buf,0); + + for(;;) + { + if(WavegenFile() != 0) + break; // finished, wavegen command queue is empty + + if(Generate(phoneme_list,&n_phoneme_list,1)==0) + SpeakNextClause(NULL,NULL,1); + } + + CloseWaveFile(samplerate); + } + +} /* end of speak_text_string */ + + + + +void speak_file(char *fname) +{//========================= + FILE *f_in; + char buf[120]; + + f_in = fopen(fname,"r"); + if(f_in == NULL) + { + fprintf(stderr,"Can't read file: '%s'",fname); + return; + } + more_text = 1; + + if(option_waveout == 0) + { + RiscosOpenSound(); + SpeakNextClause(f_in,NULL,0); + } + else + { + more_text = 0; + SpeakNextClause(f_in,NULL,0); + + for(;;) + { + if(WavegenFile() != 0) + break; // finished, wavegen command queue is empty + + if(Generate(phoneme_list,&n_phoneme_list,1)==0) + SpeakNextClause(NULL,NULL,1); + } + + CloseWaveFile(samplerate); + } +} + + + +void set_say_options(int reg2, int reg3) +/**************************************/ +/* Sets options from information in 'say' SWI */ +/* R3 bits 0-7 stress indicator character + bit 8 inhibit unpronouncable check */ +{ + option_linelength = 0; + option_phonemes = 0; + option_waveout = 0; + option_harmonic1 = 8; + option_multibyte = 0; // auto + option_capitals = 0; + option_punctuation = 0; + option_punctlist[0] = 0; +} /* end of set_say_options */ + + + +void jsd_swi_functions(int *r) +/****************************/ +{ + switch(r[0]) + { + case 0: /* major version */ + r[0] = 3; + break; + + case 1: /* register user */ + break; + + case 2: /* deregister user */ + break; + + case 3: +// r[0] = (int)speech_to_phonemes((char *)r[1]); + break; + + case 4: +// r[0] = reload_word_dict(NULL); + break; + + case 5: /* get table of voice names */ + r[0] = (int)voice_names; + break; + + case 6: /* update voice data, r1 = voice_number */ + if(r[1] < N_VOICE_NAMES) + { + SetVoiceByName(voice_names[r[1]]); + current_voice_num = r[1]; + WavegenSetVoice(voice); + } + break; + + case 7: /* load voice data */ +// init_voice((char *)r[1]); + break; + + default: + r[0] = 0; + r[1] = 0; + break; + } +} /* end of jsd_swi_functions */ + + + + +_kernel_oserror *swi_handler(int swi_no, int *r, void *pw) +/*********************************************************/ +{ + int value; + int q_length; + int speed; + int amp; + value = r[0]; + + switch(swi_no) + { + + case 0: // ready ? + // returns the index into the source text of the currently speaking word + if(current_source_index > 0) + r[1] = current_source_index-1; + else + r[1] = current_source_index; /* source index */ + r[2] = 0; /* source tag */ + r[3] = 0; /* for future expansion */ + r[4] = 0; + r[5] = 0; + + if(wcmdq_head == wcmdq_tail) + { + r[0] = -1; /* ready, or nearly */ + } + else + r[0] = 0; + break; + + case 1: /* restore old sound channel. DO NOTHING */ + break; + + case 2: /* miscellaneous functions */ + jsd_swi_functions(r); + break; + + case 3: /* speak text */ +// _kernel_irqs_on(); + set_say_options(r[2],r[3]); + speak_text_string((char *)r[0],'\r',r[1],0,r[2]); + break; + + case 4: /* speak text and wait */ +// _kernel_irqs_on(); /* enable interrupts */ + set_say_options(r[2],r[3]); + speak_text_string((char *)r[0],'\r',r[1],1,r[2]); + break; + + case 5: /* stop speaking */ + SpeakNextClause(NULL,NULL,2); + more_text = 0; + break; + + case 7: /* pitch */ + // not implemented + break; + + case 8: /* speed */ + speed = (value * 160)/140; + SetParameter(espeakRATE,speed,0); + break; + + case 9: /* word_gap */ + // not implemented + break; + + case 10: /* pitch_range */ + // not implemented + break; + + case 12: /* reset */ + // not implemented + break; + + case 13: /* volume */ + amp = (value*45)/100; + SetParameter(espeakVOLUME,amp,0); + WavegenSetVoice(voice); + break; + } + return(NULL); +} /* end of swi_handler */ + + + +void PitchAdjust(int pitch_adjustment) +{//=================================== + int ix, factor; + voice_t *voice = &voice_data; + extern unsigned char pitch_adjust_tab[100]; + + voice->pitch_base = (voice->pitch_base * pitch_adjust_tab[pitch_adjustment])/128; + + // adjust formants to give better results for a different voice pitch + factor = 256 + (25 * (pitch_adjustment - 50))/50; + for(ix=0; ix<=5; ix++) + { + voice->freq[ix] = (voice->freq2[ix] * factor)/256; + } +} // end of PitchAdjustment + + + +char *param_string(char **argp) +{//============================ + char *p; + int ix=0; + static char buf[80]; + + p = *argp; + while(*p == ' ') p++; + while(!isspace(*p)) + buf[ix++] = *p++; + buf[ix]=0; + + *argp = p; + return(buf); +} + +int param_number(char **argp) +{//========================== + int value; + char *p; + + p = *argp; + while(*p == ' ') p++; + + value = atoi(p); + while(!isspace(*p)) p++; + *argp = p; + return(value); +} + +void command_line(char *arg_string, int wait) +{//========================================== + + int option_index = 0; + int c; + int value; + int speed; + int amp; + int speaking = 0; + int flag_stdin = 0; + int flag_compile = 0; + int error; + int pitch_adjustment = 50; + char filename[80]; + char voicename[40]; + char command[80]; + char *p; + int ix; + + voicename[0] = 0; + wavefile[0] = 0; + filename[0] = 0; + option_linelength = 0; + option_phonemes = 0; + option_waveout = 0; + option_quiet = 0; + option_harmonic1 = 8; + option_multibyte = 0; // auto + option_capitals = 0; + option_punctuation = 0; + option_punctlist[0] = 0; + + f_trans = stdout; + + p = arg_string; + + for(;;) + { + while(*p==' ') p++; // skip spaces + if(*p == '\r') break; // end of line + + if(*p == '-') + { + // a command line argument + p++; + switch(*p++) + { + case 'h': + printf("\nspeak text-to-speech: %s\n%s",version_string,help_text); + return; + + case 'b': + option_multibyte = espeakCHARS_8BIT; + break; + + case 'a': + amp = param_number(&p); + SetParameter(espeakVOLUME,amp,0); + break; + + case 'f': + strncpy0(filename,param_string(&p),sizeof(filename)); + break; + + case 'k': + option_capitals = param_number(&p); + SetParameter(espeakCAPITALS,option_capitals,0); + break; + + case 'l': + option_linelength = param_number(&p); + break; + + case 'p': + pitch_adjustment = param_number(&p); + break; + + case 'q': + option_quiet = 1; + break; + + case 's': + speed = param_number(&p); + SetParameter(espeakRATE,speed,0); + break; + + case 'v': + strncpy0(voicename,param_string(&p),sizeof(voicename)); + break; + + case 'w': + option_waveout=1; + strncpy0(wavefile,param_string(&p),sizeof(wavefile)); + break; + + case 'x': + option_phonemes = 1; + break; + + case 'X': + option_phonemes = 2; + break; + + case '-': + strncpy0(command,param_string(&p),sizeof(command)); + if(memcmp(command,"compile=",8)==0) + { + CompileDictionary(NULL,&command[8],NULL,NULL); + return; + } + else + if(strcmp(command,"help")==0) + { + printf("\nspeak text-to-speech: %s\n%s",version,help_text); + return; + } + else + if(memcmp(command,"punct",5)==0) + { + option_punctuation = 1; + if((command[5]=='=') && (command[6]=='"')) + { + ix = 0; + while((ix < N_PUNCTLIST) && ((option_punctlist[ix] = command[ix+7]) != 0)) ix++; + option_punctlist[N_PUNCTLIST-1] = 0; + option_punctuation = 2; + } + SetParameter(espeakPUNCTUATION,option_punctuation,0); + } + else + { + printf("Command not recognised\n"); + } + break; + + default: + printf("Command not recognised\n"); + break; + } + + } + else + { + break; + } + } + + SetVoiceByName(voicename); + + if((filename[0]==0) && (p[0]=='\r')) + { + // nothing to speak + if(option_quiet) + { + SpeakNextClause(NULL,NULL,2); // stop speaking + more_text = 0; + } + } + + if(option_waveout || option_quiet) + { + // write speech to a WAV file + if(option_quiet) + { + OpenWaveFile(NULL,samplerate); + option_waveout = 2; + } + else + { + if(OpenWaveFile(wavefile,samplerate) != 0) + { + fprintf(stderr,"Can't write to output file '%s'\n'",wavefile); + return; + } + } + } + + if(pitch_adjustment != 50) + { + PitchAdjust(pitch_adjustment); + } + WavegenSetVoice(voice); + + if(filename[0]==0) + speak_text_string(p,'\r',0,wait,-1); + else + speak_file(filename); +} + + + +_kernel_oserror *command_handler(char *arg_string, int argc, int cmd_no, void *pw) +/********************************************************************************/ +{ + switch(cmd_no) + { + case 0: /* Say */ + command_line(arg_string,0); // for compatibility with speak V2 + break; + + case 1: /* Sayw ] */ + command_line(arg_string,0); + break; + + } + return(NULL); +} /* end of cmd_handler */ + + +// sound handler data +int current_sound_handler=0; +int prev_sound_handler=0; +int prev_sound_data=0; +int prev_sound_rate=13; +int sound_handler_changed=0; + + +void RiscosCloseSound() +{//==================== +_kernel_swi_regs regs; + if((sound_handler_changed) && (prev_sound_handler != (int)DMA_Handler)) + { + // check whether current handler is ours + regs.r[0]=0; + _kernel_swi(0x40145,®s,®s); + if(regs.r[1] == (int)DMA_Handler) + { + regs.r[0]=1; + regs.r[1]=prev_sound_handler; + regs.r[2]=prev_sound_data; + _kernel_swi(0x40145,®s,®s); // Sound LinearHandler 1 + + // reset to the previous sample rate + regs.r[0]=3; + regs.r[1]=prev_sound_rate; + _kernel_swi(0x40146,®s,®s); // Sound_SampleRate 3 + + current_sound_handler = prev_sound_handler; + sound_handler_changed = 0; + } + } +} // end of RiscosCloseSound + + + +void RiscosOpenSound() +{//=================== + _kernel_swi_regs regs; + + if(current_sound_handler != (int)DMA_Handler) + { + // register the sound handler + regs.r[0]=1; + regs.r[1]=(int)DMA_Handler; + regs.r[2]=(int)module_data; + _kernel_swi(0x40145,®s,®s); // Sound_LinearHandler 1 + prev_sound_handler = regs.r[1]; + prev_sound_data = regs.r[2]; + + // set the sample rate + regs.r[0]=3; + regs.r[1]=sample_rate_index; + regs.r[2]=0; + _kernel_swi(0x40146,®s,®s); // Sound_SampleRate + prev_sound_rate = regs.r[1]; + + current_sound_handler = (int)DMA_Handler; + sound_handler_changed = 1; + } +} // end of RiscosOpenSound + + + + + +int callback_handler(_kernel_swi_regs *r, void *pw) +/*************************************************/ +{ + if(Generate(phoneme_list,&n_phoneme_list,1)==0) + { + more_text = SpeakNextClause(NULL,NULL,1); + } + + if((WcmdqUsed() == 0) && (more_text == 0)) + { + RiscosCloseSound(); + } + callback_inhibit = 0; + + return(1); +} /* end of callback_handler */ + + + +int sound_handler(_kernel_swi_regs *r, void *pw) +/**********************************************/ +{ + int n_queue; + int size; + int *dma_buf; + int x; + int ix; + + module_data = (int *)pw; + dma_buf = (int *)r->r[1]; + size = (r->r[2] - r->r[1])/4; + FillSoundBuf(size); + + for(ix=0; ixr[0] = 0; + if(callback_inhibit == 0) + { + // set a callback either: + // - queue is low and there is more text to be processed + // - queue is empty and no more text, so callback handler will remove the sound handler + if(((n_queue < 20) && (more_text != 0)) || + ((n_queue==0) && (more_text == 0))) + { + callback_inhibit = 1; + r->r[0] = 1; + r->r[1] = (int)pw; + } + } + return(1); +} + + + + +int InitSound16(int sample_rate) +/******************************/ +/* Find sample rate index */ +{ + int current_rate_index; // current value + + int sound_mode; + int sound_config; + int srate; + int n_srix; + int ix; + _kernel_swi_regs regs; + _kernel_oserror *error; + + sound_mode = 0; + regs.r[0] = 0; + error = _kernel_swi(0x40144+os_X,®s,®s); + sound_mode = regs.r[0]; + sound_config = regs.r[1]; + + if((error == NULL) && (sound_mode == 1)) + { + /* 16 bit sound, find sample rate index */ + regs.r[0] = 0; + regs.r[1] = 0; + _kernel_swi(0x40146,®s,®s); + n_srix = regs.r[1]; + + regs.r[0] = 1; + regs.r[1] = 0; + _kernel_swi(0x40146,®s,®s); + current_rate_index = regs.r[1]; // current sample rate index + srate = regs.r[2]; + for(ix=1; ix<=n_srix; ix++) + { + regs.r[0] = 2; + regs.r[1] = ix; + _kernel_swi(0x40146,®s,®s); + srate = regs.r[2]; + if(srate >= (sample_rate*1024)) + { + return(ix); + } + } + } + return(14); // this was the index for 22050 +} // end of InitSound16 + + + +void RemoveCallback() +/*******************/ +{ + _kernel_swi_regs regs; + + regs.r[0] = (int)callback_entry; + regs.r[1] = (int)module_data; + _kernel_swi(0x5f, ®s, ®s); +} + + +void terminate_module(void) +/*************************/ +{ + RiscosCloseSound(); + RemoveCallback(); + delete translator; + FreePhData(); +} /* end of terminate_module */ + + +void kill_module(void) +/********************/ +{ + _kernel_swi_regs regs; + regs.r[0]=4; + regs.r[1]=(int)"Speak"; + _kernel_swi(0x1e,®s,®s); /* RMKill */ +} + + +_kernel_oserror *user_init(char *cmd_fail, int podule_base, void *pw) +/*******************************************************************/ +{ + _kernel_swi_regs regs; + _kernel_oserror *error; + int param; + + // It seems that the wctype functions don't work until the locale has been set + // to something other than the default "C". Then, not only Latin1 but also the + // other characters give the correct results with iswalpha() etc. + + static char *locale = "ISO8859-1"; + setlocale(LC_CTYPE,locale); + + module_data = pw; + + sample_rate_index = InitSound16(22050); + + if(initialise() < 0) + { + // exit module, errblk.errmess is set by initialise() + errblk.errnum = 0x101; + return(&errblk); + } + + ReadVoiceNames(); + SetVoiceByName("default"); + + for(param=0; paramlangopts.stress_rule = 3; // stress on final syllable - tr->langopts.stress_flags = 0x20; // don't use secondary stress + tr->langopts.stress_flags = 0x0024; // don't use secondary stress tr->langopts.param[LOPT_IT_LENGTHEN] = 1; // remove lengthen indicator from unstressed syllables tr->langopts.numbers = 0x1509; diff --git a/src/translate.h b/src/translate.h index c49114e2..0ceca9be 100755 --- a/src/translate.h +++ b/src/translate.h @@ -254,7 +254,7 @@ typedef struct { // bit6=light syllable followed by heavy, move secondary stress to the heavy syllable. LANG=Finnish // bit8=stress last syllable if it doesn't end in a vowel // bit9=stress last syllable if it doesn't end in vowel or "s" or "n" LANG=Spanish -// bit12= In 2-syllable words, give the first syllable a secondary stress +// bit12= If there is only one syllable before the primary stress, give it a secondary stress int stress_flags; int unstressed_wd1; // stress for $u word of 1 syllable diff --git a/src/voices.cpp b/src/voices.cpp index 82afd18f..aaf413eb 100755 --- a/src/voices.cpp +++ b/src/voices.cpp @@ -47,6 +47,9 @@ MNEM_TAB genders [] = { {"female", 2}, {NULL, 0 }}; +//int tone_points[10] = {250,140, 1200,110, -1,0, -1,0, -1,0}; +int tone_points[10] = {600,180, 1200,140, 2000,110, 3000,110, -1,0}; + // limit the rate of change for each formant number //static int formant_rate_22050[9] = {50, 104, 165, 230, 220, 220, 220, 220, 220}; // values for 22kHz sample rate static int formant_rate_22050[9] = {50, 100, 165, 200, 200, 200, 200, 200, 200}; // values for 22kHz sample rate @@ -155,7 +158,6 @@ const char variants_female[N_VOICE_VARIANTS] = {11,12,13,14,0}; const char *variant_lists[3] = {variants_either, variants_male, variants_female}; -int tone_points[10] = {250,140, 1200,110, -1,0, -1,0, -1,0}; void SetToneAdjust(voice_t *voice, int *tone_pts) {//============================================== @@ -544,11 +546,6 @@ voice_t *LoadVoice(char *vname, int control) } f_voice = fopen(buf,"r"); - if(first_voice == NULL) - { - first_voice = ReadVoiceFile(f_voice,buf+len_path_voices,voicename); - rewind(f_voice); - } language_type = "en"; // default if(f_voice == NULL) @@ -560,6 +557,13 @@ voice_t *LoadVoice(char *vname, int control) language_type = voicename; } + if(first_voice == NULL) + { + first_voice = ReadVoiceFile(f_voice,buf+strlen(path_voices),voicename); + rewind(f_voice); + } + + if(!tone_only && (translator != NULL)) { delete translator;