From 736e6deb285f28a310803ee5f8665fbfb4945ec7 Mon Sep 17 00:00:00 2001 From: jonsd Date: Mon, 17 Sep 2012 21:04:16 +0000 Subject: [PATCH] Numbers: Support "myriad" (10^4) based number systems (lang=ko). Lang=pt: fix ordinal numbers 11-19. Lang=en-us: minor vowel changes. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@291 d46cf337-b52f-0410-862d-fd96e6ae7743 --- dictsource/dict_phonemes | 2 +- dictsource/ko_list | 114 +++++++++++++++++++-------------------- dictsource/ko_rules | 14 ++++- dictsource/pt_list | 2 +- docs/phonemes.html | 11 ++-- phsource/compile_report | 16 +++--- phsource/ph_english_us | 2 +- phsource/vdiph/aae | Bin 2921 -> 2921 bytes phsource/vowel/V_6 | Bin 6239 -> 6755 bytes phsource/vowel/aa_8 | Bin 2156 -> 2758 bytes phsource/vwl_en_us/3_us | Bin 1348 -> 1692 bytes phsource/vwl_en_us/3_us2 | Bin 1671 -> 2101 bytes phsource/vwl_en_us/ee | Bin 3352 -> 3782 bytes src/numbers.cpp | 82 +++++++++++++++++++++------- src/synthdata.cpp | 50 +++++++++++------ src/synthesize.h | 1 + src/tr_languages.cpp | 5 +- src/translate.h | 8 ++- src/vowelchart.cpp | 31 ++--------- 19 files changed, 196 insertions(+), 142 deletions(-) diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index 8d75b59b..4f3bf635 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -825,7 +825,7 @@ R s S S; t w x z Z Z; -Dictionary ko_dict 2012-09-14 +Dictionary ko_dict 2012-09-15 @ a e E i o u u- diff --git a/dictsource/ko_list b/dictsource/ko_list index 00082ddf..8f7a1e71 100644 --- a/dictsource/ko_list +++ b/dictsource/ko_list @@ -1,68 +1,64 @@ -$textmode +// eSpeak Korean rules. Changed pronunciation, as numbers were not announced. + // Number forms: -_0 ᅧᆼ -_1 ᅵᆯ -_2 ᅵ -_3 삼 -_4 사 -_5 ᅩ -_6 ᅲᆨ -_7 칠 -_8 팔 -_9 구 -_1X 십 -_2X ᅵ십 -_3X 삼십 -_4X 사십 -_5X ᅩ십 -_6X ᅲᆨ십 -_7X 칠십 -_8X 팔십 -_9X 구십 -_0C 백 -_0M1 천 -_1M1 천 - -$phonememode -_0M2 m'an // 10^4 -_1M2 m'an -_0M3 tSh-@n||m'an // 10^7 -_1M3 tSh-@n||m'an -_0M4 '@q // 10^8 -_1M4 '@q -_0M5 tSh-@n||'@q // 10^11 -_1M5 tSh-@n||'@q -_0M6 tS;'o // 10^12 -_1M6 tS;'o -_0M7 tSh-@n||tS;'o -_1M7 tSh-@n||tS;'o -_0M8 gj'@nN -_1M8 gj'@nN -$textmode +_0 j'@N_! +_1 'iR_! +_2 'i_! +_3 s'am_! +_4 s'a_! +_5 'o_! +_6 j'uq_! +_7 tS'h'iR_! +_8 ph'aR_! +_9 g'u_! +_1X s'ip_! +_2X 'i_!||s'ip_! +_3X s'am_!||s'ip_! +_4X s'a_!||s'ip_! +_5X 'o_!||s'ip_! +_6X j'uq_!||s'ip_! +_7X tS'h'iR_!s'ip_! +_8X ph'aR_!||s'ip_! +_9X g'u_!||s'ip_! +_0C p'Eq_! +// Larger numbers +_0M0 tS'h-@n // 10^3 +_1M0 tS'h-@n +_0M1 m'an // 10^4 +_1M1 m'an +_0M2 '@q // 10^8 +_1M2 '@q +_0M3 tS;'o // 10^12 +_1M3 tS;'o +_0M4 gj'@N +_1M4 gj'@N // Character names: -ㄱ ㄱㅣㅇㅕㄱ -ㄲ ㅆㅏㅇㄱㅣㅇㅕㄱ -ㄴ ㄴㅣㅇㅡㄴ -ㄷ ㄷㅣㄱㅡㄷ -ㄸ ㅆㅏㅇㄷㅣㄱㅡㄷ -ㄹ ㄹㅣㅇㅡㄹ -ㅁ ㅁㅣㅇㅡㅁ -ㅂ ㅂㅣㅇㅡㅂ -ㅃ ㅆㅏㅇㅂㅣㅇㅡㅂ -ㅅ ㅅㅣㅇㅗㅅ -ㅆ ㅆㅏㅇㅅㅣㅇㅗㅅ -ㅇ ㅇㅣㅇㅡㅇ -ㅈ ㅈㅣㅇㅡㅈ -ㅉ ㅆㅏㅇㅈㅣㅇㅡㅈ -ㅊ ㅊㅣㅇㅡㅊ -ㅋ ㅋㅣㅇㅡㅋ -ㅌ ㅌㅣㅇㅡㅌ -ㅍ ㅍㅣㅇㅡㅍ -ㅎ ㅎㅣㅇㅡㅎ +ᄀ gij'@q +ᄁ 's-aNq,ij@q +ᄂ ni;'u-n +ᄃ diq'u-d- +ᄄ 's-aNd,iqu-d- +ᄅ *i;'u-rr +ᄆ mi;'u-m +ᄇ pi;'u-p +ᄈ 's-aNb,i;u-p +ᄉ si;'ot- +ᄊ 's-aNs,i;ot- +ᄋ i;'u-N +ᄌ tS;i;'u-t +ᄍ 's-aNdZ;,i;u-t +ᄎ tSh-'i;u-t +ᄏ khi;'u-k +ᄐ thi;'u-t- +ᄑ phi;'u-p +ᄒ hi;'u-t- +// end of character names. + +$textmode // Misc: // 사ᅵ시ᅩᆺ 고랫재 고랟째 diff --git a/dictsource/ko_rules b/dictsource/ko_rules index 12d89194..6190cbe0 100644 --- a/dictsource/ko_rules +++ b/dictsource/ko_rules @@ -1,5 +1,14 @@ +// eSpeak Korean rules // This file is UTF8 encoded +// char names (mostly to catch "ng" sound): +.group ᄋ +ᄋ i;'u-N + + + + + .replace // Note: These specific range of "normalized" unicode characters of Korean are @@ -15,6 +24,9 @@ // h-finals: ㅎ ㄶㅀ .L03 ᇂ ᆭ ᆶ +// Char names: + + // Initials // Order: ㄱㄲㅋ ㄷㄸㅌ ㅂㅃㅍ ㅅㅆㅈㅉㅊ ㄴㅁ ㄹ ㅎ @@ -241,7 +253,7 @@ ᆷ m .group ᆼ // ㅇ - ᆼ nN + ᆼ N .group ᇂ // ㅎ ᇂ t- diff --git a/dictsource/pt_list b/dictsource/pt_list index f9a2b59d..76fcb2fd 100755 --- a/dictsource/pt_list +++ b/dictsource/pt_list @@ -217,7 +217,7 @@ _6o s'est _7o s'EtSim _8o oIt'av _9o n'on -_10o d'Esim +_1Xo d'Esim _2Xo viZ'Ezim _3Xo tRiZ'Ezim _4Xo kwad*aZ'Ezim diff --git a/docs/phonemes.html b/docs/phonemes.html index 0c3f80e4..c0ab5fc7 100644 --- a/docs/phonemes.html +++ b/docs/phonemes.html @@ -24,8 +24,8 @@ Phoneme mnemonics can be used directly in the text input to espeak -[p] -[b] +[p] +[b] [t] [d] @@ -92,7 +92,7 @@ In rhotic accents, such as General American, the phonemes [3:], [A@], [e@]
[@] -alphaschwa +alphaschwa
[3] betterrhotic schwa. In British English this is the same as [@], but it includes 'r' colouring in American and other rhotic accents. In these cases a separate [r] should not be included unless it is followed immediately by another vowel. @@ -105,7 +105,7 @@ In rhotic accents, such as General American, the phonemes [3:], [A@], [e@]
[a]trap
[aa]bathThis is [a] in some accents, [A:] in others. -
[a2]aboutThis may be [@] or may be a more open schwa. +
[a#]aboutThis may be [@] or may be a more open schwa.
[A:]palm
[A@]start

@@ -161,7 +161,8 @@ Other languages will have their own vowel definitions, eg:

- +

+ [:] can be used to lengthen a vowel, eg [e:] diff --git a/phsource/compile_report b/phsource/compile_report index 38e51190..fad5477c 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -417,7 +417,7 @@ l/l_ [l] base [l/] fr l/l_@ [l/3] base [l/] fr -l/l@ [h1ø] base +l/l@ [hÖ{] base [l#] base [l] fr [l/2] fr @@ -451,7 +451,7 @@ l/L2_oL [l/2] base l/L2_uL [l/2] base l/l_3 [l/] de l/l_4 [ll] sq -l/la [h1ø] base +l/la [hÖ{] base [l#] base [l] fr [l/2] fr @@ -459,7 +459,7 @@ l/la [h1 [K] tn l/l_a [l/3] base [l/] fr -l/le [h1ø] base +l/le [hÖ{] base [l#] base [l] fr [l/2] fr @@ -471,7 +471,7 @@ l/L_eL_af [&] af [&:] af l/l_front [L] sq l/l_front_ [l/4] sq -l/li [h1ø] base +l/li [hÖ{] base [l#] base [l] fr [l/2] fr @@ -485,7 +485,7 @@ ll/ll [L] base ll/_ll [L] base l/l_long [l] base [l] fr -l/lo [h1ø] base +l/lo [hÖ{] base [l#] base [l/2] fr [K] nso @@ -496,7 +496,7 @@ l^/l_rfx [l.] base [l;] lt [l] ru [l^] ru -l/lu [h1ø] base +l/lu [hÖ{] base [l#] base [l] fr [l/2] fr @@ -1088,11 +1088,11 @@ vdiph2/uu@ [U@] en [U@] en-n [U@] en-wm [u@] vi -vdiph2/uw [u:] en-us vdiph2/uw_2 [u:] en vdiph2/uw_3 [yU] ro vdiph2/uw_4 [u:] en-n -vdiph2/uw_6 [u#] kk +vdiph2/uw_6 [u:] en-us + [u#] kk vdiph2/y@ [y@] zh vdiph2/y#@ [Y@] af vdiph2/ye [yE] sq diff --git a/phsource/ph_english_us b/phsource/ph_english_us index edf8229f..e564ce9b 100644 --- a/phsource/ph_english_us +++ b/phsource/ph_english_us @@ -235,7 +235,7 @@ endphoneme phoneme u: vowel starttype #u endtype #u length 190 - FMT(vdiph2/uw) + FMT(vdiph2/uw_6) endphoneme diff --git a/phsource/vdiph/aae b/phsource/vdiph/aae index 92973c8e94f65a7dd48469273b125c13ab663ef4..29232deceb1d97ab4df1288f698ee9555bdd3602 100644 GIT binary patch delta 423 zcmaDU_EKzuZ@mm-12+@%Jf=tn1_lsjV31*UkaA&?VTuB>L70Kz4a)%u8Kx;rJwP@H zGcXu&IS4#pe89-U$iM)?3=9Rl4ZNr#|M(g>QAIXLA7BEBd;#hJVFreZ$>*4@C$lro zV_YzK8KXSST=VWf@vf<7+5mKo0keEPHzNc0J0|3?;b(S`2to-P71jnZ2b8dp;d0+p@14h^!Knt5$(hcZgv-uqJY<2){Hc=7) delta 423 zcmaDU_EKzuZ@mN~1J^vJc}$TE3=AO5!0>?SfVd2k3{w=44Z;iz8(0oVPGOqD)B|LL zFayI4P6qx5j1L%D7#SEqn1P{ymw^ve#D<@N8&$+Xx&f%?0pk~-4iIKwsF-|?*?KZN z<2=Tm$;%k!Y37=D|A}`^J<|rp36l+&L9RK#i5WIin3gai!sZPTVdKH;Ab=VYZ}^A^ Lo6YB#XR`wUs4-I# diff --git a/phsource/vowel/V_6 b/phsource/vowel/V_6 index 3e8a2a976ea0a0af0eeda87ca4f2c6bbf09319fa..ccf454d1f7b0cc5467fb8b5fbd95a70c7cdb6b68 100644 GIT binary patch delta 1223 zcmchW!7Bt&9LK-!H#_xqX;$GN<+9S|BstmLkR&&2sa+RW2g!1AP~<2j|ABDaiFD!J~2UL~pn1z5C(__=5# z=^?*49G?ZYwDosquVF2h$U3uAL6~!9)tjn!M<+hLg>QPMw0(MuM)_yGOzj&0G3oQe zpyY@=GC*85pm!nb8Eu5VGAdC4%SuK|`UJX_jNW96P&3*$TE!n_WZMl$+%(rE;E^z? zgn30`MV~=jk+5aIPr@`RKPOQS0`LVAak4(!wZki=Rt6r%?K(g#5FezT0G(NR~}XERVM?_wI9J%^-6tFi?vBT z$>)^Br}ek6k_yEw+Gm7ui|o8h+I8|`Kl0MTaPp?*<1cw#!p-XxZeF*r@)WaGKk;lT zQ?~Ao4jtVL?{~KGF3Op`jdkf`f7^y(*xS%s9Wh+EeXc48l(*i9}z8b2v+C(uuscALgP)}A5 z8k4Gt>BWP}MNb}jpfNEdew-RThzAojF%lCKY&FHa9?R;Trr-q*A?^?~N}fO?c;_2_^Os!zQdX3gjh>op9CW*}wSAbd`ee2M>g=>pd+=WG2jo2}CPVsrW zC7i|M66q4zz&l*7bt?Yz_B-ELZN1oUYre={EHGeD_MMRvWVemklR=H{g~3R?n!!kX ze;MTTAo>nb30L%*p4a#KL`ymamwuGWSOQ(}7=S?$Iv2?PX-G^%;56r>mO%!E>tK;Z z|3mDot&B8WT6jwuZEJ0wr??umn|X7NsBZgd(pF1~s049!mckFueQ1UCV!wLUkQe>S zH=t1V&EZ)Jyc|^&N~O)JN+^}?g@RN~VZSS3fNUP28qVl46kgF+`bsm2PRB{P0GMk&2&3R`vG@BF5=DhQ1Xfkvp{ini{q1v;1Hm~jTY(Aog>Gq>k z!By7R`Unb(5b(vKdeB2LhmjuMwbS2K^(WO)jDrtkQ( zz|?_RW%Uh#1_&7n&AdAUMMKHV=0vdKa4FvTDb*iv_}L5Ozk7JGvTq(=g+t#i4jIc~ zDa4_K=cuzC;xM#}!=}48hcEY)LxEZtqZ)>FPA}?Jea?iwh{_{O2h*22S!VL~!ex*y zG^Zz-&kHb^WzVrZ2>DYw1+7-9!F01$t9BHP%}h3(CN49z<7jR2-ppe2?WmdhF&)c% Ok1|oUe2X$xT>k=<3Qi;d delta 880 zcmb7?ze@sP9LAq}y--fGLJZ5x#ViY#vdn&fMoCdthJiyv89_l{4GuP4EkR?QOF`Ju zW*|8tG7`{Cu~zMtoPpBMXQyDc7z%&f&Dt1N(IawBNO z)|qWokWr-@2ZSedfztqlNs0O906ke@Dhii4jk6Y&WeiwV1~#1~+`JgGmfymO7l^9MgEm4H9CG-0d_KFhF0xZ_)((COrYs%DxKqS+ZQN zhm~dhS%5YR(3{ndDfnsNMWk?yLpsW@EZz(qBE!7?9|JihRlM4@N7mm<>97Nvu zCOBw^)R*X>4dY2#X%$Bs#*@7A(hjqBMyfXqzZ!O}+pr;wBZvTvnW5h^ay0IW_+TpT g_BJ?lDh@HlL8d%Hs)~cJ!J+(z!=sLa=;JQG0N>KJ=l}o! diff --git a/phsource/vwl_en_us/3_us b/phsource/vwl_en_us/3_us index b390b26c720fa9ba81a8c647c4aa991090065929..e6eee317bd7d633a3cd67e451515e5d10db83aa0 100644 GIT binary patch literal 1692 zcmeH`y>Aj>9LK+R-j##nfY#blTQP`YeXE2T+lZB?1tQW!X+Xu7r0QUFkU?Xjg9$pQ zgVw~^!J&hTTStdZrh@~6e*md*?_koznAGoc94!akOgHbB-}CZ&Uh?Goxo@eM%aluV zNe#gG{NqO&ZgSNA3H_%t71~m3v{@^#a@nb_Z!ACRCi@G z7H_Mhp+`|QC8F%pt&yYn1lQ@G3&b^G>y%-YEv;w8IQ0kjEUVcun=EaFw$PmA#0kSVWCl zC#ic9N0ETQ4RSh1E~l7NT+5Q)ZD&;Ao(M*$=MeSXPnDa>N=*ZHSkzdukYv0z8G}qL zG8p8UDB}PQA;xxqRD# zL!?M%jH<=>_s2P#A-!pOB!Oe}$#L?S`>ib2BSC3)?ZP hcQO0e#jNf@z)dL2$G9sW_^eK5wO#+2Nop--e*qcf&j0`b delta 538 zcmbQkdxT3kIKb68B-k~Og@J*=IKH%)g&}gHuxb7G|9uP%>?@cIn1JF84;YIDWtbi? zg4kPFr9|48BEaH#94-P686n~kJWqHb?C<~c__lCAhKj36JFvpo6>@4!Ft&y=gzdqQ zz!1gI%h1FS%#gw03B(}`X_I9c*JoX@C*KVW45YYWau3sudOZ$g>#iVqc?pu2Kd?LU z!@TUllgI;OPvVQ~`T{fV*Q39|Mv*8kos)2LQ8~cCr8f diff --git a/phsource/vwl_en_us/3_us2 b/phsource/vwl_en_us/3_us2 index c79e3c81490f1db7d6c0f9fc53d6ec1318435a3a..673df821eeb0fc114fc0a808b23a6cfb1362d891 100644 GIT binary patch literal 2101 zcmd^9J5Ll*7(KJ@>~m%xxbkpu6<1gAfdq^Y5%-PG%&~O9 z(yiFME9c@`NCzVR<+_4a(A*jz9hf&n*omxdw1q6gi2(cJ!XuHN+#wx!oB+S%L|T(6 z2huAS*-vYEu-OmcD$h5E7nr~;oTE?TCSKtg29ZGzPN5rFT*MgrlQ_=y82c>e8OF{d zjTCmF0ef%=El3~=KO(4OZ@`2PUe3J;(hYh;w}c2WTyvM-k!*KLYGcTKf0L zC69eVp|2E*M-}b`*guO3HVGGQl>Q{2o`vPv4i13r=Aaux7{^`AF#CO&;w;C^j^YUx zVKLX8%zGyeqXPn0$kQ3}a)RE+*dW=vRvHa+O#;o#XA|?gmsu`mR^~Kho5>tYE+jL4 zn;9QDG08y#_q5RV;~&a@EJeq7Jb8>%r{ms;`8eUdP3^;iy-+3UPo`a~;#%Il{ z(#Bg|#AX$3SUyD6d;iE-HdSOaB!ViEj6?sTC_!pNMWi+=$X43;cX;{!bg9J4dr_oA zxGTJrvFi+#YgW7OHQ-bA@<~ITTC)~)#9k`A{P3z33dk9vszN;oiNLD1>Zog}INV=r zcu^6_O9k1Amo^OJH1Gde+{PVrv1$!a8U1WWSbd-49(t*mcHZVBt5S-y0jjE>wW|Y1 zSig=^Cp{dG(6X#!y>!7HyLrgi3?QzNw~-xlP1f_$H0o77Q&JJaj6oE4dqt)tp&7DtyQzNG++z|HauK{d)tY delta 637 zcmdlg(9SCo9N_9466_kt%D}*29A8>&#L5skQN*{mA4-HUl&(FCbaDfRzCr;}_T&_+ZvV@G!uw?BHWSva*4hkd*)< Cnv3E9 diff --git a/phsource/vwl_en_us/ee b/phsource/vwl_en_us/ee index bd9f69371381880e389da12335e808ff2170062f..a0ced591c82e94fe4e068bae40e82bb06d0ab3a4 100644 GIT binary patch delta 1015 zcmb`FKS&!<9LK-!cS-KNBX=n#QtX+*fMjs686(73MH=JMk`5Z`pQ-KCO^CIa6ITZv z1jj%}2Nl<}WD-ZA&`vEGx&@rBorLsVF21`&DGq(`d++YU?~dQ+{eDNI7h_ua#r)i> z^2^+TR;WR&S?yBn*K|$G;#|fG?TP?g=CX<)6)dXXL;w>sL3@IT&_@__pF|iCVQup# zwM}4&mdGa}5p@e_P$NX#QJ=WtEBBe$fNDB~x+I$klW8xhyRx?r@;p18q}ub|Yp25* zj4Q?NndE5|MdHZ>U6F56R4-wxPU@qm(l^-|I*veZ4!2l~`E{4f19}(dRzSSpTNXFM zWKL_@O~oVbyrJMuerZtTZ+>VxdaqS`=GZ$1ic zyR84fM%*z2@+G0Ly4BPJ;@#V!jfh9&Y;`)-^xcjW9@>#@E$3@|hhyx^vHHx`uue$6 zkrHm~RN*nCs#3z$+Cl<}puo504YuM4Nq8mKEoVSt!RCPk!;DC}PvYqVB|bei=r1S& Bx>W!G delta 681 zcmX>mJ41>iIKb68B-k}@B8OeQ6UPY#28MS`@0enlni*o57#O}Veqr=xzsBIr&cL9? zq{hU+CC13W1!2GDyT|mJkAWeADFUdHfnfnZ1H&GsJz(}1DFnMh4#Cz?hOj5>jFfed^WBSHq#T3V&z{DUVz;uDhgZ%`< z1GWXCH9!j+IajlYa2*hS!1#dCi*F)R3$F)1hz)Uw2RDT6%<(|xATvz7Lavqx#@0~w z0<(LyJ#}8_y6gAqH|uTHiPN6CnVm(NsXh^84g<^)%1n81M<}t^v%(y)n%#pN<_I}1 zX-1eM)(ccKF5rhbf`NgcBMiNbei-MN?lzriGTlhqaR27-Z1PO?b{v-(9JrmCzcIaL ztYmOt>K3*JhQe32&D;~%0z|8Tq2SHFhe3qvfgs3N!CZG4N_qG2f!O;5n1K#>$p!Q6 zR2gm-2>bv43b}ZsP_P5D|B4#ON~`v02570NcgmZJ@W_7E*tq#Mrz}(bb%qA+iOe!g zdl};y5}3q9(tu9*!nT3gfsH}50_cP<9It^+U=RQqpU(G(p_*48>;ylangopts.numbers2 & NUM2_NO_TEEN_ORDINALS)) + { + // don't use numbers 10-99 to make ordinals, always use _1Xo etc (lang=pt) + } + else + { + sprintf(string,"_%d",value); + found = Lookup(tr, string, ph_digits); + } } } } @@ -1251,7 +1262,7 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out) else { - if((control & 1) && + if((is_ordinal) && ((units == 0) || (tr->langopts.numbers & NUM_SWAP_TENS) || (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL))) { sprintf(string,"_%dX%c", tens, ord_type); @@ -1300,7 +1311,7 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out) sprintf(string,"_%df",units); found = Lookup(tr, string, ph_digits); } - if((control & 1) && ((tr->langopts.numbers & NUM_SWAP_TENS) == 0)) + if((is_ordinal) && ((tr->langopts.numbers & NUM_SWAP_TENS) == 0)) { // ordinal sprintf(string,"_%d%c",units,ord_type); @@ -1335,7 +1346,7 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out) } } - if((control & 1) && (found_ordinal == 0) && (ph_ordinal[0] == 0)) + if((is_ordinal) && (found_ordinal == 0) && (ph_ordinal[0] == 0)) { if((value >= 20) && (((value % 10) == 0) || (tr->langopts.numbers & NUM_SWAP_TENS))) Lookup(tr, "_ord20", ph_ordinal); @@ -1347,7 +1358,7 @@ static int LookupNum2(Translator *tr, int value, int control, char *ph_out) { Lookup(tr, "_0and", ph_and); - if((control & 1) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) + if((is_ordinal) && (tr->langopts.numbers2 & NUM2_MULTIPLE_ORDINAL)) ph_and[0] = 0; if(tr->langopts.numbers & NUM_SWAP_TENS) @@ -1406,6 +1417,7 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null int ix; int exact; int ordinal; + int tplex; int say_zero_hundred=0; char string[12]; // for looking up entries in **_list char buf1[100]; @@ -1465,10 +1477,16 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null if ((value % 1000) == 0) exact = 1; - if(LookupThousands(tr, hundreds / 10, thousandplex+1, exact | ordinal, ph_10T) == 0) + tplex = thousandplex+1; + if(tr->langopts.numbers2 & NUM2_MYRIADS) + { + tplex = 0; + } + + if(LookupThousands(tr, hundreds / 10, tplex, exact | ordinal, ph_10T) == 0) { x = 0; - if(tr->langopts.numbers2 & (1 << (thousandplex+1))) + if(tr->langopts.numbers2 & (1 << tplex)) x = 8; // use variant (feminine) for before thousands and millions LookupNum2(tr, hundreds/10, x, ph_digits); } @@ -1615,6 +1633,23 @@ static int LookupNum3(Translator *tr, int value, char *ph_out, int suppress_null } // end of LookupNum3 +bool CheckThousandsGroup(char *word, int group_len) +{//================================================ +// Is this a group of 3 digits which looks like a thousands group? + int ix; + + if(isdigit(word[group_len]) || isdigit(-1)) + return(false); + + for(ix=0; ix < group_len; ix++) + { + if(!isdigit(word[ix])) + return(false); + } + return(true); +} + + static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int *flags, WORD_TAB *wtab, int control) {//===================================================================================================================== // Number translation with various options @@ -1640,6 +1675,7 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned int decimal_mode; int suffix_ix; int skipwords = 0; + int group_len; char *p; char string[32]; // for looking up entries in **_list char buf1[100]; @@ -1662,8 +1698,12 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned n_digits = ix; value = this_value = atoi(word); + group_len = 3; + if(tr->langopts.numbers2 & NUM2_MYRIADS) + group_len = 4; + // is there a previous thousands part (as a previous "word") ? - if((n_digits == 3) && (word[-2] == tr->langopts.thousands_sep) && isdigit(word[-3])) + if((n_digits == group_len) && (word[-2] == tr->langopts.thousands_sep) && isdigit(word[-3])) { prev_thousands = 1; } @@ -1777,14 +1817,19 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned // a "thousand"/"million" suffix to this one digix = n_digits + thousands_inc; - while(((wtab[thousandplex+1].flags & FLAG_MULTIPLE_SPACES) == 0) && - isdigit(word[digix]) && isdigit(word[digix+1]) && isdigit(word[digix+2]) && !isdigit(word[digix+3]) && !isdigit(word[digix-1])) + while(((wtab[thousandplex+1].flags & FLAG_MULTIPLE_SPACES) == 0) && CheckThousandsGroup(&word[digix], group_len)) { - if((word[digix] != '0') || (word[digix+1] != '0') || (word[digix+2] != '0')) - thousands_exact = 0; + for(ix=0; ixlangopts.thousands_sep) || ((tr->langopts.numbers & NUM_ALLOW_SPACE) && (word[digix] == ' '))) { suffix_ix = digix+2; @@ -1820,7 +1865,8 @@ static int TranslateNumber_1(Translator *tr, char *word, char *ph_out, unsigned { if(thousands_inc > 0) { - if((thousandplex > 0) && (value < 1000)) + if(thousandplex > 0) +// if((thousandplex > 0) && (value < 1000)) { if((suppress_null == 0) && (LookupThousands(tr,value,thousandplex, thousands_exact, ph_append))) { diff --git a/src/synthdata.cpp b/src/synthdata.cpp index d39d90d5..40fadfe4 100644 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -881,39 +881,57 @@ static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT } // end of SwitchVowelType -static int NumInstnWords(USHORT *prog) -{//=================================== +int NumInstnWords(USHORT *prog) +{//============================ int instn; int instn2; int instn_type; int n; - static const char n_words[16] = {1,1,0,0,1,1,1,1,1,2,4,0,0,0,0,0}; + int type2; + static const char n_words[16] = {0,1,0,0,1,1,0,1,1,2,4,0,0,0,0,0}; instn = *prog; instn_type = instn >> 12; if((n = n_words[instn_type]) > 0) return(n); - if(instn_type < 4) + switch(instn_type) { + case 0: + if(((instn & 0xf00) >> 8) == i_IPA_NAME) + { + n = ((instn & 0xff) + 1) / 2; + return(n+1); + } + return(1);; + + case 6: + type2 = (instn & 0xf00) >> 9; + if((type2 == 5) || (type2 == 6)) + return(12); // switch on vowel type + return(1); + + case 2: + case 3: // a condition, check for a 2-word instruction if(((n = instn & 0x0f00) == 0x600) || (n == 0x0d00)) return(2); return(1); - } - // instn_type 11 to 15, 2 words - instn2 = prog[2]; - if((instn2 >> 12) == 0xf) - { - // This instruction is followed by addWav(), 2 more words - return(4); + default: + // instn_type 11 to 15, 2 words + instn2 = prog[2]; + if((instn2 >> 12) == 0xf) + { + // This instruction is followed by addWav(), 2 more words + return(4); + } + if(instn2 == i_CONTINUE) + { + return(3); + } + return(2); } - if(instn2 == i_CONTINUE) - { - return(3); - } - return(2); } // end of NumInstnWords diff --git a/src/synthesize.h b/src/synthesize.h index b7041b72..fb9c7e7a 100644 --- a/src/synthesize.h +++ b/src/synthesize.h @@ -571,6 +571,7 @@ int DoSpect2(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, PHONEME_L int PauseLength(int pause, int control); int LookupPhonemeTable(const char *name); unsigned char *GetEnvelope(int index); +int NumInstnWords(USHORT *prog); void InitBreath(void); diff --git a/src/tr_languages.cpp b/src/tr_languages.cpp index eb6ca4b4..dfd15b3b 100644 --- a/src/tr_languages.cpp +++ b/src/tr_languages.cpp @@ -957,7 +957,8 @@ SetLengthMods(tr,3); // all equal tr->langopts.stress_rule = 8; // ?? 1st syllable if it is heavy, else 2nd syllable tr->langopts.param[LOPT_UNPRONOUNCABLE] = 1; // disable check for unpronouncable words tr->langopts.numbers = NUM_OMIT_1_HUNDRED; - tr->langopts.break_numbers = 0x9999998; + tr->langopts.numbers2 = NUM2_MYRIADS; + tr->langopts.break_numbers = 0x1111110; tr->langopts.max_digits = 20; } break; @@ -1115,7 +1116,7 @@ SetLengthMods(tr,3); // all equal tr->langopts.stress_rule = STRESSPOSN_1R; // stress on final syllable tr->langopts.stress_flags = 0x6 | 0x10 | 0x2000 | 0x20000; tr->langopts.numbers = NUM_DECIMAL_COMMA | NUM_DFRACTION_2 | NUM_HUNDRED_AND | NUM_AND_UNITS | NUM_ROMAN; - tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL; + tr->langopts.numbers2 = NUM2_MULTIPLE_ORDINAL | NUM2_NO_TEEN_ORDINALS; SetLetterVowel(tr,'y'); ResetLetterBits(tr,0x2); SetLetterBits(tr,1,"bcdfgjkmnpqstvxz"); // B hard consonants, excluding h,l,r,w,y diff --git a/src/translate.h b/src/translate.h index 9beb3e78..a8192956 100644 --- a/src/translate.h +++ b/src/translate.h @@ -445,7 +445,9 @@ typedef struct { int numbers; #define NUM2_MULTIPLE_ORDINAL 0x1000 -#define NUM2_ENGLISH_NUMERALS 0x2000 +#define NUM2_NO_TEEN_ORDINALS 0x2000 +#define NUM2_MYRIADS 0x4000 +#define NUM2_ENGLISH_NUMERALS 0x8000 #define NUM2_THOUSANDS_VAR1 0x40 #define NUM2_THOUSANDS_VAR2 0x80 #define NUM2_THOUSANDS_VAR3 0xc0 @@ -455,7 +457,9 @@ typedef struct { // bits 6-8 use different forms of thousand, million, etc (M MA MB) // bit9=(LANG=rw) say "thousand" and "million" before its number, not after // bit12=(LANG=el,es) use ordinal form of hundreds and tens as well as units - // bit13=(LANG=ne) speak (non-replaced) English numerals in English + // bit13=(LANG=pt) don't use 11-19 numbers to make ordinals + // bit14=(LANG=ko) use myriads (groups of 4 digits) not thousands (groups of 3) + // bit15=(LANG=ne) speak (non-replaced) English numerals in English int numbers2; #define BREAK_THOUSANDS 0x49249248 diff --git a/src/vowelchart.cpp b/src/vowelchart.cpp index 642bd66c..b555afb9 100644 --- a/src/vowelchart.cpp +++ b/src/vowelchart.cpp @@ -525,42 +525,17 @@ static void FindVowelFmt(int prog_start, int length) prog_end = prog_start + length; n_vowelfmt_addr = 0; - for(prog = &phoneme_index[prog_start]; prog < &phoneme_index[prog_end]; prog++) + for(prog = &phoneme_index[prog_start]; prog < &phoneme_index[prog_end]; prog += NumInstnWords(prog)) { instn = *prog; - switch(instn >> 12) + if((instn >> 12) == 11) { - case 2: - case 3: - // conditions - while((instn & 0xe000) == 0x2000) - { - instn = *(++prog); - } - prog--; - break; - - case 10: // Vowelin, Vowelout - prog += 3; - break; - - case 9: - case 12: // WAV - case 13: // VowelStart - case 14: // VowelEnd - case 15: // addWav - prog++; - break; - - case 11: // FMT + // FMT instruction if(n_vowelfmt_addr < N_VOWELFMT_ADDR) { vowelfmt_addr[n_vowelfmt_addr++] = ((instn & 0xf) << 18) + (prog[1] << 2); } - prog++; - - break; } } } // end of FindVowelFmt