diff --git a/dictsource/dict_phonemes b/dictsource/dict_phonemes index 923dd7fd..691c270f 100644 --- a/dictsource/dict_phonemes +++ b/dictsource/dict_phonemes @@ -129,15 +129,16 @@ s S t T tS ts v w x z Z -Dictionary es_dict 2012-09-04 +Dictionary es_dict 2012-09-11 @ a aI aU e E eI eU i o O oI u -: b B d D f g h -j J J^ k l m n N -n^ p Q r R R2 s S -t T tS w x z +: b B d D dZ f g +h j J J^ k l l^ m +n N n^ p Q r R R2 +s S t T tS ts w x +z Dictionary fi_dict 2011-10-14 @@ -202,7 +203,7 @@ q r r. s S s. t T t. th th. v w x z -Dictionary ta_dict 2012-09-05 +Dictionary ta_dict 2012-09-11 a a: aI aU e E e: i I i: o o: u U u2 u: @@ -375,7 +376,7 @@ S s; S; t t; tS ts tS; ts; v w x z Z Z; -Dictionary pt_dict 2012-09-08 +Dictionary pt_dict 2012-09-11 & &/ &U~ &~ @ @- a A aI aU e E eI EI eU EU @@ -813,12 +814,21 @@ tS ts tS; v x z Z z; Z; -Dictionary tt_dict 2012-09-09 +Dictionary tt_dict 2012-09-11 -a A e i I o u V -W y +a A A2 e e2 i I o +u u2 V W y : ? b d f g h j k l m n N p q r R s S S; t w x z Z Z; + + +Dictionary ko_dict 2012-06-14 + +@ a e E i o u u- + +* - ; b d dZ; g h +j k k- kh l m n p +p- ph s t t- tS tS; w diff --git a/dictsource/es_list b/dictsource/es_list index 2c718059..b7b3063d 100644 --- a/dictsource/es_list +++ b/dictsource/es_list @@ -158,7 +158,7 @@ _0M1o mil'Esim vi bi // not a Roman number - +// unstressed words // articles el $u el $atend @@ -224,9 +224,9 @@ vuestra $u vuestra $atend vuestras $u vuestras $atend - // prepositions a $u // at +a $atend al $u al $atend de $u // of,from @@ -243,22 +243,32 @@ por $u // for,through,along,via por $atend tras $u tras $atend -ante $u +ante $u $only ante $atend para $u // for,in order,by para $atend entre $u -entre $atend $capital +entre $atend +sobre $u +sobre $atend +bajo $u +bajo $atend desde $u // from,since desde $atend hasta $u hasta $atend hacia $u hacia $atend -// conjunctions + + e $u $only +e $atend y %i // and o $u // or +o $atend +u $u +u $atend + aunque $u // although aunque $atend @@ -266,6 +276,8 @@ pero $u pero $atend porque $u // because porque $atend + + que $u // what que $atend cuando $u @@ -276,15 +288,16 @@ donde $u donde $atend como $u como $atend +quien $u +quien $atend +quienes $u +quienes $atend mientras $u mientras $atend si $u si $atend -// negative -// auxillary verbs -// some common adjectives and adverbs // Letters @@ -315,21 +328,16 @@ x _|Ekis z TEta _a a -a a $atend _e e -e e $atend _o o -o o $atend -_y igr'iEQa -y igr'iEQa $atend +_y igri'eQa +y igri'eQa $atend ch tSe -ll EJ^e -?2 ll Ej:e +ll 'El^e á 'a||aTEntw'aDa é 'e||aTEntw'aDa í 'i||aTEntw'aDa _ó 'o||aTEntw'aDa -ó 'o||aTEntw'aDa $atend ú 'u||aTEntw'aDa ü ,uDj'ErEsis @@ -375,7 +383,7 @@ microsoft m'aIkrosoft software s'oftwer hardware h'ardwer skype sk'aIp -messenger m'esenJer +messenger m'esendZer live l'aIB facebook f'eIsbuk twitter tw'iter @@ -394,9 +402,14 @@ apple 'ap@l iphone 'aIfon (i pod) 'aIpod ipod 'aIpod -jaws J'os +jaws dZ'os window w'indow eyes 'aIs free fr'i google g'ug@l chrome kr'owm +office 'ofis +service s'erBis +power p'awer +thunderbird t'anderbird +jazz dZ'as diff --git a/dictsource/es_rules b/dictsource/es_rules index db475932..b9b0ea9d 100644 --- a/dictsource/es_rules +++ b/dictsource/es_rules @@ -42,7 +42,7 @@ c (Y T // ce, ci ch tS - +A) ck k .group d d d @@ -94,12 +94,12 @@ .group h h // silent - _) hi (A J^ + _) hi (A j .group i i i - i (A J^ + i (A j C) i (A j gu) i (A j ?!3 l) i (A %i @@ -117,22 +117,19 @@ .group l l l - _) ll (A J^ // allowe _ll - ll J^ -?2 A) ll (A j: +ll (_ l + _) ll (A l^ // allowe _ll +?2 _) ll (A J^ +?2 ll j: +?2 n_) ll (A dZ + ll l^ .group m m m _) mn (em n - - m (K n - m (L04 m - m (_L04 m - m (L05 N - m (_L05 N - m (j N +_) mb (A mb .group n @@ -140,9 +137,10 @@ n (L04 m n (_L04 m n (L05 N - n (_L05 N + n (_L05 N n (j N - +ny (A n^ // catalan words +_) nh (A n .group o o o @@ -153,13 +151,14 @@ oi oI oy (K oI oy (_ 'oI - +ou ow .group p p p _) p (L01A p // allow pl pr at start of word p (t p: - _) ph f + _) ph (A f +ph (@ f ph (K f _) ps (i s _) ps (eudo s @@ -169,7 +168,8 @@ .group q q k - qu k + qu (Y k // que, qui +_) qw (A kw // qwerty .group r @@ -189,26 +189,28 @@ .group s s s &) s (_S1 s - _) s (C@ %Es - ss (K s +_) s (K@ s + ss s _) sh (A S _) sh (L01A S sh (K S - +?!1 sc (Y s // sce sci for non castilian accent .group t t t _) t (L01A t // all tr at start of word - _) th (A t + _) th (@ t th (K t +_) tx (A tS +tx tS .group u u u +u (u u u (A w !?3 l) u (A %u !?3 r) u (A %u - g) u (e g) u (i g) u (é @@ -235,25 +237,24 @@ g) u (í .group x x ks -?1 A) x (A Qs - x (_ =Qs _) x ($unpr s // ? - +?!1 xc (Y ks // xce xci for non castilian accent .group y y i _) y ($unpr J - _m) y J - n) y J - _l) y J - y (A J^ -?2 A) y (A j: -u) y (K j + _m) y (A j + _l) y (A j + y (A j: +_) y (A J^ +u) y (K j: +n_) y (A dZ +y (_ i .group z z T ?2 z (L02 z - +zz ts .group diff --git a/dictsource/ko_list b/dictsource/ko_list new file mode 100644 index 00000000..2cb02d83 --- /dev/null +++ b/dictsource/ko_list @@ -0,0 +1,126 @@ +$textmode + +_0 ᅧᆼ +_1 ᅵᆯ +_2 ᅵ +_3 삼 +_4 사 +_5 ᅩ +_6 ᅲᆨ +_7 칠 +_8 팔 +_9 구 +_1X 십 +_2X ᅵ십 +_3X 삼십 +_4X 사십 +_5X ᅩ십 +_6X ᅲᆨ십 +_7X 칠십 +_8X 팔십 +_9X 구십 +_0C 백 +_0M1 천 +_1M1 천 + +// 사ᅵ시ᅩᆺ +고랫재 고랟째 +귓밥 귇빱 +나룻배 나룯빼 +나뭇가지 나묻까지 +냇가 낻ː까 +댓가지 댇까지 +뒷갈망 뒫ː깔망 +맷돌 맫똘 +머릿기름 머릳끼림 +모깃불 모ː긷뿔 +못자리 몯짜리 +바닷가 바닫까 +뱃길 밷낄 +볏가리 볃까리 +부싯돌 부싣똘 +선짓국 선짇꾹 +쇳조각 쉗쪼각 +ᅡ랫집 ᅡ랟찝 +ᅮ렁ᅵᆺ속 ᅮ렁ᅵᆮ쏙 +ᅵᆺ자국 ᅵᆮ짜국 +잿더미 잳떠미 +조갯살 조갣쌀 +찻집 찯찝 +쳇바퀴 첻빠퀴 +킷값 킫깝 +핏대 핃때 +햇볕 핻뼏 +혓바늘 혇빠늘 + +// (2) 뒷말ᅴ 첫소리 'ᄂ, ᄆ' ᅡᇁᅦ서 'ᄂ' 소리가 덧나는 것 +멧나물 멘나물 +ᅡ랫니 ᅡ랜니 +텃마당 턴마당 +ᅡ랫마ᅳᆯ ᅡ랜마ᅳᆯ +뒷머리 뒨ː머리 +ᅵᆺ몸 ᅵᆫ몸 +깻묵 깬묵 +냇물 낸ː물 +빗물 빈물 + +// (3) 뒷말ᅴ 첫소리 모ᅳᆷ ᅡᇁᅦ서 'ᄂᄂ' 소리가 덧나는 것 +도리깻ᅧᆯ 도리깬녈 +뒷ᅲᆾ 뒨ː뉻 +두렛ᅵᆯ 두렌닐 +뒷ᅵᆯ 뒨ː닐 +뒷ᅵᆸ맛 뒨ː님맏 +베갯ᅵᆺ 베갠닏 +ᅭᆺᅵᆺ ᅭᆫ닏 +깻ᅵᇁ 깬닙 +나뭇ᅵᇁ 나문닙 +댓ᅵᇁ 댄닙 + +// 2. 순 ᅮ리말과 한자ᅥ로 된 합성ᅥ로서 ᅡᇁ말ᅵ 모ᅳᆷᅳ로 끝난 경ᅮ +// (1) 뒷말ᅴ 첫소리가 된소리로 나는 것 +귓병 귇뼝 +머릿방 머릳빵 +뱃병 밷뼝 +봇둑 볻뚝 +사잣밥 사ː잗빱 +샛강 샏ː깡 +ᅡ랫방 ᅡ랟빵 +자릿세 자릳쎄 +전깃세 전긷쎄 +전셋집 전섿찝 +찻잔 찯짠 +찻종 찯쫑 +촛국 촏꾹 +콧병 콛뼝 +탯줄 탣쭐 +텃세 턷쎄 +핏기 핃끼 +햇수 핻쑤 +횟가루 휃까루 +횟배 휃빼 + +// (2) 뒷말ᅴ 첫소리 'ᄂ, ᄆ' ᅡᇁᅦ서 'ᄂ' 소리가 덧나는 것 +곗날 곈ː날/겐ː날 +제삿날 제ː삳날 +훗날 훈ː날 +툇마루 퇸ː마루/퉨ː마루 +ᅣᆼ칫물 ᅣᆼ친물 + +// (3) 뒷말ᅴ 첫소리 모ᅳᆷ ᅡᇁᅦ서 'ᄂᄂ' 소리가 덧나는 것 +가ᅬᆺᅵᆯ 가ᅬᆫ닐/가ᅰᆫ닐 +사삿ᅵᆯ 사산닐 +ᅨ삿ᅵᆯ ᅨː산닐 +훗ᅵᆯ 훈ː닐 + +// 3. 두 ᅳᆷ절로 된 다ᅳᆷ 한자ᅥ +곳간 곧깐 +셋방 섿빵 +숫자 숟짜 +찻간 찯깐 +툇간 퇻깐 +횟수 횓쑤 + +찻잔 찯짠 + +ᄉᄇ 시바 + diff --git a/dictsource/ko_rules b/dictsource/ko_rules new file mode 100644 index 00000000..328e5a33 --- /dev/null +++ b/dictsource/ko_rules @@ -0,0 +1,286 @@ +// This file is UTF8 encoded + +.replace + +// Note: These specific range of "normalized" unicode characters of Korean are +// hardly used as individually, and look broken and badly aligned in most +// fonts. +// We're using hard tabs so that we can recognize where they are placed at +// the first place. + +// Stop finals and their consorts: ㄱㄲㅋ ㄷㅌ ㅂㅍ ㅅㅆㅈㅊ +.L01 ᆨ ᆩ ᆿ ᆮ ᇀ ᆸ ᇁ ᆺ ᆻ ᆽ ᆾ ᆪ ᆹ ᆬ ᆰ ᆱ ᆲ ᆳ ᆴ ᆵ +// i and j-vowels: ㅣ ㅑㅒ ㅕㅖ ㅛㅠ +.L02 ᅵ ᅣ ᅤ ᅧ ᅨ ᅭ ᅲ +// h-finals: ㅎ ㄶㅀ +.L03 ᇂ ᆭ ᆶ + +// Initials +// Order: ㄱㄲㅋ ㄷㄸㅌ ㅂㅃㅍ ㅅㅆㅈㅉㅊ ㄴㅁ ㄹ ㅎ + +.group ᄀ // ㄱ + ᄀ g + _) ᄀ k + L01) ᄀ k- + L03) ᄀ kh + +.group ᄁ // ㄲ + ᄁ k- + +.group ᄏ // ㅋ + ᄏ kh + +.group ᄃ // ㄷ + ᄃ d + _) ᄃ t + L01) ᄃ t- + L03) ᄃ th + +.group ᄄ // ㄸ + ᄄ t- + +.group ᄐ // ㅌ + ᄐ th + +.group ᄇ // ㅂ + ᄇ b + _) ᄇ p + L01) ᄇ p- + L03) ᄇ ph + +.group ᄈ // ㅃ + ᄈ p- + +.group ᄑ // ㅍ + ᄑ ph + +.group ᄉ // ㅅ + ᄉ s + L01) ᄉ s- + +.group ᄊ // ㅆ + ᄊ s- // TODO: phoneme + +.group ᄌ // ㅈ + ᄌ dZ; + _) ᄌ tS; + L01) ᄌ tS;- + L03) ᄌ tSh; + +.group ᄍ // ㅉ + ᄍ tS;- // TODO: phoneme + +.group ᄎ // ㅊ + ᄎ tSh; // TODO: phoneme + +.group ᄂ // ㄴ + ᄂ n + +.group ᄆ // ㅁ + ᄆ m + +.group ᄅ // ㄹ + ᄅ * // TODO: alveolar flap [ɾ] + ᄅ (_ l + +.group ᄒ // ㅎ + ᄒ h // TODO: [ɦ] + _) ᄒ h + +// Medials + +.group ᅡ // ㅏ + ᅡ a + +.group ᅢ // ㅐ + ᅢ E + +.group ᅣ // ㅑ + ᅣ ja + +.group ᅤ // ㅒ + ᅤ jE + +.group ᅥ // ㅓ + ᅥ @ + +.group ᅦ // ㅔ + ᅦ e + +.group ᅧ // ㅕ + ᅧ j@ + +.group ᅨ // ㅖ + ᅨ je + +.group ᅩ // ㅗ + ᅩ o + +.group ᅪ // ㅘ + ᅪ wa + +.group ᅫ // ㅙ + ᅫ wE + +.group ᅬ // ㅚ + ᅬ we // was [Y] until 1970s + +.group ᅭ // ㅛ + ᅭ jo + +.group ᅮ // ㅜ + ᅮ u + +.group ᅯ // ㅝ + ᅯ w@ + +.group ᅰ // ㅞ + ᅰ we + +.group ᅱ // ㅟ + ᅱ wi // was [y] until 1970s + +.group ᅲ // ㅠ + ᅲ ju + +.group ᅳ // ㅡ + ᅳ u- + +.group ᅴ // ㅢ + ᅴ u-j // TODO: [ɰi] + C) ᅴ i + +.group ᅵ // ㅣ + ᅵ i + +// Finals +// Order: ㄱㄳㄲㅋ ㄷㅌ ㅂㅍ ㅅㅆㅈㅊ ㄴㅁ ㅇㅎ ㄹ + +.group ᆨ // ㄱ + ᆨ k // TODO: final stops + ᆨᄒ kh + +.group ᆪ // ㄳ + ᆪ k + ᆪ (A ks + ᆪᄒ kh + +.group ᆩ // ㄲ + ᆩ k + ᆩ (A k- + ᆩᄒ kh // 꺾히다 + +.group ᆿ // ㅋ + ᆿ k + ᆿ (A kh + +.group ᆮ // ㄷ + ᆮ t + ᆮᄂ nn + ᆮᄆ mm + ᆮᄒ th + ᆮ (L02 dZ; + +.group ᇀ // ㅌ + ᇀ t + ᇀᄂ nn + ᇀᄆ mm + ᇀ (A th + ᇀ (L02 tSh; + +.group ᆸ // ㅂ + ᆸ p + ᆸᄒ ph + +.group ᆹ // ㅄ + ᆹ p + ᆹ (A ps- + ᆹᄒ ps- + +.group ᇁ // ㅍ + ᇁ p + ᇁ (A ph + +.group ᆺ // ㅅ + ᆺ t + ᆺᄂ nn + ᆺᄆ mm + ᆺ (A s + ᆺᄒ s- + +.group ᆻ // ㅆ + ᆻ t + ᆻᄂ nn + ᆻᄆ mm + ᆻ (A s- + +.group ᆽ // ㅈ + ᆽ t + ᆽᄂ nn + ᆽᄆ mm + ᆽ (A tS; + +.group ᆾ // ㅊ + ᆾ t + ᆾᄂ nn + ᆾᄆ mm + ᆾ (A tSh; + +.group ᆫ // ㄴ + ᆫ n + +.group ᆬ // ㄵ + ᆬ n + ᆬ (A ndZ; + +.group ᆭ // ㄶ + ᆭ n + ᆭ (A n // no nh + +.group ᆷ // ㅁ + ᆷ m + +.group ᆼ // ㅇ + ᆼ ng + +.group ᇂ // ㅎ + ᇂ t + ᇂ (A + +.group ᆯ // ㄹ + ᆯ l + ᆯᄅ l + ᆯ (A * + +.group ᆰ // ㄺ + ᆰ k + ᆰ (A lg + +.group ᆱ // ㄻ + ᆱ m + ᆱ (A lm + +.group ᆲ // ㄼ + ᆲ p + ᆲ (A lb + +.group ᆳ // ㄽ + ᆳ l + ᆳ (A ls + +.group ᆴ // ㄾ + ᆴ l + ᆴ (A lth + +.group ᆵ // ㄿ + ᆵ p + ᆵ (A lph + +.group ᆶ // ㅀ + ᆶ l + ᆶ (A * + +.group + . + ː + diff --git a/dictsource/pt_list b/dictsource/pt_list index ac16eab7..0c125207 100755 --- a/dictsource/pt_list +++ b/dictsource/pt_list @@ -651,6 +651,7 @@ albatrozes $alt alcateia $alt alferes $alt algozes $alt +alicerce $alt amanheça $alt2 amanheço $alt2 amarelo $alt @@ -659,6 +660,9 @@ amores $alt2 anoiteça $alt2 anoiteço $alt2 apreço $alt2 +aperto $alt2 $noun +apoio $alt $verb +aprendeste $alt2 assembleia $alt atrozes $alt austera $alt @@ -685,6 +689,7 @@ cerco $alt $verb chamego $alt2 chefe $alt chinelo $alt +choro $alt2 $noun coco $alt2 cofre $alt colmeia $alt @@ -697,6 +702,7 @@ coreia $alt corneta $alt2 cornos $alt corpos $alt +correste $alt2 corto $alt corvos $alt coto $alt2 @@ -706,32 +712,40 @@ couberdes $alt couberes $alt crede $alt2 cresce $alt +crescem $alt der $alt desce $alt descem $alt descova $alt2 desfecho $alt2 +desprezo $alt $verb deva $alt2 devo $alt2 dez $alt diarreia $alt discordo $alt +dobro $alt2 $noun doce $alt2 droga $alt endereço $alt2 enumerem $alt +enxerto $alt2 $noun epopeia $alt eritreia $alt erro $alt2 $noun escopeta $alt2 escroto $alt2 +esforço $alt $verb esforços $alt esperma $alt +espeto $alt2 $noun espiroqueta $alt2 -estrofe $alt +enterro $alt2 $noun estiverdes $alt estiveres $alt +estrofe $alt etiqueta $alt2 +exagero $alt $verb expeça $alt2 expeço $alt2 farofa $alt @@ -740,11 +754,13 @@ fere $alt ferem $alt fezes $alt fizer $alt +Fizeram $alt fizerem $alt fizerdes $alt fizeres $alt fogos $alt fores $alt2 +forro $alt $verb fosse $alt2 fossem $alt2 foste $alt2 @@ -755,6 +771,7 @@ gelo $alt $verb germe $alt gesso $alt2 gonorreia $alt +gozo $alt $verb grego $alt2 grelha $alt groselha $alt @@ -783,7 +800,7 @@ mexo m'eSU miolo $alt2 modo $alt modos $alt -molho $alt $verb +molho $alt2 $noun monera $alt morcego $alt2 morda $alt2 @@ -796,6 +813,7 @@ muito mw'iNtU // -s is included as a suffix muita mw'iNt& mulheres $alt mureta $alt2 +mutreta $alt2 naquele $alt2 negro $alt2 novos $alt @@ -804,6 +822,7 @@ onu $1 opereta $alt2 osso $alt2 ovos $alt +padeceste $alt2 paexa paeSa pangeia $alt palheta $alt2 @@ -828,6 +847,7 @@ porra $alt2 portos $alt pose $alt2 povos $alt +poxa p'oS& preta $alt2 preto $alt2 profere $alt @@ -838,14 +858,19 @@ recordo $alt recorto $alt rede $alt2 reforços $alt +refresco $alt $verb remorso $alt resolve $alt resolvem $alt -rixa xiS& +rixa x'iS& rogas $alt saleta $alt2 seborreia $alt +seco $alt2 $noun +selo $alt $verb selvagem seUv'aZeIN +sincera $alt +sincero $alt sobe $alt sobem $alt soco $alt2 @@ -855,6 +880,7 @@ sofreste $alt2 sopre $alt soprem $alt sorvete $alt2 +sossego $alt2 $noun souber $alt souberdes $alt souberes $alt @@ -864,7 +890,6 @@ sugerem $alt suor swOr tapete $alt2 teta $alt2 -tijolo $alt2 tiver $alt tiveres $alt toga $alt @@ -882,6 +907,7 @@ verme $alt vierem $alt violeta $alt2 vozes $alt +zelo $alt $verb zero $alt zorra $alt2 diff --git a/dictsource/pt_rules b/dictsource/pt_rules index 09314321..227096e9 100755 --- a/dictsource/pt_rules +++ b/dictsource/pt_rules @@ -151,8 +151,6 @@ ?1 e (_iN =i/ // drop final [i] is next word starts with another i ?1 e (e i //eg: candeeiro -?2 ee i -?2 pr) ee (n ee ?2 el (K EU e (lh+ e @@ -342,6 +340,7 @@ _estr) ei (L01_ EI _inv) e (jL02_ E _dec) e (pL02_ E + _g) e (rL02_ E _op) e (rL02_ E _qu) e (rL02_ E _alt) e (rL02_ E @@ -547,11 +546,9 @@ _reapar) e (çL01_ e oi ($w_alt OI oi (a_ OI // ?? oi (cA_ OI + oi (de_ OI oi (s oI o (iCK o - oo u - oon u~N - c) oo oo ?1 C) oo (_ ow // eg: voo, enjoo, etc... oy OI @@ -660,7 +657,7 @@ _reapar) e (çL01_ e c) o (rrL03_ o // escorra, incorra, corra, recorra _m) o (rrL03_ o _ap) oi (L03_ OI - p) o (stos_ O // dispostos etc. + p) ostos (_ Ost=Us# // dispostos etc. .group ô ô ''o diff --git a/dictsource/ta_rules b/dictsource/ta_rules index 9f31dcf7..9e09328c 100644 --- a/dictsource/ta_rules +++ b/dictsource/ta_rules @@ -1888,7 +1888,8 @@ _அகாலி_) த (ள dV _) தௌலதாப (ாத daUlVd.a:b _சா) த்த (ியக்கூற dd _சா) த்த (ியங்கள dd - _சா) த்தியத்த ddijVddV# + _சா) த்த (ியத்த dd + _சா) த்த (ியந் dd _சா) த்த (ியப்பட dd _சா) த்த (ியம dd _) த (்ராட்சை d diff --git a/dictsource/tt_list b/dictsource/tt_list index 0025d46b..340e2c8f 100644 --- a/dictsource/tt_list +++ b/dictsource/tt_list @@ -80,4 +80,4 @@ _1M3 milli'Ard _0M4 billi'on _1M4 billi'on -_dpt bWt,Wn +_dpt bWt,en diff --git a/dictsource/tt_rules b/dictsource/tt_rules index 733ef010..09d21a83 100755 --- a/dictsource/tt_rules +++ b/dictsource/tt_rules @@ -21,7 +21,8 @@ д d .group е - е e // may be [je] [j@] + _) е je2 // may be [je] [jV] + е e .group ё ё jo @@ -119,10 +120,10 @@ э e .group ю - ю ju // or jy + ю ju2 // or jy .group я - я jA // or ja + я jA2 // or ja .group $ dolAR diff --git a/phsource/compile_report b/phsource/compile_report index 390015a5..6b7406f3 100644 --- a/phsource/compile_report +++ b/phsource/compile_report @@ -1,4 +1,4 @@ -82 phoneme tables +83 phoneme tables new total base 107 107 consonants 10 116 @@ -81,7 +81,8 @@ consonants 10 116 kk 20 117 fa 9 110 ga 21 125 - tt 15 113 + tt 18 116 + ko 15 114 Data file Used by b/b [b] base @@ -198,6 +199,7 @@ dzh/dzh [dZ] base [dZ] sr [dZ;] sr [dZ;] sq + [dZ;] ko dzh/dzh_ [dZ] base [dZ;] base [dZ;] lt @@ -415,7 +417,7 @@ l/l_ [l] base [l/] fr l/l_@ [l/3] base [l/] fr -l/l@ [h6r] base +l/l@ [hæu] base [l#] base [l] fr [l/2] fr @@ -449,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 [h6r] base +l/la [hæu] base [l#] base [l] fr [l/2] fr @@ -457,7 +459,7 @@ l/la [h6r] base [K] tn l/l_a [l/3] base [l/] fr -l/le [h6r] base +l/le [hæu] base [l#] base [l] fr [l/2] fr @@ -469,7 +471,7 @@ l/L_eL_af [&] af [&:] af l/l_front [L] sq l/l_front_ [l/4] sq -l/li [h6r] base +l/li [hæu] base [l#] base [l] fr [l/2] fr @@ -483,7 +485,7 @@ ll/ll [L] bg ll/_ll [L] bg l/l_long [l] base [l] fr -l/lo [h6r] base +l/lo [hæu] base [l#] base [l/2] fr [K] nso @@ -494,7 +496,7 @@ l^/l_rfx [l.] base [l;] lt [l] ru [l^] ru -l/lu [h6r] base +l/lu [hæu] base [l#] base [l] fr [l/2] fr @@ -690,7 +692,9 @@ r3/rx [*] base r3/rz_cs [R^] sk [R^/] sk r3/@tap [**] base + [*] ko r3/@tap2 [**] base + [*] ko r3/@tap_rfx [r.] base r/a_ [r] da r/aa [R] da @@ -873,6 +877,7 @@ ustop/k_unasp [k] base [k] sq [k-] tn ustop/k_unasp_ [k] zh + [k-] ko ustop/null [?] base [t2] hu ustop/p [p] base @@ -1007,6 +1012,7 @@ ustop/ts_pzd_ [c2] consonants ustop/ts_pzd2 [c2] consonants ustop/ts_pzd3 [tS;] hr [dZ;] hr + [tS;] ko ustop/t_sr [d] sr [t] sr ustop/ts_rfx [ts.] zh @@ -1014,6 +1020,7 @@ ustop/ts_rfx_unasp [ts.] zh ustop/ts_sr [tS;] sr [dZ;] sr ustop/ts_unasp [ts] zh +ustop/t_unasp [t-] ko ustop/t_unasp2 [t] el [t] zh vdiph/0i [OI] pt @@ -1675,6 +1682,7 @@ vowel/aa_8 [0] en-us [A1] et [A] nl [a:] is + [a] ko vowel/aa_9 [a] fi [a] et [a:] hi @@ -1783,6 +1791,7 @@ vowel/ee_5 [E] en [E] wo [E:] wo [E] tn + [E] ko vowel/ee_6 [&] sk [E3] sv [E] ku @@ -1934,6 +1943,7 @@ vowel/i_7 [i:] et [i] sq vowel/i#_7 [i1] et [i[] zh + [u-] ko vowel/i_8 [i] et [i] fr [i] ht @@ -2082,6 +2092,7 @@ vowel/o_6 [O] nl vowel/o_7 [o] ku vowel/o_8 [o] fr [o] ht + [o] ko vowel/oe [W] af [W] de [W] hy @@ -2151,6 +2162,7 @@ vowel/oo_2 [0] en-sc [o] cs [0] da [O] ak + [@] ko vowel/oo_3 [O] af vowel/oo_4 [O] base2 [0] en-wm @@ -2277,6 +2289,7 @@ vowel/u_bck [u] base2 [u] pa [u] mt [u:] ga + [u] ko vowel/u_bck2 [u] et [u] fr [u:] fr @@ -2621,6 +2634,7 @@ x/dzh_ [dZ] base [dZ;] ru x/dz_pzd [dZ;] base [dZ;] mk + [dZ;] ko x/g [g] fr x/g_ [g] base [g] cy diff --git a/phsource/mbrola/hn1 b/phsource/mbrola/hn1 new file mode 100644 index 00000000..1125687f --- /dev/null +++ b/phsource/mbrola/hn1 @@ -0,0 +1,27 @@ + +// Korean + +0 k- NULL 0 k_> +0 t- NULL 0 t_> +0 * NULL 0 4 +0 p- NULL 0 p_> +0 s- NULL 0 s_> +0 tS; NULL 0 ts\ +0 tS;- NULL 0 ts\_> +0 tSh; NULL 0 ts\_h +0 k_h NULL 0 ts\_h +0 tSh; NULL 0 ts\_h +0 kh NULL 0 k_h +0 th NULL 0 t_h +0 ph NULL 0 p_h +0 dZ; NULL 0 dz\ + +0 ng NULL 0 N + +0 @ NULL 0 V +0 j@ NULL 0 jV +0 Y NULL 0 2 +0 w@ NULL 0 wV +0 u- NULL 0 M +0 u-j NULL 0 M\i + diff --git a/phsource/ph_korean b/phsource/ph_korean new file mode 100644 index 00000000..3e40d0cb --- /dev/null +++ b/phsource/ph_korean @@ -0,0 +1,110 @@ + +// vowels + +phoneme a // a(ㅏ) + ipa ɐ + vowel starttype #a endtype #a + length 200 + FMT(vowel/aa_8) +endphoneme + +phoneme E // ae(ㅐ) + ipa ɛ + vowel starttype #e endtype #e + length 200 + FMT(vowel/ee_5) +endphoneme + +phoneme @ // eo(ㅓ) + ipa ʌ + vowel starttype #@ endtype #@ + length 200 + FMT(vowel/oo_2) +endphoneme + +phoneme o // o(ㅗ) + ipa o + vowel starttype #o endtype #o + length 200 + FMT(vowel/o_8) +endphoneme + +phoneme u // u(ㅜ) + ipa u + vowel starttype #u endtype #u + length 200 + FMT(vowel/u_bck) +endphoneme + +phoneme u- // eu(ㅡ) + ipa ɯ + vowel starttype #u endtype #u + length 200 + FMT(vowel/i#_7) +endphoneme + +// diphthongs + + +// consonants + +phoneme k- // /ㄲ/ + vls vel stop + lengthmod 3 + Vowelin f1=1 f2=1700 0 200 f3=-300 80 f4 + Vowelout f1=1 f2=1700 0 200 f3=-300 80 f4 rms=30 + WAV(ustop/k_unasp_, 75) + length 100 +endphoneme + +phoneme kh // /ㅋ/ + import_phoneme consonants/kh +endphoneme + +phoneme t- // /ㄸ/ + vls alv stop + lengthmod 3 + Vowelin f1=0 f2=1700 -300 300 f3=-100 80 rms=40 + Vowelout f1=0 f2=1700 -300 250 f3=-100 80 rms=20 + WAV(ustop/t_unasp, 40) // TODO +endphoneme + +// TODO: ㅌ + +phoneme p- // /ㅃ/ + import_phoneme consonants/p- +endphoneme + +phoneme ph // /ㅍ/ + import_phoneme consonants/ph +endphoneme + +phoneme tS; // voiceless /ㅈ/ + vls pla afr sibilant palatal + ipa tɕ + lengthmod 2 + Vowelin f1=0 f2=2700 400 600 f3=300 80 + WAV(ustop/ts_pzd3) +endphoneme + +phoneme dZ; // voiced /ㅈ/ + vcd pla afr sibilant palatal + ipa dʑ + lengthmod 2 + Vowelin f1=0 f2=2700 400 600 f3=300 80 + FMT(dzh/dzh) addWav(x/dz_pzd) +endphoneme + +phoneme * // r(ㄹ) at initial, medial + vcd alv flp rhotic + ipa ɾ + lengthmod 3 + Vowelout f1=3 f2=1600 -300 300 f3=-300 80 rms=35 len=15 + Vowelin f1=2 f2=1600 -300 300 f3=-100 80 len=20 + + IF prevPh(#i) OR prevPh(#e) THEN + FMT(r3/@tap2) + ENDIF + FMT(r3/@tap) +endphoneme + diff --git a/phsource/ph_tatar b/phsource/ph_tatar index fc5d9341..a6e6b1ff 100644 --- a/phsource/ph_tatar +++ b/phsource/ph_tatar @@ -1,12 +1,15 @@ + +// use 'flag1' for front vowels + phoneme i - vowel starttype #i endtype #i + vowel flag1 starttype #i endtype #i length 180 FMT(vowel/i) endphoneme phoneme y - vowel starttype #u endtype #u + vowel flag1 starttype #u endtype #u length 180 FMT(vowel/y) endphoneme @@ -17,16 +20,34 @@ phoneme u FMT(vowel/u) endphoneme +phoneme u2 // letter 'ю' + vowel starttype #u endtype #u + length 180 + IF prevVowel(isFlag1) OR nextVowel(isFlag1) THEN + ChangePhoneme(y) + ELSE + ChangePhoneme(u) + ENDIF +endphoneme phoneme e - vowel starttype #@ endtype #@ + vowel flag1 starttype #@ endtype #@ length 100 FMT(vowel/ii#) endphoneme -phoneme W +phoneme e2 // 'e' at start of word vowel starttype #@ endtype #@ length 100 + IF nextVowel(isFlag1) THEN + ChangePhoneme(e) + ENDIF + ChangePhoneme(V) +endphoneme + +phoneme W + vowel flag1 starttype #@ endtype #@ + length 100 FMT(vowel/oe) endphoneme @@ -44,7 +65,7 @@ endphoneme phoneme a - vowel starttype #a endtype #a + vowel flag1 starttype #a endtype #a length 180 FMT(vowel/&_2) endphoneme @@ -55,22 +76,30 @@ phoneme A IF thisPh(isFirstVowel) THEN ChangePhoneme(0) ENDIF - IF thisPh(isSeqFlag1) THEN + IF prevVowel(0) THEN ChangePhoneme(0) ENDIF FMT(vowel/aa) endphoneme +phoneme A2 // letter 'я' + vowel starttype #a endtype #a + length 180 + IF prevVowel(isFlag1) OR nextVowel(isFlag1) THEN + ChangePhoneme(a) + ENDIF + ChangePhoneme(A) +endphoneme + phoneme 0 vowel starttype #o endtype #o - flag1 length 180 FMT(vowel/0_3) endphoneme phoneme I - vowel starttype #i endtype #i + vowel flag1 starttype #i endtype #i length 100 FMT(vowel/ii) endphoneme diff --git a/phsource/phonemes b/phsource/phonemes index a7011dbb..dab4c599 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -1900,3 +1900,7 @@ include ph_irish phonemetable tt base include ph_tatar + +phonemetable ko base +include ph_korean + diff --git a/src/compiledata.cpp b/src/compiledata.cpp index e84767ab..d0f005b1 100644 --- a/src/compiledata.cpp +++ b/src/compiledata.cpp @@ -90,17 +90,18 @@ static keywtab_t k_conditions[] = { {"AND", 0, k_AND}, {"OR", 0, k_OR}, {"THEN", 0, k_THEN}, - {"prevPh", tWHICH_PHONEME, 0x000}, - {"prevPhW", tWHICH_PHONEME, 0x500}, - {"thisPh", tWHICH_PHONEME, 0x100}, - {"nextPh", tWHICH_PHONEME, 0x200}, - {"next2Ph", tWHICH_PHONEME, 0x300}, - {"nextPhW", tWHICH_PHONEME, 0x400}, - {"nextVowel",tWHICH_PHONEME, 0x600}, -// {"next2PhW", tWHICH_PHONEME, 0x700}, + {"prevPh", tWHICH_PHONEME, 0}, + {"prevPhW", tWHICH_PHONEME, 5}, + {"thisPh", tWHICH_PHONEME, 1}, + {"nextPh", tWHICH_PHONEME, 2}, + {"next2Ph", tWHICH_PHONEME, 3}, + {"nextPhW", tWHICH_PHONEME, 4}, + {"next2PhW", tWHICH_PHONEME, 6}, + {"nextVowel",tWHICH_PHONEME, 7}, + {"prevVowel",tWHICH_PHONEME, 8}, +// {"next2PhW", tWHICH_PHONEME, 0x800}, // {"numVowels", tTEST, 0x000}, -// {"afterStress", tTEST, 0x000}, {"PreVoicing", tTEST, 0xf01}, {"KlattSynth", tTEST, 0xf02}, @@ -605,7 +606,7 @@ return; case 13: case 14: case 15: - address = ((instn & 0xf) << 16) + *pc++; + address = ((instn & 0xf) << 16) + *pc++; fprintf(f_out, " %d %.5x",(instn >> 4) & 0xff,address*4); break; } @@ -770,7 +771,7 @@ static void CompileReport(void) } n = ix; qsort((void *)list,n,sizeof(REF_HASH_TAB *),(int (*)(const void *,const void *))ref_sorter); - + data_path = ""; prev_mnemonic = 0; prev_table = 0; @@ -1197,7 +1198,7 @@ static int LookupPhoneme(const char *string, int control) // don't use phoneme number 0, reserved for string terminator start = 1; - + if(control==2) start = 8; // don't look for control and stress phonemes (allows these characters to be // used for other purposes) @@ -1267,12 +1268,12 @@ static int NextItem(int type) int sign; char *p; keywtab_t *pk; - + item_type = -1; f_in_displ = ftell(f_in); f_in_linenum = linenum; - + while(!feof(f_in)) { c = get_char(); @@ -1592,7 +1593,7 @@ int LoadSpect(const char *path, int control) wxString filename = path_phsource + path_sep + wxString(path,wxConvLocal); wxFileInputStream stream(filename); - + if(stream.Ok() == FALSE) { error("Failed to open: '%s'",path); @@ -1616,7 +1617,7 @@ int LoadSpect(const char *path, int control) seq_out.sqflags=0; seq_out.length_total=0; - total = 0; + total = 0; for(frame=0; frame < spectseq->numframes; frame++) { @@ -1650,7 +1651,7 @@ for(ix=0; ix<8; ix++) seq_out.n_frames++; if(frame > 0) total += spectseq->frames[frame-1]->length; - } + } } seq_out.length_total = int(total); @@ -1665,7 +1666,7 @@ for(ix=0; ix<8; ix++) for(frame=0; frame < spectseq->numframes; frame++) { fr = spectseq->frames[frame]; - + if(fr->keyframe) { if(klatt_flag) @@ -1756,7 +1757,7 @@ for(ix=0; ix<8; ix++) n_frames++; } } - + if(klatt_flag) { seqk_out.n_frames = seq_out.n_frames; @@ -1799,7 +1800,7 @@ static int LoadWavefile(FILE *f, const char *fname) fseek(f,24,SEEK_SET); sr1 = Read4Bytes(f); sr2 = Read4Bytes(f); - fseek(f,40,SEEK_SET); + fseek(f,40,SEEK_SET); if((sr1 != samplerate_native) || (sr2 != sr1*2)) { @@ -1828,7 +1829,7 @@ static int LoadWavefile(FILE *f, const char *fname) return(0); } } - + f = fopen(fname_temp,"rb"); if(f == NULL) { @@ -2078,7 +2079,7 @@ static int LoadDataFile(const char *path, int control) if(addr == 0) { sprintf(buf,"%s%s",path_source,path); - + if((f = fopen(buf,"rb")) == NULL) { sprintf(buf,"%s%s.wav",path_source,path); @@ -2091,7 +2092,7 @@ static int LoadDataFile(const char *path, int control) id = Read4Bytes(f); rewind(f); - + if(id == 0x43455053) { addr = LoadSpect(path, control); @@ -2121,7 +2122,7 @@ static int LoadDataFile(const char *path, int control) addr = -1; } fclose(f); - + if(addr > 0) { fprintf(f_phcontents,"%c 0x%.5x %s\n",type_code,addr & 0x7fffff,path); @@ -2188,7 +2189,7 @@ static int CompileToneSpec(void) *prog_out++ = i_AMPENV + ((amp_env >> 16) & 0xf); *prog_out++ = amp_env; } - + return(0); } // end of CompileToneSpec @@ -2217,7 +2218,7 @@ int CompileSound(int keyword, int isvowel) { value = -128; error("Parameter < -128",NULL); - } + } } else { @@ -2256,6 +2257,7 @@ int CompileIf(int elif) int key; int finish = 0; int word = 0; + int word2 = 0; int data; int bitmap; int brackets; @@ -2274,10 +2276,18 @@ int CompileIf(int elif) if((key = NextItem(tCONDITION)) < 0) error("Expected a condition, not '%s'",item_string); - + if(item_type == tWHICH_PHONEME) { - // prevPh(), thisPh(), nextPh(), next2Ph() + // prevPh(), thisPh(), nextPh(), next2Ph() etc + if(key >= 6) + { + // put the 'which' code in the next instruction + word2 = key; + key = 6; + } + key = key << 8; + data = NextItemBrackets(tPROPERTIES,0); if(data >= 0) { @@ -2320,6 +2330,9 @@ int CompileIf(int elif) prog_last_if = prog_out; *prog_out++ = word | i_CONDITION; + if(word2 != 0) + *prog_out++ = word2; + // expect AND, OR, THEN switch(NextItem(tCONDITION)) { @@ -2416,7 +2429,7 @@ int CompileElse(void) { ref = prog_out; *prog_out++ = 0; - + if((p = if_stack[if_level].p_else) != NULL) { *ref = ref - p; // backwards offset to the previous else @@ -2461,14 +2474,14 @@ int CompileEndif(void) do { chain = *p; // a chain of previous else links - + offset = prog_out - p; if(offset > MAX_JUMP) { error("IF block is too long",NULL); } *p = i_JUMP + offset; - + p -= chain; } while (chain > 0); } @@ -2489,7 +2502,7 @@ static int CompileSwitch(int type) // check the instructions in the Switch return(0); } - + // count_VowelStart = 0; // count_VowelEnding = 0; @@ -2664,7 +2677,7 @@ int CompilePhoneme(int compile_phoneme) phoneme_flags = 0; place_articulation = 0; - NextItem(tSTRING); + NextItem(tSTRING); if(compile_phoneme) { phcode = LookupPhoneme(item_string,1); // declare phoneme if not already there @@ -2825,7 +2838,7 @@ int CompilePhoneme(int compile_phoneme) phcode = LookupPhoneme(item_string,1); phoneme_out->start_type = phcode; break; - + case kENDTYPE: phcode = NextItem(tPHONEMEMNEM); if(phcode == -1) @@ -2882,7 +2895,7 @@ int CompilePhoneme(int compile_phoneme) case kSWITCH_PREVVOWEL: endphoneme = CompileSwitch(1); break; - + case kSWITCH_NEXTVOWEL: endphoneme = CompileSwitch(2); break; @@ -2908,7 +2921,7 @@ int CompilePhoneme(int compile_phoneme) DecThenCount(); endphoneme = CompileSound(keyword,0); break; - + case kVOWELIN: DecThenCount(); endphoneme = CompileVowelTransition(1); @@ -2968,7 +2981,7 @@ int CompilePhoneme(int compile_phoneme) } phoneme_out->phflags = place_articulation << 16; phoneme_out->phflags |= phoneme_flags; - + if(phoneme_out->phflags & phVOICED) { if(phoneme_out->type == phSTOP) @@ -2977,15 +2990,15 @@ int CompilePhoneme(int compile_phoneme) if(phoneme_out->type == phFRICATIVE) phoneme_out->type = phVFRICATIVE; } - + if(phoneme_out->std_length == 0) { if(phoneme_out->type == phVOWEL) phoneme_out->std_length = 180/2; // default length for vowel } - + phoneme_out->phflags |= phLOCAL; //declared in this phoneme table - + if(phoneme_out->type == phDELETED) { phoneme_out->mnemonic = 0x01; // will not be recognised @@ -3334,7 +3347,7 @@ static void CompilePhonemeFiles() stack[stack_ix].linenum = linenum; strcpy(stack[stack_ix].fname,current_fname); stack[stack_ix++].file = f_in; - + f_in = f; strncpy0(current_fname,item_string,sizeof(current_fname)); linenum = 1; @@ -3382,7 +3395,7 @@ static void CompilePhonemeData2(const char *source) wxString report_dict; #ifdef MAKE_ENVELOPES -make_envs(); +make_envs(); #endif n_envelopes = 0; @@ -3525,7 +3538,7 @@ fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references { strncpy0(fname,(report+report_dict).mb_str(wxConvLocal),sizeof(fname)); fprintf(stderr,"%s\n",fname); - + } } // end of CompilePhonemeData @@ -3605,7 +3618,7 @@ void CompileMbrola() wxLogError(_T("Can't write to: ")+wxString(buf,wxConvLocal)); return; } - + data[count].name = 0; // list terminator Write4Bytes(f_out, mbrola_ctrl); diff --git a/src/dictionary.cpp b/src/dictionary.cpp index 1ecf649b..85a4ead6 100644 --- a/src/dictionary.cpp +++ b/src/dictionary.cpp @@ -18,7 +18,7 @@ ***************************************************************************/ #include "StdAfx.h" - + #include #include #include @@ -218,7 +218,7 @@ static void InitGroups(Translator *tr) { if(tr->groups2_start[c] == 255) tr->groups2_start[c] = tr->n_groups2; - + tr->groups2_count[c]++; tr->groups2[tr->n_groups2] = p; tr->groups2_name[tr->n_groups2++] = (c + (c2 << 8)); @@ -489,7 +489,7 @@ sprintf(outptr,"* "); continue; /* indicates unrecognised phoneme */ if((ph = phoneme_tab[phcode]) == NULL) continue; - + if((ph->type == phSTRESS) && (ph->std_length <= 4) && (ph->program == 0)) { if(ph->std_length > 1) @@ -499,7 +499,7 @@ sprintf(outptr,"* "); { mnem = ph->mnemonic; - while((c = (mnem & 0xff)) != 0) + while((c = (mnem & 0xff)) != 0) { *outptr++ = c; mnem = mnem >> 8; @@ -565,7 +565,7 @@ char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int } else { - InterpretPhoneme(NULL, 0, plist, &phdata); + InterpretPhoneme(NULL, 0, plist, &phdata, NULL); } len = strlen(phdata.ipa_string); @@ -638,7 +638,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa) char *buf; char phon_buf[30]; PHONEME_LIST *plist; - + static const char *stress_chars = "==,,''"; if(phon_out != NULL) @@ -694,7 +694,7 @@ void GetTranslatedPhonemeString(char *phon_out, int n_phon_out, int use_ipa) buf = WritePhMnemonic(buf, phoneme_tab[plist->tone_ph], NULL, use_ipa); } } - + len = buf - phon_buf; max_len = (n_phon_out - phon_out_ix - 5); // allow for " ..." and zero byte terminator if(len > max_len) @@ -939,7 +939,7 @@ static int GetVowelStress(Translator *tr, unsigned char *phonemes, signed char * max_stress = 4; primary_posn = j; } - + /* reduce any preceding primary stress markers */ for(ix=1; ixlangopts.stress_rule) { case 8: @@ -1275,12 +1275,12 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, mnem = phoneme_tab[final_ph]->mnemonic; mnem2 = phoneme_tab[final_ph2]->mnemonic; - if((mnem == 's') && (mnem2 == 'n')) + if((mnem == 's') && (phoneme_tab[final_ph2]->type == phNASAL)) { // -ns stress remains on penultimate syllable } else - if(((mnem != 'n') && (mnem != 's')) || (phoneme_tab[final_ph2]->type != phVOWEL)) + if(((phoneme_tab[final_ph]->type != phNASAL) && (mnem != 's')) || (phoneme_tab[final_ph2]->type != phVOWEL)) { stressed_syllable = vowel_count - 1; } @@ -1710,7 +1710,7 @@ void AppendPhonemes(Translator *tr, char *string, int size, const char *ph) /* Add new phoneme string "ph" to "string" Keeps count of the number of vowel phonemes in the word, and whether these can be stressed syllables. These values can be used in translation rules -*/ +*/ const char *p; unsigned char c; int unstress_mark; @@ -1748,7 +1748,7 @@ void AppendPhonemes(Translator *tr, char *string, int size, const char *ph) } } } - + if(string != NULL) strcat(string,ph); } /* end of AppendPhonemes */ @@ -1843,7 +1843,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ match.points = 1; match.end_type = 0; match.del_fwd = NULL; - + pre_ptr = *word; post_ptr = *word + group_length; @@ -1909,7 +1909,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ case RULE_CONDITION: /* conditional rule, next byte gives condition number */ condition_num = *rule++; - + if(condition_num >= 32) { // allow the rule only if the condition number is NOT set @@ -2017,7 +2017,7 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ else failed = 1; break; - + case RULE_NONALPHA: if(!iswalpha(letter_w)) { @@ -2388,13 +2388,13 @@ static void MatchRule(Translator *tr, char *word[], char *word_start, int group_ memcpy(&best,&match,sizeof(match)); total_consumed = consumed; } - + if((option_phonemes == 2) && (match.points > 0) && ((word_flags & FLAG_NO_TRACE) == 0)) { // show each rule that matches, and it's points score int pts; char decoded_phonemes[80]; - + pts = match.points; if(group_length > 1) pts += 35; // to account for an extra letter matching @@ -2490,10 +2490,10 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c p = p_start; tr->word_vowel_count = 0; tr->word_stressed_count = 0; - + if(end_phonemes != NULL) end_phonemes[0] = 0; - + while(((c = *p) != ' ') && (c != 0)) { wc_bytes = utf8_in(&wc,p); @@ -2511,7 +2511,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c string[1+wc_bytes] = 0; Lookup(tr, string,buf); if(++digit_count >= 2) - { + { strcat(buf,str_pause); digit_count=0; } @@ -2538,7 +2538,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c /* there are some 2 byte chains for this initial letter */ c2 = p[1]; c12 = c + (c2 << 8); /* 2 characters */ - + g1 = tr->groups2_start[c]; for(g=g1; g < (g1+n); g++) { @@ -2563,7 +2563,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c } } } - + if(!found) { /* alphabetic, single letter chain */ @@ -2619,14 +2619,14 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c p[-1] = ix; while((p[0] = p[n]) != ' ') p++; while(n-- > 0) *p++ = ' '; // replacement character must be no longer than original - + if(tr->langopts.param[LOPT_DIERESES] && (lookupwchar(diereses_list,letter) > 0)) { // vowel with dieresis, replace and continue from this point p = p2; continue; } - + phonemes[0] = 0; // delete any phonemes which have been produced so far p = p_start; tr->word_vowel_count = 0; @@ -2685,7 +2685,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c if(match1.phonemes == NULL) match1.phonemes = ""; - + if(match1.points > 0) { if(word_flags & FLAG_UNPRON_TEST) @@ -2888,7 +2888,7 @@ int TransposeAlphabet(Translator *tr, char *text) if(bits >= 8) { bits -= 8; - *p2++ = (acc >> bits); + *p2++ = (acc >> bits); } } if(bits > 0) @@ -3206,7 +3206,7 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor if(flags != NULL) flags[0] |= FLAG_FOUND; // this flag indicates word was found in dictionary - + if(option_phonemes == 2) { char ph_decoded[N_WORD_PHONEMES]; @@ -3344,9 +3344,9 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f if(found == 0) { ph_out[0] = 0; - + // try modifications to find a recognised word - + if((end_flags & FLAG_SUFX_E_ADDED) && (word[length-1] == 'e')) { // try removing an 'e' which has been added by RemoveEnding @@ -3439,7 +3439,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) This routine is language specific. In English it deals with reversing y->i and e-dropping that were done when the suffix was added to the original word. */ - + int i; char *word_end; int len_ending; @@ -3447,7 +3447,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) const char *p; int len; static char ending[12]; - + // these lists are language specific, but are only relevent if the 'e' suffix flag is used static const char *add_e_exceptions[] = { "ion", NULL }; @@ -3476,7 +3476,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) len_ending++; } } - + // remove bytes from the end of the word and replace them by spaces for(i=0; itranslator_name == L('n','l')) @@ -3517,7 +3517,7 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) if(IsLetter(tr, word_end[-1],LETTERGP_VOWEL2) && IsLetter(tr, word_end[0],1)) { // vowel(incl.'y') + hard.consonant - + for(i=0; (p = add_e_exceptions[i]) != NULL; i++) { len = strlen(p); diff --git a/src/phonemelist.cpp b/src/phonemelist.cpp index 6d94de55..0449a116 100644 --- a/src/phonemelist.cpp +++ b/src/phonemelist.cpp @@ -63,24 +63,24 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out) { if(ix < (n_ph_list2 -1)) next = phoneme_tab[ph_list2[ix+1].phcode]; - + word_end = 0; if((plist2+1)->sourceix || ((next != 0) && (next->type == phPAUSE))) word_end = 1; // this phoneme is the end of a word - + // check whether a Voice has specified that we should replace this phoneme for(k=0; kphcode == replace_phonemes[k].old_ph) { replace_flags = replace_phonemes[k].type; - + if((replace_flags & 1) && (word_end == 0)) continue; // this replacement only occurs at the end of a word - + if((replace_flags & 2) && ((plist2->stresslevel & 0x7) > 3)) continue; // this replacement doesn't occur in stressed syllables - + // substitute the replacement phoneme plist2->phcode = replace_phonemes[k].new_ph; if((plist2->stresslevel > 1) && (phoneme_tab[plist2->phcode]->phflags & phUNSTRESSED)) @@ -88,7 +88,7 @@ static int SubstitutePhonemes(Translator *tr, PHONEME_LIST *plist_out) break; } } - + if(plist2->phcode == 0) { continue; // phoneme has been replaced by NULL, so don't copy it @@ -131,7 +131,9 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) PHONEME_LIST ph_list3[N_PHONEME_LIST]; PHONEME_LIST2 *plist2; + WORD_PH_DATA worddata; + memset(&worddata, 0, sizeof(worddata)); plist2 = ph_list2; phlist = phoneme_list; end_sourceix = plist2[n_ph_list2-1].sourceix; @@ -339,7 +341,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) if(ph == NULL) continue; - InterpretPhoneme(tr, 0x100, plist3, &phdata); + InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); if((alternative = phdata.pd_param[pd_INSERTPHONEME]) > 0) { @@ -363,7 +365,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) // re-interpret the changed phoneme // But it doesn't obey a second ChangePhoneme() - InterpretPhoneme(tr, 0x100, plist3, &phdata); + InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); } if((alternative = phdata.pd_param[pd_CHANGEPHONEME]) > 0) @@ -388,7 +390,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) // re-interpret the changed phoneme // But it doesn't obey a second ChangePhoneme() - InterpretPhoneme(tr, 0x100, plist3, &phdata); + InterpretPhoneme(tr, 0x100, plist3, &phdata, &worddata); } if(ph->type == phVOWEL) @@ -478,7 +480,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) else insert_ph = phonPAUSE_VSHORT; } - + if((ph->type == phVOWEL) && ((x = tr->langopts.vowel_pause & 0x03) != 0)) { // adjacent vowels over a word boundary @@ -487,7 +489,7 @@ void MakePhonemeList(Translator *tr, int post_pause, int start_sentence) else insert_ph = phonPAUSE_VSHORT; } - + if(((plist3+1)->stresslevel >= 4) && (tr->langopts.vowel_pause & 0x100)) { // pause before a words which starts with a stressed vowel diff --git a/src/synth_mbrola.cpp b/src/synth_mbrola.cpp index fe6fe556..0abda433 100644 --- a/src/synth_mbrola.cpp +++ b/src/synth_mbrola.cpp @@ -77,7 +77,7 @@ HINSTANCE hinstDllMBR = NULL; BOOL load_MBR() { if(hinstDllMBR != NULL) - return TRUE; // already loaded + return TRUE; // already loaded if ((hinstDllMBR=LoadLibraryA("mbrola.dll")) == 0) return FALSE; @@ -150,14 +150,14 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int } } } - close_MBR(); + close_MBR(); #endif #ifdef PLATFORM_WINDOWS if(load_MBR() == FALSE) // load mbrola.dll { fprintf(stderr, "Can't load mbrola.dll\n"); return(EE_INTERNAL_ERROR); - } + } #endif if(init_MBR(path) != 0) // initialise the required mbrola voice @@ -169,14 +169,14 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int sprintf(path,"%s/mbrola_ph/%s",path_home,phtrans); size = GetFileLength(path); if((f_in = fopen(path,"rb")) == NULL) { - close_MBR(); + close_MBR(); return(EE_NOT_FOUND); } if((mbrola_tab = (MBROLA_TAB *)realloc(mbrola_tab,size)) == NULL) { fclose(f_in); - close_MBR(); + close_MBR(); return(EE_INTERNAL_ERROR); } @@ -190,7 +190,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int fclose(f_in); setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0f); -// srate = getFreq_MBR(); +// srate = getFreq_MBR(); samplerate = srate; if(srate == 22050) SetParameter(espeakVOICETYPE,0,0); @@ -543,7 +543,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr if(released == 0) p->synthflags |= SFLAG_NEXT_PAUSE; - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, NULL); len = DoSample3(&phdata, 0, -1); len = (len * 1000)/samplerate; // convert to mS @@ -556,7 +556,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr case phFRICATIVE: len = 0; - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, NULL); if(p->synthflags & SFLAG_LENGTHEN) len = DoSample3(&phdata, p->length, -1); // play it twice for [s:] etc. len += DoSample3(&phdata, p->length, -1); @@ -568,7 +568,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr if(next->type != phVOWEL) { memset(&fmtp, 0, sizeof(fmtp)); - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, NULL); fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; len = DoSpect2(p->ph, 0, &fmtp, p, -1); // len = DoSpect(p->ph,prev->ph,phoneme_tab[phonPAUSE],2,p,-1); @@ -601,7 +601,7 @@ int MbrolaTranslate(PHONEME_LIST *plist, int n_phonemes, int resume, FILE *f_mbr if(pause) { - len += PauseLength(pause,0); + len += PauseLength(pause,0); ptr += sprintf(ptr,"_ \t%d\n",PauseLength(pause,0)); pause = 0; } @@ -655,7 +655,7 @@ int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) int again = MbrolaTranslate(phoneme_list, *n_ph, resume, f_mbrola); if (!again) *n_ph = 0; - return again; + return again; } @@ -710,7 +710,7 @@ void MbrolaReset(void) espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int srate) { - return(EE_INTERNAL_ERROR); + return(EE_INTERNAL_ERROR); } int MbrolaGenerate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) diff --git a/src/synthdata.cpp b/src/synthdata.cpp index e7a7bfba..eb557105 100644 --- a/src/synthdata.cpp +++ b/src/synthdata.cpp @@ -35,8 +35,8 @@ #include "translate.h" #include "wave.h" -const char *version_string = "1.46.23 09.Sep.12"; -const int version_phdata = 0x014600; +const char *version_string = "1.46.24 11.Sep.12"; +const int version_phdata = 0x014624; int option_device_number = -1; FILE *f_logespeak = NULL; @@ -80,7 +80,7 @@ static char *ReadPhFile(void *ptr, const char *fname, int *size) sprintf(buf,"%s%c%s",path_home,PATHSEP,fname); length = GetFileLength(buf); - + if((f_in = fopen(buf,"rb")) == NULL) { fprintf(stderr,"Can't read data file: '%s'\n",buf); @@ -89,7 +89,7 @@ static char *ReadPhFile(void *ptr, const char *fname, int *size) if(ptr != NULL) Free(ptr); - + if((p = Alloc(length)) == NULL) { fclose(f_in); @@ -230,7 +230,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, SPECT_SEQK *seqk, *seqk2; frame_t *frame; static frameref_t frames_buf[N_SEQ_FRAMES]; - + seq = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt_addr]); seqk = (SPECT_SEQK *)seq; nf = seq->n_frames; @@ -268,7 +268,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, nf -= seq_break; } } - + // do we need to modify a frame for blending with a consonant? if((this_ph->type == phVOWEL) && (fmt_params->fmt2_addr == 0) && (fmt_params->use_vowelin)) { @@ -286,7 +286,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, // add these spectra to the main sequence seq2 = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt2_addr]); seqk2 = (SPECT_SEQK *)seq2; - + // first frame of the addition just sets the length of the last frame of the main seq nf--; for(ix=0; ixn_frames; ix++) @@ -306,7 +306,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, } wavefile_ix = 0; } - + if(length1 > 0) { if(which==2) @@ -324,7 +324,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, length_factor = (length_std * 256)/ length1; - + for(ix=0; ixlangopts.param[LOPT_REDUCE] & 0x2) && (stress_level >= pl->wordstress)) { // treat the most stressed syllable in an unstressed word as stressed @@ -607,69 +607,107 @@ static int CountVowelPosition(PHONEME_LIST *plist) } // end of CoundVowelPosition -static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, int instn) -{//======================================================================================== +static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, USHORT *p_prog, WORD_PH_DATA *worddata) +{//======================================================================================================================== int which; unsigned int data; + int instn; int instn2; int count; PHONEME_TAB *ph; PHONEME_LIST *plist_this; - static int ph_position[8] = {0, 1, 2, 3, 2, 0, 1, 3}; // prevPh, thisPh, nextPh, next2Ph, nextPhW, prevPhW, nextVowel, (other conditions) // instruction: 2xxx, 3xxx - // bits 8-10 = 0 to 6, which phoneme + // bits 8-10 = 0 to 5, which phoneme, =6 the 'which' information is in the next instruction. // bit 11 = 0, bits 0-7 are a phoneme code // bit 11 = 1, bits 5-7 type of data, bits 0-4 data value // bits 8-10 = 7, other conditions - + instn = (*p_prog) & 0xfff; data = instn & 0xff; instn2 = instn >> 8; if(instn2 < 14) { + plist_this = plist; which = (instn2) % 7; + if(which==6) + { + // the 'which' code is in the next instruction + p_prog++; + which = (*p_prog); + } + if(which==4) { - // nextPh not word boundary + // nextPhW not word boundary if(plist[1].sourceix) return(false); } if(which==5) { - // prevPh, not word boundary + // prevPhW, not word boundary if(plist[0].sourceix) return(false); } if(which==6) - { + { + // next2PhW, not word boundary + if(plist[1].sourceix || plist[2].sourceix) + return(false); + } + + + switch(which) + { + case 0: // prevPh + case 5: // prevPhW + plist--; + break; + + case 1: // thisPh + break; + + case 2: // nextPh + case 4: // nextPhW + plist++; + break; + + case 3: // next2Ph + case 6: // next2PhW + plist += 2; + break; + + case 7: // nextVowel, not word boundary - for(which=2;;which++) + for(which=1;;which++) { - if(plist[which-1].sourceix) + if(plist[which].sourceix) return(false); - if(phoneme_tab[plist[which-1].phcode]->type == phVOWEL) + if(phoneme_tab[plist[which].phcode]->type == phVOWEL) + { + plist = &plist[which]; break; + } } - } - else - { - which = ph_position[which]; - } + break; - plist_this = plist; - plist = &plist[which-1]; + case 8: // prevVowel in this word + if((worddata==NULL) || (worddata->prev_vowel.ph == NULL)) + return(false); // no previous vowel + plist = &(worddata->prev_vowel); + break; + } - if(which == 0) + if((which == 0) || (which == 5)) { if(plist->phcode == 1) { // This is a NULL phoneme, a phoneme has been deleted so look at the previous phoneme - plist = &plist[-1]; + plist--; } } @@ -739,7 +777,7 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, plist--; if((plist->stresslevel & 0xf) >= 4) return(true); - + } while (plist->sourceix == 0); break; @@ -814,8 +852,8 @@ static bool InterpretCondition(Translator *tr, int control, PHONEME_LIST *plist, } // end of InterpretCondition -static void SwitchVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT **p_prog, int instn_type) -{//===================================================================================================== +static void SwitchOnVowelType(PHONEME_LIST *plist, PHONEME_DATA *phdata, USHORT **p_prog, int instn_type) +{//======================================================================================================== USHORT *prog; int voweltype; signed char x; @@ -848,18 +886,27 @@ static int NumInstnWords(USHORT *prog) int instn; int instn2; int instn_type; - static char n_words[11] = {1,1,1,1,1,1,1,1,1,2,4}; + int n; + static const char n_words[16] = {1,1,0,0,1,1,1,1,1,2,4,0,0,0,0,0}; instn = *prog; instn_type = instn >> 12; - if(instn_type < 11) - return(n_words[instn_type]); + if((n = n_words[instn_type]) > 0) + return(n); - // 11 to 15, 2 words + if(instn_type < 4) + { + // 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) { - // addWav(), 2 more words + // This instruction is followed by addWav(), 2 more words return(4); } if(instn2 == i_CONTINUE) @@ -871,8 +918,8 @@ static int NumInstnWords(USHORT *prog) -void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata) -{//========================================================================================== +void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata) +{//=================================================================================================================== // control: //bit 0: PreVoicing //bit 8: change phonemes @@ -893,6 +940,12 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ ph = plist->ph; + if((worddata != NULL) && (plist->sourceix)) + { + // start of a word, reset word data + worddata->prev_vowel.ph = NULL; + } + memset(phdata, 0, sizeof(PHONEME_DATA)); phdata->pd_param[i_SET_LENGTH] = ph->std_length; phdata->pd_param[i_LENGTH_MOD] = ph->length_mod; @@ -901,13 +954,13 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ return; end_flag = 0; - + for(prog = &phoneme_index[ph->program]; end_flag != 1; prog++) { instn = *prog; instn2 = (instn >> 8) & 0xf; or_flag = 0; - + switch(instn >> 12) { case 0: // 0xxx @@ -992,11 +1045,13 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ { // process a sequence of conditions, using boolean accumulator if(or_flag) - truth = (truth || InterpretCondition(tr, control, plist, instn & 0xfff)); + truth = (truth || InterpretCondition(tr, control, plist, prog, worddata)); else - truth = (truth && InterpretCondition(tr, control, plist, instn & 0xfff)); + truth = (truth && InterpretCondition(tr, control, plist, prog, worddata)); or_flag = instn & 0x1000; - instn = *(++prog); + prog += NumInstnWords(prog); + instn = *prog; +// instn = *(++prog); } if(truth == false) @@ -1010,7 +1065,7 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ // instruction after a condition is not JUMP_FALSE, so skip the instruction. prog += NumInstnWords(prog); if((prog[0] & 0xfe00) == 0x6000) - prog++; // and skip ELSE jump + prog++; // and skip ELSE jump } } prog--; @@ -1029,11 +1084,11 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ break; case 5: // NexttVowelStarts - SwitchVowelType(plist, phdata, &prog, 2); + SwitchOnVowelType(plist, phdata, &prog, 2); break; case 6: // PrevVowelTypeEndings - SwitchVowelType(plist, phdata, &prog, 3); + SwitchOnVowelType(plist, phdata, &prog, 3); break; } break; @@ -1130,6 +1185,11 @@ void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_ } } + if((worddata != NULL) && (plist->type == phVOWEL)) + { + memcpy(&worddata->prev_vowel, &plist[0], sizeof(PHONEME_LIST)); + } + } // end of InterpretPhoneme @@ -1150,5 +1210,5 @@ void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata) plist[1].ph = phoneme_tab[phcode]; plist[2].sourceix = 1; - InterpretPhoneme(NULL, 0, &plist[1], phdata); + InterpretPhoneme(NULL, 0, &plist[1], phdata, NULL); } // end of InterpretPhoneme2 diff --git a/src/synthesize.cpp b/src/synthesize.cpp index 26e54707..d4e6a769 100644 --- a/src/synthesize.cpp +++ b/src/synthesize.cpp @@ -483,7 +483,7 @@ static void set_frame_rms(frame_t *fr, int new_rms) } return; } - + if(fr->rms == 0) return; // check for divide by zero x = (new_rms * 64)/fr->rms; if(x >= 200) x = 199; @@ -507,7 +507,7 @@ static void formants_reduce_hf(frame_t *fr, int level) if(voice->klattv[0]) return; - + for(ix=2; ix < 8; ix++) { x = fr->fheight[ix] * level; @@ -594,7 +594,7 @@ static void AdjustFormants(frame_t *fr, int target, int min, int max, int f1_adj fr->ffreq[1] += x; fr->ffreq[0] += x; } - formants_reduce_hf(fr,hf_reduce); + formants_reduce_hf(fr,hf_reduce); } @@ -717,7 +717,7 @@ if(voice->klattv[0]) fr = CopyFrame(seq[n_frames-1].frame,0); seq[n_frames-1].frame = fr; rms = RMS_GLOTTAL1; - + // degree of glottal-stop effect depends on closeness of vowel (indicated by f1 freq) modn_flags = 0x400 + (VowelCloseness(fr) << 8); } @@ -726,7 +726,7 @@ if(voice->klattv[0]) fr = DuplicateLastFrame(seq,n_frames++,len); if(len > 36) seq_len_adjust += (len - 36); - + if(f2 != 0) { AdjustFormants(fr, f2, f2_min, f2_max, f1, f3_adj, f3_amp, flags); @@ -741,7 +741,7 @@ if(voice->klattv[0]) { fr = CopyFrame(seq[ix].frame,0); seq[ix].frame = fr; - + for(formant=1; formant<=5; formant++) { int x; @@ -1182,7 +1182,7 @@ if(which==1) q[1] = len + (modulation << 16); q[2] = (long64)frame1; q[3] = (long64)frame2; - + WcmdqInc(); } last_frame = frame1 = frame2; @@ -1348,6 +1348,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) PHONEME_DATA phdata_next; PHONEME_DATA phdata_tone; FMT_PARAMS fmtp; + static WORD_PH_DATA worddata; if(option_quiet) return(0); @@ -1372,6 +1373,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) syllable_centre = -1; last_pitch_cmd = -1; memset(vowel_transition,0,sizeof(vowel_transition)); + memset(&worddata, 0, sizeof(worddata)); DoPause(0,0); // isolate from the previous clause } @@ -1463,13 +1465,13 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) if(released == 0) p->synthflags |= SFLAG_NEXT_PAUSE; - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, &worddata); phdata.pd_control |= pd_DONTLENGTHEN; DoSample3(&phdata, 0, 0); break; case phFRICATIVE: - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, &worddata); if(p->synthflags & SFLAG_LENGTHEN) { @@ -1509,7 +1511,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) if((prev->type==phVOWEL) || (prev->ph->phflags & phVOWEL2) || (ph->phflags & phPREVOICE)) { // a period of voicing before the release - InterpretPhoneme(NULL, 0x01, p, &phdata); + InterpretPhoneme(NULL, 0x01, p, &phdata, &worddata); fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; fmtp.fmt_amp = phdata.sound_param[pd_FMT]; @@ -1537,7 +1539,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) { p->synthflags |= SFLAG_NEXT_PAUSE; } - InterpretPhoneme(NULL,0, p, &phdata); + InterpretPhoneme(NULL,0, p, &phdata, &worddata); fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; fmtp.fmt_amp = phdata.sound_param[pd_FMT]; fmtp.wav_addr = phdata.sound_addr[pd_ADDWAV]; @@ -1582,7 +1584,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) { p->synthflags |= SFLAG_NEXT_PAUSE; } - InterpretPhoneme(NULL,0, p, &phdata); + InterpretPhoneme(NULL,0, p, &phdata, &worddata); memset(&fmtp, 0, sizeof(fmtp)); fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2; fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; @@ -1608,7 +1610,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) last_frame = NULL; } - InterpretPhoneme(NULL,0, p, &phdata); + InterpretPhoneme(NULL,0, p, &phdata, &worddata); fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2; fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; fmtp.fmt_amp = phdata.sound_param[pd_FMT]; @@ -1653,7 +1655,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) { StartSyllable(); } - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, &worddata); fmtp.std_length = phdata.pd_param[i_SET_LENGTH]*2; fmtp.fmt_addr = phdata.sound_addr[pd_FMT]; fmtp.fmt_amp = phdata.sound_param[pd_FMT]; @@ -1669,7 +1671,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) memset(&fmtp, 0, sizeof(fmtp)); - InterpretPhoneme(NULL, 0, p, &phdata); + InterpretPhoneme(NULL, 0, p, &phdata, &worddata); fmtp.std_length = phdata.pd_param[i_SET_LENGTH] * 2; if(((fmtp.fmt_addr = phdata.sound_addr[pd_VWLSTART]) != 0) && ((phdata.pd_control & pd_FORNEXTPH) == 0)) @@ -1681,7 +1683,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) if(prev->type != phPAUSE) { // check the previous phoneme - InterpretPhoneme(NULL, 0, prev, &phdata_prev); + InterpretPhoneme(NULL, 0, prev, &phdata_prev, NULL); if((fmtp.fmt_addr = phdata_prev.sound_addr[pd_VWLSTART]) != 0) { // a vowel start has been specified by the Vowel program @@ -1763,7 +1765,7 @@ int Generate(PHONEME_LIST *phoneme_list, int *n_ph, int resume) if(next->type != phPAUSE) { fmtp.fmt2_lenadj = 0; - InterpretPhoneme(NULL, 0, next, &phdata_next); + InterpretPhoneme(NULL, 0, next, &phdata_next, NULL); fmtp.use_vowelin = 1; fmtp.transition0 = phdata_next.vowel_transition[2]; // always do vowel_transition, even if ph_VWLEND ?? consider [N] @@ -1939,7 +1941,7 @@ int SpeakNextClause(FILE *f_in, const void *text_in, int control) if(option_phonemes > 0) { fprintf(f_trans,"%s\n",translator->phon_out); - + if(!iswalpha(0x010d)) { // check that c-caron is recognized as an alphabetic character diff --git a/src/synthesize.h b/src/synthesize.h index 9c3c9ed6..10151e09 100644 --- a/src/synthesize.h +++ b/src/synthesize.h @@ -265,6 +265,9 @@ typedef struct { int std_length; } FMT_PARAMS; +typedef struct { + PHONEME_LIST prev_vowel; +} WORD_PH_DATA; // instructions @@ -417,7 +420,7 @@ typedef struct { unsigned char split_tail_start; unsigned char split_tail_end; unsigned char split_tune; - + unsigned char spare[8]; int spare2; // the struct length should be a multiple of 4 bytes } TUNE; diff --git a/src/translate.h b/src/translate.h index cbd5b367..9beb3e78 100644 --- a/src/translate.h +++ b/src/translate.h @@ -18,7 +18,7 @@ ***************************************************************************/ -#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer for translator name +#define L(c1,c2) (c1<<8)+c2 // combine two characters into an integer for translator name #define CTRL_EMBEDDED 0x01 // control character at the start of an embedded command #define REPLACED_E 'E' // 'e' replaced by silent e @@ -29,7 +29,7 @@ #define N_RULE_GROUP2 120 // max num of two-letter rule chains #define N_HASH_DICT 1024 #define N_CHARSETS 20 -#define N_LETTER_GROUPS 95 // maximum is 127-32 +#define N_LETTER_GROUPS 95 // maximum is 127-32 /* dictionary flags, word 1 */ @@ -52,7 +52,7 @@ #define FLAG_STEM 0x40000 // must have a suffix #define FLAG_DOUBLING 0x80000 // doubles the following consonant -#define BITNUM_FLAG_ALT 19 // bit number of FLAG_ALT_TRANS - 1 +#define BITNUM_FLAG_ALT 19 // bit number of FLAG_ALT_TRANS - 1 #define FLAG_ALT_TRANS 0x100000 // language specific #define FLAG_ALT2_TRANS 0x200000 // language specific #define FLAG_ALT3_TRANS 0x400000 // language specific @@ -110,7 +110,7 @@ #define FLAG_MULTIPLE_SPACES 0x40000 // word is preceded by multiple spaces, newline, or tab #define FLAG_INDIVIDUAL_DIGITS 0x80000 // speak number as individual digits #define FLAG_DELETE_WORD 0x100000 // don't speak this word, it has been spoken as part of the previous word -#define FLAG_CHAR_REPLACED 0x200000 // characters have been replaced by .replace in the *_rules +#define FLAG_CHAR_REPLACED 0x200000 // characters have been replaced by .replace in the *_rules #define FLAG_SUFFIX_VOWEL 0x08000000 // remember an initial vowel from the suffix #define FLAG_NO_TRACE 0x10000000 // passed to TranslateRules() to suppress dictionary lookup printout @@ -235,7 +235,7 @@ typedef struct { int end_type; char *del_fwd; } MatchRecord; - + // used to mark words with the source[] buffer typedef struct{ @@ -377,7 +377,7 @@ typedef struct { // bit20= hyphenated words, 2nd part is unstressed // bit21= don't lengthen vowels at end-of-clause - int stress_flags; + int stress_flags; int unstressed_wd1; // stress for $u word of 1 syllable int unstressed_wd2; // stress for $u word of >1 syllable int param[N_LOPTS]; @@ -542,18 +542,18 @@ typedef struct // groups1 and groups2 are indexes into data_dictrules, set up by InitGroups() // the two-letter rules for each letter must be consecutive in the language_rules source - + char *groups1[256]; // translation rule lists, index by single letter char *groups3[128]; // index by offset letter char *groups2[N_RULE_GROUP2]; // translation rule lists, indexed by two-letter pairs unsigned int groups2_name[N_RULE_GROUP2]; // the two letter pairs for groups2[] int n_groups2; // number of groups2[] entries used - + unsigned char groups2_count[256]; // number of 2 letter groups for this initial letter unsigned char groups2_start[256]; // index into groups2 const short *frequent_pairs; // list of frequent pairs of letters, for use in compressed *_list - - + + int expect_verb; int expect_past; // expect past tense int expect_verb_s; @@ -563,7 +563,7 @@ typedef struct int word_vowel_count; // number of vowels so far int word_stressed_count; // number of vowels so far which could be stressed - + int clause_upper_count; // number of upper case letters in the clause int clause_lower_count; // number of lower case letters in the clause @@ -685,7 +685,7 @@ void *TranslateClause(Translator *tr, FILE *f_text, const void *vp_input, int *t int ReadClause(Translator *tr, FILE *f_in, char *buf, short *charix, int *charix_top, int n_buf, int *tone_type, char *voice_change); void SetVoiceStack(espeak_VOICE *v, const char *variant_name); -void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata); +void InterpretPhoneme(Translator *tr, int control, PHONEME_LIST *plist, PHONEME_DATA *phdata, WORD_PH_DATA *worddata); void InterpretPhoneme2(int phcode, PHONEME_DATA *phdata); char *WritePhMnemonic(char *phon_out, PHONEME_TAB *ph, PHONEME_LIST *plist, int use_ipa);