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