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