1 /* ----------------------------------------------------------------- */
2 /* The HMM-Based Speech Synthesis Engine "hts_engine API" */
3 /* developed by HTS Working Group */
4 /* http://hts-engine.sourceforge.net/ */
5 /* ----------------------------------------------------------------- */
6 /* */
7 /* Copyright (c) 2001-2015 Nagoya Institute of Technology */
8 /* Department of Computer Science */
9 /* */
10 /* 2001-2008 Tokyo Institute of Technology */
11 /* Interdisciplinary Graduate School of */
12 /* Science and Engineering */
13 /* */
14 /* All rights reserved. */
15 /* */
16 /* Redistribution and use in source and binary forms, with or */
17 /* without modification, are permitted provided that the following */
18 /* conditions are met: */
19 /* */
20 /* - Redistributions of source code must retain the above copyright */
21 /* notice, this list of conditions and the following disclaimer. */
22 /* - Redistributions in binary form must reproduce the above */
23 /* copyright notice, this list of conditions and the following */
24 /* disclaimer in the documentation and/or other materials provided */
25 /* with the distribution. */
26 /* - Neither the name of the HTS working group nor the names of its */
27 /* contributors may be used to endorse or promote products derived */
28 /* from this software without specific prior written permission. */
29 /* */
30 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */
31 /* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */
32 /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
33 /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
34 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */
35 /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
36 /* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
37 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
38 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
39 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */
40 /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY */
41 /* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
42 /* POSSIBILITY OF SUCH DAMAGE. */
43 /* ----------------------------------------------------------------- */
44
45 #ifndef HTS_MODEL_C
46 #define HTS_MODEL_C
47
48 #ifdef __cplusplus
49 #define HTS_MODEL_C_START extern "C" {
50 #define HTS_MODEL_C_END }
51 #else
52 #define HTS_MODEL_C_START
53 #define HTS_MODEL_C_END
54 #endif /* __CPLUSPLUS */
55
56 HTS_MODEL_C_START;
57
58 #include <stdlib.h> /* for atoi(),abs() */
59 #include <string.h> /* for strlen(),strstr(),strrchr(),strcmp() */
60 #include <ctype.h> /* for isdigit() */
61
62 /* hts_engine libraries */
63 #include "HTS_hidden.h"
64
65 #ifdef WIN32
66 typedef unsigned __int32 uint32_t;
67 #else
68 #include <stdint.h>
69 #endif /* WIN32 */
70
71 /* HTS_dp_match: recursive matching */
HTS_dp_match(const char * string,const char * pattern,size_t pos,size_t max)72 static HTS_Boolean HTS_dp_match(const char *string, const char *pattern, size_t pos, size_t max)
73 {
74 if (pos > max)
75 return FALSE;
76 if (string[0] == '\0' && pattern[0] == '\0')
77 return TRUE;
78 if (pattern[0] == '*') {
79 if (HTS_dp_match(string + 1, pattern, pos + 1, max) == 1)
80 return TRUE;
81 else
82 return HTS_dp_match(string, pattern + 1, pos, max);
83 }
84 if (string[0] == pattern[0] || pattern[0] == '?') {
85 if (HTS_dp_match(string + 1, pattern + 1, pos + 1, max + 1) == 1)
86 return TRUE;
87 }
88
89 return FALSE;
90 }
91
92 /* HTS_pattern_match: pattern matching function */
HTS_pattern_match(const char * string,const char * pattern)93 static HTS_Boolean HTS_pattern_match(const char *string, const char *pattern)
94 {
95 size_t i, j;
96 size_t buff_length, max = 0, nstar = 0, nquestion = 0;
97 char buff[HTS_MAXBUFLEN];
98 size_t pattern_length = strlen(pattern);
99
100 for (i = 0; i < pattern_length; i++) {
101 switch (pattern[i]) {
102 case '*':
103 nstar++;
104 break;
105 case '?':
106 nquestion++;
107 max++;
108 break;
109 default:
110 max++;
111 }
112 }
113 if (nstar == 2 && nquestion == 0 && pattern[0] == '*' && pattern[i - 1] == '*') {
114 /* only string matching is required */
115 buff_length = i - 2;
116 for (i = 0, j = 1; i < buff_length; i++, j++)
117 buff[i] = pattern[j];
118 buff[buff_length] = '\0';
119 if (strstr(string, buff) != NULL)
120 return TRUE;
121 else
122 return FALSE;
123 } else
124 return HTS_dp_match(string, pattern, 0, strlen(string) - max);
125 }
126
127 /* HTS_is_num: check given buffer is number or not */
HTS_is_num(const char * buff)128 static HTS_Boolean HTS_is_num(const char *buff)
129 {
130 size_t i;
131 size_t length = strlen(buff);
132
133 for (i = 0; i < length; i++)
134 if (!(isdigit((int) buff[i]) || (buff[i] == '-')))
135 return FALSE;
136
137 return TRUE;
138 }
139
140 /* HTS_name2num: convert name of node to number */
HTS_name2num(const char * buff)141 static size_t HTS_name2num(const char *buff)
142 {
143 size_t i;
144
145 for (i = strlen(buff) - 1; '0' <= buff[i] && buff[i] <= '9'; i--);
146 i++;
147
148 return (size_t) atoi(&buff[i]);
149 }
150
151 /* HTS_get_state_num: return the number of state */
HTS_get_state_num(const char * string)152 static size_t HTS_get_state_num(const char *string)
153 {
154 const char *left, *right;
155
156 left = strchr(string, '[');
157 if (left == NULL)
158 return 0;
159 left++;
160
161 right = strchr(left, ']');
162 if (right == NULL)
163 return 0;
164
165 return (size_t) atoi(left);
166 }
167
168 /* HTS_Question_initialize: initialize question */
HTS_Question_initialize(HTS_Question * question)169 static void HTS_Question_initialize(HTS_Question * question)
170 {
171 question->string = NULL;
172 question->head = NULL;
173 question->next = NULL;
174 }
175
176 /* HTS_Question_clear: clear loaded question */
HTS_Question_clear(HTS_Question * question)177 static void HTS_Question_clear(HTS_Question * question)
178 {
179 HTS_Pattern *pattern, *next_pattern;
180
181 if (question->string != NULL)
182 HTS_free(question->string);
183 for (pattern = question->head; pattern; pattern = next_pattern) {
184 next_pattern = pattern->next;
185 HTS_free(pattern->string);
186 HTS_free(pattern);
187 }
188 HTS_Question_initialize(question);
189 }
190
191 /* HTS_Question_load: Load questions from file */
HTS_Question_load(HTS_Question * question,HTS_File * fp)192 static HTS_Boolean HTS_Question_load(HTS_Question * question, HTS_File * fp)
193 {
194 char buff[HTS_MAXBUFLEN];
195 HTS_Pattern *pattern, *last_pattern;
196
197 if (question == NULL || fp == NULL)
198 return FALSE;
199
200 HTS_Question_clear(question);
201
202 /* get question name */
203 if (HTS_get_pattern_token(fp, buff) == FALSE)
204 return FALSE;
205 question->string = HTS_strdup(buff);
206
207 /* get pattern list */
208 if (HTS_get_pattern_token(fp, buff) == FALSE) {
209 HTS_Question_clear(question);
210 return FALSE;
211 }
212
213 last_pattern = NULL;
214 if (strcmp(buff, "{") == 0) {
215 while (1) {
216 if (HTS_get_pattern_token(fp, buff) == FALSE) {
217 HTS_Question_clear(question);
218 return FALSE;
219 }
220 pattern = (HTS_Pattern *) HTS_calloc(1, sizeof(HTS_Pattern));
221 if (question->head != NULL)
222 last_pattern->next = pattern;
223 else /* first time */
224 question->head = pattern;
225 pattern->string = HTS_strdup(buff);
226 pattern->next = NULL;
227 if (HTS_get_pattern_token(fp, buff) == FALSE) {
228 HTS_Question_clear(question);
229 return FALSE;
230 }
231 if (!strcmp(buff, "}"))
232 break;
233 last_pattern = pattern;
234 }
235 }
236 return TRUE;
237 }
238
239 /* HTS_Question_match: check given string match given question */
HTS_Question_match(HTS_Question * question,const char * string)240 static HTS_Boolean HTS_Question_match(HTS_Question * question, const char *string)
241 {
242 HTS_Pattern *pattern;
243
244 for (pattern = question->head; pattern; pattern = pattern->next)
245 if (HTS_pattern_match(string, pattern->string))
246 return TRUE;
247
248 return FALSE;
249 }
250
251 /* HTS_Question_find: find question from question list */
HTS_Question_find(HTS_Question * question,const char * string)252 static HTS_Question *HTS_Question_find(HTS_Question * question, const char *string)
253 {
254 for (; question; question = question->next)
255 if (strcmp(string, question->string) == 0)
256 return question;
257
258 return NULL;
259 }
260
261 /* HTS_Node_initialzie: initialize node */
HTS_Node_initialize(HTS_Node * node)262 static void HTS_Node_initialize(HTS_Node * node)
263 {
264 node->index = 0;
265 node->pdf = 0;
266 node->yes = NULL;
267 node->no = NULL;
268 node->next = NULL;
269 node->quest = NULL;
270 }
271
272 /* HTS_Node_clear: recursive function to free node */
HTS_Node_clear(HTS_Node * node)273 static void HTS_Node_clear(HTS_Node * node)
274 {
275 if (node->yes != NULL) {
276 HTS_Node_clear(node->yes);
277 HTS_free(node->yes);
278 }
279 if (node->no != NULL) {
280 HTS_Node_clear(node->no);
281 HTS_free(node->no);
282 }
283 HTS_Node_initialize(node);
284 }
285
286 /* HTS_Node_find: find node for given number */
HTS_Node_find(HTS_Node * node,int num)287 static HTS_Node *HTS_Node_find(HTS_Node * node, int num)
288 {
289 for (; node; node = node->next)
290 if (node->index == num)
291 return node;
292
293 return NULL;
294 }
295
296 /* HTS_Tree_initialize: initialize tree */
HTS_Tree_initialize(HTS_Tree * tree)297 static void HTS_Tree_initialize(HTS_Tree * tree)
298 {
299 tree->head = NULL;
300 tree->next = NULL;
301 tree->root = NULL;
302 tree->state = 0;
303 }
304
305 /* HTS_Tree_clear: clear given tree */
HTS_Tree_clear(HTS_Tree * tree)306 static void HTS_Tree_clear(HTS_Tree * tree)
307 {
308 HTS_Pattern *pattern, *next_pattern;
309
310 for (pattern = tree->head; pattern; pattern = next_pattern) {
311 next_pattern = pattern->next;
312 HTS_free(pattern->string);
313 HTS_free(pattern);
314 }
315 if (tree->root != NULL) {
316 HTS_Node_clear(tree->root);
317 HTS_free(tree->root);
318 }
319 HTS_Tree_initialize(tree);
320 }
321
322 /* HTS_Tree_parse_pattern: parse pattern specified for each tree */
HTS_Tree_parse_pattern(HTS_Tree * tree,char * string)323 static void HTS_Tree_parse_pattern(HTS_Tree * tree, char *string)
324 {
325 char *left, *right;
326 HTS_Pattern *pattern, *last_pattern;
327
328 tree->head = NULL;
329 last_pattern = NULL;
330 /* parse tree pattern */
331 if ((left = strchr(string, '{')) != NULL) { /* pattern is specified */
332 string = left + 1;
333 if (*string == '(')
334 ++string;
335
336 right = strrchr(string, '}');
337 if (string < right && *(right - 1) == ')')
338 --right;
339 *right = ',';
340
341 /* parse pattern */
342 while ((left = strchr(string, ',')) != NULL) {
343 pattern = (HTS_Pattern *) HTS_calloc(1, sizeof(HTS_Pattern));
344 if (tree->head) {
345 last_pattern->next = pattern;
346 } else {
347 tree->head = pattern;
348 }
349 *left = '\0';
350 pattern->string = HTS_strdup(string);
351 string = left + 1;
352 pattern->next = NULL;
353 last_pattern = pattern;
354 }
355 }
356 }
357
358 /* HTS_Tree_load: load trees */
HTS_Tree_load(HTS_Tree * tree,HTS_File * fp,HTS_Question * question)359 static HTS_Boolean HTS_Tree_load(HTS_Tree * tree, HTS_File * fp, HTS_Question * question)
360 {
361 char buff[HTS_MAXBUFLEN];
362 HTS_Node *node, *last_node;
363
364 if (tree == NULL || fp == NULL)
365 return FALSE;
366
367 if (HTS_get_pattern_token(fp, buff) == FALSE) {
368 HTS_Tree_clear(tree);
369 return FALSE;
370 }
371 node = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node));
372 HTS_Node_initialize(node);
373 tree->root = last_node = node;
374
375 if (strcmp(buff, "{") == 0) {
376 while (HTS_get_pattern_token(fp, buff) == TRUE && strcmp(buff, "}") != 0) {
377 node = HTS_Node_find(last_node, atoi(buff));
378 if (node == NULL) {
379 HTS_error(0, "HTS_Tree_load: Cannot find node %d.\n", atoi(buff));
380 HTS_Tree_clear(tree);
381 return FALSE;
382 }
383 if (HTS_get_pattern_token(fp, buff) == FALSE) {
384 HTS_Tree_clear(tree);
385 return FALSE;
386 }
387 node->quest = HTS_Question_find(question, buff);
388 if (node->quest == NULL) {
389 HTS_error(0, "HTS_Tree_load: Cannot find question %s.\n", buff);
390 HTS_Tree_clear(tree);
391 return FALSE;
392 }
393 node->yes = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node));
394 node->no = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node));
395 HTS_Node_initialize(node->yes);
396 HTS_Node_initialize(node->no);
397
398 if (HTS_get_pattern_token(fp, buff) == FALSE) {
399 node->quest = NULL;
400 free(node->yes);
401 free(node->no);
402 HTS_Tree_clear(tree);
403 return FALSE;
404 }
405 if (HTS_is_num(buff))
406 node->no->index = atoi(buff);
407 else
408 node->no->pdf = HTS_name2num(buff);
409 node->no->next = last_node;
410 last_node = node->no;
411
412 if (HTS_get_pattern_token(fp, buff) == FALSE) {
413 node->quest = NULL;
414 free(node->yes);
415 free(node->no);
416 HTS_Tree_clear(tree);
417 return FALSE;
418 }
419 if (HTS_is_num(buff))
420 node->yes->index = atoi(buff);
421 else
422 node->yes->pdf = HTS_name2num(buff);
423 node->yes->next = last_node;
424 last_node = node->yes;
425 }
426 } else {
427 node->pdf = HTS_name2num(buff);
428 }
429
430 return TRUE;
431 }
432
433 /* HTS_Node_search: tree search */
HTS_Tree_search_node(HTS_Tree * tree,const char * string)434 static size_t HTS_Tree_search_node(HTS_Tree * tree, const char *string)
435 {
436 HTS_Node *node = tree->root;
437
438 while (node != NULL) {
439 if (node->quest == NULL)
440 return node->pdf;
441 if (HTS_Question_match(node->quest, string)) {
442 if (node->yes->pdf > 0)
443 return node->yes->pdf;
444 node = node->yes;
445 } else {
446 if (node->no->pdf > 0)
447 return node->no->pdf;
448 node = node->no;
449 }
450 }
451
452 HTS_error(0, "HTS_Tree_search_node: Cannot find node.\n");
453 return 1;
454 }
455
456 /* HTS_Window_initialize: initialize dynamic window */
HTS_Window_initialize(HTS_Window * win)457 static void HTS_Window_initialize(HTS_Window * win)
458 {
459 win->size = 0;
460 win->l_width = NULL;
461 win->r_width = NULL;
462 win->coefficient = NULL;
463 win->max_width = 0;
464 }
465
466 /* HTS_Window_clear: free dynamic window */
HTS_Window_clear(HTS_Window * win)467 static void HTS_Window_clear(HTS_Window * win)
468 {
469 size_t i;
470
471 if (win->coefficient != NULL) {
472 for (i = 0; i < win->size; i++) {
473 win->coefficient[i] += win->l_width[i];
474 HTS_free(win->coefficient[i]);
475 }
476 HTS_free(win->coefficient);
477 }
478 if (win->l_width)
479 HTS_free(win->l_width);
480 if (win->r_width)
481 HTS_free(win->r_width);
482
483 HTS_Window_initialize(win);
484 }
485
486 /* HTS_Window_load: load dynamic windows */
HTS_Window_load(HTS_Window * win,HTS_File ** fp,size_t size)487 static HTS_Boolean HTS_Window_load(HTS_Window * win, HTS_File ** fp, size_t size)
488 {
489 size_t i, j;
490 size_t fsize, length;
491 char buff[HTS_MAXBUFLEN];
492 HTS_Boolean result = TRUE;
493
494 /* check */
495 if (win == NULL || fp == NULL || size == 0)
496 return FALSE;
497
498 win->size = size;
499 win->l_width = (int *) HTS_calloc(win->size, sizeof(int));
500 win->r_width = (int *) HTS_calloc(win->size, sizeof(int));
501 win->coefficient = (double **) HTS_calloc(win->size, sizeof(double *));
502 /* set delta coefficents */
503 for (i = 0; i < win->size; i++) {
504 if (HTS_get_token_from_fp(fp[i], buff) == FALSE) {
505 result = FALSE;
506 fsize = 1;
507 } else {
508 fsize = atoi(buff);
509 if (fsize == 0) {
510 result = FALSE;
511 fsize = 1;
512 }
513 }
514 /* read coefficients */
515 win->coefficient[i] = (double *) HTS_calloc(fsize, sizeof(double));
516 for (j = 0; j < fsize; j++) {
517 if (HTS_get_token_from_fp(fp[i], buff) == FALSE) {
518 result = FALSE;
519 win->coefficient[i][j] = 0.0;
520 } else {
521 win->coefficient[i][j] = (double) atof(buff);
522 }
523 }
524 /* set pointer */
525 length = fsize / 2;
526 win->coefficient[i] += length;
527 win->l_width[i] = -1 * (int) length;
528 win->r_width[i] = (int) length;
529 if (fsize % 2 == 0)
530 win->r_width[i]--;
531 }
532 /* calcurate max_width to determine size of band matrix */
533 win->max_width = 0;
534 for (i = 0; i < win->size; i++) {
535 if (win->max_width < (size_t) abs(win->l_width[i]))
536 win->max_width = abs(win->l_width[i]);
537 if (win->max_width < (size_t) abs(win->r_width[i]))
538 win->max_width = abs(win->r_width[i]);
539 }
540
541 if (result == FALSE) {
542 HTS_Window_clear(win);
543 return FALSE;
544 }
545 return TRUE;
546 }
547
548 /* HTS_Model_initialize: initialize model */
HTS_Model_initialize(HTS_Model * model)549 static void HTS_Model_initialize(HTS_Model * model)
550 {
551 model->vector_length = 0;
552 model->num_windows = 0;
553 model->is_msd = FALSE;
554 model->ntree = 0;
555 model->npdf = NULL;
556 model->pdf = NULL;
557 model->tree = NULL;
558 model->question = NULL;
559 }
560
561 /* HTS_Model_clear: free pdfs and trees */
HTS_Model_clear(HTS_Model * model)562 static void HTS_Model_clear(HTS_Model * model)
563 {
564 size_t i, j;
565 HTS_Question *question, *next_question;
566 HTS_Tree *tree, *next_tree;
567
568 for (question = model->question; question; question = next_question) {
569 next_question = question->next;
570 HTS_Question_clear(question);
571 HTS_free(question);
572 }
573 for (tree = model->tree; tree; tree = next_tree) {
574 next_tree = tree->next;
575 HTS_Tree_clear(tree);
576 HTS_free(tree);
577 }
578 if (model->pdf) {
579 for (i = 2; i <= model->ntree + 1; i++) {
580 for (j = 1; j <= model->npdf[i]; j++) {
581 HTS_free(model->pdf[i][j]);
582 }
583 model->pdf[i]++;
584 HTS_free(model->pdf[i]);
585 }
586 model->pdf += 2;
587 HTS_free(model->pdf);
588 }
589 if (model->npdf) {
590 model->npdf += 2;
591 HTS_free(model->npdf);
592 }
593 HTS_Model_initialize(model);
594 }
595
596 /* HTS_Model_load_tree: load trees */
HTS_Model_load_tree(HTS_Model * model,HTS_File * fp)597 static HTS_Boolean HTS_Model_load_tree(HTS_Model * model, HTS_File * fp)
598 {
599 char buff[HTS_MAXBUFLEN];
600 HTS_Question *question, *last_question;
601 HTS_Tree *tree, *last_tree;
602 size_t state;
603
604 /* check */
605 if (model == NULL) {
606 HTS_error(0, "HTS_Model_load_tree: File for trees is not specified.\n");
607 return FALSE;
608 }
609
610 if (fp == NULL) {
611 model->ntree = 1;
612 return TRUE;
613 }
614
615 model->ntree = 0;
616 last_question = NULL;
617 last_tree = NULL;
618 while (!HTS_feof(fp)) {
619 HTS_get_pattern_token(fp, buff);
620 /* parse questions */
621 if (strcmp(buff, "QS") == 0) {
622 question = (HTS_Question *) HTS_calloc(1, sizeof(HTS_Question));
623 HTS_Question_initialize(question);
624 if (HTS_Question_load(question, fp) == FALSE) {
625 free(question);
626 HTS_Model_clear(model);
627 return FALSE;
628 }
629 if (model->question)
630 last_question->next = question;
631 else
632 model->question = question;
633 question->next = NULL;
634 last_question = question;
635 }
636 /* parse trees */
637 state = HTS_get_state_num(buff);
638 if (state != 0) {
639 tree = (HTS_Tree *) HTS_calloc(1, sizeof(HTS_Tree));
640 HTS_Tree_initialize(tree);
641 tree->state = state;
642 HTS_Tree_parse_pattern(tree, buff);
643 if (HTS_Tree_load(tree, fp, model->question) == FALSE) {
644 free(tree);
645 HTS_Model_clear(model);
646 return FALSE;
647 }
648 if (model->tree)
649 last_tree->next = tree;
650 else
651 model->tree = tree;
652 tree->next = NULL;
653 last_tree = tree;
654 model->ntree++;
655 }
656 }
657 /* No Tree information in tree file */
658 if (model->tree == NULL)
659 model->ntree = 1;
660
661 return TRUE;
662 }
663
664 /* HTS_Model_load_pdf: load pdfs */
HTS_Model_load_pdf(HTS_Model * model,HTS_File * fp,size_t vector_length,size_t num_windows,HTS_Boolean is_msd)665 static HTS_Boolean HTS_Model_load_pdf(HTS_Model * model, HTS_File * fp, size_t vector_length, size_t num_windows, HTS_Boolean is_msd)
666 {
667 uint32_t i;
668 size_t j, k;
669 HTS_Boolean result = TRUE;
670 size_t len;
671
672 /* check */
673 if (model == NULL || fp == NULL || model->ntree <= 0) {
674 HTS_error(1, "HTS_Model_load_pdf: File for pdfs is not specified.\n");
675 return FALSE;
676 }
677
678 /* read MSD flag */
679 model->vector_length = vector_length;
680 model->num_windows = num_windows;
681 model->is_msd = is_msd;
682 model->npdf = (size_t *) HTS_calloc(model->ntree, sizeof(size_t));
683 model->npdf -= 2;
684 /* read the number of pdfs */
685 for (j = 2; j <= model->ntree + 1; j++) {
686 if (HTS_fread_little_endian(&i, sizeof(i), 1, fp) != 1) {
687 result = FALSE;
688 break;
689 }
690 model->npdf[j] = (size_t) i;
691 }
692 for (j = 2; j <= model->ntree + 1; j++) {
693 if (model->npdf[j] <= 0) {
694 HTS_error(1, "HTS_Model_load_pdf: # of pdfs at %d-th state should be positive.\n", j);
695 result = FALSE;
696 break;
697 }
698 }
699 if (result == FALSE) {
700 model->npdf += 2;
701 free(model->npdf);
702 HTS_Model_initialize(model);
703 return FALSE;
704 }
705 model->pdf = (float ***) HTS_calloc(model->ntree, sizeof(float **));
706 model->pdf -= 2;
707 /* read means and variances */
708 if (is_msd) /* for MSD */
709 len = model->vector_length * model->num_windows * 2 + 1;
710 else
711 len = model->vector_length * model->num_windows * 2;
712 for (j = 2; j <= model->ntree + 1; j++) {
713 model->pdf[j] = (float **) HTS_calloc(model->npdf[j], sizeof(float *));
714 model->pdf[j]--;
715 for (k = 1; k <= model->npdf[j]; k++) {
716 model->pdf[j][k] = (float *) HTS_calloc(len, sizeof(float));
717 if (HTS_fread_little_endian(model->pdf[j][k], sizeof(float), len, fp) != len)
718 result = FALSE;
719 }
720 }
721 if (result == FALSE) {
722 HTS_Model_clear(model);
723 return FALSE;
724 }
725 return TRUE;
726 }
727
728 /* HTS_Model_load: load pdf and tree */
HTS_Model_load(HTS_Model * model,HTS_File * pdf,HTS_File * tree,size_t vector_length,size_t num_windows,HTS_Boolean is_msd)729 static HTS_Boolean HTS_Model_load(HTS_Model * model, HTS_File * pdf, HTS_File * tree, size_t vector_length, size_t num_windows, HTS_Boolean is_msd)
730 {
731 /* check */
732 if (model == NULL || pdf == NULL || vector_length == 0 || num_windows == 0)
733 return FALSE;
734
735 /* reset */
736 HTS_Model_clear(model);
737
738 /* load tree */
739 if (HTS_Model_load_tree(model, tree) != TRUE) {
740 HTS_Model_clear(model);
741 return FALSE;
742 }
743
744 /* load pdf */
745 if (HTS_Model_load_pdf(model, pdf, vector_length, num_windows, is_msd) != TRUE) {
746 HTS_Model_clear(model);
747 return FALSE;
748 }
749
750 return TRUE;
751 }
752
753
754 /* HTS_Model_get_index: get index of tree and PDF */
HTS_Model_get_index(HTS_Model * model,size_t state_index,const char * string,size_t * tree_index,size_t * pdf_index)755 static void HTS_Model_get_index(HTS_Model * model, size_t state_index, const char *string, size_t * tree_index, size_t * pdf_index)
756 {
757 HTS_Tree *tree;
758 HTS_Pattern *pattern;
759 HTS_Boolean find;
760
761 (*tree_index) = 2;
762 (*pdf_index) = 1;
763
764 if (model->tree == NULL)
765 return;
766
767 find = FALSE;
768 for (tree = model->tree; tree; tree = tree->next) {
769 if (tree->state == state_index) {
770 pattern = tree->head;
771 if (!pattern)
772 find = TRUE;
773 for (; pattern; pattern = pattern->next)
774 if (HTS_pattern_match(string, pattern->string)) {
775 find = TRUE;
776 break;
777 }
778 if (find)
779 break;
780 }
781 (*tree_index)++;
782 }
783
784 if (tree != NULL) {
785 (*pdf_index) = HTS_Tree_search_node(tree, string);
786 } else {
787 (*pdf_index) = HTS_Tree_search_node(model->tree, string);
788 }
789 }
790
791 /* HTS_ModelSet_initialize: initialize model set */
HTS_ModelSet_initialize(HTS_ModelSet * ms)792 void HTS_ModelSet_initialize(HTS_ModelSet * ms)
793 {
794 ms->hts_voice_version = NULL;
795 ms->sampling_frequency = 0;
796 ms->frame_period = 0;
797 ms->num_voices = 0;
798 ms->num_states = 0;
799 ms->num_streams = 0;
800 ms->stream_type = NULL;
801 ms->fullcontext_format = NULL;
802 ms->fullcontext_version = NULL;
803 ms->gv_off_context = NULL;
804 ms->option = NULL;
805
806 ms->duration = NULL;
807 ms->window = NULL;
808 ms->stream = NULL;
809 ms->gv = NULL;
810 }
811
812 /* HTS_ModelSet_clear: free model set */
HTS_ModelSet_clear(HTS_ModelSet * ms)813 void HTS_ModelSet_clear(HTS_ModelSet * ms)
814 {
815 size_t i, j;
816
817 if (ms->hts_voice_version != NULL)
818 free(ms->hts_voice_version);
819 if (ms->stream_type != NULL)
820 free(ms->stream_type);
821 if (ms->fullcontext_format != NULL)
822 free(ms->fullcontext_format);
823 if (ms->fullcontext_version != NULL)
824 free(ms->fullcontext_version);
825 if (ms->gv_off_context != NULL) {
826 HTS_Question_clear(ms->gv_off_context);
827 free(ms->gv_off_context);
828 }
829 if (ms->option != NULL) {
830 for (i = 0; i < ms->num_streams; i++)
831 if (ms->option[i] != NULL)
832 free(ms->option[i]);
833 free(ms->option);
834 }
835
836 if (ms->duration != NULL) {
837 for (i = 0; i < ms->num_voices; i++)
838 HTS_Model_clear(&ms->duration[i]);
839 free(ms->duration);
840 }
841 if (ms->window != NULL) {
842 for (i = 0; i < ms->num_streams; i++)
843 HTS_Window_clear(&ms->window[i]);
844 free(ms->window);
845 }
846 if (ms->stream != NULL) {
847 for (i = 0; i < ms->num_voices; i++) {
848 for (j = 0; j < ms->num_streams; j++)
849 HTS_Model_clear(&ms->stream[i][j]);
850 free(ms->stream[i]);
851 }
852 HTS_free(ms->stream);
853 }
854 if (ms->gv != NULL) {
855 for (i = 0; i < ms->num_voices; i++) {
856 for (j = 0; j < ms->num_streams; j++)
857 HTS_Model_clear(&ms->gv[i][j]);
858 free(ms->gv[i]);
859 }
860 free(ms->gv);
861 }
862 HTS_ModelSet_initialize(ms);
863 }
864
865 /* HTS_match_head_string: return true if head of str is equal to pattern */
HTS_match_head_string(const char * str,const char * pattern,size_t * matched_size)866 static HTS_Boolean HTS_match_head_string(const char *str, const char *pattern, size_t * matched_size)
867 {
868
869 (*matched_size) = 0;
870 while (1) {
871 if (pattern[(*matched_size)] == '\0')
872 return TRUE;
873 if (str[(*matched_size)] == '\0')
874 return FALSE;
875 if (str[(*matched_size)] != pattern[(*matched_size)])
876 return FALSE;
877 (*matched_size)++;
878 }
879 }
880
881 /* HTS_strequal: strcmp wrapper */
HTS_strequal(const char * s1,const char * s2)882 static HTS_Boolean HTS_strequal(const char *s1, const char *s2)
883 {
884 if (s1 == NULL && s2 == NULL)
885 return TRUE;
886 else if (s1 == NULL || s2 == NULL)
887 return FALSE;
888 else
889 return strcmp(s1, s2) == 0 ? TRUE : FALSE;
890 }
891
892 /* HTS_ModelSet_load: load model set */
HTS_ModelSet_load(HTS_ModelSet * ms,char ** voices,size_t num_voices)893 HTS_Boolean HTS_ModelSet_load(HTS_ModelSet * ms, char **voices, size_t num_voices)
894 {
895 size_t i, j, k, s, e;
896 HTS_Boolean error = FALSE;
897 HTS_File *fp = NULL;
898 char buff1[HTS_MAXBUFLEN];
899 char buff2[HTS_MAXBUFLEN];
900 size_t matched_size;
901
902 char **stream_type_list = NULL;
903
904 size_t *vector_length = NULL;
905 HTS_Boolean *is_msd = NULL;
906 size_t *num_windows = NULL;
907 HTS_Boolean *use_gv = NULL;
908
909 char *gv_off_context = NULL;
910
911 /* temporary values */
912 char *temp_hts_voice_version;
913 size_t temp_sampling_frequency;
914 size_t temp_frame_period;
915 size_t temp_num_states;
916 size_t temp_num_streams;
917 char *temp_stream_type;
918 char *temp_fullcontext_format;
919 char *temp_fullcontext_version;
920
921 char *temp_gv_off_context;
922
923 size_t *temp_vector_length;
924 HTS_Boolean *temp_is_msd;
925 size_t *temp_num_windows;
926 HTS_Boolean *temp_use_gv;
927 char **temp_option;
928
929 char *temp_duration_pdf;
930 char *temp_duration_tree;
931 char ***temp_stream_win;
932 char **temp_stream_pdf;
933 char **temp_stream_tree;
934 char **temp_gv_pdf;
935 char **temp_gv_tree;
936
937 long start_of_data;
938 HTS_File *pdf_fp = NULL;
939 HTS_File *tree_fp = NULL;
940 HTS_File **win_fp = NULL;
941 HTS_File *gv_off_context_fp = NULL;
942
943 HTS_ModelSet_clear(ms);
944
945 if (ms == NULL || voices == NULL || num_voices < 1)
946 return FALSE;
947
948 ms->num_voices = num_voices;
949
950 for (i = 0; i < num_voices && error == FALSE; i++) {
951 /* open file */
952 fp = HTS_fopen_from_fn(voices[i], "rb");
953 if (fp == NULL) {
954 error = TRUE;
955 break;
956 }
957 /* reset GLOBAL options */
958 temp_hts_voice_version = NULL;
959 temp_sampling_frequency = 0;
960 temp_frame_period = 0;
961 temp_num_states = 0;
962 temp_num_streams = 0;
963 temp_stream_type = NULL;
964 temp_fullcontext_format = NULL;
965 temp_fullcontext_version = NULL;
966 temp_gv_off_context = NULL;
967 if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) {
968 error = TRUE;
969 break;
970 }
971 /* load GLOBAL options */
972 if (HTS_strequal(buff1, "[GLOBAL]") != TRUE) {
973 error = TRUE;
974 break;
975 }
976 while (1) {
977 if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) {
978 error = TRUE;
979 break;
980 }
981 if (HTS_strequal(buff1, "[STREAM]") == TRUE) {
982 break;
983 } else if (HTS_match_head_string(buff1, "HTS_VOICE_VERSION:", &matched_size) == TRUE) {
984 if (temp_hts_voice_version != NULL)
985 free(temp_hts_voice_version);
986 temp_hts_voice_version = HTS_strdup(&buff1[matched_size]);
987 } else if (HTS_match_head_string(buff1, "SAMPLING_FREQUENCY:", &matched_size) == TRUE) {
988 temp_sampling_frequency = (size_t) atoi(&buff1[matched_size]);
989 } else if (HTS_match_head_string(buff1, "FRAME_PERIOD:", &matched_size) == TRUE) {
990 temp_frame_period = (size_t) atoi(&buff1[matched_size]);
991 } else if (HTS_match_head_string(buff1, "NUM_STATES:", &matched_size) == TRUE) {
992 temp_num_states = (size_t) atoi(&buff1[matched_size]);
993 } else if (HTS_match_head_string(buff1, "NUM_STREAMS:", &matched_size) == TRUE) {
994 temp_num_streams = (size_t) atoi(&buff1[matched_size]);
995 } else if (HTS_match_head_string(buff1, "STREAM_TYPE:", &matched_size) == TRUE) {
996 if (temp_stream_type != NULL)
997 free(temp_stream_type);
998 temp_stream_type = HTS_strdup(&buff1[matched_size]);
999 } else if (HTS_match_head_string(buff1, "FULLCONTEXT_FORMAT:", &matched_size) == TRUE) {
1000 if (temp_fullcontext_format != NULL)
1001 free(temp_fullcontext_format);
1002 temp_fullcontext_format = HTS_strdup(&buff1[matched_size]);
1003 } else if (HTS_match_head_string(buff1, "FULLCONTEXT_VERSION:", &matched_size) == TRUE) {
1004 if (temp_fullcontext_version != NULL)
1005 free(temp_fullcontext_version);
1006 temp_fullcontext_version = HTS_strdup(&buff1[matched_size]);
1007 } else if (HTS_match_head_string(buff1, "GV_OFF_CONTEXT:", &matched_size) == TRUE) {
1008 if (temp_gv_off_context != NULL)
1009 free(temp_gv_off_context);
1010 temp_gv_off_context = HTS_strdup(&buff1[matched_size]);
1011 } else if (HTS_match_head_string(buff1, "COMMENT:", &matched_size) == TRUE) {
1012 } else {
1013 HTS_error(0, "HTS_ModelSet_load: Unknown option %s.\n", buff1);
1014 }
1015 }
1016 /* check GLOBAL options */
1017 if (i == 0) {
1018 ms->hts_voice_version = temp_hts_voice_version;
1019 ms->sampling_frequency = temp_sampling_frequency;
1020 ms->frame_period = temp_frame_period;
1021 ms->num_states = temp_num_states;
1022 ms->num_streams = temp_num_streams;
1023 ms->stream_type = temp_stream_type;
1024 ms->fullcontext_format = temp_fullcontext_format;
1025 ms->fullcontext_version = temp_fullcontext_version;
1026 gv_off_context = temp_gv_off_context;
1027 } else {
1028 if (HTS_strequal(ms->hts_voice_version, temp_hts_voice_version) != TRUE)
1029 error = TRUE;
1030 if (ms->sampling_frequency != temp_sampling_frequency)
1031 error = TRUE;
1032 if (ms->frame_period != temp_frame_period)
1033 error = TRUE;
1034 if (ms->num_states != temp_num_states)
1035 error = TRUE;
1036 if (ms->num_streams != temp_num_streams)
1037 error = TRUE;
1038 if (HTS_strequal(ms->stream_type, temp_stream_type) != TRUE)
1039 error = TRUE;
1040 if (HTS_strequal(ms->fullcontext_format, temp_fullcontext_format) != TRUE)
1041 error = TRUE;
1042 if (HTS_strequal(ms->fullcontext_version, temp_fullcontext_version) != TRUE)
1043 error = TRUE;
1044 if (HTS_strequal(gv_off_context, temp_gv_off_context) != TRUE)
1045 error = TRUE;
1046 if (temp_hts_voice_version != NULL)
1047 free(temp_hts_voice_version);
1048 if (temp_stream_type != NULL)
1049 free(temp_stream_type);
1050 if (temp_fullcontext_format != NULL)
1051 free(temp_fullcontext_format);
1052 if (temp_fullcontext_version != NULL)
1053 free(temp_fullcontext_version);
1054 if (temp_gv_off_context != NULL)
1055 free(temp_gv_off_context);
1056 }
1057 /* find stream names */
1058 if (i == 0) {
1059 stream_type_list = (char **) HTS_calloc(ms->num_streams, sizeof(char *));
1060 for (j = 0, matched_size = 0; j < ms->num_streams; j++) {
1061 if (HTS_get_token_from_string_with_separator(ms->stream_type, &matched_size, buff2, ',') == TRUE) {
1062 stream_type_list[j] = HTS_strdup(buff2);
1063 } else {
1064 stream_type_list[j] = NULL;
1065 error = TRUE;
1066 }
1067 }
1068 }
1069 if (error != FALSE) {
1070 if (fp != NULL) {
1071 HTS_fclose(fp);
1072 fp = NULL;
1073 }
1074 break;
1075 }
1076 /* reset STREAM options */
1077 temp_vector_length = (size_t *) HTS_calloc(ms->num_streams, sizeof(size_t));
1078 for (j = 0; j < ms->num_streams; j++)
1079 temp_vector_length[j] = 0;
1080 temp_is_msd = (HTS_Boolean *) HTS_calloc(ms->num_streams, sizeof(HTS_Boolean));
1081 for (j = 0; j < ms->num_streams; j++)
1082 temp_is_msd[j] = FALSE;
1083 temp_num_windows = (size_t *) HTS_calloc(ms->num_streams, sizeof(size_t));
1084 for (j = 0; j < ms->num_streams; j++)
1085 temp_num_windows[j] = 0;
1086 temp_use_gv = (HTS_Boolean *) HTS_calloc(ms->num_streams, sizeof(HTS_Boolean));
1087 for (j = 0; j < ms->num_streams; j++)
1088 temp_use_gv[j] = FALSE;
1089 temp_option = (char **) HTS_calloc(ms->num_streams, sizeof(char *));
1090 for (j = 0; j < ms->num_streams; j++)
1091 temp_option[j] = NULL;
1092 /* load STREAM options */
1093 while (1) {
1094 if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) {
1095 error = TRUE;
1096 break;
1097 }
1098 if (strcmp(buff1, "[POSITION]") == 0) {
1099 break;
1100 } else if (HTS_match_head_string(buff1, "VECTOR_LENGTH[", &matched_size) == TRUE) {
1101 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1102 if (buff1[matched_size++] == ':') {
1103 for (j = 0; j < ms->num_streams; j++)
1104 if (strcmp(stream_type_list[j], buff2) == 0) {
1105 temp_vector_length[j] = (size_t) atoi(&buff1[matched_size]);
1106 break;
1107 }
1108 }
1109 }
1110 } else if (HTS_match_head_string(buff1, "IS_MSD[", &matched_size) == TRUE) {
1111 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1112 if (buff1[matched_size++] == ':') {
1113 for (j = 0; j < ms->num_streams; j++)
1114 if (strcmp(stream_type_list[j], buff2) == 0) {
1115 temp_is_msd[j] = (buff1[matched_size] == '1') ? TRUE : FALSE;
1116 break;
1117 }
1118 }
1119 }
1120 } else if (HTS_match_head_string(buff1, "NUM_WINDOWS[", &matched_size) == TRUE) {
1121 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1122 if (buff1[matched_size++] == ':') {
1123 for (j = 0; j < ms->num_streams; j++)
1124 if (strcmp(stream_type_list[j], buff2) == 0) {
1125 temp_num_windows[j] = (size_t) atoi(&buff1[matched_size]);
1126 break;
1127 }
1128 }
1129 }
1130 } else if (HTS_match_head_string(buff1, "USE_GV[", &matched_size) == TRUE) {
1131 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1132 if (buff1[matched_size++] == ':') {
1133 for (j = 0; j < ms->num_streams; j++)
1134 if (strcmp(stream_type_list[j], buff2) == 0) {
1135 temp_use_gv[j] = (buff1[matched_size] == '1') ? TRUE : FALSE;
1136 break;
1137 }
1138 }
1139 }
1140 } else if (HTS_match_head_string(buff1, "OPTION[", &matched_size) == TRUE) {
1141 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1142 if (buff1[matched_size++] == ':') {
1143 for (j = 0; j < ms->num_streams; j++)
1144 if (strcmp(stream_type_list[j], buff2) == 0) {
1145 if (temp_option[j] != NULL)
1146 free(temp_option[j]);
1147 temp_option[j] = HTS_strdup(&buff1[matched_size]);
1148 break;
1149 }
1150 }
1151 }
1152 } else {
1153 HTS_error(0, "HTS_ModelSet_load: Unknown option %s.\n", buff1);
1154 }
1155 }
1156 /* check STREAM options */
1157 if (i == 0) {
1158 vector_length = temp_vector_length;
1159 is_msd = temp_is_msd;
1160 num_windows = temp_num_windows;
1161 use_gv = temp_use_gv;
1162 ms->option = temp_option;
1163 } else {
1164 for (j = 0; j < ms->num_streams; j++)
1165 if (vector_length[j] != temp_vector_length[j])
1166 error = TRUE;
1167 for (j = 0; j < ms->num_streams; j++)
1168 if (is_msd[j] != is_msd[j])
1169 error = TRUE;
1170 for (j = 0; j < ms->num_streams; j++)
1171 if (num_windows[j] != temp_num_windows[j])
1172 error = TRUE;
1173 for (j = 0; j < ms->num_streams; j++)
1174 if (use_gv[j] != temp_use_gv[j])
1175 error = TRUE;
1176 for (j = 0; j < ms->num_streams; j++)
1177 if (HTS_strequal(ms->option[j], temp_option[j]) != TRUE)
1178 error = TRUE;
1179 free(temp_vector_length);
1180 free(temp_is_msd);
1181 free(temp_num_windows);
1182 free(temp_use_gv);
1183 for (j = 0; j < ms->num_streams; j++)
1184 if (temp_option[j] != NULL)
1185 free(temp_option[j]);
1186 free(temp_option);
1187 }
1188 if (error != FALSE) {
1189 if (fp != NULL) {
1190 HTS_fclose(fp);
1191 fp = NULL;
1192 }
1193 break;
1194 }
1195 /* reset POSITION */
1196 temp_duration_pdf = NULL;
1197 temp_duration_tree = NULL;
1198 temp_stream_win = (char ***) HTS_calloc(ms->num_streams, sizeof(char **));
1199 for (j = 0; j < ms->num_streams; j++) {
1200 temp_stream_win[j] = (char **) HTS_calloc(num_windows[j], sizeof(char *));
1201 for (k = 0; k < num_windows[j]; k++)
1202 temp_stream_win[j][k] = NULL;
1203 }
1204 temp_stream_pdf = (char **) HTS_calloc(ms->num_streams, sizeof(char *));
1205 for (j = 0; j < ms->num_streams; j++)
1206 temp_stream_pdf[j] = NULL;
1207 temp_stream_tree = (char **) HTS_calloc(ms->num_streams, sizeof(char *));
1208 for (j = 0; j < ms->num_streams; j++)
1209 temp_stream_tree[j] = NULL;
1210 temp_gv_pdf = (char **) HTS_calloc(ms->num_streams, sizeof(char *));
1211 for (j = 0; j < ms->num_streams; j++)
1212 temp_gv_pdf[j] = NULL;
1213 temp_gv_tree = (char **) HTS_calloc(ms->num_streams, sizeof(char *));
1214 for (j = 0; j < ms->num_streams; j++)
1215 temp_gv_tree[j] = NULL;
1216 /* load POSITION */
1217 while (1) {
1218 if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) {
1219 error = TRUE;
1220 break;
1221 }
1222 if (strcmp(buff1, "[DATA]") == 0) {
1223 break;
1224 } else if (HTS_match_head_string(buff1, "DURATION_PDF:", &matched_size) == TRUE) {
1225 if (temp_duration_pdf != NULL)
1226 free(temp_duration_pdf);
1227 temp_duration_pdf = HTS_strdup(&buff1[matched_size]);
1228 } else if (HTS_match_head_string(buff1, "DURATION_TREE:", &matched_size) == TRUE) {
1229 if (temp_duration_tree != NULL)
1230 free(temp_duration_tree);
1231 temp_duration_tree = HTS_strdup(&buff1[matched_size]);
1232 } else if (HTS_match_head_string(buff1, "STREAM_WIN[", &matched_size) == TRUE) {
1233 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1234 if (buff1[matched_size++] == ':') {
1235 for (j = 0; j < ms->num_streams; j++) {
1236 if (strcmp(stream_type_list[j], buff2) == 0) {
1237 for (k = 0; k < num_windows[j]; k++) {
1238 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ',') == TRUE)
1239 temp_stream_win[j][k] = HTS_strdup(buff2);
1240 else
1241 error = TRUE;
1242 }
1243 break;
1244 }
1245 }
1246 }
1247 }
1248 } else if (HTS_match_head_string(buff1, "STREAM_PDF[", &matched_size) == TRUE) {
1249 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1250 if (buff1[matched_size++] == ':') {
1251 for (j = 0; j < ms->num_streams; j++) {
1252 if (strcmp(stream_type_list[j], buff2) == 0) {
1253 if (temp_stream_pdf[j] != NULL)
1254 free(temp_stream_pdf[j]);
1255 temp_stream_pdf[j] = HTS_strdup(&buff1[matched_size]);
1256 break;
1257 }
1258 }
1259 }
1260 }
1261 } else if (HTS_match_head_string(buff1, "STREAM_TREE[", &matched_size) == TRUE) {
1262 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1263 if (buff1[matched_size++] == ':') {
1264 for (j = 0; j < ms->num_streams; j++) {
1265 if (strcmp(stream_type_list[j], buff2) == 0) {
1266 if (temp_stream_tree[j] != NULL)
1267 free(temp_stream_tree[j]);
1268 temp_stream_tree[j] = HTS_strdup(&buff1[matched_size]);
1269 break;
1270 }
1271 }
1272 }
1273 }
1274 } else if (HTS_match_head_string(buff1, "GV_PDF[", &matched_size) == TRUE) {
1275 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1276 if (buff1[matched_size++] == ':') {
1277 for (j = 0; j < ms->num_streams; j++) {
1278 if (strcmp(stream_type_list[j], buff2) == 0) {
1279 if (temp_gv_pdf[j] != NULL)
1280 free(temp_gv_pdf[j]);
1281 temp_gv_pdf[j] = HTS_strdup(&buff1[matched_size]);
1282 break;
1283 }
1284 }
1285 }
1286 }
1287 } else if (HTS_match_head_string(buff1, "GV_TREE[", &matched_size) == TRUE) {
1288 if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) {
1289 if (buff1[matched_size++] == ':') {
1290 for (j = 0; j < ms->num_streams; j++) {
1291 if (strcmp(stream_type_list[j], buff2) == 0) {
1292 if (temp_gv_tree[j] != NULL)
1293 free(temp_gv_tree[j]);
1294 temp_gv_tree[j] = HTS_strdup(&buff1[matched_size]);
1295 break;
1296 }
1297 }
1298 }
1299 }
1300 } else {
1301 HTS_error(0, "HTS_ModelSet_load: Unknown option %s.\n", buff1);
1302 }
1303 }
1304 /* check POSITION */
1305 if (temp_duration_pdf == NULL)
1306 error = TRUE;
1307 for (j = 0; j < ms->num_streams; j++)
1308 for (k = 0; k < num_windows[j]; k++)
1309 if (temp_stream_win[j][k] == NULL)
1310 error = TRUE;
1311 for (j = 0; j < ms->num_streams; j++)
1312 if (temp_stream_pdf[j] == NULL)
1313 error = TRUE;
1314 /* prepare memory */
1315 if (i == 0) {
1316 ms->duration = (HTS_Model *) HTS_calloc(num_voices, sizeof(HTS_Model));
1317 for (j = 0; j < num_voices; j++)
1318 HTS_Model_initialize(&ms->duration[j]);
1319 ms->window = (HTS_Window *) HTS_calloc(ms->num_streams, sizeof(HTS_Window));
1320 for (j = 0; j < ms->num_streams; j++)
1321 HTS_Window_initialize(&ms->window[j]);
1322 ms->stream = (HTS_Model **) HTS_calloc(num_voices, sizeof(HTS_Model *));
1323 for (j = 0; j < num_voices; j++) {
1324 ms->stream[j] = (HTS_Model *) HTS_calloc(ms->num_streams, sizeof(HTS_Model));
1325 for (k = 0; k < ms->num_streams; k++)
1326 HTS_Model_initialize(&ms->stream[j][k]);
1327 }
1328 ms->gv = (HTS_Model **) HTS_calloc(num_voices, sizeof(HTS_Model *));
1329 for (j = 0; j < num_voices; j++) {
1330 ms->gv[j] = (HTS_Model *) HTS_calloc(ms->num_streams, sizeof(HTS_Model));
1331 for (k = 0; k < ms->num_streams; k++)
1332 HTS_Model_initialize(&ms->gv[j][k]);
1333 }
1334 }
1335 start_of_data = HTS_ftell(fp);
1336 /* load duration */
1337 pdf_fp = NULL;
1338 tree_fp = NULL;
1339 matched_size = 0;
1340 if (HTS_get_token_from_string_with_separator(temp_duration_pdf, &matched_size, buff2, '-') == TRUE) {
1341 s = (size_t) atoi(buff2);
1342 e = (size_t) atoi(&temp_duration_pdf[matched_size]);
1343 HTS_fseek(fp, (long) s, SEEK_CUR);
1344 pdf_fp = HTS_fopen_from_fp(fp, e - s + 1);
1345 HTS_fseek(fp, start_of_data, SEEK_SET);
1346 }
1347 matched_size = 0;
1348 if (HTS_get_token_from_string_with_separator(temp_duration_tree, &matched_size, buff2, '-') == TRUE) {
1349 s = (size_t) atoi(buff2);
1350 e = (size_t) atoi(&temp_duration_tree[matched_size]);
1351 HTS_fseek(fp, (long) s, SEEK_CUR);
1352 tree_fp = HTS_fopen_from_fp(fp, e - s + 1);
1353 HTS_fseek(fp, start_of_data, SEEK_SET);
1354 }
1355 if (HTS_Model_load(&ms->duration[i], pdf_fp, tree_fp, ms->num_states, 1, FALSE) != TRUE)
1356 error = TRUE;
1357 HTS_fclose(pdf_fp);
1358 HTS_fclose(tree_fp);
1359 /* load windows */
1360 for (j = 0; j < ms->num_streams; j++) {
1361 win_fp = (HTS_File **) HTS_calloc(num_windows[j], sizeof(HTS_File *));
1362 for (k = 0; k < num_windows[j]; k++)
1363 win_fp[k] = NULL;
1364 for (k = 0; k < num_windows[j]; k++) {
1365 matched_size = 0;
1366 if (HTS_get_token_from_string_with_separator(temp_stream_win[j][k], &matched_size, buff2, '-') == TRUE) {
1367 s = (size_t) atoi(buff2);
1368 e = (size_t) atoi(&temp_stream_win[j][k][matched_size]);
1369 HTS_fseek(fp, (long) s, SEEK_CUR);
1370 win_fp[k] = HTS_fopen_from_fp(fp, e - s + 1);
1371 HTS_fseek(fp, start_of_data, SEEK_SET);
1372 }
1373 }
1374 HTS_Window_clear(&ms->window[j]); /* if windows were loaded already, release them */
1375 if (HTS_Window_load(&ms->window[j], win_fp, num_windows[j]) != TRUE)
1376 error = TRUE;
1377 for (k = 0; k < num_windows[j]; k++)
1378 HTS_fclose(win_fp[k]);
1379 free(win_fp);
1380 }
1381 /* load streams */
1382 for (j = 0; j < ms->num_streams; j++) {
1383 pdf_fp = NULL;
1384 tree_fp = NULL;
1385 matched_size = 0;
1386 if (HTS_get_token_from_string_with_separator(temp_stream_pdf[j], &matched_size, buff2, '-') == TRUE) {
1387 s = (size_t) atoi(buff2);
1388 e = (size_t) atoi(&temp_stream_pdf[j][matched_size]);
1389 HTS_fseek(fp, (long) s, SEEK_CUR);
1390 pdf_fp = HTS_fopen_from_fp(fp, e - s + 1);
1391 HTS_fseek(fp, start_of_data, SEEK_SET);
1392 }
1393 matched_size = 0;
1394 if (HTS_get_token_from_string_with_separator(temp_stream_tree[j], &matched_size, buff2, '-') == TRUE) {
1395 s = (size_t) atoi(buff2);
1396 e = (size_t) atoi(&temp_stream_tree[j][matched_size]);
1397 HTS_fseek(fp, (long) s, SEEK_CUR);
1398 tree_fp = HTS_fopen_from_fp(fp, e - s + 1);
1399 HTS_fseek(fp, start_of_data, SEEK_SET);
1400 }
1401 if (HTS_Model_load(&ms->stream[i][j], pdf_fp, tree_fp, vector_length[j], num_windows[j], is_msd[j]) != TRUE)
1402 error = TRUE;
1403 HTS_fclose(pdf_fp);
1404 HTS_fclose(tree_fp);
1405 }
1406 /* load GVs */
1407 for (j = 0; j < ms->num_streams; j++) {
1408 pdf_fp = NULL;
1409 tree_fp = NULL;
1410 matched_size = 0;
1411 if (HTS_get_token_from_string_with_separator(temp_gv_pdf[j], &matched_size, buff2, '-') == TRUE) {
1412 s = (size_t) atoi(buff2);
1413 e = (size_t) atoi(&temp_gv_pdf[j][matched_size]);
1414 HTS_fseek(fp, (long) s, SEEK_CUR);
1415 pdf_fp = HTS_fopen_from_fp(fp, e - s + 1);
1416 HTS_fseek(fp, start_of_data, SEEK_SET);
1417 }
1418 matched_size = 0;
1419 if (HTS_get_token_from_string_with_separator(temp_gv_tree[j], &matched_size, buff2, '-') == TRUE) {
1420 s = (size_t) atoi(buff2);
1421 e = (size_t) atoi(&temp_gv_tree[j][matched_size]);
1422 HTS_fseek(fp, (long) s, SEEK_CUR);
1423 tree_fp = HTS_fopen_from_fp(fp, e - s + 1);
1424 HTS_fseek(fp, start_of_data, SEEK_SET);
1425 }
1426 if (use_gv[j] == TRUE) {
1427 if (HTS_Model_load(&ms->gv[i][j], pdf_fp, tree_fp, vector_length[j], 1, FALSE) != TRUE)
1428 error = TRUE;
1429 }
1430 HTS_fclose(pdf_fp);
1431 HTS_fclose(tree_fp);
1432 }
1433 /* free */
1434 if (temp_duration_pdf != NULL)
1435 free(temp_duration_pdf);
1436 if (temp_duration_tree != NULL)
1437 free(temp_duration_tree);
1438 for (j = 0; j < ms->num_streams; j++) {
1439 for (k = 0; k < num_windows[j]; k++)
1440 if (temp_stream_win[j][k] != NULL)
1441 free(temp_stream_win[j][k]);
1442 free(temp_stream_win[j]);
1443 }
1444 free(temp_stream_win);
1445 for (j = 0; j < ms->num_streams; j++)
1446 if (temp_stream_pdf[j] != NULL)
1447 free(temp_stream_pdf[j]);
1448 free(temp_stream_pdf);
1449 for (j = 0; j < ms->num_streams; j++)
1450 if (temp_stream_tree[j] != NULL)
1451 free(temp_stream_tree[j]);
1452 free(temp_stream_tree);
1453 for (j = 0; j < ms->num_streams; j++)
1454 if (temp_gv_pdf[j] != NULL)
1455 free(temp_gv_pdf[j]);
1456 free(temp_gv_pdf);
1457 for (j = 0; j < ms->num_streams; j++)
1458 if (temp_gv_tree[j] != NULL)
1459 free(temp_gv_tree[j]);
1460 free(temp_gv_tree);
1461 /* fclose */
1462 if (fp != NULL) {
1463 HTS_fclose(fp);
1464 fp = NULL;
1465 }
1466 if (error != FALSE)
1467 break;
1468 }
1469
1470 if (gv_off_context != NULL) {
1471 sprintf(buff1, "GV-Off { %s }", gv_off_context);
1472 gv_off_context_fp = HTS_fopen_from_data((void *) buff1, strlen(buff1) + 1);
1473 ms->gv_off_context = (HTS_Question *) HTS_calloc(1, sizeof(HTS_Question));
1474 HTS_Question_initialize(ms->gv_off_context);
1475 HTS_Question_load(ms->gv_off_context, gv_off_context_fp);
1476 HTS_fclose(gv_off_context_fp);
1477 free(gv_off_context);
1478 }
1479
1480 if (stream_type_list != NULL) {
1481 for (i = 0; i < ms->num_streams; i++)
1482 if (stream_type_list[i] != NULL)
1483 free(stream_type_list[i]);
1484 free(stream_type_list);
1485 }
1486
1487 if (vector_length != NULL)
1488 free(vector_length);
1489 if (is_msd != NULL)
1490 free(is_msd);
1491 if (num_windows != NULL)
1492 free(num_windows);
1493 if (use_gv != NULL)
1494 free(use_gv);
1495
1496 return !error;
1497 }
1498
1499 /* HTS_ModelSet_get_sampling_frequency: get sampling frequency of HTS voices */
HTS_ModelSet_get_sampling_frequency(HTS_ModelSet * ms)1500 size_t HTS_ModelSet_get_sampling_frequency(HTS_ModelSet * ms)
1501 {
1502 return ms->sampling_frequency;
1503 }
1504
1505 /* HTS_ModelSet_get_fperiod: get frame period of HTS voices */
HTS_ModelSet_get_fperiod(HTS_ModelSet * ms)1506 size_t HTS_ModelSet_get_fperiod(HTS_ModelSet * ms)
1507 {
1508 return ms->frame_period;
1509 }
1510
1511 /* HTS_ModelSet_get_fperiod: get stream option */
HTS_ModelSet_get_option(HTS_ModelSet * ms,size_t stream_index)1512 const char *HTS_ModelSet_get_option(HTS_ModelSet * ms, size_t stream_index)
1513 {
1514 return ms->option[stream_index];
1515 }
1516
1517 /* HTS_ModelSet_get_gv_flag: get GV flag */
HTS_ModelSet_get_gv_flag(HTS_ModelSet * ms,const char * string)1518 HTS_Boolean HTS_ModelSet_get_gv_flag(HTS_ModelSet * ms, const char *string)
1519 {
1520 if (ms->gv_off_context == NULL)
1521 return TRUE;
1522 else if (HTS_Question_match(ms->gv_off_context, string) == TRUE)
1523 return FALSE;
1524 else
1525 return TRUE;
1526 }
1527
1528 /* HTS_ModelSet_get_nstate: get number of state */
HTS_ModelSet_get_nstate(HTS_ModelSet * ms)1529 size_t HTS_ModelSet_get_nstate(HTS_ModelSet * ms)
1530 {
1531 return ms->num_states;
1532 }
1533
1534 /* HTS_Engine_get_fullcontext_label_format: get full-context label format */
HTS_ModelSet_get_fullcontext_label_format(HTS_ModelSet * ms)1535 const char *HTS_ModelSet_get_fullcontext_label_format(HTS_ModelSet * ms)
1536 {
1537 return ms->fullcontext_format;
1538 }
1539
1540 /* HTS_Engine_get_fullcontext_label_version: get full-context label version */
HTS_ModelSet_get_fullcontext_label_version(HTS_ModelSet * ms)1541 const char *HTS_ModelSet_get_fullcontext_label_version(HTS_ModelSet * ms)
1542 {
1543 return ms->fullcontext_version;
1544 }
1545
1546 /* HTS_ModelSet_get_nstream: get number of stream */
HTS_ModelSet_get_nstream(HTS_ModelSet * ms)1547 size_t HTS_ModelSet_get_nstream(HTS_ModelSet * ms)
1548 {
1549 return ms->num_streams;
1550 }
1551
1552 /* HTS_ModelSet_get_nvoices: get number of stream */
HTS_ModelSet_get_nvoices(HTS_ModelSet * ms)1553 size_t HTS_ModelSet_get_nvoices(HTS_ModelSet * ms)
1554 {
1555 return ms->num_voices;
1556 }
1557
1558 /* HTS_ModelSet_get_vector_length: get vector length */
HTS_ModelSet_get_vector_length(HTS_ModelSet * ms,size_t stream_index)1559 size_t HTS_ModelSet_get_vector_length(HTS_ModelSet * ms, size_t stream_index)
1560 {
1561 return ms->stream[0][stream_index].vector_length;
1562 }
1563
1564 /* HTS_ModelSet_is_msd: get MSD flag */
HTS_ModelSet_is_msd(HTS_ModelSet * ms,size_t stream_index)1565 HTS_Boolean HTS_ModelSet_is_msd(HTS_ModelSet * ms, size_t stream_index)
1566 {
1567 return ms->stream[0][stream_index].is_msd;
1568 }
1569
1570 /* HTS_ModelSet_get_window_size: get dynamic window size */
HTS_ModelSet_get_window_size(HTS_ModelSet * ms,size_t stream_index)1571 size_t HTS_ModelSet_get_window_size(HTS_ModelSet * ms, size_t stream_index)
1572 {
1573 return ms->window[stream_index].size;
1574 }
1575
1576 /* HTS_ModelSet_get_window_left_width: get left width of dynamic window */
HTS_ModelSet_get_window_left_width(HTS_ModelSet * ms,size_t stream_index,size_t window_index)1577 int HTS_ModelSet_get_window_left_width(HTS_ModelSet * ms, size_t stream_index, size_t window_index)
1578 {
1579 return ms->window[stream_index].l_width[window_index];
1580 }
1581
1582 /* HTS_ModelSet_get_window_right_width: get right width of dynamic window */
HTS_ModelSet_get_window_right_width(HTS_ModelSet * ms,size_t stream_index,size_t window_index)1583 int HTS_ModelSet_get_window_right_width(HTS_ModelSet * ms, size_t stream_index, size_t window_index)
1584 {
1585 return ms->window[stream_index].r_width[window_index];
1586 }
1587
1588 /* HTS_ModelSet_get_window_coefficient: get coefficient of dynamic window */
HTS_ModelSet_get_window_coefficient(HTS_ModelSet * ms,size_t stream_index,size_t window_index,size_t coefficient_index)1589 double HTS_ModelSet_get_window_coefficient(HTS_ModelSet * ms, size_t stream_index, size_t window_index, size_t coefficient_index)
1590 {
1591 return ms->window[stream_index].coefficient[window_index][coefficient_index];
1592 }
1593
1594 /* HTS_ModelSet_get_window_max_width: get max width of dynamic window */
HTS_ModelSet_get_window_max_width(HTS_ModelSet * ms,size_t stream_index)1595 size_t HTS_ModelSet_get_window_max_width(HTS_ModelSet * ms, size_t stream_index)
1596 {
1597 return ms->window[stream_index].max_width;
1598 }
1599
1600 /* HTS_ModelSet_use_gv: get GV flag */
HTS_ModelSet_use_gv(HTS_ModelSet * ms,size_t stream_index)1601 HTS_Boolean HTS_ModelSet_use_gv(HTS_ModelSet * ms, size_t stream_index)
1602 {
1603 if (ms->gv[0][stream_index].vector_length != 0)
1604 return TRUE;
1605 else
1606 return FALSE;
1607 }
1608
1609 /* HTS_Model_add_parameter: get parameter using interpolation weight */
HTS_Model_add_parameter(HTS_Model * model,size_t state_index,const char * string,double * mean,double * vari,double * msd,double weight)1610 static void HTS_Model_add_parameter(HTS_Model * model, size_t state_index, const char *string, double *mean, double *vari, double *msd, double weight)
1611 {
1612 size_t i;
1613 size_t tree_index, pdf_index;
1614 size_t len = model->vector_length * model->num_windows;
1615
1616 HTS_Model_get_index(model, state_index, string, &tree_index, &pdf_index);
1617 for (i = 0; i < len; i++) {
1618 mean[i] += weight * model->pdf[tree_index][pdf_index][i];
1619 vari[i] += weight * model->pdf[tree_index][pdf_index][i + len];
1620 }
1621 if (msd != NULL && model->is_msd == TRUE)
1622 *msd += weight * model->pdf[tree_index][pdf_index][len + len];
1623 }
1624
1625 /* HTS_ModelSet_get_duration_index: get duration PDF & tree index */
HTS_ModelSet_get_duration_index(HTS_ModelSet * ms,size_t voice_index,const char * string,size_t * tree_index,size_t * pdf_index)1626 void HTS_ModelSet_get_duration_index(HTS_ModelSet * ms, size_t voice_index, const char *string, size_t * tree_index, size_t * pdf_index)
1627 {
1628 HTS_Model_get_index(&ms->duration[voice_index], 2, string, tree_index, pdf_index);
1629 }
1630
1631 /* HTS_ModelSet_get_duration: get duration using interpolation weight */
HTS_ModelSet_get_duration(HTS_ModelSet * ms,const char * string,const double * iw,double * mean,double * vari)1632 void HTS_ModelSet_get_duration(HTS_ModelSet * ms, const char *string, const double *iw, double *mean, double *vari)
1633 {
1634 size_t i;
1635 size_t len = ms->num_states;
1636
1637 for (i = 0; i < len; i++) {
1638 mean[i] = 0.0;
1639 vari[i] = 0.0;
1640 }
1641 for (i = 0; i < ms->num_voices; i++)
1642 if (iw[i] != 0.0)
1643 HTS_Model_add_parameter(&ms->duration[i], 2, string, mean, vari, NULL, iw[i]);
1644 }
1645
1646 /* HTS_ModelSet_get_parameter_index: get paramter PDF & tree index */
HTS_ModelSet_get_parameter_index(HTS_ModelSet * ms,size_t voice_index,size_t stream_index,size_t state_index,const char * string,size_t * tree_index,size_t * pdf_index)1647 void HTS_ModelSet_get_parameter_index(HTS_ModelSet * ms, size_t voice_index, size_t stream_index, size_t state_index, const char *string, size_t * tree_index, size_t * pdf_index)
1648 {
1649 HTS_Model_get_index(&ms->stream[voice_index][stream_index], state_index, string, tree_index, pdf_index);
1650 }
1651
1652 /* HTS_ModelSet_get_parameter: get parameter using interpolation weight */
HTS_ModelSet_get_parameter(HTS_ModelSet * ms,size_t stream_index,size_t state_index,const char * string,const double * const * iw,double * mean,double * vari,double * msd)1653 void HTS_ModelSet_get_parameter(HTS_ModelSet * ms, size_t stream_index, size_t state_index, const char *string, const double *const *iw, double *mean, double *vari, double *msd)
1654 {
1655 size_t i;
1656 size_t len = ms->stream[0][stream_index].vector_length * ms->stream[0][stream_index].num_windows;
1657
1658 for (i = 0; i < len; i++) {
1659 mean[i] = 0.0;
1660 vari[i] = 0.0;
1661 }
1662 if (msd != NULL)
1663 *msd = 0.0;
1664
1665 for (i = 0; i < ms->num_voices; i++)
1666 if (iw[i][stream_index] != 0.0)
1667 HTS_Model_add_parameter(&ms->stream[i][stream_index], state_index, string, mean, vari, msd, iw[i][stream_index]);
1668 }
1669
1670 /* HTS_ModelSet_get_gv_index: get gv PDF & tree index */
HTS_ModelSet_get_gv_index(HTS_ModelSet * ms,size_t voice_index,size_t stream_index,const char * string,size_t * tree_index,size_t * pdf_index)1671 void HTS_ModelSet_get_gv_index(HTS_ModelSet * ms, size_t voice_index, size_t stream_index, const char *string, size_t * tree_index, size_t * pdf_index)
1672 {
1673 HTS_Model_get_index(&ms->gv[voice_index][stream_index], 2, string, tree_index, pdf_index);
1674 }
1675
1676 /* HTS_ModelSet_get_gv: get GV using interpolation weight */
HTS_ModelSet_get_gv(HTS_ModelSet * ms,size_t stream_index,const char * string,const double * const * iw,double * mean,double * vari)1677 void HTS_ModelSet_get_gv(HTS_ModelSet * ms, size_t stream_index, const char *string, const double *const *iw, double *mean, double *vari)
1678 {
1679 size_t i;
1680 size_t len = ms->stream[0][stream_index].vector_length;
1681
1682 for (i = 0; i < len; i++) {
1683 mean[i] = 0.0;
1684 vari[i] = 0.0;
1685 }
1686 for (i = 0; i < ms->num_voices; i++)
1687 if (iw[i][stream_index] != 0.0)
1688 HTS_Model_add_parameter(&ms->gv[i][stream_index], 2, string, mean, vari, NULL, iw[i][stream_index]);
1689 }
1690
1691 HTS_MODEL_C_END;
1692
1693 #endif /* !HTS_MODEL_C */
1694