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