cmu_grapheme_lex.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*************************************************************************/
  2. /* */
  3. /* Language Technologies Institute */
  4. /* Carnegie Mellon University */
  5. /* Copyright (c) 2013 */
  6. /* All Rights Reserved. */
  7. /* */
  8. /* Permission is hereby granted, free of charge, to use and distribute */
  9. /* this software and its documentation without restriction, including */
  10. /* without limitation the rights to use, copy, modify, merge, publish, */
  11. /* distribute, sublicense, and/or sell copies of this work, and to */
  12. /* permit persons to whom this work is furnished to do so, subject to */
  13. /* the following conditions: */
  14. /* 1. The code must retain the above copyright notice, this list of */
  15. /* conditions and the following disclaimer. */
  16. /* 2. Any modifications must be clearly marked as such. */
  17. /* 3. Original authors' names are not deleted. */
  18. /* 4. The authors' names are not used to endorse or promote products */
  19. /* derived from this software without specific prior written */
  20. /* permission. */
  21. /* */
  22. /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */
  23. /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
  24. /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
  25. /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */
  26. /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
  27. /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
  28. /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
  29. /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
  30. /* THIS SOFTWARE. */
  31. /* */
  32. /*************************************************************************/
  33. /* */
  34. /* grapheme Lexical function */
  35. /* */
  36. /*************************************************************************/
  37. #include "flite.h"
  38. #include "cst_val.h"
  39. #include "cst_voice.h"
  40. #include "cst_lexicon.h"
  41. #include "cst_ffeatures.h"
  42. #include "cmu_grapheme_lex.h"
  43. static int cst_find_u2sampa(char *ord)
  44. {
  45. int i;
  46. /* Now this is inefficient ... */
  47. for (i=0; i<num_unicode_sampa_mapping; i++)
  48. if (cst_streq(ord,unicode_sampa_mapping[i][0]))
  49. return i;
  50. return -1;
  51. }
  52. static int cst_utf8_as_hex(const char *in,char *out)
  53. {
  54. int o;
  55. o = cst_utf8_ord_string(in);
  56. if ((o > 96) && (o < 123))
  57. {
  58. cst_sprintf(out,"let_%c",(unsigned char)o);
  59. }
  60. else if ((o > 64) && (o < 91))
  61. { /* Map uppercase to lowercase */
  62. cst_sprintf(out,"let_%c",(unsigned char)o+32);
  63. }
  64. else
  65. cst_sprintf(out,"u%04Xp",o);
  66. return o;
  67. }
  68. cst_val *cmu_grapheme_lex_lts_function(const struct lexicon_struct *l,
  69. const char *word, const char *pos,
  70. const cst_features *feats)
  71. {
  72. cst_val *phones = 0;
  73. cst_val *utflets = 0;
  74. const cst_val *v;
  75. char ord[10];
  76. int i,phindex;
  77. /* string to utf8 chars */
  78. utflets = cst_utf8_explode(word);
  79. for (v=utflets; v; v=val_cdr(v))
  80. {
  81. /* We will add the found phones in reverse order and reverse then */
  82. /* afterwards */
  83. cst_utf8_as_hex(val_string(val_car(v)),ord);
  84. phindex = cst_find_u2sampa(ord);
  85. if (phindex < 0)
  86. printf("awb_debug no sampa %s %s\n",val_string(val_car(v)),ord);
  87. for (i=4; (phindex>=0) && (i>0); i--)
  88. {
  89. if (unicode_sampa_mapping[phindex][i])
  90. phones = cons_val(string_val(unicode_sampa_mapping[phindex][i]),
  91. phones);
  92. }
  93. }
  94. phones = val_reverse(phones);
  95. #if 1
  96. printf("cmu_grapheme_lex.c: word \"%s\" ",word);
  97. val_print(stdout,phones);
  98. printf("\n");
  99. #endif
  100. delete_val(utflets);
  101. return phones;
  102. }
  103. cst_utterance *cmu_grapheme_postlex(cst_utterance *u)
  104. {
  105. return u;
  106. }
  107. static int cmu_grapheme_is_vowel(const char *p)
  108. {
  109. /* This a place holder, we know its sampa, so I should look it up */
  110. /* in the list, not guess from typographical conventions */
  111. if (strchr("aeiouAEIOU",p[0]) == NULL)
  112. return FALSE;
  113. else
  114. return TRUE;
  115. }
  116. static int cmu_grapheme_contains_vowel(const cst_val *r)
  117. {
  118. const cst_val *x;
  119. for (x=r; x; x=val_cdr(x))
  120. {
  121. if (cmu_grapheme_is_vowel(val_string(val_car(x))))
  122. return TRUE;
  123. }
  124. return FALSE;
  125. }
  126. static int cmu_grapheme_has_vowel_in_syl(const cst_item *i)
  127. {
  128. const cst_item *n;
  129. for (n=i; n; n=item_prev(n))
  130. if (cmu_grapheme_is_vowel(ffeature_string(n,"name")))
  131. return TRUE;
  132. return FALSE;
  133. }
  134. int cmu_grapheme_syl_boundary(const cst_item *i,const cst_val *rest)
  135. {
  136. if (!rest)
  137. return TRUE;
  138. else if (!cmu_grapheme_contains_vowel(rest))
  139. return FALSE;
  140. else if (!cmu_grapheme_has_vowel_in_syl(i))
  141. return FALSE;
  142. #if 0
  143. else if (rest && val_cdr(rest) &&
  144. cst_streq("n",val_string(val_car(rest))) &&
  145. !cmu_grapheme_is_vowel(val_string(val_car(rest))))
  146. return FALSE;
  147. else if (rest && val_cdr(rest) &&
  148. cmu_grapheme_is_vowel(ffeature_string(i,"name")) &&
  149. !cmu_grapheme_is_vowel(val_string(val_car(rest))) &&
  150. !cmu_grapheme_is_vowel(val_string(val_car(val_cdr(rest)))))
  151. return FALSE;
  152. else if (rest && val_cdr(rest) && val_cdr(val_cdr(rest)) &&
  153. !cmu_grapheme_is_vowel(val_string(val_car(rest))) &&
  154. !cmu_grapheme_is_vowel(val_string(val_car(val_cdr(rest)))) &&
  155. !cmu_grapheme_is_vowel(val_string(val_car(val_cdr(val_cdr(rest))))))
  156. return FALSE;
  157. else if (rest && val_cdr(rest) &&
  158. (cst_streq(val_string(val_car(rest)),
  159. val_string(val_car(val_cdr(rest))))))
  160. return FALSE;
  161. #endif
  162. else
  163. return TRUE;
  164. }
  165. cst_lexicon cmu_grapheme_lex;
  166. cst_lexicon *cmu_grapheme_lex_init(void)
  167. {
  168. /* Should it be global const or dynamic */
  169. /* Can make lts_rules just a cart tree like others */
  170. cst_lexicon *l;
  171. if (cmu_grapheme_lex.lts_function)
  172. return &cmu_grapheme_lex;
  173. l = &cmu_grapheme_lex;
  174. l->name = "cmu_grapheme_lex";
  175. l->lts_function = cmu_grapheme_lex_lts_function;
  176. l->syl_boundary = cmu_grapheme_syl_boundary;
  177. l->postlex = cmu_grapheme_postlex;
  178. return l;
  179. }