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