Bug Summary

File:modules/hts_engine/HTS_model.c
Location:line 555, column 33
Description:Access to field 'next' results in a dereference of a null pointer (loaded from variable 'last_question')

Annotated Source Code

1/* ----------------------------------------------------------------- */
2/* The HMM-Based Speech Synthesis System (HTS) */
3/* hts_engine API developed by HTS Working Group */
4/* http://hts-engine.sourceforge.net/ */
5/* ----------------------------------------------------------------- */
6/* */
7/* Copyright (c) 2001-2010 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
56HTS_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 */
66static HTS_Boolean HTS_dp_match(const char *string, const char *pattern,
67 const int pos, const int max)
68{
69 if (pos > max)
70 return FALSE0;
71 if (string[0] == '\0' && pattern[0] == '\0')
72 return TRUE1;
73 if (pattern[0] == '*') {
74 if (HTS_dp_match(string + 1, pattern, pos + 1, max) == 1)
75 return TRUE1;
76 else
77 return HTS_dp_match(string, pattern + 1, pos, max);
78 }
79 if (string[0] == pattern[0] || pattern[0] == '?') {
80 if (HTS_dp_match(string + 1, pattern + 1, pos + 1, max + 1) == 1)
81 return TRUE1;
82 }
83
84 return FALSE0;
85}
86
87/* HTS_pattern_match: pattern matching function */
88static HTS_Boolean HTS_pattern_match(const char *string, const char *pattern)
89{
90 int i, j;
91 int buff_length, max = 0, nstar = 0, nquestion = 0;
92 char buff[HTS_MAXBUFLEN1024];
93 const int pattern_length = strlen(pattern);
94
95 for (i = 0; i < pattern_length; i++) {
96 switch (pattern[i]) {
97 case '*':
98 nstar++;
99 break;
100 case '?':
101 nquestion++;
102 max++;
103 break;
104 default:
105 max++;
106 }
107 }
108 if (nstar == 2 && nquestion == 0 && pattern[0] == '*'
109 && pattern[i - 1] == '*') {
110 /* only string matching is required */
111 buff_length = i - 2;
112 for (i = 0, j = 1; i < buff_length; i++, j++)
113 buff[i] = pattern[j];
114 buff[buff_length] = '\0';
115 if (strstr(string, buff) != NULL((void*)0))
116 return TRUE1;
117 else
118 return FALSE0;
119 } else
120 return HTS_dp_match(string, pattern, 0, (int) (strlen(string) - max));
121}
122
123/* HTS_is_num: check given buffer is number or not */
124static HTS_Boolean HTS_is_num(const char *buff)
125{
126 int i;
127 const int length = (int) strlen(buff);
128
129 for (i = 0; i < length; i++)
130 if (!(isdigit((int) buff[i])((*__ctype_b_loc ())[(int) (((int) buff[i]))] & (unsigned
short int) _ISdigit)
|| (buff[i] == '-')))
131 return FALSE0;
132
133 return TRUE1;
134}
135
136/* HTS_name2num: convert name of node to number */
137static int HTS_name2num(const char *buff)
138{
139 int i;
140
141 for (i = strlen(buff) - 1; '0' <= buff[i] && buff[i] <= '9' && i >= 0; i--);
142 i++;
143
144 return atoi(&buff[i]);
145}
146
147/* HTS_get_state_num: return the number of state */
148static int HTS_get_state_num(char *string)
149{
150 char *left, *right;
151
152 if (((left = strchr(string, '[')) == NULL((void*)0))
153 || ((right = strrchr(string, ']')) == NULL((void*)0)))
154 return 0;
155 *right = '\0';
156 string = left + 1;
157
158 return atoi(string);
159}
160
161/* HTS_Question_load: Load questions from file */
162static void HTS_Question_load(HTS_Question * question, FILE * fp)
163{
164 char buff[HTS_MAXBUFLEN1024];
165 HTS_Pattern *pattern, *last_pattern;
166
167 /* get question name */
168 HTS_get_pattern_token(fp, buff);
169 question->string = HTS_strdup(buff);
170 question->head = NULL((void*)0);
171 /* get pattern list */
172 HTS_get_pattern_token(fp, buff);
173 last_pattern = NULL((void*)0);
174 if (strcmp(buff, "{") == 0) {
175 while (1) {
176 HTS_get_pattern_token(fp, buff);
177 pattern = (HTS_Pattern *) HTS_calloc(1, sizeof(HTS_Pattern));
178 if (question->head)
179 last_pattern->next = pattern;
180 else /* first time */
181 question->head = pattern;
182 pattern->string = HTS_strdup(buff);
183 pattern->next = NULL((void*)0);
184 HTS_get_pattern_token(fp, buff);
185 if (!strcmp(buff, "}"))
186 break;
187 last_pattern = pattern;
188 }
189 }
190}
191
192/* HTS_Question_match: check given string match given question */
193static HTS_Boolean HTS_Question_match(const HTS_Question * question,
194 const char *string)
195{
196 HTS_Pattern *pattern;
197
198 for (pattern = question->head; pattern; pattern = pattern->next)
199 if (HTS_pattern_match(string, pattern->string))
200 return TRUE1;
201
202 return FALSE0;
203}
204
205/* HTS_Question_find_question: find question from question list */
206static HTS_Question *HTS_Question_find_question(HTS_Question * question,
207 const char *buff)
208{
209
210 for (; question; question = question->next)
211 if (strcmp(buff, question->string) == 0)
212 return question;
213
214 HTS_error(1, "HTS_Question_find_question: Cannot find question %s.\n", buff);
215 return NULL((void*)0); /* make compiler happy */
216}
217
218/* HTS_Question_clear: clear loaded question */
219static void HTS_Question_clear(HTS_Question * question)
220{
221 HTS_Pattern *pattern, *next_pattern;
222
223 HTS_free(question->string);
224 for (pattern = question->head; pattern; pattern = next_pattern) {
225 next_pattern = pattern->next;
226 HTS_free(pattern->string);
227 HTS_free(pattern);
228 }
229}
230
231/* HTS_Node_find: find node for given number */
232static HTS_Node *HTS_Node_find(HTS_Node * node, const int num)
233{
234 for (; node; node = node->next)
235 if (node->index == num)
236 return node;
237
238 HTS_error(1, "HTS_Node_find: Cannot find node %d.\n", num);
239 return NULL((void*)0); /* make compiler happy */
240}
241
242/* HTS_Node_clear: recursive function to free Node */
243static void HTS_Node_clear(HTS_Node * node)
244{
245 if (node->yes != NULL((void*)0))
246 HTS_Node_clear(node->yes);
247 if (node->no != NULL((void*)0))
248 HTS_Node_clear(node->no);
249 HTS_free(node);
250}
251
252/* HTS_Tree_parse_pattern: parse pattern specified for each tree */
253static void HTS_Tree_parse_pattern(HTS_Tree * tree, char *string)
254{
255 char *left, *right;
256 HTS_Pattern *pattern, *last_pattern;
257
258 tree->head = NULL((void*)0);
259 last_pattern = NULL((void*)0);
260 /* parse tree pattern */
261 if ((left = strchr(string, '{')) != NULL((void*)0)) { /* pattern is specified */
262 string = left + 1;
263 if (*string == '(')
264 ++string;
265
266 right = strrchr(string, '}');
267 if (string < right && *(right - 1) == ')')
268 --right;
269 *right = ',';
270
271 /* parse pattern */
272 while ((left = strchr(string, ',')) != NULL((void*)0)) {
273 pattern = (HTS_Pattern *) HTS_calloc(1, sizeof(HTS_Pattern));
274 if (tree->head) {
275 last_pattern->next = pattern;
276 } else {
277 tree->head = pattern;
278 }
279 *left = '\0';
280 pattern->string = HTS_strdup(string);
281 string = left + 1;
282 pattern->next = NULL((void*)0);
283 last_pattern = pattern;
284 }
285 }
286}
287
288/* HTS_Tree_load: Load trees */
289static void HTS_Tree_load(HTS_Tree * tree, FILE * fp, HTS_Question * question)
290{
291 char buff[HTS_MAXBUFLEN1024];
292 HTS_Node *node, *last_node;
293
294 HTS_get_pattern_token(fp, buff);
295 node = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node));
296 node->index = 0;
297 tree->root = last_node = node;
298
299 if (strcmp(buff, "{") == 0) {
300 while (HTS_get_pattern_token(fp, buff), strcmp(buff, "}") != 0) {
301 node = HTS_Node_find(last_node, atoi(buff));
302 HTS_get_pattern_token(fp, buff); /* load question at this node */
303
304 node->quest = HTS_Question_find_question(question, buff);
305 node->yes = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node));
306 node->no = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node));
307
308 HTS_get_pattern_token(fp, buff);
309 if (HTS_is_num(buff))
310 node->no->index = atoi(buff);
311 else
312 node->no->pdf = HTS_name2num(buff);
313 node->no->next = last_node;
314 last_node = node->no;
315
316 HTS_get_pattern_token(fp, buff);
317 if (HTS_is_num(buff))
318 node->yes->index = atoi(buff);
319 else
320 node->yes->pdf = HTS_name2num(buff);
321 node->yes->next = last_node;
322 last_node = node->yes;
323 }
324 } else {
325 node->pdf = HTS_name2num(buff);
326 }
327}
328
329/* HTS_Node_search: tree search */
330static int HTS_Tree_search_node(HTS_Tree * tree, const char *string)
331{
332 HTS_Node *node = tree->root;
333
334 while (node != NULL((void*)0)) {
335 if (node->quest == NULL((void*)0))
336 return node->pdf;
337 if (HTS_Question_match(node->quest, string)) {
338 if (node->yes->pdf > 0)
339 return node->yes->pdf;
340 node = node->yes;
341 } else {
342 if (node->no->pdf > 0)
343 return node->no->pdf;
344 node = node->no;
345 }
346 }
347
348 HTS_error(1, "HTS_Tree_search_node: Cannot find node.\n");
349 return -1; /* make compiler happy */
350}
351
352/* HTS_Tree_clear: clear given tree */
353static void HTS_Tree_clear(HTS_Tree * tree)
354{
355 HTS_Pattern *pattern, *next_pattern;
356
357 for (pattern = tree->head; pattern; pattern = next_pattern) {
358 next_pattern = pattern->next;
359 HTS_free(pattern->string);
360 HTS_free(pattern);
361 }
362
363 HTS_Node_clear(tree->root);
364}
365
366/* HTS_Window_initialize: initialize dynamic window */
367static void HTS_Window_initialize(HTS_Window * win)
368{
369 win->size = 0;
370 win->l_width = NULL((void*)0);
371 win->r_width = NULL((void*)0);
372 win->coefficient = NULL((void*)0);
373 win->max_width = 0;
374}
375
376/* HTS_Window_load: load dynamic windows */
377static void HTS_Window_load(HTS_Window * win, FILE ** fp, int size)
378{
379 int i, j;
380 int fsize, length;
381 char buff[HTS_MAXBUFLEN1024];
382
383 win->size = size;
384 win->l_width = (int *) HTS_calloc(win->size, sizeof(int));
385 win->r_width = (int *) HTS_calloc(win->size, sizeof(int));
386 win->coefficient = (double **) HTS_calloc(win->size, sizeof(double *));
387 /* set delta coefficents */
388 for (i = 0; i < win->size; i++) {
389 HTS_get_token(fp[i], buff);
390 fsize = atoi(buff);
391 /* read coefficients */
392 win->coefficient[i] = (double *) HTS_calloc(fsize, sizeof(double));
393 for (j = 0; j < fsize; j++) {
394 HTS_get_token(fp[i], buff);
395 win->coefficient[i][j] = (double) atof(buff);
396 }
397 /* set pointer */
398 length = fsize / 2;
399 win->coefficient[i] += length;
400 win->l_width[i] = -length;
401 win->r_width[i] = length;
402 if (fsize % 2 == 0)
403 win->r_width[i]--;
404 }
405 /* calcurate max_width to determine size of band matrix */
406 win->max_width = 0;
407 for (i = 0; i < win->size; i++) {
408 if (win->max_width < abs(win->l_width[i]))
409 win->max_width = abs(win->l_width[i]);
410 if (win->max_width < abs(win->r_width[i]))
411 win->max_width = abs(win->r_width[i]);
412 }
413}
414
415/* HTS_Window_clear: free dynamic window */
416static void HTS_Window_clear(HTS_Window * win)
417{
418 int i;
419
420 if (win->coefficient) {
421 for (i = win->size - 1; i >= 0; i--) {
422 win->coefficient[i] += win->l_width[i];
423 HTS_free(win->coefficient[i]);
424 }
425 HTS_free(win->coefficient);
426 }
427 if (win->l_width)
428 HTS_free(win->l_width);
429 if (win->r_width)
430 HTS_free(win->r_width);
431
432 HTS_Window_initialize(win);
433}
434
435/* HTS_Model_initialize: initialize model */
436static void HTS_Model_initialize(HTS_Model * model)
437{
438 model->vector_length = 0;
439 model->ntree = 0;
440 model->npdf = NULL((void*)0);
441 model->pdf = NULL((void*)0);
442 model->tree = NULL((void*)0);
443 model->question = NULL((void*)0);
444}
445
446/* HTS_Model_load_pdf: load pdfs */
447static void HTS_Model_load_pdf(HTS_Model * model, FILE * fp, int ntree,
448 HTS_Boolean msd_flag)
449{
450 int i, j, k, l, m;
451 float temp;
452 int ssize;
453
454 /* check */
455 if (fp == NULL((void*)0))
456 HTS_error(1, "HTS_Model_load_pdf: File for pdfs is not specified.\n");
457
458 /* load pdf */
459 model->ntree = ntree;
460 /* read MSD flag */
461 HTS_fread_big_endian(&i, sizeof(int), 1, fp);
462 if ((i != 0 || msd_flag != FALSE0) && (i != 1 || msd_flag != TRUE1))
463 HTS_error(1, "HTS_Model_load_pdf: Failed to load header of pdfs.\n");
464 /* read stream size */
465 HTS_fread_big_endian(&ssize, sizeof(int), 1, fp);
466 if (ssize < 1)
467 HTS_error(1, "HTS_Model_load_pdf: Failed to load header of pdfs.\n");
468 /* read vector size */
469 HTS_fread_big_endian(&model->vector_length, sizeof(int), 1, fp);
470 if (model->vector_length < 0)
471 HTS_error(1,
472 "HTS_Model_load_pdf: # of HMM states %d should be positive.\n",
473 model->vector_length);
474 model->npdf = (int *) HTS_calloc(ntree, sizeof(int));
475 model->npdf -= 2;
476 /* read the number of pdfs */
477 HTS_fread_big_endian(&model->npdf[2], sizeof(int), ntree, fp);
478 for (i = 2; i <= ntree + 1; i++)
479 if (model->npdf[i] < 0)
480 HTS_error(1,
481 "HTS_Model_load_pdf: # of pdfs at %d-th state should be positive.\n",
482 i);
483 model->pdf = (double ***) HTS_calloc(ntree, sizeof(double **));
484 model->pdf -= 2;
485 /* read means and variances */
486 if (msd_flag) { /* for MSD */
487 for (j = 2; j <= ntree + 1; j++) {
488 model->pdf[j] = (double **)
489 HTS_calloc(model->npdf[j], sizeof(double *));
490 model->pdf[j]--;
491 for (k = 1; k <= model->npdf[j]; k++) {
492 model->pdf[j][k] = (double *)
493 HTS_calloc(2 * model->vector_length + 1, sizeof(double));
494 for (l = 0; l < ssize; l++) {
495 for (m = 0; m < model->vector_length / ssize; m++) {
496 HTS_fread_big_endian(&temp, sizeof(float), 1, fp);
497 model->pdf[j][k][l * model->vector_length / ssize + m] =
498 (double) temp;
499 HTS_fread_big_endian(&temp, sizeof(float), 1, fp);
500 model->pdf[j][k][l * model->vector_length / ssize + m +
501 model->vector_length] = (double) temp;
502 }
503 HTS_fread_big_endian(&temp, sizeof(float), 1, fp);
504 if (l == 0) {
505 if (temp < 0.0 || temp > 1.0)
506 HTS_error(1,
507 "HTS_Model_load_pdf: MSD weight should be within 0.0 to 1.0.\n");
508 model->pdf[j][k][2 * model->vector_length] = (double) temp;
509 }
510 HTS_fread_big_endian(&temp, sizeof(float), 1, fp);
511 }
512 }
513 }
514 } else { /* for non MSD */
515 for (j = 2; j <= ntree + 1; j++) {
516 model->pdf[j] =
517 (double **) HTS_calloc(model->npdf[j], sizeof(double *));
518 model->pdf[j]--;
519 for (k = 1; k <= model->npdf[j]; k++) {
520 model->pdf[j][k] =
521 (double *) HTS_calloc(2 * model->vector_length, sizeof(double));
522 for (l = 0; l < model->vector_length; l++) {
523 HTS_fread_big_endian(&temp, sizeof(float), 1, fp);
524 model->pdf[j][k][l] = (double) temp;
525 HTS_fread_big_endian(&temp, sizeof(float), 1, fp);
526 model->pdf[j][k][l + model->vector_length] = (double) temp;
527 }
528 }
529 }
530 }
531}
532
533/* HTS_Model_load_tree: load trees */
534static void HTS_Model_load_tree(HTS_Model * model, FILE * fp)
535{
536 char buff[HTS_MAXBUFLEN1024];
537 HTS_Question *question, *last_question;
538 HTS_Tree *tree, *last_tree;
539 int state;
540
541 /* check */
542 if (fp == NULL((void*)0))
4
Taking false branch
543 HTS_error(1, "HTS_Model_load_tree: File for trees is not specified.\n");
544
545 model->ntree = 0;
546 last_question = NULL((void*)0);
5
Null pointer value stored to 'last_question'
547 last_tree = NULL((void*)0);
548 while (!feof(fp)) {
6
Loop condition is true. Entering loop body
549 HTS_get_pattern_token(fp, buff);
550 /* parse questions */
551 if (strcmp(buff, "QS") == 0) {
7
Taking true branch
552 question = (HTS_Question *) HTS_calloc(1, sizeof(HTS_Question));
553 HTS_Question_load(question, fp);
554 if (model->question)
8
Taking true branch
555 last_question->next = question;
9
Access to field 'next' results in a dereference of a null pointer (loaded from variable 'last_question')
556 else
557 model->question = question;
558 question->next = NULL((void*)0);
559 last_question = question;
560 }
561 /* parse trees */
562 state = HTS_get_state_num(buff);
563 if (state != 0) {
564 tree = (HTS_Tree *) HTS_calloc(1, sizeof(HTS_Tree));
565 tree->next = NULL((void*)0);
566 tree->root = NULL((void*)0);
567 tree->head = NULL((void*)0);
568 tree->state = state;
569 HTS_Tree_parse_pattern(tree, buff);
570 HTS_Tree_load(tree, fp, model->question);
571 if (model->tree)
572 last_tree->next = tree;
573 else
574 model->tree = tree;
575 tree->next = NULL((void*)0);
576 last_tree = tree;
577 model->ntree++;
578 }
579 }
580 /* No Tree information in tree file */
581 if (model->tree == NULL((void*)0))
582 HTS_error(1, "HTS_Model_load_tree: No trees are loaded.\n");
583}
584
585/* HTS_Model_clear: free pdfs and trees */
586static void HTS_Model_clear(HTS_Model * model)
587{
588 int i, j;
589 HTS_Question *question, *next_question;
590 HTS_Tree *tree, *next_tree;
591
592 for (question = model->question; question; question = next_question) {
593 next_question = question->next;
594 HTS_Question_clear(question);
595 HTS_free(question);
596 }
597 for (tree = model->tree; tree; tree = next_tree) {
598 next_tree = tree->next;
599 HTS_Tree_clear(tree);
600 HTS_free(tree);
601 }
602 if (model->pdf) {
603 for (i = 2; i <= model->ntree + 1; i++) {
604 for (j = 1; j <= model->npdf[i]; j++) {
605 HTS_free(model->pdf[i][j]);
606 }
607 model->pdf[i]++;
608 HTS_free(model->pdf[i]);
609 }
610 model->pdf += 2;
611 HTS_free(model->pdf);
612 }
613 if (model->npdf) {
614 model->npdf += 2;
615 HTS_free(model->npdf);
616 }
617 HTS_Model_initialize(model);
618}
619
620/* HTS_Stream_initialize: initialize stream */
621static void HTS_Stream_initialize(HTS_Stream * stream)
622{
623 stream->vector_length = 0;
624 stream->model = NULL((void*)0);
625 HTS_Window_initialize(&stream->window);
626 stream->msd_flag = FALSE0;
627 stream->interpolation_size = 0;
628}
629
630/* HTS_Stream_load_pdf: load pdf */
631static void HTS_Stream_load_pdf(HTS_Stream * stream, FILE ** fp, int ntree,
632 HTS_Boolean msd_flag, int interpolation_size)
633{
634 int i;
635
636 /* initialize */
637 stream->msd_flag = msd_flag;
638 stream->interpolation_size = interpolation_size;
639 stream->model =
640 (HTS_Model *) HTS_calloc(interpolation_size, sizeof(HTS_Model));
641 /* load pdfs */
642 for (i = 0; i < stream->interpolation_size; i++) {
643 HTS_Model_initialize(&stream->model[i]);
644 HTS_Model_load_pdf(&stream->model[i], fp[i], ntree, stream->msd_flag);
645 }
646 /* check */
647 for (i = 1; i < stream->interpolation_size; i++)
648 if (stream->model[0].vector_length != stream->model[1].vector_length)
649 HTS_error(1,
650 "HTS_Stream_load_pdf: # of states are different in between given modelsets.\n");
651 /* set */
652 stream->vector_length = stream->model[0].vector_length;
653}
654
655/* HTS_Stream_load_pdf_and_tree: load PDFs and trees */
656static void HTS_Stream_load_pdf_and_tree(HTS_Stream * stream, FILE ** pdf_fp,
657 FILE ** tree_fp, HTS_Boolean msd_flag,
658 int interpolation_size)
659{
660 int i;
661
662 /* initialize */
663 stream->msd_flag = msd_flag;
664 stream->interpolation_size = interpolation_size;
665 stream->model =
666 (HTS_Model *) HTS_calloc(interpolation_size, sizeof(HTS_Model));
667 /* load */
668 for (i = 0; i < stream->interpolation_size; i++) {
669 if (!pdf_fp[i])
670 HTS_error(1,
671 "HTS_Stream_load_pdf_and_tree: File for duration PDFs is not specified.\n");
672 if (!tree_fp[i])
673 HTS_error(1,
674 "HTS_Stream_load_pdf_and_tree: File for duration trees is not specified.\n");
675 HTS_Model_initialize(&stream->model[i]);
676 HTS_Model_load_tree(&stream->model[i], tree_fp[i]);
677 HTS_Model_load_pdf(&stream->model[i], pdf_fp[i], stream->model[i].ntree,
678 stream->msd_flag);
679 }
680 /* check */
681 for (i = 1; i < stream->interpolation_size; i++)
682 if (stream->model[0].vector_length != stream->model[i].vector_length)
683 HTS_error(1,
684 "HTS_Stream_load_pdf_and_tree: Vector sizes of state output vectors are different in between given modelsets.\n");
685 /* set */
686 stream->vector_length = stream->model[0].vector_length;
687}
688
689/* HTS_Stream_load_dynamic_window: load windows */
690static void HTS_Stream_load_dynamic_window(HTS_Stream * stream, FILE ** fp,
691 int size)
692{
693 HTS_Window_load(&stream->window, fp, size);
694}
695
696/* HTS_Stream_clear: free stream */
697static void HTS_Stream_clear(HTS_Stream * stream)
698{
699 int i;
700
701 if (stream->model) {
702 for (i = 0; i < stream->interpolation_size; i++)
703 HTS_Model_clear(&stream->model[i]);
704 HTS_free(stream->model);
705 }
706 HTS_Window_clear(&stream->window);
707 HTS_Stream_initialize(stream);
708}
709
710/* HTS_ModelSet_initialize: initialize model set */
711void HTS_ModelSet_initialize(HTS_ModelSet * ms, int nstream)
712{
713 HTS_Stream_initialize(&ms->duration);
714 ms->stream = NULL((void*)0);
715 ms->gv = NULL((void*)0);
716 HTS_Model_initialize(&ms->gv_switch);
717 ms->nstate = -1;
718 ms->nstream = nstream;
719}
720
721/* HTS_ModelSet_load_duration: load duration model and number of state */
722void HTS_ModelSet_load_duration(HTS_ModelSet * ms, FILE ** pdf_fp,
723 FILE ** tree_fp, int interpolation_size)
724{
725 /* check */
726 if (pdf_fp == NULL((void*)0))
727 HTS_error(1,
728 "HTS_ModelSet_load_duration: File for duration PDFs is not specified.\n");
729 if (tree_fp == NULL((void*)0))
730 HTS_error(1,
731 "HTS_ModelSet_load_duration: File for duration trees is not specified.\n");
732
733 HTS_Stream_load_pdf_and_tree(&ms->duration, pdf_fp, tree_fp, FALSE0,
734 interpolation_size);
735 ms->nstate = ms->duration.vector_length;
736}
737
738/* HTS_ModelSet_load_parameter: load model */
739void HTS_ModelSet_load_parameter(HTS_ModelSet * ms, FILE ** pdf_fp,
740 FILE ** tree_fp, FILE ** win_fp,
741 int stream_index, HTS_Boolean msd_flag,
742 int window_size, int interpolation_size)
743{
744 int i;
745
746 /* check */
747 if (pdf_fp == NULL((void*)0))
748 HTS_error(1,
749 "HTS_ModelSet_load_parameter: File for pdfs is not specified.\n");
750 if (tree_fp == NULL((void*)0))
751 HTS_error(1,
752 "HTS_ModelSet_load_parameter: File for wins is not specified.\n");
753 if (win_fp == NULL((void*)0))
754 HTS_error(1,
755 "HTS_ModelSet_load_parameter: File for wins is not specified.\n");
756 /* initialize */
757 if (!ms->stream) {
758 ms->stream = (HTS_Stream *) HTS_calloc(ms->nstream, sizeof(HTS_Stream));
759 for (i = 0; i < ms->nstream; i++)
760 HTS_Stream_initialize(&ms->stream[i]);
761 }
762 /* load */
763 HTS_Stream_load_pdf_and_tree(&ms->stream[stream_index], pdf_fp, tree_fp,
764 msd_flag, interpolation_size);
765 HTS_Stream_load_dynamic_window(&ms->stream[stream_index], win_fp,
766 window_size);
767}
768
769/* HTS_ModelSet_load_gv: load GV model */
770void HTS_ModelSet_load_gv(HTS_ModelSet * ms, FILE ** pdf_fp, FILE ** tree_fp,
771 int stream_index, int interpolation_size)
772{
773 int i;
774
775 /* check */
776 if (pdf_fp == NULL((void*)0))
777 HTS_error(1,
778 "HTS_ModelSet_load_gv: File for GV pdfs is not specified.\n");
779 /* initialize */
780 if (!ms->gv) {
781 ms->gv = (HTS_Stream *) HTS_calloc(ms->nstream, sizeof(HTS_Stream));
782 for (i = 0; i < ms->nstream; i++)
783 HTS_Stream_initialize(&ms->gv[i]);
784 }
785 if (tree_fp)
786 HTS_Stream_load_pdf_and_tree(&ms->gv[stream_index], pdf_fp, tree_fp,
787 FALSE0, interpolation_size);
788 else
789 HTS_Stream_load_pdf(&ms->gv[stream_index], pdf_fp, 1, FALSE0,
790 interpolation_size);
791}
792
793/* HTS_ModelSet_have_gv_tree: if context-dependent GV is used, return true */
794HTS_Boolean HTS_ModelSet_have_gv_tree(HTS_ModelSet * ms, int stream_index)
795{
796 int i;
797
798 for (i = 0; i < ms->gv[stream_index].interpolation_size; i++)
799 if (ms->gv[stream_index].model[i].tree == NULL((void*)0))
800 return FALSE0;
801 return TRUE1;
802}
803
804/* HTS_ModelSet_load_gv_switch: load GV switch */
805void HTS_ModelSet_load_gv_switch(HTS_ModelSet * ms, FILE * fp)
806{
807 if (fp != NULL((void*)0))
1
Assuming 'fp' is not equal to null
2
Taking true branch
808 HTS_Model_load_tree(&ms->gv_switch, fp);
3
Calling 'HTS_Model_load_tree'
809}
810
811/* HTS_ModelSet_have_gv_switch: if GV switch is used, return true */
812HTS_Boolean HTS_ModelSet_have_gv_switch(HTS_ModelSet * ms)
813{
814 if (ms->gv_switch.tree != NULL((void*)0))
815 return TRUE1;
816 else
817 return FALSE0;
818}
819
820/* HTS_ModelSet_get_nstate: get number of state */
821int HTS_ModelSet_get_nstate(HTS_ModelSet * ms)
822{
823 return ms->nstate;
824}
825
826/* HTS_ModelSet_get_nstream: get number of stream */
827int HTS_ModelSet_get_nstream(HTS_ModelSet * ms)
828{
829 return ms->nstream;
830}
831
832/* HTS_ModelSet_get_vector_length: get vector length */
833int HTS_ModelSet_get_vector_length(HTS_ModelSet * ms, int stream_index)
834{
835 return ms->stream[stream_index].vector_length;
836}
837
838/* HTS_ModelSet_is_msd: get MSD flag */
839HTS_Boolean HTS_ModelSet_is_msd(HTS_ModelSet * ms, int stream_index)
840{
841 return ms->stream[stream_index].msd_flag;
842}
843
844/* HTS_ModelSet_get_window_size: get dynamic window size */
845int HTS_ModelSet_get_window_size(HTS_ModelSet * ms, int stream_index)
846{
847 return ms->stream[stream_index].window.size;
848}
849
850/* HTS_ModelSet_get_window_left_width: get left width of dynamic window */
851int HTS_ModelSet_get_window_left_width(HTS_ModelSet * ms, int stream_index,
852 int window_index)
853{
854 return ms->stream[stream_index].window.l_width[window_index];
855}
856
857/* HTS_ModelSet_get_window_right_width: get right width of dynamic window */
858int HTS_ModelSet_get_window_right_width(HTS_ModelSet * ms, int stream_index,
859 int window_index)
860{
861 return ms->stream[stream_index].window.r_width[window_index];
862}
863
864/* HTS_ModelSet_get_window_coefficient: get coefficient of dynamic window */
865double HTS_ModelSet_get_window_coefficient(HTS_ModelSet * ms, int stream_index,
866 int window_index,
867 int coefficient_index)
868{
869 return ms->stream[stream_index].window.
870 coefficient[window_index][coefficient_index];
871}
872
873/* HTS_ModelSet_get_window_max_width: get max width of dynamic window */
874int HTS_ModelSet_get_window_max_width(HTS_ModelSet * ms, int stream_index)
875{
876 return ms->stream[stream_index].window.max_width;
877}
878
879/* HTS_ModelSet_get_duration_interpolation_size: get interpolation size (duration model) */
880int HTS_ModelSet_get_duration_interpolation_size(HTS_ModelSet * ms)
881{
882 return ms->duration.interpolation_size;
883}
884
885/* HTS_ModelSet_get_parameter_interpolation_size: get interpolation size (parameter model) */
886int HTS_ModelSet_get_parameter_interpolation_size(HTS_ModelSet * ms,
887 int stream_index)
888{
889 return ms->stream[stream_index].interpolation_size;
890}
891
892/* HTS_ModelSet_get_gv_interpolation_size: get interpolation size (GV model) */
893int HTS_ModelSet_get_gv_interpolation_size(HTS_ModelSet * ms, int stream_index)
894{
895 return ms->gv[stream_index].interpolation_size;
896}
897
898/* HTS_ModelSet_use_gv: get GV flag */
899HTS_Boolean HTS_ModelSet_use_gv(HTS_ModelSet * ms, int stream_index)
900{
901 if (!ms->gv)
902 return FALSE0;
903 if (ms->gv[stream_index].vector_length > 0)
904 return TRUE1;
905 return FALSE0;
906}
907
908/* HTS_ModelSet_get_duration_index: get index of duration tree and PDF */
909void HTS_ModelSet_get_duration_index(HTS_ModelSet * ms, char *string,
910 int *tree_index, int *pdf_index,
911 int interpolation_index)
912{
913 HTS_Tree *tree;
914 HTS_Pattern *pattern;
915 HTS_Boolean find;
916
917 find = FALSE0;
918 (*tree_index) = 2;
919 (*pdf_index) = 1;
920 for (tree = ms->duration.model[interpolation_index].tree; tree;
921 tree = tree->next) {
922 pattern = tree->head;
923 if (!pattern)
924 find = TRUE1;
925 for (; pattern; pattern = pattern->next)
926 if (HTS_pattern_match(string, pattern->string)) {
927 find = TRUE1;
928 break;
929 }
930 if (find)
931 break;
932 (*tree_index)++;
933 }
934
935 if (tree == NULL((void*)0))
936 HTS_error(1, "HTS_ModelSet_get_duration_index: Cannot find model %s.\n",
937 string);
938 (*pdf_index) = HTS_Tree_search_node(tree, string);
939}
940
941/* HTS_ModelSet_get_duration: get duration using interpolation weight */
942void HTS_ModelSet_get_duration(HTS_ModelSet * ms, char *string, double *mean,
943 double *vari, double *iw)
944{
945 int i, j;
946 int tree_index, pdf_index;
947 const int vector_length = ms->duration.vector_length;
948
949 for (i = 0; i < ms->nstate; i++) {
950 mean[i] = 0.0;
951 vari[i] = 0.0;
952 }
953 for (i = 0; i < ms->duration.interpolation_size; i++) {
954 HTS_ModelSet_get_duration_index(ms, string, &tree_index, &pdf_index, i);
955 for (j = 0; j < ms->nstate; j++) {
956 mean[j] += iw[i] * ms->duration.model[i].pdf[tree_index][pdf_index][j];
957 vari[j] += iw[i] * iw[i] * ms->duration.model[i]
958 .pdf[tree_index][pdf_index][j + vector_length];
959 }
960 }
961}
962
963/* HTS_ModelSet_get_parameter_index: get index of parameter tree and PDF */
964void HTS_ModelSet_get_parameter_index(HTS_ModelSet * ms, char *string,
965 int *tree_index, int *pdf_index,
966 int stream_index, int state_index,
967 int interpolation_index)
968{
969 HTS_Tree *tree;
970 HTS_Pattern *pattern;
971 HTS_Boolean find;
972
973 find = FALSE0;
974 (*tree_index) = 2;
975 (*pdf_index) = 1;
976 for (tree = ms->stream[stream_index].model[interpolation_index].tree; tree;
977 tree = tree->next) {
978 if (tree->state == state_index) {
979 pattern = tree->head;
980 if (!pattern)
981 find = TRUE1;
982 for (; pattern; pattern = pattern->next)
983 if (HTS_pattern_match(string, pattern->string)) {
984 find = TRUE1;
985 break;
986 }
987 if (find)
988 break;
989 }
990 (*tree_index)++;
991 }
992
993 if (tree == NULL((void*)0))
994 HTS_error(1, "HTS_ModelSet_get_parameter_index: Cannot find model %s.\n",
995 string);
996 (*pdf_index) = HTS_Tree_search_node(tree, string);
997}
998
999/* HTS_ModelSet_get_parameter: get parameter using interpolation weight */
1000void HTS_ModelSet_get_parameter(HTS_ModelSet * ms, char *string, double *mean,
1001 double *vari, double *msd, int stream_index,
1002 int state_index, double *iw)
1003{
1004 int i, j;
1005 int tree_index, pdf_index;
1006 const int vector_length = ms->stream[stream_index].vector_length;
1007
1008 for (i = 0; i < vector_length; i++) {
1009 mean[i] = 0.0;
1010 vari[i] = 0.0;
1011 }
1012 if (msd)
1013 *msd = 0.0;
1014 for (i = 0; i < ms->stream[stream_index].interpolation_size; i++) {
1015 HTS_ModelSet_get_parameter_index(ms, string, &tree_index, &pdf_index,
1016 stream_index, state_index, i);
1017 for (j = 0; j < vector_length; j++) {
1018 mean[j] += iw[i] *
1019 ms->stream[stream_index].model[i].pdf[tree_index][pdf_index][j];
1020 vari[j] += iw[i] * iw[i] * ms->stream[stream_index].model[i]
1021 .pdf[tree_index][pdf_index][j + vector_length];
1022 }
1023 if (ms->stream[stream_index].msd_flag) {
1024 *msd += iw[i] * ms->stream[stream_index].model[i]
1025 .pdf[tree_index][pdf_index][2 * vector_length];
1026 }
1027 }
1028}
1029
1030/* HTS_ModelSet_get_gv_index: get index of GV tree and PDF */
1031void HTS_ModelSet_get_gv_index(HTS_ModelSet * ms, char *string, int *tree_index,
1032 int *pdf_index, int stream_index,
1033 int interpolation_index)
1034{
1035 HTS_Tree *tree;
1036 HTS_Pattern *pattern;
1037 HTS_Boolean find;
1038
1039 find = FALSE0;
1040 (*tree_index) = 2;
1041 (*pdf_index) = 1;
1042
1043 if (HTS_ModelSet_have_gv_tree(ms, stream_index) == FALSE0)
1044 return;
1045 for (tree = ms->gv[stream_index].model[interpolation_index].tree; tree;
1046 tree = tree->next) {
1047 pattern = tree->head;
1048 if (!pattern)
1049 find = TRUE1;
1050 for (; pattern; pattern = pattern->next)
1051 if (HTS_pattern_match(string, pattern->string)) {
1052 find = TRUE1;
1053 break;
1054 }
1055 if (find)
1056 break;
1057 (*tree_index)++;
1058 }
1059
1060 if (tree == NULL((void*)0))
1061 HTS_error(1, "HTS_ModelSet_get_gv_index: Cannot find model %s.\n",
1062 string);
1063 (*pdf_index) = HTS_Tree_search_node(tree, string);
1064}
1065
1066/* HTS_ModelSet_get_gv: get GV using interpolation weight */
1067void HTS_ModelSet_get_gv(HTS_ModelSet * ms, char *string, double *mean,
1068 double *vari, int stream_index, double *iw)
1069{
1070 int i, j;
1071 int tree_index, pdf_index;
1072 const int vector_length = ms->gv[stream_index].vector_length;
1073
1074 for (i = 0; i < vector_length; i++) {
1075 mean[i] = 0.0;
1076 vari[i] = 0.0;
1077 }
1078 for (i = 0; i < ms->gv[stream_index].interpolation_size; i++) {
1079 HTS_ModelSet_get_gv_index(ms, string, &tree_index, &pdf_index,
1080 stream_index, i);
1081 for (j = 0; j < vector_length; j++) {
1082 mean[j] += iw[i] *
1083 ms->gv[stream_index].model[i].pdf[tree_index][pdf_index][j];
1084 vari[j] += iw[i] * iw[i] * ms->gv[stream_index].model[i]
1085 .pdf[tree_index][pdf_index][j + vector_length];
1086 }
1087 }
1088}
1089
1090/* HTS_ModelSet_get_gv_switch_index: get index of GV switch tree and PDF */
1091void HTS_ModelSet_get_gv_switch_index(HTS_ModelSet * ms, char *string,
1092 int *tree_index, int *pdf_index)
1093{
1094 HTS_Tree *tree;
1095 HTS_Pattern *pattern;
1096 HTS_Boolean find;
1097
1098 find = FALSE0;
1099 (*tree_index) = 2;
1100 (*pdf_index) = 1;
1101 for (tree = ms->gv_switch.tree; tree; tree = tree->next) {
1102 pattern = tree->head;
1103 if (!pattern)
1104 find = TRUE1;
1105 for (; pattern; pattern = pattern->next)
1106 if (HTS_pattern_match(string, pattern->string)) {
1107 find = TRUE1;
1108 break;
1109 }
1110 if (find)
1111 break;
1112 (*tree_index)++;
1113 }
1114
1115 if (tree == NULL((void*)0))
1116 HTS_error(1, "HTS_ModelSet_get_gv_switch_index: Cannot find model %s.\n",
1117 string);
1118 (*pdf_index) = HTS_Tree_search_node(tree, string);
1119}
1120
1121/* HTS_ModelSet_get_gv_switch: get GV switch */
1122HTS_Boolean HTS_ModelSet_get_gv_switch(HTS_ModelSet * ms, char *string)
1123{
1124 int tree_index, pdf_index;
1125
1126 if (ms->gv_switch.tree == NULL((void*)0))
1127 return TRUE1;
1128 HTS_ModelSet_get_gv_switch_index(ms, string, &tree_index, &pdf_index);
1129 if (pdf_index == 1)
1130 return FALSE0;
1131 else
1132 return TRUE1;
1133}
1134
1135/* HTS_ModelSet_clear: free model set */
1136void HTS_ModelSet_clear(HTS_ModelSet * ms)
1137{
1138 int i;
1139
1140 HTS_Stream_clear(&ms->duration);
1141 if (ms->stream) {
1142 for (i = 0; i < ms->nstream; i++)
1143 HTS_Stream_clear(&ms->stream[i]);
1144 HTS_free(ms->stream);
1145 }
1146 if (ms->gv) {
1147 for (i = 0; i < ms->nstream; i++)
1148 HTS_Stream_clear(&ms->gv[i]);
1149 HTS_free(ms->gv);
1150 }
1151 HTS_Model_clear(&ms->gv_switch);
1152 HTS_ModelSet_initialize(ms, -1);
1153}
1154
1155HTS_MODEL_C_END;
1156
1157#endif /* !HTS_MODEL_C */