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-2011  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 HTS106_MODEL_C
46 #define HTS106_MODEL_C
47 
48 #ifdef __cplusplus
49 #define HTS106_MODEL_C_START extern "C" {
50 #define HTS106_MODEL_C_END   }
51 #else
52 #define HTS106_MODEL_C_START
53 #define HTS106_MODEL_C_END
54 #endif                          /* __CPLUSPLUS */
55 
56 HTS106_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 "HTS106_hidden.h"
64 
65 /* HTS106_dp_match: recursive matching */
66 static HTS106_Boolean HTS106_dp_match(const char *string, const char *pattern, const int pos, const int max)
67 {
68    if (pos > max)
69       return FALSE;
70    if (string[0] == '\0' && pattern[0] == '\0')
71       return TRUE;
72    if (pattern[0] == '*') {
73       if (HTS106_dp_match(string + 1, pattern, pos + 1, max) == 1)
74          return TRUE;
75       else
76          return HTS106_dp_match(string, pattern + 1, pos, max);
77    }
78    if (string[0] == pattern[0] || pattern[0] == '?') {
79       if (HTS106_dp_match(string + 1, pattern + 1, pos + 1, max + 1) == 1)
80          return TRUE;
81    }
82 
83    return FALSE;
84 }
85 
86 /* HTS106_pattern_match: pattern matching function */
87 static HTS106_Boolean HTS106_pattern_match(const char *string, const char *pattern)
88 {
89    int i, j;
90    int buff_length, max = 0, nstar = 0, nquestion = 0;
91    char buff[HTS106_MAXBUFLEN];
92    const int pattern_length = strlen(pattern);
93 
94    for (i = 0; i < pattern_length; i++) {
95       switch (pattern[i]) {
96       case '*':
97          nstar++;
98          break;
99       case '?':
100          nquestion++;
101          max++;
102          break;
103       default:
104          max++;
105       }
106    }
107    if (nstar == 2 && nquestion == 0 && pattern[0] == '*' && pattern[i - 1] == '*') {
108       /* only string matching is required */
109       buff_length = i - 2;
110       for (i = 0, j = 1; i < buff_length; i++, j++)
111          buff[i] = pattern[j];
112       buff[buff_length] = '\0';
113       if (strstr(string, buff) != NULL)
114          return TRUE;
115       else
116          return FALSE;
117    } else
118       return HTS106_dp_match(string, pattern, 0, (int) (strlen(string) - max));
119 }
120 
121 /* HTS106_is_num: check given buffer is number or not */
122 static HTS106_Boolean HTS106_is_num(const char *buff)
123 {
124    int i;
125    const int length = (int) strlen(buff);
126 
127    for (i = 0; i < length; i++)
128       if (!(isdigit((int) buff[i]) || (buff[i] == '-')))
129          return FALSE;
130 
131    return TRUE;
132 }
133 
134 /* HTS106_name2num: convert name of node to number */
135 static int HTS106_name2num(const char *buff)
136 {
137    int i;
138 
139    for (i = strlen(buff) - 1; '0' <= buff[i] && buff[i] <= '9' && i >= 0; i--);
140    i++;
141 
142    return atoi(&buff[i]);
143 }
144 
145 /* HTS106_get_state_num: return the number of state */
146 static int HTS106_get_state_num(char *string)
147 {
148    char *left, *right;
149 
150    if (((left = strchr(string, '[')) == NULL)
151        || ((right = strrchr(string, ']')) == NULL))
152       return 0;
153    *right = '\0';
154    string = left + 1;
155 
156    return atoi(string);
157 }
158 
159 static void HTS106_Question_clear(HTS106_Question * question);
160 
161 /* HTS106_Question_load: Load questions from file */
162 static HTS106_Boolean HTS106_Question_load(HTS106_Question * question, HTS106_File * fp)
163 {
164    char buff[HTS106_MAXBUFLEN];
165    HTS106_Pattern *pattern, *last_pattern;
166 
167    if (question == NULL || fp == NULL)
168       return FALSE;
169 
170    /* get question name */
171    if (HTS106_get_pattern_token(fp, buff) == FALSE)
172       return FALSE;
173    question->string = HTS106_strdup(buff);
174    question->head = NULL;
175    /* get pattern list */
176    if (HTS106_get_pattern_token(fp, buff) == FALSE) {
177       free(question->string);
178       question->string = NULL;
179       return FALSE;
180    }
181    last_pattern = NULL;
182    if (strcmp(buff, "{") == 0) {
183       while (1) {
184          if (HTS106_get_pattern_token(fp, buff) == FALSE) {
185             HTS106_Question_clear(question);
186             return FALSE;
187          }
188          pattern = (HTS106_Pattern *) HTS106_calloc(1, sizeof(HTS106_Pattern));
189          if (question->head)
190             last_pattern->next = pattern;
191          else                   /* first time */
192             question->head = pattern;
193          pattern->string = HTS106_strdup(buff);
194          pattern->next = NULL;
195          if (HTS106_get_pattern_token(fp, buff) == FALSE) {
196             HTS106_Question_clear(question);
197             return FALSE;
198          }
199          if (!strcmp(buff, "}"))
200             break;
201          last_pattern = pattern;
202       }
203    }
204    return TRUE;
205 }
206 
207 /* HTS106_Question_match: check given string match given question */
208 static HTS106_Boolean HTS106_Question_match(const HTS106_Question * question, const char *string, const RHVoice_parsed_label_string* parsed)
209 {
210    HTS106_Pattern *pattern;
211 
212    for (pattern = question->head; pattern; pattern = pattern->next) {
213      if(parsed!=NULL) {
214        if(RHVoice_question_match(parsed, pattern->string))
215          return TRUE;
216 }
217      else if (HTS106_pattern_match(string, pattern->string))
218          return TRUE;
219    }
220 
221    return FALSE;
222 }
223 
224 /* HTS106_Question_find_question: find question from question list */
225 static HTS106_Question *HTS106_Question_find_question(HTS106_Question * question, const char *buff)
226 {
227 
228    for (; question; question = question->next)
229       if (strcmp(buff, question->string) == 0)
230          return question;
231 
232    HTS106_error(1, "HTS106_Question_find_question: Cannot find question %s.\n", buff);
233    return NULL;                 /* make compiler happy */
234 }
235 
236 /* HTS106_Question_clear: clear loaded question */
237 static void HTS106_Question_clear(HTS106_Question * question)
238 {
239    HTS106_Pattern *pattern, *next_pattern;
240 
241    HTS106_free(question->string);
242    for (pattern = question->head; pattern; pattern = next_pattern) {
243       next_pattern = pattern->next;
244       HTS106_free(pattern->string);
245       HTS106_free(pattern);
246    }
247 }
248 
249 /* HTS106_Node_find: find node for given number */
250 static HTS106_Node *HTS106_Node_find(HTS106_Node * node, const int num)
251 {
252    for (; node; node = node->next)
253       if (node->index == num)
254          return node;
255 
256    HTS106_error(1, "HTS106_Node_find: Cannot find node %d.\n", num);
257    return NULL;                 /* make compiler happy */
258 }
259 
260 /* HTS106_Node_clear: recursive function to free Node */
261 static void HTS106_Node_clear(HTS106_Node * node)
262 {
263    if (node->yes != NULL)
264       HTS106_Node_clear(node->yes);
265    if (node->no != NULL)
266       HTS106_Node_clear(node->no);
267    HTS106_free(node);
268 }
269 
270 /* HTS106_Tree_parse_pattern: parse pattern specified for each tree */
271 static void HTS106_Tree_parse_pattern(HTS106_Tree * tree, char *string)
272 {
273    char *left, *right;
274    HTS106_Pattern *pattern, *last_pattern;
275 
276    tree->head = NULL;
277    last_pattern = NULL;
278    /* parse tree pattern */
279    if ((left = strchr(string, '{')) != NULL) {  /* pattern is specified */
280       string = left + 1;
281       if (*string == '(')
282          ++string;
283 
284       right = strrchr(string, '}');
285       if (string < right && *(right - 1) == ')')
286          --right;
287       *right = ',';
288 
289       /* parse pattern */
290       while ((left = strchr(string, ',')) != NULL) {
291          pattern = (HTS106_Pattern *) HTS106_calloc(1, sizeof(HTS106_Pattern));
292          if (tree->head) {
293             last_pattern->next = pattern;
294          } else {
295             tree->head = pattern;
296          }
297          *left = '\0';
298          pattern->string = HTS106_strdup(string);
299          string = left + 1;
300          pattern->next = NULL;
301          last_pattern = pattern;
302       }
303    }
304 }
305 
306 static void HTS106_Tree_clear(HTS106_Tree * tree);
307 
308 /* HTS106_Tree_load: Load trees */
309 static HTS106_Boolean HTS106_Tree_load(HTS106_Tree * tree, HTS106_File * fp, HTS106_Question * question)
310 {
311    char buff[HTS106_MAXBUFLEN];
312    HTS106_Node *node, *last_node;
313 
314    if (tree == NULL || fp == NULL)
315       return FALSE;
316 
317    if (HTS106_get_pattern_token(fp, buff) == FALSE) {
318       HTS106_Tree_clear(tree);
319       return FALSE;
320    }
321    node = (HTS106_Node *) HTS106_calloc(1, sizeof(HTS106_Node));
322    node->index = 0;
323    tree->root = last_node = node;
324 
325    if (strcmp(buff, "{") == 0) {
326       while (HTS106_get_pattern_token(fp, buff) == TRUE && strcmp(buff, "}") != 0) {
327          node = HTS106_Node_find(last_node, atoi(buff));
328          if (node == NULL) {
329             HTS106_Tree_clear(tree);
330             return FALSE;
331          }
332          if (HTS106_get_pattern_token(fp, buff) == FALSE) {
333             HTS106_Tree_clear(tree);
334             return FALSE;
335          }
336          node->quest = HTS106_Question_find_question(question, buff);
337          if (node->quest == NULL) {
338             HTS106_Tree_clear(tree);
339             return FALSE;
340          }
341          node->yes = (HTS106_Node *) HTS106_calloc(1, sizeof(HTS106_Node));
342          node->no = (HTS106_Node *) HTS106_calloc(1, sizeof(HTS106_Node));
343 
344          if (HTS106_get_pattern_token(fp, buff) == FALSE) {
345             node->quest = NULL;
346             free(node->yes);
347             free(node->no);
348             HTS106_Tree_clear(tree);
349             return FALSE;
350          }
351          if (HTS106_is_num(buff))
352             node->no->index = atoi(buff);
353          else
354             node->no->pdf = HTS106_name2num(buff);
355          node->no->next = last_node;
356          last_node = node->no;
357 
358          if (HTS106_get_pattern_token(fp, buff) == FALSE) {
359             node->quest = NULL;
360             free(node->yes);
361             free(node->no);
362             HTS106_Tree_clear(tree);
363             return FALSE;
364          }
365          if (HTS106_is_num(buff))
366             node->yes->index = atoi(buff);
367          else
368             node->yes->pdf = HTS106_name2num(buff);
369          node->yes->next = last_node;
370          last_node = node->yes;
371       }
372    } else {
373       node->pdf = HTS106_name2num(buff);
374    }
375 
376    return TRUE;
377 }
378 
379 /* HTS106_Node_search: tree search */
380 static int HTS106_Tree_search_node(HTS106_Tree * tree, const char *string, const RHVoice_parsed_label_string* parsed)
381 {
382    HTS106_Node *node = tree->root;
383 
384    while (node != NULL) {
385       if (node->quest == NULL)
386          return node->pdf;
387       if (HTS106_Question_match(node->quest, string, parsed)) {
388          if (node->yes->pdf > 0)
389             return node->yes->pdf;
390          node = node->yes;
391       } else {
392          if (node->no->pdf > 0)
393             return node->no->pdf;
394          node = node->no;
395       }
396    }
397 
398    HTS106_error(1, "HTS106_Tree_search_node: Cannot find node.\n");
399    return -1;                   /* make compiler happy */
400 }
401 
402 /* HTS106_Tree_clear: clear given tree */
403 static void HTS106_Tree_clear(HTS106_Tree * tree)
404 {
405    HTS106_Pattern *pattern, *next_pattern;
406 
407    for (pattern = tree->head; pattern; pattern = next_pattern) {
408       next_pattern = pattern->next;
409       HTS106_free(pattern->string);
410       HTS106_free(pattern);
411    }
412 
413    HTS106_Node_clear(tree->root);
414 }
415 
416 /* HTS106_Window_initialize: initialize dynamic window */
417 static void HTS106_Window_initialize(HTS106_Window * win)
418 {
419    win->size = 0;
420    win->l_width = NULL;
421    win->r_width = NULL;
422    win->coefficient = NULL;
423    win->max_width = 0;
424 }
425 
426 static void HTS106_Window_clear(HTS106_Window * win);
427 
428 /* HTS106_Window_load: load dynamic windows */
429 static HTS106_Boolean HTS106_Window_load(HTS106_Window * win, HTS106_File ** fp, int size)
430 {
431    int i, j;
432    int fsize, length;
433    char buff[HTS106_MAXBUFLEN];
434    HTS106_Boolean result = TRUE;
435 
436    /* check */
437    if (win == NULL || fp == NULL || size <= 0)
438       return FALSE;
439 
440    win->size = size;
441    win->l_width = (int *) HTS106_calloc(win->size, sizeof(int));
442    win->r_width = (int *) HTS106_calloc(win->size, sizeof(int));
443    win->coefficient = (double **) HTS106_calloc(win->size, sizeof(double *));
444    /* set delta coefficents */
445    for (i = 0; i < win->size; i++) {
446       if (HTS106_get_token(fp[i], buff) == FALSE) {
447          result = FALSE;
448          fsize = 1;
449       } else {
450          fsize = atoi(buff);
451          if (fsize <= 0) {
452             result = FALSE;
453             fsize = 1;
454          }
455       }
456       /* read coefficients */
457       win->coefficient[i] = (double *) HTS106_calloc(fsize, sizeof(double));
458       for (j = 0; j < fsize; j++) {
459          if (HTS106_get_token(fp[i], buff) == FALSE) {
460             result = FALSE;
461             win->coefficient[i][j] = 0.0;
462          } else {
463             win->coefficient[i][j] = (double) atof(buff);
464          }
465       }
466       /* set pointer */
467       length = fsize / 2;
468       win->coefficient[i] += length;
469       win->l_width[i] = -length;
470       win->r_width[i] = length;
471       if (fsize % 2 == 0)
472          win->r_width[i]--;
473    }
474    /* calcurate max_width to determine size of band matrix */
475    win->max_width = 0;
476    for (i = 0; i < win->size; i++) {
477       if (win->max_width < abs(win->l_width[i]))
478          win->max_width = abs(win->l_width[i]);
479       if (win->max_width < abs(win->r_width[i]))
480          win->max_width = abs(win->r_width[i]);
481    }
482 
483    if (result == FALSE) {
484       HTS106_Window_clear(win);
485       return FALSE;
486    }
487    return TRUE;
488 }
489 
490 /* HTS106_Window_clear: free dynamic window */
491 static void HTS106_Window_clear(HTS106_Window * win)
492 {
493    int i;
494 
495    if (win->coefficient) {
496       for (i = win->size - 1; i >= 0; i--) {
497          win->coefficient[i] += win->l_width[i];
498          HTS106_free(win->coefficient[i]);
499       }
500       HTS106_free(win->coefficient);
501    }
502    if (win->l_width)
503       HTS106_free(win->l_width);
504    if (win->r_width)
505       HTS106_free(win->r_width);
506 
507    HTS106_Window_initialize(win);
508 }
509 
510 /* HTS106_Model_initialize: initialize model */
511 static void HTS106_Model_initialize(HTS106_Model * model)
512 {
513    model->vector_length = 0;
514    model->ntree = 0;
515    model->npdf = NULL;
516    model->pdf = NULL;
517    model->tree = NULL;
518    model->question = NULL;
519 }
520 
521 static void HTS106_Model_clear(HTS106_Model * model);
522 
523 /* HTS106_Model_load_pdf: load pdfs */
524 static HTS106_Boolean HTS106_Model_load_pdf(HTS106_Model * model, HTS106_File * fp, int ntree, HTS106_Boolean msd_flag)
525 {
526    int i, j, k, l, m;
527    float temp;
528    int ssize;
529    HTS106_Boolean result = TRUE;
530 
531    /* check */
532    if (model == NULL || fp == NULL || ntree <= 0) {
533       HTS106_error(1, "HTS106_Model_load_pdf: File for pdfs is not specified.\n");
534       return FALSE;
535    }
536 
537    /* load pdf */
538    model->ntree = ntree;
539    /* read MSD flag */
540    HTS106_fread_big_endian(&i, sizeof(int), 1, fp);
541    if ((i != 0 || msd_flag != FALSE) && (i != 1 || msd_flag != TRUE)) {
542       HTS106_error(1, "HTS106_Model_load_pdf: Failed to load header of pdfs.\n");
543       HTS106_Model_initialize(model);
544       return FALSE;
545    }
546    /* read stream size */
547    HTS106_fread_big_endian(&ssize, sizeof(int), 1, fp);
548    if (ssize < 1) {
549       HTS106_error(1, "HTS106_Model_load_pdf: Failed to load header of pdfs.\n");
550       HTS106_Model_initialize(model);
551       return FALSE;
552    }
553    /* read vector size */
554    HTS106_fread_big_endian(&model->vector_length, sizeof(int), 1, fp);
555    if (model->vector_length <= 0) {
556       HTS106_error(1, "HTS106_Model_load_pdf: # of HMM states %d should be positive.\n", model->vector_length);
557       HTS106_Model_initialize(model);
558       return FALSE;
559    }
560    model->npdf = (int *) HTS106_calloc(ntree, sizeof(int));
561    model->npdf -= 2;
562    /* read the number of pdfs */
563    if (HTS106_fread_big_endian(&model->npdf[2], sizeof(int), ntree, fp) != ntree)
564       result = FALSE;
565    for (i = 2; i <= ntree + 1; i++)
566       if (model->npdf[i] <= 0) {
567          HTS106_error(1, "HTS106_Model_load_pdf: # of pdfs at %d-th state should be positive.\n", i);
568          result = FALSE;
569          break;
570       }
571    if (result == FALSE) {
572       model->npdf += 2;
573       free(model->npdf);
574       HTS106_Model_initialize(model);
575       return FALSE;
576    }
577    model->pdf = (double ***) HTS106_calloc(ntree, sizeof(double **));
578    model->pdf -= 2;
579    /* read means and variances */
580    if (msd_flag) {              /* for MSD */
581       for (j = 2; j <= ntree + 1; j++) {
582          model->pdf[j] = (double **) HTS106_calloc(model->npdf[j], sizeof(double *));
583          model->pdf[j]--;
584          for (k = 1; k <= model->npdf[j]; k++) {
585             model->pdf[j][k] = (double *) HTS106_calloc(2 * model->vector_length + 1, sizeof(double));
586             for (l = 0; l < ssize; l++) {
587                for (m = 0; m < model->vector_length / ssize; m++) {
588                   if (HTS106_fread_big_endian(&temp, sizeof(float), 1, fp) != 1)
589                      result = FALSE;
590                   model->pdf[j][k][l * model->vector_length / ssize + m] = (double) temp;
591                   if (HTS106_fread_big_endian(&temp, sizeof(float), 1, fp) != 1)
592                      result = FALSE;
593                   model->pdf[j][k][l * model->vector_length / ssize + m + model->vector_length] = (double) temp;
594                }
595                if (HTS106_fread_big_endian(&temp, sizeof(float), 1, fp) != 1)
596                   result = FALSE;
597                if (l == 0) {
598                   if (temp < 0.0 || temp > 1.0) {
599                      HTS106_error(1, "HTS106_Model_load_pdf: MSD weight should be within 0.0 to 1.0.\n");
600                      result = FALSE;
601                   }
602                   model->pdf[j][k][2 * model->vector_length] = (double) temp;
603                }
604                if (HTS106_fread_big_endian(&temp, sizeof(float), 1, fp) != 1)
605                   result = FALSE;
606             }
607          }
608       }
609    } else {                     /* for non MSD */
610       for (j = 2; j <= ntree + 1; j++) {
611          model->pdf[j] = (double **) HTS106_calloc(model->npdf[j], sizeof(double *));
612          model->pdf[j]--;
613          for (k = 1; k <= model->npdf[j]; k++) {
614             model->pdf[j][k] = (double *) HTS106_calloc(2 * model->vector_length, sizeof(double));
615             for (l = 0; l < model->vector_length; l++) {
616                if (HTS106_fread_big_endian(&temp, sizeof(float), 1, fp) != 1)
617                   result = FALSE;
618                model->pdf[j][k][l] = (double) temp;
619                if (HTS106_fread_big_endian(&temp, sizeof(float), 1, fp) != 1)
620                   result = FALSE;
621                model->pdf[j][k][l + model->vector_length] = (double) temp;
622             }
623          }
624       }
625    }
626    if (result == FALSE) {
627       HTS106_Model_clear(model);
628       return FALSE;
629    }
630    return TRUE;
631 }
632 
633 /* HTS106_Model_load_tree: load trees */
634 static HTS106_Boolean HTS106_Model_load_tree(HTS106_Model * model, HTS106_File * fp)
635 {
636    char buff[HTS106_MAXBUFLEN];
637    HTS106_Question *question, *last_question;
638    HTS106_Tree *tree, *last_tree;
639    int state;
640 
641    /* check */
642    if (model == NULL || fp == NULL) {
643       HTS106_error(1, "HTS106_Model_load_tree: File for trees is not specified.\n");
644       return FALSE;
645    }
646 
647    model->ntree = 0;
648    last_question = NULL;
649    last_tree = NULL;
650    while (!HTS106_feof(fp)) {
651       HTS106_get_pattern_token(fp, buff);
652       /* parse questions */
653       if (strcmp(buff, "QS") == 0) {
654          question = (HTS106_Question *) HTS106_calloc(1, sizeof(HTS106_Question));
655          if (HTS106_Question_load(question, fp) == FALSE) {
656             free(question);
657             HTS106_Model_clear(model);
658             return FALSE;
659          }
660          if (model->question)
661             last_question->next = question;
662          else
663             model->question = question;
664          question->next = NULL;
665          last_question = question;
666       }
667       /* parse trees */
668       state = HTS106_get_state_num(buff);
669       if (state != 0) {
670          tree = (HTS106_Tree *) HTS106_calloc(1, sizeof(HTS106_Tree));
671          tree->next = NULL;
672          tree->root = NULL;
673          tree->head = NULL;
674          tree->state = state;
675          HTS106_Tree_parse_pattern(tree, buff);
676          if (HTS106_Tree_load(tree, fp, model->question) == FALSE) {
677             free(tree);
678             HTS106_Model_clear(model);
679             return FALSE;
680          }
681          if (model->tree)
682             last_tree->next = tree;
683          else
684             model->tree = tree;
685          tree->next = NULL;
686          last_tree = tree;
687          model->ntree++;
688       }
689    }
690    /* No Tree information in tree file */
691    if (model->tree == NULL) {
692       HTS106_error(1, "HTS106_Model_load_tree: No trees are loaded.\n");
693       return FALSE;
694    }
695    return TRUE;
696 }
697 
698 /* HTS106_Model_clear: free pdfs and trees */
699 static void HTS106_Model_clear(HTS106_Model * model)
700 {
701    int i, j;
702    HTS106_Question *question, *next_question;
703    HTS106_Tree *tree, *next_tree;
704 
705    for (question = model->question; question; question = next_question) {
706       next_question = question->next;
707       HTS106_Question_clear(question);
708       HTS106_free(question);
709    }
710    for (tree = model->tree; tree; tree = next_tree) {
711       next_tree = tree->next;
712       HTS106_Tree_clear(tree);
713       HTS106_free(tree);
714    }
715    if (model->pdf) {
716       for (i = 2; i <= model->ntree + 1; i++) {
717          for (j = 1; j <= model->npdf[i]; j++) {
718             HTS106_free(model->pdf[i][j]);
719          }
720          model->pdf[i]++;
721          HTS106_free(model->pdf[i]);
722       }
723       model->pdf += 2;
724       HTS106_free(model->pdf);
725    }
726    if (model->npdf) {
727       model->npdf += 2;
728       HTS106_free(model->npdf);
729    }
730    HTS106_Model_initialize(model);
731 }
732 
733 /* HTS106_Stream_initialize: initialize stream */
734 static void HTS106_Stream_initialize(HTS106_Stream * stream)
735 {
736    stream->vector_length = 0;
737    stream->model = NULL;
738    HTS106_Window_initialize(&stream->window);
739    stream->msd_flag = FALSE;
740    stream->interpolation_size = 0;
741 }
742 
743 static void HTS106_Stream_clear(HTS106_Stream * stream);
744 
745 /* HTS106_Stream_load_pdf: load pdf */
746 static HTS106_Boolean HTS106_Stream_load_pdf(HTS106_Stream * stream, HTS106_File ** fp, int ntree, HTS106_Boolean msd_flag, int interpolation_size)
747 {
748    int i;
749    HTS106_Boolean result = TRUE;
750 
751    /* initialize */
752    stream->msd_flag = msd_flag;
753    stream->interpolation_size = interpolation_size;
754    stream->model = (HTS106_Model *) HTS106_calloc(interpolation_size, sizeof(HTS106_Model));
755    /* load pdfs */
756    for (i = 0; i < stream->interpolation_size; i++) {
757       HTS106_Model_initialize(&stream->model[i]);
758       if (HTS106_Model_load_pdf(&stream->model[i], fp[i], ntree, stream->msd_flag) == FALSE)
759          result = FALSE;
760    }
761    if (result == FALSE) {
762       HTS106_Stream_clear(stream);
763       return FALSE;
764    }
765    /* check */
766    for (i = 1; i < stream->interpolation_size; i++) {
767       if (stream->model[0].vector_length != stream->model[1].vector_length) {
768          HTS106_error(1, "HTS106_Stream_load_pdf: # of states are different in between given modelsets.\n");
769          HTS106_Stream_clear(stream);
770          return FALSE;
771       }
772    }
773    /* set */
774    stream->vector_length = stream->model[0].vector_length;
775 
776    return TRUE;
777 }
778 
779 /* HTS106_Stream_load_pdf_and_tree: load PDFs and trees */
780 static HTS106_Boolean HTS106_Stream_load_pdf_and_tree(HTS106_Stream * stream, HTS106_File ** pdf_fp, HTS106_File ** tree_fp, HTS106_Boolean msd_flag, int interpolation_size)
781 {
782    int i;
783    HTS106_Boolean result = TRUE;
784 
785    /* initialize */
786    stream->msd_flag = msd_flag;
787    stream->interpolation_size = interpolation_size;
788    stream->model = (HTS106_Model *) HTS106_calloc(interpolation_size, sizeof(HTS106_Model));
789    /* load */
790    for (i = 0; i < stream->interpolation_size; i++) {
791       if (!pdf_fp[i]) {
792          HTS106_error(1, "HTS106_Stream_load_pdf_and_tree: File for duration PDFs is not specified.\n");
793          HTS106_Stream_clear(stream);
794          return FALSE;
795       }
796       if (!tree_fp[i]) {
797          HTS106_error(1, "HTS106_Stream_load_pdf_and_tree: File for duration trees is not specified.\n");
798          HTS106_Stream_clear(stream);
799          return FALSE;
800       }
801       HTS106_Model_initialize(&stream->model[i]);
802       result = HTS106_Model_load_tree(&stream->model[i], tree_fp[i]);
803       if (result == FALSE) {
804          HTS106_Stream_clear(stream);
805          return FALSE;
806       }
807       result = HTS106_Model_load_pdf(&stream->model[i], pdf_fp[i], stream->model[i].ntree, stream->msd_flag);
808       if (result == FALSE) {
809          HTS106_Stream_clear(stream);
810          return FALSE;
811       }
812    }
813    /* check */
814    for (i = 1; i < stream->interpolation_size; i++)
815       if (stream->model[0].vector_length != stream->model[i].vector_length) {
816          HTS106_error(1, "HTS106_Stream_load_pdf_and_tree: Vector sizes of state output vectors are different in between given modelsets.\n");
817          HTS106_Stream_clear(stream);
818          return FALSE;
819       }
820    /* set */
821    stream->vector_length = stream->model[0].vector_length;
822 
823    return TRUE;
824 }
825 
826 /* HTS106_Stream_load_dynamic_window: load windows */
827 static HTS106_Boolean HTS106_Stream_load_dynamic_window(HTS106_Stream * stream, HTS106_File ** fp, int size)
828 {
829    return HTS106_Window_load(&stream->window, fp, size);
830 }
831 
832 /* HTS106_Stream_clear: free stream */
833 static void HTS106_Stream_clear(HTS106_Stream * stream)
834 {
835    int i;
836 
837    if (stream->model) {
838       for (i = 0; i < stream->interpolation_size; i++)
839          HTS106_Model_clear(&stream->model[i]);
840       HTS106_free(stream->model);
841    }
842    HTS106_Window_clear(&stream->window);
843    HTS106_Stream_initialize(stream);
844 }
845 
846 /* HTS106_ModelSet_initialize: initialize model set */
847 void HTS106_ModelSet_initialize(HTS106_ModelSet * ms, int nstream)
848 {
849    HTS106_Stream_initialize(&ms->duration);
850    ms->stream = NULL;
851    ms->gv = NULL;
852    HTS106_Model_initialize(&ms->gv_switch);
853    ms->nstate = -1;
854    ms->nstream = nstream;
855 }
856 
857 /* HTS106_ModelSet_load_duration: load duration model and number of state */
858 HTS106_Boolean HTS106_ModelSet_load_duration(HTS106_ModelSet * ms, HTS106_File ** pdf_fp, HTS106_File ** tree_fp, int interpolation_size)
859 {
860    /* check */
861    if (ms == NULL) {
862       return FALSE;
863    }
864    if (interpolation_size <= 0) {
865       HTS106_ModelSet_clear(ms);
866       return FALSE;
867    }
868    if (pdf_fp == NULL) {
869       HTS106_error(1, "HTS106_ModelSet_load_duration: File for duration PDFs is not specified.\n");
870       HTS106_ModelSet_clear(ms);
871       return FALSE;
872    }
873    if (tree_fp == NULL) {
874       HTS106_error(1, "HTS106_ModelSet_load_duration: File for duration trees is not specified.\n");
875       HTS106_ModelSet_clear(ms);
876       return FALSE;
877    }
878 
879    if (HTS106_Stream_load_pdf_and_tree(&ms->duration, pdf_fp, tree_fp, FALSE, interpolation_size) == FALSE) {
880       HTS106_ModelSet_clear(ms);
881       return FALSE;
882    }
883    ms->nstate = ms->duration.vector_length;
884 
885    return TRUE;
886 }
887 
888 /* HTS106_ModelSet_load_parameter: load model */
889 HTS106_Boolean HTS106_ModelSet_load_parameter(HTS106_ModelSet * ms, HTS106_File ** pdf_fp, HTS106_File ** tree_fp, HTS106_File ** win_fp, int stream_index, HTS106_Boolean msd_flag, int window_size, int interpolation_size)
890 {
891    int i;
892 
893    /* check */
894    if (ms == NULL) {
895       return FALSE;
896    }
897    if (stream_index < 0 || stream_index >= ms->nstream || window_size <= 0 || interpolation_size <= 0) {
898       HTS106_ModelSet_clear(ms);
899       return FALSE;
900    }
901    if (pdf_fp == NULL) {
902       HTS106_error(1, "HTS106_ModelSet_load_parameter: File for pdfs is not specified.\n");
903       HTS106_ModelSet_clear(ms);
904       return FALSE;
905    }
906    if (tree_fp == NULL) {
907       HTS106_error(1, "HTS106_ModelSet_load_parameter: File for wins is not specified.\n");
908       HTS106_ModelSet_clear(ms);
909       return FALSE;
910    }
911    if (win_fp == NULL) {
912       HTS106_error(1, "HTS106_ModelSet_load_parameter: File for wins is not specified.\n");
913       HTS106_ModelSet_clear(ms);
914       return FALSE;
915    }
916    /* initialize */
917    if (!ms->stream) {
918       ms->stream = (HTS106_Stream *) HTS106_calloc(ms->nstream, sizeof(HTS106_Stream));
919       for (i = 0; i < ms->nstream; i++)
920          HTS106_Stream_initialize(&ms->stream[i]);
921    }
922    /* load */
923    if (HTS106_Stream_load_pdf_and_tree(&ms->stream[stream_index], pdf_fp, tree_fp, msd_flag, interpolation_size) == FALSE) {
924       HTS106_ModelSet_clear(ms);
925       return FALSE;
926    }
927    if (HTS106_Stream_load_dynamic_window(&ms->stream[stream_index], win_fp, window_size) == FALSE) {
928       HTS106_ModelSet_clear(ms);
929       return FALSE;
930    }
931 
932    return TRUE;
933 }
934 
935 /* HTS106_ModelSet_load_gv: load GV model */
936 HTS106_Boolean HTS106_ModelSet_load_gv(HTS106_ModelSet * ms, HTS106_File ** pdf_fp, HTS106_File ** tree_fp, int stream_index, int interpolation_size)
937 {
938    int i;
939 
940    /* check */
941    if (ms == NULL) {
942       return FALSE;
943    }
944    if (stream_index < 0 || stream_index >= ms->nstream || interpolation_size <= 0) {
945       HTS106_ModelSet_clear(ms);
946       return FALSE;
947    }
948    if (pdf_fp == NULL) {
949       HTS106_error(1, "HTS106_ModelSet_load_gv: File for GV pdfs is not specified.\n");
950       HTS106_ModelSet_clear(ms);
951       return FALSE;
952    }
953    /* initialize */
954    if (!ms->gv) {
955       ms->gv = (HTS106_Stream *) HTS106_calloc(ms->nstream, sizeof(HTS106_Stream));
956       for (i = 0; i < ms->nstream; i++)
957          HTS106_Stream_initialize(&ms->gv[i]);
958    }
959    if (tree_fp) {
960       if (HTS106_Stream_load_pdf_and_tree(&ms->gv[stream_index], pdf_fp, tree_fp, FALSE, interpolation_size) == FALSE) {
961          HTS106_ModelSet_clear(ms);
962          return FALSE;
963       }
964    } else {
965       if (HTS106_Stream_load_pdf(&ms->gv[stream_index], pdf_fp, 1, FALSE, interpolation_size) == FALSE) {
966          HTS106_ModelSet_clear(ms);
967          return FALSE;
968       }
969    }
970 
971    return TRUE;
972 }
973 
974 /* HTS106_ModelSet_have_gv_tree: if context-dependent GV is used, return true */
975 HTS106_Boolean HTS106_ModelSet_have_gv_tree(HTS106_ModelSet * ms, int stream_index)
976 {
977    int i;
978 
979    for (i = 0; i < ms->gv[stream_index].interpolation_size; i++)
980       if (ms->gv[stream_index].model[i].tree == NULL)
981          return FALSE;
982    return TRUE;
983 }
984 
985 /* HTS106_ModelSet_load_gv_switch: load GV switch */
986 HTS106_Boolean HTS106_ModelSet_load_gv_switch(HTS106_ModelSet * ms, HTS106_File * fp)
987 {
988    if (fp != NULL)
989       return HTS106_Model_load_tree(&ms->gv_switch, fp);
990    return FALSE;
991 }
992 
993 /* HTS106_ModelSet_have_gv_switch: if GV switch is used, return true */
994 HTS106_Boolean HTS106_ModelSet_have_gv_switch(HTS106_ModelSet * ms)
995 {
996    if (ms->gv_switch.tree != NULL)
997       return TRUE;
998    else
999       return FALSE;
1000 }
1001 
1002 /* HTS106_ModelSet_get_nstate: get number of state */
1003 int HTS106_ModelSet_get_nstate(HTS106_ModelSet * ms)
1004 {
1005    return ms->nstate;
1006 }
1007 
1008 /* HTS106_ModelSet_get_nstream: get number of stream */
1009 int HTS106_ModelSet_get_nstream(HTS106_ModelSet * ms)
1010 {
1011    return ms->nstream;
1012 }
1013 
1014 /* HTS106_ModelSet_get_vector_length: get vector length */
1015 int HTS106_ModelSet_get_vector_length(HTS106_ModelSet * ms, int stream_index)
1016 {
1017    return ms->stream[stream_index].vector_length;
1018 }
1019 
1020 /* HTS106_ModelSet_is_msd: get MSD flag */
1021 HTS106_Boolean HTS106_ModelSet_is_msd(HTS106_ModelSet * ms, int stream_index)
1022 {
1023    return ms->stream[stream_index].msd_flag;
1024 }
1025 
1026 /* HTS106_ModelSet_get_window_size: get dynamic window size */
1027 int HTS106_ModelSet_get_window_size(HTS106_ModelSet * ms, int stream_index)
1028 {
1029    return ms->stream[stream_index].window.size;
1030 }
1031 
1032 /* HTS106_ModelSet_get_window_left_width: get left width of dynamic window */
1033 int HTS106_ModelSet_get_window_left_width(HTS106_ModelSet * ms, int stream_index, int window_index)
1034 {
1035    return ms->stream[stream_index].window.l_width[window_index];
1036 }
1037 
1038 /* HTS106_ModelSet_get_window_right_width: get right width of dynamic window */
1039 int HTS106_ModelSet_get_window_right_width(HTS106_ModelSet * ms, int stream_index, int window_index)
1040 {
1041    return ms->stream[stream_index].window.r_width[window_index];
1042 }
1043 
1044 /* HTS106_ModelSet_get_window_coefficient: get coefficient of dynamic window */
1045 double HTS106_ModelSet_get_window_coefficient(HTS106_ModelSet * ms, int stream_index, int window_index, int coefficient_index)
1046 {
1047    return ms->stream[stream_index].window.coefficient[window_index][coefficient_index];
1048 }
1049 
1050 /* HTS106_ModelSet_get_window_max_width: get max width of dynamic window */
1051 int HTS106_ModelSet_get_window_max_width(HTS106_ModelSet * ms, int stream_index)
1052 {
1053    return ms->stream[stream_index].window.max_width;
1054 }
1055 
1056 /* HTS106_ModelSet_get_duration_interpolation_size: get interpolation size (duration model) */
1057 int HTS106_ModelSet_get_duration_interpolation_size(HTS106_ModelSet * ms)
1058 {
1059    return ms->duration.interpolation_size;
1060 }
1061 
1062 /* HTS106_ModelSet_get_parameter_interpolation_size: get interpolation size (parameter model) */
1063 int HTS106_ModelSet_get_parameter_interpolation_size(HTS106_ModelSet * ms, int stream_index)
1064 {
1065    return ms->stream[stream_index].interpolation_size;
1066 }
1067 
1068 /* HTS106_ModelSet_get_gv_interpolation_size: get interpolation size (GV model) */
1069 int HTS106_ModelSet_get_gv_interpolation_size(HTS106_ModelSet * ms, int stream_index)
1070 {
1071    return ms->gv[stream_index].interpolation_size;
1072 }
1073 
1074 /* HTS106_ModelSet_use_gv: get GV flag */
1075 HTS106_Boolean HTS106_ModelSet_use_gv(HTS106_ModelSet * ms, int stream_index)
1076 {
1077    if (!ms->gv)
1078       return FALSE;
1079    if (ms->gv[stream_index].vector_length > 0)
1080       return TRUE;
1081    return FALSE;
1082 }
1083 
1084 /* HTS106_ModelSet_get_duration_index: get index of duration tree and PDF */
1085 void HTS106_ModelSet_get_duration_index(HTS106_ModelSet * ms, char *string, const RHVoice_parsed_label_string* parsed, int *tree_index, int *pdf_index, int interpolation_index)
1086 {
1087    HTS106_Tree *tree;
1088    HTS106_Pattern *pattern;
1089    HTS106_Boolean find;
1090 
1091    find = FALSE;
1092    (*tree_index) = 2;
1093    (*pdf_index) = 1;
1094    for (tree = ms->duration.model[interpolation_index].tree; tree; tree = tree->next) {
1095       pattern = tree->head;
1096       if (!pattern)
1097          find = TRUE;
1098       for (; pattern; pattern = pattern->next)
1099          if (HTS106_pattern_match(string, pattern->string)) {
1100             find = TRUE;
1101             break;
1102          }
1103       if (find)
1104          break;
1105       (*tree_index)++;
1106    }
1107 
1108    if (tree == NULL) {
1109       HTS106_error(1, "HTS106_ModelSet_get_duration_index: Cannot find model %s.\n", string);
1110       return;
1111    }
1112    (*pdf_index) = HTS106_Tree_search_node(tree, string, parsed);
1113 }
1114 
1115 /* HTS106_ModelSet_get_duration: get duration using interpolation weight */
1116 void HTS106_ModelSet_get_duration(HTS106_ModelSet * ms, char *string, const RHVoice_parsed_label_string* parsed, double *mean, double *vari, double *iw)
1117 {
1118    int i, j;
1119    int tree_index, pdf_index;
1120    const int vector_length = ms->duration.vector_length;
1121 
1122    for (i = 0; i < ms->nstate; i++) {
1123       mean[i] = 0.0;
1124       vari[i] = 0.0;
1125    }
1126    for (i = 0; i < ms->duration.interpolation_size; i++) {
1127      HTS106_ModelSet_get_duration_index(ms, string, parsed, &tree_index, &pdf_index, i);
1128       for (j = 0; j < ms->nstate; j++) {
1129          mean[j] += iw[i] * ms->duration.model[i].pdf[tree_index][pdf_index][j];
1130          vari[j] += iw[i] * iw[i] * ms->duration.model[i].pdf[tree_index][pdf_index][j + vector_length];
1131       }
1132    }
1133 }
1134 
1135 /* HTS106_ModelSet_get_parameter_index: get index of parameter tree and PDF */
1136 void HTS106_ModelSet_get_parameter_index(HTS106_ModelSet * ms, char *string, const RHVoice_parsed_label_string* parsed, int *tree_index, int *pdf_index, int stream_index, int state_index, int interpolation_index)
1137 {
1138    HTS106_Tree *tree;
1139    HTS106_Pattern *pattern;
1140    HTS106_Boolean find;
1141 
1142    find = FALSE;
1143    (*tree_index) = 2;
1144    (*pdf_index) = 1;
1145    for (tree = ms->stream[stream_index].model[interpolation_index].tree; tree; tree = tree->next) {
1146       if (tree->state == state_index) {
1147          pattern = tree->head;
1148          if (!pattern)
1149             find = TRUE;
1150          for (; pattern; pattern = pattern->next)
1151             if (HTS106_pattern_match(string, pattern->string)) {
1152                find = TRUE;
1153                break;
1154             }
1155          if (find)
1156             break;
1157       }
1158       (*tree_index)++;
1159    }
1160 
1161    if (tree == NULL) {
1162       HTS106_error(1, "HTS106_ModelSet_get_parameter_index: Cannot find model %s.\n", string);
1163       return;
1164    }
1165    (*pdf_index) = HTS106_Tree_search_node(tree, string, parsed);
1166 }
1167 
1168 /* HTS106_ModelSet_get_parameter: get parameter using interpolation weight */
1169 void HTS106_ModelSet_get_parameter(HTS106_ModelSet * ms, char *string, const RHVoice_parsed_label_string* parsed, double *mean, double *vari, double *msd, int stream_index, int state_index, double *iw)
1170 {
1171    int i, j;
1172    int tree_index, pdf_index;
1173    const int vector_length = ms->stream[stream_index].vector_length;
1174 
1175    for (i = 0; i < vector_length; i++) {
1176       mean[i] = 0.0;
1177       vari[i] = 0.0;
1178    }
1179    if (msd)
1180       *msd = 0.0;
1181    for (i = 0; i < ms->stream[stream_index].interpolation_size; i++) {
1182      HTS106_ModelSet_get_parameter_index(ms, string, parsed, &tree_index, &pdf_index, stream_index, state_index, i);
1183       for (j = 0; j < vector_length; j++) {
1184          mean[j] += iw[i] * ms->stream[stream_index].model[i].pdf[tree_index][pdf_index][j];
1185          vari[j] += iw[i] * iw[i] * ms->stream[stream_index].model[i]
1186              .pdf[tree_index][pdf_index][j + vector_length];
1187       }
1188       if (ms->stream[stream_index].msd_flag) {
1189          *msd += iw[i] * ms->stream[stream_index].model[i]
1190              .pdf[tree_index][pdf_index][2 * vector_length];
1191       }
1192    }
1193 }
1194 
1195 /* HTS106_ModelSet_get_gv_index: get index of GV tree and PDF */
1196 void HTS106_ModelSet_get_gv_index(HTS106_ModelSet * ms, char *string, int *tree_index, int *pdf_index, int stream_index, int interpolation_index)
1197 {
1198    HTS106_Tree *tree;
1199    HTS106_Pattern *pattern;
1200    HTS106_Boolean find;
1201 
1202    find = FALSE;
1203    (*tree_index) = 2;
1204    (*pdf_index) = 1;
1205 
1206    if (HTS106_ModelSet_have_gv_tree(ms, stream_index) == FALSE)
1207       return;
1208    for (tree = ms->gv[stream_index].model[interpolation_index].tree; tree; tree = tree->next) {
1209       pattern = tree->head;
1210       if (!pattern)
1211          find = TRUE;
1212       for (; pattern; pattern = pattern->next)
1213          if (HTS106_pattern_match(string, pattern->string)) {
1214             find = TRUE;
1215             break;
1216          }
1217       if (find)
1218          break;
1219       (*tree_index)++;
1220    }
1221 
1222    if (tree == NULL) {
1223       HTS106_error(1, "HTS106_ModelSet_get_gv_index: Cannot find model %s.\n", string);
1224       return;
1225    }
1226    (*pdf_index) = HTS106_Tree_search_node(tree, string, NULL);
1227 }
1228 
1229 /* HTS106_ModelSet_get_gv: get GV using interpolation weight */
1230 void HTS106_ModelSet_get_gv(HTS106_ModelSet * ms, char *string, double *mean, double *vari, int stream_index, double *iw)
1231 {
1232    int i, j;
1233    int tree_index, pdf_index;
1234    const int vector_length = ms->gv[stream_index].vector_length;
1235 
1236    for (i = 0; i < vector_length; i++) {
1237       mean[i] = 0.0;
1238       vari[i] = 0.0;
1239    }
1240    for (i = 0; i < ms->gv[stream_index].interpolation_size; i++) {
1241       HTS106_ModelSet_get_gv_index(ms, string, &tree_index, &pdf_index, stream_index, i);
1242       for (j = 0; j < vector_length; j++) {
1243          mean[j] += iw[i] * ms->gv[stream_index].model[i].pdf[tree_index][pdf_index][j];
1244          vari[j] += iw[i] * iw[i] * ms->gv[stream_index].model[i]
1245              .pdf[tree_index][pdf_index][j + vector_length];
1246       }
1247    }
1248 }
1249 
1250 /* HTS106_ModelSet_get_gv_switch_index: get index of GV switch tree and PDF */
1251 void HTS106_ModelSet_get_gv_switch_index(HTS106_ModelSet * ms, char *string, int *tree_index, int *pdf_index)
1252 {
1253    HTS106_Tree *tree;
1254    HTS106_Pattern *pattern;
1255    HTS106_Boolean find;
1256 
1257    find = FALSE;
1258    (*tree_index) = 2;
1259    (*pdf_index) = 1;
1260    for (tree = ms->gv_switch.tree; tree; tree = tree->next) {
1261       pattern = tree->head;
1262       if (!pattern)
1263          find = TRUE;
1264       for (; pattern; pattern = pattern->next)
1265          if (HTS106_pattern_match(string, pattern->string)) {
1266             find = TRUE;
1267             break;
1268          }
1269       if (find)
1270          break;
1271       (*tree_index)++;
1272    }
1273 
1274    if (tree == NULL) {
1275       HTS106_error(1, "HTS106_ModelSet_get_gv_switch_index: Cannot find model %s.\n", string);
1276       return;
1277    }
1278    (*pdf_index) = HTS106_Tree_search_node(tree, string, NULL);
1279 }
1280 
1281 /* HTS106_ModelSet_get_gv_switch: get GV switch */
1282 HTS106_Boolean HTS106_ModelSet_get_gv_switch(HTS106_ModelSet * ms, char *string)
1283 {
1284    int tree_index, pdf_index;
1285 
1286    if (ms->gv_switch.tree == NULL)
1287       return TRUE;
1288    HTS106_ModelSet_get_gv_switch_index(ms, string, &tree_index, &pdf_index);
1289    if (pdf_index == 1)
1290       return FALSE;
1291    else
1292       return TRUE;
1293 }
1294 
1295 /* HTS106_ModelSet_clear: free model set */
1296 void HTS106_ModelSet_clear(HTS106_ModelSet * ms)
1297 {
1298    int i;
1299 
1300    HTS106_Stream_clear(&ms->duration);
1301    if (ms->stream) {
1302       for (i = 0; i < ms->nstream; i++)
1303          HTS106_Stream_clear(&ms->stream[i]);
1304       HTS106_free(ms->stream);
1305    }
1306    if (ms->gv) {
1307       for (i = 0; i < ms->nstream; i++)
1308          HTS106_Stream_clear(&ms->gv[i]);
1309       HTS106_free(ms->gv);
1310    }
1311    HTS106_Model_clear(&ms->gv_switch);
1312    HTS106_ModelSet_initialize(ms, -1);
1313 }
1314 
1315 HTS106_MODEL_C_END;
1316 
1317 #endif                          /* !HTS106_MODEL_C */
1318