/* ----------------------------------------------------------------- */ /* The HMM-Based Speech Synthesis Engine "hts_engine API" */ /* developed by HTS Working Group */ /* http://hts-engine.sourceforge.net/ */ /* ----------------------------------------------------------------- */ /* */ /* Copyright (c) 2001-2013 Nagoya Institute of Technology */ /* Department of Computer Science */ /* */ /* 2001-2008 Tokyo Institute of Technology */ /* Interdisciplinary Graduate School of */ /* Science and Engineering */ /* */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or */ /* without modification, are permitted provided that the following */ /* conditions are met: */ /* */ /* - Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* - Redistributions in binary form must reproduce the above */ /* copyright notice, this list of conditions and the following */ /* disclaimer in the documentation and/or other materials provided */ /* with the distribution. */ /* - Neither the name of the HTS working group nor the names of its */ /* contributors may be used to endorse or promote products derived */ /* from this software without specific prior written permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */ /* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */ /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS */ /* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */ /* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */ /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY */ /* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ /* POSSIBILITY OF SUCH DAMAGE. */ /* ----------------------------------------------------------------- */ #ifndef HTS_MODEL_C #define HTS_MODEL_C #ifdef __cplusplus #define HTS_MODEL_C_START extern "C" { #define HTS_MODEL_C_END } #else #define HTS_MODEL_C_START #define HTS_MODEL_C_END #endif /* __CPLUSPLUS */ HTS_MODEL_C_START; #include /* for atoi(),abs() */ #include /* for strlen(),strstr(),strrchr(),strcmp() */ #include /* for isdigit() */ /* hts_engine libraries */ #include "HTS_hidden.h" /* HTS_dp_match: recursive matching */ static HTS_Boolean HTS_dp_match(const char *string, const char *pattern, size_t pos, size_t max) { if (pos > max) return FALSE; if (string[0] == '\0' && pattern[0] == '\0') return TRUE; if (pattern[0] == '*') { if (HTS_dp_match(string + 1, pattern, pos + 1, max) == 1) return TRUE; else return HTS_dp_match(string, pattern + 1, pos, max); } if (string[0] == pattern[0] || pattern[0] == '?') { if (HTS_dp_match(string + 1, pattern + 1, pos + 1, max + 1) == 1) return TRUE; } return FALSE; } /* HTS_pattern_match: pattern matching function */ static HTS_Boolean HTS_pattern_match(const char *string, const char *pattern) { size_t i, j; size_t buff_length, max = 0, nstar = 0, nquestion = 0; char buff[HTS_MAXBUFLEN]; size_t pattern_length = strlen(pattern); for (i = 0; i < pattern_length; i++) { switch (pattern[i]) { case '*': nstar++; break; case '?': nquestion++; max++; break; default: max++; } } if (nstar == 2 && nquestion == 0 && pattern[0] == '*' && pattern[i - 1] == '*') { /* only string matching is required */ buff_length = i - 2; for (i = 0, j = 1; i < buff_length; i++, j++) buff[i] = pattern[j]; buff[buff_length] = '\0'; if (strstr(string, buff) != NULL) return TRUE; else return FALSE; } else return HTS_dp_match(string, pattern, 0, strlen(string) - max); } /* HTS_is_num: check given buffer is number or not */ static HTS_Boolean HTS_is_num(const char *buff) { size_t i; size_t length = strlen(buff); for (i = 0; i < length; i++) if (!(isdigit((int) buff[i]) || (buff[i] == '-'))) return FALSE; return TRUE; } /* HTS_name2num: convert name of node to number */ static size_t HTS_name2num(const char *buff) { size_t i; for (i = strlen(buff) - 1; '0' <= buff[i] && buff[i] <= '9' && i >= 0; i--); i++; return (size_t) atoi(&buff[i]); } /* HTS_get_state_num: return the number of state */ static size_t HTS_get_state_num(const char *string) { char *left, *right; left = strchr(string, '['); if (left == NULL) return 0; left++; right = strchr(left, ']'); if (right == NULL) return 0; return (size_t) atoi(left); } /* HTS_Question_initialize: initialize question */ static void HTS_Question_initialize(HTS_Question * question) { question->string = NULL; question->head = NULL; question->next = NULL; } /* HTS_Question_clear: clear loaded question */ static void HTS_Question_clear(HTS_Question * question) { HTS_Pattern *pattern, *next_pattern; if (question->string != NULL) HTS_free(question->string); for (pattern = question->head; pattern; pattern = next_pattern) { next_pattern = pattern->next; HTS_free(pattern->string); HTS_free(pattern); } HTS_Question_initialize(question); } /* HTS_Question_load: Load questions from file */ static HTS_Boolean HTS_Question_load(HTS_Question * question, HTS_File * fp) { char buff[HTS_MAXBUFLEN]; HTS_Pattern *pattern, *last_pattern; if (question == NULL || fp == NULL) return FALSE; HTS_Question_clear(question); /* get question name */ if (HTS_get_pattern_token(fp, buff) == FALSE) return FALSE; question->string = HTS_strdup(buff); /* get pattern list */ if (HTS_get_pattern_token(fp, buff) == FALSE) { HTS_Question_clear(question); return FALSE; } last_pattern = NULL; if (strcmp(buff, "{") == 0) { while (1) { if (HTS_get_pattern_token(fp, buff) == FALSE) { HTS_Question_clear(question); return FALSE; } pattern = (HTS_Pattern *) HTS_calloc(1, sizeof(HTS_Pattern)); if (question->head != NULL) last_pattern->next = pattern; else /* first time */ question->head = pattern; pattern->string = HTS_strdup(buff); pattern->next = NULL; if (HTS_get_pattern_token(fp, buff) == FALSE) { HTS_Question_clear(question); return FALSE; } if (!strcmp(buff, "}")) break; last_pattern = pattern; } } return TRUE; } /* HTS_Question_match: check given string match given question */ static HTS_Boolean HTS_Question_match(HTS_Question * question, const char *string) { HTS_Pattern *pattern; for (pattern = question->head; pattern; pattern = pattern->next) if (HTS_pattern_match(string, pattern->string)) return TRUE; return FALSE; } /* HTS_Question_find: find question from question list */ static HTS_Question *HTS_Question_find(HTS_Question * question, const char *string) { for (; question; question = question->next) if (strcmp(string, question->string) == 0) return question; return NULL; } /* HTS_Node_initialzie: initialize node */ static void HTS_Node_initialize(HTS_Node * node) { node->index = 0; node->pdf = 0; node->yes = NULL; node->no = NULL; node->next = NULL; node->quest = NULL; } /* HTS_Node_clear: recursive function to free node */ static void HTS_Node_clear(HTS_Node * node) { if (node->yes != NULL) { HTS_Node_clear(node->yes); HTS_free(node->yes); } if (node->no != NULL) { HTS_Node_clear(node->no); HTS_free(node->no); } HTS_Node_initialize(node); } /* HTS_Node_find: find node for given number */ static HTS_Node *HTS_Node_find(HTS_Node * node, int num) { for (; node; node = node->next) if (node->index == num) return node; return NULL; } /* HTS_Tree_initialize: initialize tree */ static void HTS_Tree_initialize(HTS_Tree * tree) { tree->head = NULL; tree->next = NULL; tree->root = NULL; tree->state = 0; } /* HTS_Tree_clear: clear given tree */ static void HTS_Tree_clear(HTS_Tree * tree) { HTS_Pattern *pattern, *next_pattern; for (pattern = tree->head; pattern; pattern = next_pattern) { next_pattern = pattern->next; HTS_free(pattern->string); HTS_free(pattern); } if (tree->root != NULL) { HTS_Node_clear(tree->root); HTS_free(tree->root); } HTS_Tree_initialize(tree); } /* HTS_Tree_parse_pattern: parse pattern specified for each tree */ static void HTS_Tree_parse_pattern(HTS_Tree * tree, char *string) { char *left, *right; HTS_Pattern *pattern, *last_pattern; tree->head = NULL; last_pattern = NULL; /* parse tree pattern */ if ((left = strchr(string, '{')) != NULL) { /* pattern is specified */ string = left + 1; if (*string == '(') ++string; right = strrchr(string, '}'); if (string < right && *(right - 1) == ')') --right; *right = ','; /* parse pattern */ while ((left = strchr(string, ',')) != NULL) { pattern = (HTS_Pattern *) HTS_calloc(1, sizeof(HTS_Pattern)); if (tree->head) { last_pattern->next = pattern; } else { tree->head = pattern; } *left = '\0'; pattern->string = HTS_strdup(string); string = left + 1; pattern->next = NULL; last_pattern = pattern; } } } /* HTS_Tree_load: load trees */ static HTS_Boolean HTS_Tree_load(HTS_Tree * tree, HTS_File * fp, HTS_Question * question) { char buff[HTS_MAXBUFLEN]; HTS_Node *node, *last_node; if (tree == NULL || fp == NULL) return FALSE; if (HTS_get_pattern_token(fp, buff) == FALSE) { HTS_Tree_clear(tree); return FALSE; } node = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node)); HTS_Node_initialize(node); tree->root = last_node = node; if (strcmp(buff, "{") == 0) { while (HTS_get_pattern_token(fp, buff) == TRUE && strcmp(buff, "}") != 0) { node = HTS_Node_find(last_node, atoi(buff)); if (node == NULL) { HTS_error(0, "HTS_Tree_load: Cannot find node %d.\n", atoi(buff)); HTS_Tree_clear(tree); return FALSE; } if (HTS_get_pattern_token(fp, buff) == FALSE) { HTS_Tree_clear(tree); return FALSE; } node->quest = HTS_Question_find(question, buff); if (node->quest == NULL) { HTS_error(0, "HTS_Tree_load: Cannot find question %s.\n", buff); HTS_Tree_clear(tree); return FALSE; } node->yes = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node)); node->no = (HTS_Node *) HTS_calloc(1, sizeof(HTS_Node)); HTS_Node_initialize(node->yes); HTS_Node_initialize(node->no); if (HTS_get_pattern_token(fp, buff) == FALSE) { node->quest = NULL; free(node->yes); free(node->no); HTS_Tree_clear(tree); return FALSE; } if (HTS_is_num(buff)) node->no->index = atoi(buff); else node->no->pdf = HTS_name2num(buff); node->no->next = last_node; last_node = node->no; if (HTS_get_pattern_token(fp, buff) == FALSE) { node->quest = NULL; free(node->yes); free(node->no); HTS_Tree_clear(tree); return FALSE; } if (HTS_is_num(buff)) node->yes->index = atoi(buff); else node->yes->pdf = HTS_name2num(buff); node->yes->next = last_node; last_node = node->yes; } } else { node->pdf = HTS_name2num(buff); } return TRUE; } /* HTS_Node_search: tree search */ static size_t HTS_Tree_search_node(HTS_Tree * tree, const char *string) { HTS_Node *node = tree->root; while (node != NULL) { if (node->quest == NULL) return node->pdf; if (HTS_Question_match(node->quest, string)) { if (node->yes->pdf > 0) return node->yes->pdf; node = node->yes; } else { if (node->no->pdf > 0) return node->no->pdf; node = node->no; } } HTS_error(0, "HTS_Tree_search_node: Cannot find node.\n"); return 1; } /* HTS_Window_initialize: initialize dynamic window */ static void HTS_Window_initialize(HTS_Window * win) { win->size = 0; win->l_width = NULL; win->r_width = NULL; win->coefficient = NULL; win->max_width = 0; } /* HTS_Window_clear: free dynamic window */ static void HTS_Window_clear(HTS_Window * win) { size_t i; if (win->coefficient != NULL) { for (i = 0; i < win->size; i++) { win->coefficient[i] += win->l_width[i]; HTS_free(win->coefficient[i]); } HTS_free(win->coefficient); } if (win->l_width) HTS_free(win->l_width); if (win->r_width) HTS_free(win->r_width); HTS_Window_initialize(win); } /* HTS_Window_load: load dynamic windows */ static HTS_Boolean HTS_Window_load(HTS_Window * win, HTS_File ** fp, size_t size) { size_t i, j; size_t fsize, length; char buff[HTS_MAXBUFLEN]; HTS_Boolean result = TRUE; /* check */ if (win == NULL || fp == NULL || size == 0) return FALSE; win->size = size; win->l_width = (int *) HTS_calloc(win->size, sizeof(int)); win->r_width = (int *) HTS_calloc(win->size, sizeof(int)); win->coefficient = (double **) HTS_calloc(win->size, sizeof(double *)); /* set delta coefficents */ for (i = 0; i < win->size; i++) { if (HTS_get_token_from_fp(fp[i], buff) == FALSE) { result = FALSE; fsize = 1; } else { fsize = atoi(buff); if (fsize == 0) { result = FALSE; fsize = 1; } } /* read coefficients */ win->coefficient[i] = (double *) HTS_calloc(fsize, sizeof(double)); for (j = 0; j < fsize; j++) { if (HTS_get_token_from_fp(fp[i], buff) == FALSE) { result = FALSE; win->coefficient[i][j] = 0.0; } else { win->coefficient[i][j] = (double) atof(buff); } } /* set pointer */ length = fsize / 2; win->coefficient[i] += length; win->l_width[i] = -1 * (int) length; win->r_width[i] = (int) length; if (fsize % 2 == 0) win->r_width[i]--; } /* calcurate max_width to determine size of band matrix */ win->max_width = 0; for (i = 0; i < win->size; i++) { if (win->max_width < (size_t) abs(win->l_width[i])) win->max_width = abs(win->l_width[i]); if (win->max_width < (size_t) abs(win->r_width[i])) win->max_width = abs(win->r_width[i]); } if (result == FALSE) { HTS_Window_clear(win); return FALSE; } return TRUE; } /* HTS_Model_initialize: initialize model */ static void HTS_Model_initialize(HTS_Model * model) { model->vector_length = 0; model->num_windows = 0; model->is_msd = FALSE; model->ntree = 0; model->npdf = NULL; model->pdf = NULL; model->tree = NULL; model->question = NULL; } /* HTS_Model_clear: free pdfs and trees */ static void HTS_Model_clear(HTS_Model * model) { size_t i, j; HTS_Question *question, *next_question; HTS_Tree *tree, *next_tree; for (question = model->question; question; question = next_question) { next_question = question->next; HTS_Question_clear(question); HTS_free(question); } for (tree = model->tree; tree; tree = next_tree) { next_tree = tree->next; HTS_Tree_clear(tree); HTS_free(tree); } if (model->pdf) { for (i = 2; i <= model->ntree + 1; i++) { for (j = 1; j <= model->npdf[i]; j++) { HTS_free(model->pdf[i][j]); } model->pdf[i]++; HTS_free(model->pdf[i]); } model->pdf += 2; HTS_free(model->pdf); } if (model->npdf) { model->npdf += 2; HTS_free(model->npdf); } HTS_Model_initialize(model); } /* HTS_Model_load_tree: load trees */ static HTS_Boolean HTS_Model_load_tree(HTS_Model * model, HTS_File * fp) { char buff[HTS_MAXBUFLEN]; HTS_Question *question, *last_question; HTS_Tree *tree, *last_tree; size_t state; /* check */ if (model == NULL) { HTS_error(0, "HTS_Model_load_tree: File for trees is not specified.\n"); return FALSE; } if (fp == NULL) { model->ntree = 1; return TRUE; } model->ntree = 0; last_question = NULL; last_tree = NULL; while (!HTS_feof(fp)) { HTS_get_pattern_token(fp, buff); /* parse questions */ if (strcmp(buff, "QS") == 0) { question = (HTS_Question *) HTS_calloc(1, sizeof(HTS_Question)); HTS_Question_initialize(question); if (HTS_Question_load(question, fp) == FALSE) { free(question); HTS_Model_clear(model); return FALSE; } if (model->question) last_question->next = question; else model->question = question; question->next = NULL; last_question = question; } /* parse trees */ state = HTS_get_state_num(buff); if (state != 0) { tree = (HTS_Tree *) HTS_calloc(1, sizeof(HTS_Tree)); HTS_Tree_initialize(tree); tree->state = state; HTS_Tree_parse_pattern(tree, buff); if (HTS_Tree_load(tree, fp, model->question) == FALSE) { free(tree); HTS_Model_clear(model); return FALSE; } if (model->tree) last_tree->next = tree; else model->tree = tree; tree->next = NULL; last_tree = tree; model->ntree++; } } /* No Tree information in tree file */ if (model->tree == NULL) model->ntree = 1; return TRUE; } /* HTS_Model_load_pdf: load pdfs */ 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) { unsigned int i; size_t j, k; HTS_Boolean result = TRUE; size_t len; /* check */ if (model == NULL || fp == NULL || model->ntree <= 0) { HTS_error(1, "HTS_Model_load_pdf: File for pdfs is not specified.\n"); return FALSE; } /* read MSD flag */ model->vector_length = vector_length; model->num_windows = num_windows; model->is_msd = is_msd; model->npdf = (size_t *) HTS_calloc(model->ntree, sizeof(size_t)); model->npdf -= 2; /* read the number of pdfs */ for (j = 2; j <= model->ntree + 1; j++) { if (HTS_fread_little_endian(&i, sizeof(unsigned int), 1, fp) != 1) { result = FALSE; break; } model->npdf[j] = (size_t) i; } for (j = 2; j <= model->ntree + 1; j++) { if (model->npdf[j] <= 0) { HTS_error(1, "HTS_Model_load_pdf: # of pdfs at %d-th state should be positive.\n", j); result = FALSE; break; } } if (result == FALSE) { model->npdf += 2; free(model->npdf); HTS_Model_initialize(model); return FALSE; } model->pdf = (float ***) HTS_calloc(model->ntree, sizeof(float **)); model->pdf -= 2; /* read means and variances */ if (is_msd) /* for MSD */ len = model->vector_length * model->num_windows * 2 + 1; else len = model->vector_length * model->num_windows * 2; for (j = 2; j <= model->ntree + 1; j++) { model->pdf[j] = (float **) HTS_calloc(model->npdf[j], sizeof(float *)); model->pdf[j]--; for (k = 1; k <= model->npdf[j]; k++) { model->pdf[j][k] = (float *) HTS_calloc(len, sizeof(float)); if (HTS_fread_little_endian(model->pdf[j][k], sizeof(float), len, fp) != len) result = FALSE; } } if (result == FALSE) { HTS_Model_clear(model); return FALSE; } return TRUE; } /* HTS_Model_load: load pdf and tree */ 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) { /* check */ if (model == NULL || pdf == NULL || vector_length == 0 || num_windows == 0) return FALSE; /* reset */ HTS_Model_clear(model); /* load tree */ if (HTS_Model_load_tree(model, tree) != TRUE) { HTS_Model_clear(model); return FALSE; } /* load pdf */ if (HTS_Model_load_pdf(model, pdf, vector_length, num_windows, is_msd) != TRUE) { HTS_Model_clear(model); return FALSE; } return TRUE; } /* HTS_Model_get_index: get index of tree and PDF */ static void HTS_Model_get_index(HTS_Model * model, size_t state_index, const char *string, size_t * tree_index, size_t * pdf_index) { HTS_Tree *tree; HTS_Pattern *pattern; HTS_Boolean find; (*tree_index) = 2; (*pdf_index) = 1; if (model->tree == NULL) return; find = FALSE; for (tree = model->tree; tree; tree = tree->next) { if (tree->state == state_index) { pattern = tree->head; if (!pattern) find = TRUE; for (; pattern; pattern = pattern->next) if (HTS_pattern_match(string, pattern->string)) { find = TRUE; break; } if (find) break; } (*tree_index)++; } if (tree != NULL) { (*pdf_index) = HTS_Tree_search_node(tree, string); } else { (*pdf_index) = HTS_Tree_search_node(model->tree, string); } } /* HTS_ModelSet_initialize: initialize model set */ void HTS_ModelSet_initialize(HTS_ModelSet * ms) { ms->hts_voice_version = NULL; ms->sampling_frequency = 0; ms->frame_period = 0; ms->num_voices = 0; ms->num_states = 0; ms->num_streams = 0; ms->stream_type = NULL; ms->fullcontext_format = NULL; ms->fullcontext_version = NULL; ms->gv_off_context = NULL; ms->option = NULL; ms->duration = NULL; ms->window = NULL; ms->stream = NULL; ms->gv = NULL; } /* HTS_ModelSet_clear: free model set */ void HTS_ModelSet_clear(HTS_ModelSet * ms) { size_t i, j; if (ms->hts_voice_version != NULL) free(ms->hts_voice_version); if (ms->stream_type != NULL) free(ms->stream_type); if (ms->fullcontext_format != NULL) free(ms->fullcontext_format); if (ms->fullcontext_version != NULL) free(ms->fullcontext_version); if (ms->gv_off_context != NULL) { HTS_Question_clear(ms->gv_off_context); free(ms->gv_off_context); } if (ms->option != NULL) { for (i = 0; i < ms->num_streams; i++) if (ms->option[i] != NULL) free(ms->option[i]); free(ms->option); } if (ms->duration != NULL) { for (i = 0; i < ms->num_voices; i++) HTS_Model_clear(&ms->duration[i]); free(ms->duration); } if (ms->window != NULL) { for (i = 0; i < ms->num_streams; i++) HTS_Window_clear(&ms->window[i]); free(ms->window); } if (ms->stream != NULL) { for (i = 0; i < ms->num_voices; i++) { for (j = 0; j < ms->num_streams; j++) HTS_Model_clear(&ms->stream[i][j]); free(ms->stream[i]); } HTS_free(ms->stream); } if (ms->gv != NULL) { for (i = 0; i < ms->num_voices; i++) { for (j = 0; j < ms->num_streams; j++) HTS_Model_clear(&ms->gv[i][j]); free(ms->gv[i]); } free(ms->gv); } HTS_ModelSet_initialize(ms); } /* HTS_match_head_string: return true if head of str is equal to pattern */ static HTS_Boolean HTS_match_head_string(const char *str, const char *pattern, size_t * matched_size) { (*matched_size) = 0; while (1) { if (pattern[(*matched_size)] == '\0') return TRUE; if (str[(*matched_size)] == '\0') return FALSE; if (str[(*matched_size)] != pattern[(*matched_size)]) return FALSE; (*matched_size)++; } } /* HTS_strequal: strcmp wrapper */ static HTS_Boolean HTS_strequal(const char *s1, const char *s2) { if (s1 == NULL && s2 == NULL) return TRUE; else if (s1 == NULL || s2 == NULL) return FALSE; else return strcmp(s1, s2) == 0 ? TRUE : FALSE; } /* HTS_ModelSet_load: load model set */ HTS_Boolean HTS_ModelSet_load(HTS_ModelSet * ms, char **voices, size_t num_voices) { size_t i, j, k, s, e; HTS_Boolean error = FALSE; HTS_File *fp; char buff1[HTS_MAXBUFLEN]; char buff2[HTS_MAXBUFLEN]; size_t matched_size; char **stream_type_list = NULL; size_t *vector_length = NULL; HTS_Boolean *is_msd = NULL; size_t *num_windows = NULL; HTS_Boolean *use_gv = NULL; char *gv_off_context = NULL; /* temporary values */ char *temp_hts_voice_version; size_t temp_sampling_frequency; size_t temp_frame_period; size_t temp_num_states; size_t temp_num_streams; char *temp_stream_type; char *temp_fullcontext_format; char *temp_fullcontext_version; char *temp_gv_off_context; size_t *temp_vector_length; HTS_Boolean *temp_is_msd; size_t *temp_num_windows; HTS_Boolean *temp_use_gv; char **temp_option; char *temp_duration_pdf; char *temp_duration_tree; char ***temp_stream_win; char **temp_stream_pdf; char **temp_stream_tree; char **temp_gv_pdf; char **temp_gv_tree; long start_of_data; HTS_File *pdf_fp = NULL; HTS_File *tree_fp = NULL; HTS_File **win_fp = NULL; HTS_File *gv_off_context_fp = NULL; HTS_ModelSet_clear(ms); if (ms == NULL || voices == NULL || num_voices < 1) return FALSE; ms->num_voices = num_voices; for (i = 0; i < num_voices && error == FALSE; i++) { /* open file */ fp = HTS_fopen_from_fn(voices[i], "rb"); if (fp == NULL) { error = TRUE; break; } /* reset GLOBAL options */ temp_hts_voice_version = NULL; temp_sampling_frequency = 0; temp_frame_period = 0; temp_num_states = 0; temp_num_streams = 0; temp_stream_type = NULL; temp_fullcontext_format = NULL; temp_fullcontext_version = NULL; temp_gv_off_context = NULL; if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) { error = TRUE; break; } /* load GLOBAL options */ if (HTS_strequal(buff1, "[GLOBAL]") != TRUE) { error = TRUE; break; } while (1) { if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) { error = TRUE; break; } if (HTS_strequal(buff1, "[STREAM]") == TRUE) { break; } else if (HTS_match_head_string(buff1, "HTS_VOICE_VERSION:", &matched_size) == TRUE) { if (temp_hts_voice_version != NULL) free(temp_hts_voice_version); temp_hts_voice_version = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "SAMPLING_FREQUENCY:", &matched_size) == TRUE) { temp_sampling_frequency = (size_t) atoi(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "FRAME_PERIOD:", &matched_size) == TRUE) { temp_frame_period = (size_t) atoi(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "NUM_STATES:", &matched_size) == TRUE) { temp_num_states = (size_t) atoi(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "NUM_STREAMS:", &matched_size) == TRUE) { temp_num_streams = (size_t) atoi(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "STREAM_TYPE:", &matched_size) == TRUE) { if (temp_stream_type != NULL) free(temp_stream_type); temp_stream_type = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "FULLCONTEXT_FORMAT:", &matched_size) == TRUE) { if (temp_fullcontext_format != NULL) free(temp_fullcontext_format); temp_fullcontext_format = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "FULLCONTEXT_VERSION:", &matched_size) == TRUE) { if (temp_fullcontext_version != NULL) free(temp_fullcontext_version); temp_fullcontext_version = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "GV_OFF_CONTEXT:", &matched_size) == TRUE) { if (temp_gv_off_context != NULL) free(temp_gv_off_context); temp_gv_off_context = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "COMMENT:", &matched_size) == TRUE) { } else { HTS_error(0, "HTS_ModelSet_load: Unknown option %s.\n", buff1); } } /* check GLOBAL options */ if (i == 0) { ms->hts_voice_version = temp_hts_voice_version; ms->sampling_frequency = temp_sampling_frequency; ms->frame_period = temp_frame_period; ms->num_states = temp_num_states; ms->num_streams = temp_num_streams; ms->stream_type = temp_stream_type; ms->fullcontext_format = temp_fullcontext_format; ms->fullcontext_version = temp_fullcontext_version; gv_off_context = temp_gv_off_context; } else { if (HTS_strequal(ms->hts_voice_version, temp_hts_voice_version) != TRUE) error = TRUE; if (ms->sampling_frequency != temp_sampling_frequency) error = TRUE; if (ms->frame_period != temp_frame_period) error = TRUE; if (ms->num_states != temp_num_states) error = TRUE; if (ms->num_streams != temp_num_streams) error = TRUE; if (HTS_strequal(ms->stream_type, temp_stream_type) != TRUE) error = TRUE; if (HTS_strequal(ms->fullcontext_format, temp_fullcontext_format) != TRUE) error = TRUE; if (HTS_strequal(ms->fullcontext_version, temp_fullcontext_version) != TRUE) error = TRUE; if (HTS_strequal(gv_off_context, temp_gv_off_context) != TRUE) error = TRUE; if (temp_hts_voice_version != NULL) free(temp_hts_voice_version); if (temp_stream_type != NULL) free(temp_stream_type); if (temp_fullcontext_format != NULL) free(temp_fullcontext_format); if (temp_fullcontext_version != NULL) free(temp_fullcontext_version); if (temp_gv_off_context != NULL) free(temp_gv_off_context); } /* find stream names */ if (i == 0) { stream_type_list = (char **) HTS_calloc(ms->num_streams, sizeof(char *)); for (j = 0, matched_size = 0; j < ms->num_streams; j++) { if (HTS_get_token_from_string_with_separator(ms->stream_type, &matched_size, buff2, ',') == TRUE) { stream_type_list[j] = HTS_strdup(buff2); } else { stream_type_list[j] = NULL; error = TRUE; } } } if (error != FALSE) { HTS_fclose(fp); break; } /* reset STREAM options */ temp_vector_length = (size_t *) HTS_calloc(ms->num_streams, sizeof(size_t)); for (j = 0; j < ms->num_streams; j++) temp_vector_length[j] = 0; temp_is_msd = (HTS_Boolean *) HTS_calloc(ms->num_streams, sizeof(HTS_Boolean)); for (j = 0; j < ms->num_streams; j++) temp_is_msd[j] = FALSE; temp_num_windows = (size_t *) HTS_calloc(ms->num_streams, sizeof(size_t)); for (j = 0; j < ms->num_streams; j++) temp_num_windows[j] = 0; temp_use_gv = (HTS_Boolean *) HTS_calloc(ms->num_streams, sizeof(HTS_Boolean)); for (j = 0; j < ms->num_streams; j++) temp_use_gv[j] = FALSE; temp_option = (char **) HTS_calloc(ms->num_streams, sizeof(char *)); for (j = 0; j < ms->num_streams; j++) temp_option[j] = NULL; /* load STREAM options */ while (1) { if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) { error = TRUE; break; } if (strcmp(buff1, "[POSITION]") == 0) { break; } else if (HTS_match_head_string(buff1, "VECTOR_LENGTH[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) if (strcmp(stream_type_list[j], buff2) == 0) { temp_vector_length[j] = (size_t) atoi(&buff1[matched_size]); break; } } } } else if (HTS_match_head_string(buff1, "IS_MSD[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) if (strcmp(stream_type_list[j], buff2) == 0) { temp_is_msd[j] = (buff1[matched_size] == '1') ? TRUE : FALSE; break; } } } } else if (HTS_match_head_string(buff1, "NUM_WINDOWS[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) if (strcmp(stream_type_list[j], buff2) == 0) { temp_num_windows[j] = (size_t) atoi(&buff1[matched_size]); break; } } } } else if (HTS_match_head_string(buff1, "USE_GV[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) if (strcmp(stream_type_list[j], buff2) == 0) { temp_use_gv[j] = (buff1[matched_size] == '1') ? TRUE : FALSE; break; } } } } else if (HTS_match_head_string(buff1, "OPTION[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) if (strcmp(stream_type_list[j], buff2) == 0) { if (temp_option[j] != NULL) free(temp_option[j]); temp_option[j] = HTS_strdup(&buff1[matched_size]); break; } } } } else { HTS_error(0, "HTS_ModelSet_load: Unknown option %s.\n", buff1); } } /* check STREAM options */ if (i == 0) { vector_length = temp_vector_length; is_msd = temp_is_msd; num_windows = temp_num_windows; use_gv = temp_use_gv; ms->option = temp_option; } else { for (j = 0; j < ms->num_streams; j++) if (vector_length[j] != temp_vector_length[j]) error = TRUE; for (j = 0; j < ms->num_streams; j++) if (is_msd[j] != is_msd[j]) error = TRUE; for (j = 0; j < ms->num_streams; j++) if (num_windows[j] != temp_num_windows[j]) error = TRUE; for (j = 0; j < ms->num_streams; j++) if (use_gv[j] != temp_use_gv[j]) error = TRUE; for (j = 0; j < ms->num_streams; j++) if (HTS_strequal(ms->option[j], temp_option[j]) != TRUE) error = TRUE; free(temp_vector_length); free(temp_is_msd); free(temp_num_windows); free(temp_use_gv); for (j = 0; j < ms->num_streams; j++) if (temp_option[j] != NULL) free(temp_option[j]); free(temp_option); } if (error != FALSE) { HTS_fclose(fp); break; } /* reset POSITION */ temp_duration_pdf = NULL; temp_duration_tree = NULL; temp_stream_win = (char ***) HTS_calloc(ms->num_streams, sizeof(char **)); for (j = 0; j < ms->num_streams; j++) { temp_stream_win[j] = (char **) HTS_calloc(num_windows[j], sizeof(char *)); for (k = 0; k < num_windows[j]; k++) temp_stream_win[j][k] = NULL; } temp_stream_pdf = (char **) HTS_calloc(ms->num_streams, sizeof(char *)); for (j = 0; j < ms->num_streams; j++) temp_stream_pdf[j] = NULL; temp_stream_tree = (char **) HTS_calloc(ms->num_streams, sizeof(char *)); for (j = 0; j < ms->num_streams; j++) temp_stream_tree[j] = NULL; temp_gv_pdf = (char **) HTS_calloc(ms->num_streams, sizeof(char *)); for (j = 0; j < ms->num_streams; j++) temp_gv_pdf[j] = NULL; temp_gv_tree = (char **) HTS_calloc(ms->num_streams, sizeof(char *)); for (j = 0; j < ms->num_streams; j++) temp_gv_tree[j] = NULL; /* load POSITION */ while (1) { if (HTS_get_token_from_fp_with_separator(fp, buff1, '\n') != TRUE) { error = TRUE; break; } if (strcmp(buff1, "[DATA]") == 0) { break; } else if (HTS_match_head_string(buff1, "DURATION_PDF:", &matched_size) == TRUE) { if (temp_duration_pdf != NULL) free(temp_duration_pdf); temp_duration_pdf = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "DURATION_TREE:", &matched_size) == TRUE) { if (temp_duration_tree != NULL) free(temp_duration_tree); temp_duration_tree = HTS_strdup(&buff1[matched_size]); } else if (HTS_match_head_string(buff1, "STREAM_WIN[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) { if (strcmp(stream_type_list[j], buff2) == 0) { for (k = 0; k < num_windows[j]; k++) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ',') == TRUE) temp_stream_win[j][k] = HTS_strdup(buff2); else error = TRUE; } break; } } } } } else if (HTS_match_head_string(buff1, "STREAM_PDF[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) { if (strcmp(stream_type_list[j], buff2) == 0) { if (temp_stream_pdf[j] != NULL) free(temp_stream_pdf[j]); temp_stream_pdf[j] = HTS_strdup(&buff1[matched_size]); break; } } } } } else if (HTS_match_head_string(buff1, "STREAM_TREE[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) { if (strcmp(stream_type_list[j], buff2) == 0) { if (temp_stream_tree[j] != NULL) free(temp_stream_tree[j]); temp_stream_tree[j] = HTS_strdup(&buff1[matched_size]); break; } } } } } else if (HTS_match_head_string(buff1, "GV_PDF[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) { if (strcmp(stream_type_list[j], buff2) == 0) { if (temp_gv_pdf[j] != NULL) free(temp_gv_pdf[j]); temp_gv_pdf[j] = HTS_strdup(&buff1[matched_size]); break; } } } } } else if (HTS_match_head_string(buff1, "GV_TREE[", &matched_size) == TRUE) { if (HTS_get_token_from_string_with_separator(buff1, &matched_size, buff2, ']') == TRUE) { if (buff1[matched_size++] == ':') { for (j = 0; j < ms->num_streams; j++) { if (strcmp(stream_type_list[j], buff2) == 0) { if (temp_gv_tree[j] != NULL) free(temp_gv_tree[j]); temp_gv_tree[j] = HTS_strdup(&buff1[matched_size]); break; } } } } } else { HTS_error(0, "HTS_ModelSet_load: Unknown option %s.\n", buff1); } } /* check POSITION */ if (temp_duration_pdf == NULL) error = TRUE; for (j = 0; j < ms->num_streams; j++) for (k = 0; k < num_windows[j]; k++) if (temp_stream_win[j][k] == NULL) error = TRUE; for (j = 0; j < ms->num_streams; j++) if (temp_stream_pdf[j] == NULL) error = TRUE; /* prepare memory */ if (i == 0) { ms->duration = (HTS_Model *) HTS_calloc(num_voices, sizeof(HTS_Model)); for (j = 0; j < num_voices; j++) HTS_Model_initialize(&ms->duration[j]); ms->window = (HTS_Window *) HTS_calloc(ms->num_streams, sizeof(HTS_Window)); for (j = 0; j < ms->num_streams; j++) HTS_Window_initialize(&ms->window[j]); ms->stream = (HTS_Model **) HTS_calloc(num_voices, sizeof(HTS_Model *)); for (j = 0; j < num_voices; j++) { ms->stream[j] = (HTS_Model *) HTS_calloc(ms->num_streams, sizeof(HTS_Model)); for (k = 0; k < ms->num_streams; k++) HTS_Model_initialize(&ms->stream[j][k]); } ms->gv = (HTS_Model **) HTS_calloc(num_voices, sizeof(HTS_Model *)); for (j = 0; j < num_voices; j++) { ms->gv[j] = (HTS_Model *) HTS_calloc(ms->num_streams, sizeof(HTS_Model)); for (k = 0; k < ms->num_streams; k++) HTS_Model_initialize(&ms->gv[j][k]); } } start_of_data = HTS_ftell(fp); /* load duration */ pdf_fp = NULL; tree_fp = NULL; matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_duration_pdf, &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_duration_pdf[matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); pdf_fp = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_duration_tree, &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_duration_tree[matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); tree_fp = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } if (HTS_Model_load(&ms->duration[i], pdf_fp, tree_fp, ms->num_states, 1, FALSE) != TRUE) error = TRUE; HTS_fclose(pdf_fp); HTS_fclose(tree_fp); /* load windows */ for (j = 0; j < ms->num_streams; j++) { win_fp = (HTS_File **) HTS_calloc(num_windows[j], sizeof(HTS_File *)); for (k = 0; k < num_windows[j]; k++) win_fp[k] = NULL; for (k = 0; k < num_windows[j]; k++) { matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_stream_win[j][k], &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_stream_win[j][k][matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); win_fp[k] = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } } if (HTS_Window_load(&ms->window[j], win_fp, num_windows[j]) != TRUE) error = TRUE; for (k = 0; k < num_windows[j]; k++) HTS_fclose(win_fp[k]); free(win_fp); } /* load streams */ for (j = 0; j < ms->num_streams; j++) { pdf_fp = NULL; tree_fp = NULL; matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_stream_pdf[j], &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_stream_pdf[j][matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); pdf_fp = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_stream_tree[j], &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_stream_tree[j][matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); tree_fp = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } if (HTS_Model_load(&ms->stream[i][j], pdf_fp, tree_fp, vector_length[j], num_windows[j], is_msd[j]) != TRUE) error = TRUE; HTS_fclose(pdf_fp); HTS_fclose(tree_fp); } /* load GVs */ for (j = 0; j < ms->num_streams; j++) { pdf_fp = NULL; tree_fp = NULL; matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_gv_pdf[j], &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_gv_pdf[j][matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); pdf_fp = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } matched_size = 0; if (HTS_get_token_from_string_with_separator(temp_gv_tree[j], &matched_size, buff2, '-') == TRUE) { s = (size_t) atoi(buff2); e = (size_t) atoi(&temp_gv_tree[j][matched_size]); HTS_fseek(fp, (long) s, SEEK_CUR); tree_fp = HTS_fopen_from_fp(fp, e - s + 1); HTS_fseek(fp, start_of_data, SEEK_SET); } if (use_gv[j] == TRUE) { if (HTS_Model_load(&ms->gv[i][j], pdf_fp, tree_fp, vector_length[j], 1, FALSE) != TRUE) error = TRUE; } HTS_fclose(pdf_fp); HTS_fclose(tree_fp); } /* free */ if (temp_duration_pdf != NULL) free(temp_duration_pdf); if (temp_duration_tree != NULL) free(temp_duration_tree); for (j = 0; j < ms->num_streams; j++) { for (k = 0; k < num_windows[j]; k++) if (temp_stream_win[j][k] != NULL) free(temp_stream_win[j][k]); free(temp_stream_win[j]); } free(temp_stream_win); for (j = 0; j < ms->num_streams; j++) if (temp_stream_pdf[j] != NULL) free(temp_stream_pdf[j]); free(temp_stream_pdf); for (j = 0; j < ms->num_streams; j++) if (temp_stream_tree[j] != NULL) free(temp_stream_tree[j]); free(temp_stream_tree); for (j = 0; j < ms->num_streams; j++) if (temp_gv_pdf[j] != NULL) free(temp_gv_pdf[j]); free(temp_gv_pdf); for (j = 0; j < ms->num_streams; j++) if (temp_gv_tree[j] != NULL) free(temp_gv_tree[j]); free(temp_gv_tree); /* fclose */ HTS_fclose(fp); if (error != FALSE) break; } if (gv_off_context != NULL) { sprintf(buff1, "GV-Off { %s }", gv_off_context); gv_off_context_fp = HTS_fopen_from_data((void *) buff1, strlen(buff1) + 1); ms->gv_off_context = (HTS_Question *) HTS_calloc(1, sizeof(HTS_Question)); HTS_Question_initialize(ms->gv_off_context); HTS_Question_load(ms->gv_off_context, gv_off_context_fp); HTS_fclose(gv_off_context_fp); free(gv_off_context); } if (stream_type_list != NULL) { for (i = 0; i < ms->num_streams; i++) if (stream_type_list[i] != NULL) free(stream_type_list[i]); free(stream_type_list); } if (vector_length != NULL) free(vector_length); if (is_msd != NULL) free(is_msd); if (num_windows != NULL) free(num_windows); if (use_gv != NULL) free(use_gv); return !error; } /* HTS_ModelSet_get_sampling_frequency: get sampling frequency of HTS voices */ size_t HTS_ModelSet_get_sampling_frequency(HTS_ModelSet * ms) { return ms->sampling_frequency; } /* HTS_ModelSet_get_fperiod: get frame period of HTS voices */ size_t HTS_ModelSet_get_fperiod(HTS_ModelSet * ms) { return ms->frame_period; } /* HTS_ModelSet_get_fperiod: get stream option */ const char *HTS_ModelSet_get_option(HTS_ModelSet * ms, size_t stream_index) { return ms->option[stream_index]; } /* HTS_ModelSet_get_gv_flag: get GV flag */ HTS_Boolean HTS_ModelSet_get_gv_flag(HTS_ModelSet * ms, const char *string) { if (ms->gv_off_context == NULL) return TRUE; else if (HTS_Question_match(ms->gv_off_context, string) == TRUE) return FALSE; else return TRUE; } /* HTS_ModelSet_get_nstate: get number of state */ size_t HTS_ModelSet_get_nstate(HTS_ModelSet * ms) { return ms->num_states; } /* HTS_ModelSet_get_nstream: get number of stream */ size_t HTS_ModelSet_get_nstream(HTS_ModelSet * ms) { return ms->num_streams; } /* HTS_ModelSet_get_nvoices: get number of stream */ size_t HTS_ModelSet_get_nvoices(HTS_ModelSet * ms) { return ms->num_voices; } /* HTS_ModelSet_get_vector_length: get vector length */ size_t HTS_ModelSet_get_vector_length(HTS_ModelSet * ms, size_t stream_index) { return ms->stream[0][stream_index].vector_length; } /* HTS_ModelSet_is_msd: get MSD flag */ HTS_Boolean HTS_ModelSet_is_msd(HTS_ModelSet * ms, size_t stream_index) { return ms->stream[0][stream_index].is_msd; } /* HTS_ModelSet_get_window_size: get dynamic window size */ size_t HTS_ModelSet_get_window_size(HTS_ModelSet * ms, size_t stream_index) { return ms->window[stream_index].size; } /* HTS_ModelSet_get_window_left_width: get left width of dynamic window */ int HTS_ModelSet_get_window_left_width(HTS_ModelSet * ms, size_t stream_index, size_t window_index) { return ms->window[stream_index].l_width[window_index]; } /* HTS_ModelSet_get_window_right_width: get right width of dynamic window */ int HTS_ModelSet_get_window_right_width(HTS_ModelSet * ms, size_t stream_index, size_t window_index) { return ms->window[stream_index].r_width[window_index]; } /* HTS_ModelSet_get_window_coefficient: get coefficient of dynamic window */ double HTS_ModelSet_get_window_coefficient(HTS_ModelSet * ms, size_t stream_index, size_t window_index, size_t coefficient_index) { return ms->window[stream_index].coefficient[window_index][coefficient_index]; } /* HTS_ModelSet_get_window_max_width: get max width of dynamic window */ size_t HTS_ModelSet_get_window_max_width(HTS_ModelSet * ms, size_t stream_index) { return ms->window[stream_index].max_width; } /* HTS_ModelSet_use_gv: get GV flag */ HTS_Boolean HTS_ModelSet_use_gv(HTS_ModelSet * ms, size_t stream_index) { if (ms->gv[0][stream_index].vector_length != 0) return TRUE; else return FALSE; } /* HTS_Model_add_parameter: get parameter using interpolation weight */ static void HTS_Model_add_parameter(HTS_Model * model, size_t state_index, const char *string, double *mean, double *vari, double *msd, double weight) { size_t i; size_t tree_index, pdf_index; size_t len = model->vector_length * model->num_windows; HTS_Model_get_index(model, state_index, string, &tree_index, &pdf_index); for (i = 0; i < len; i++) { mean[i] += weight * model->pdf[tree_index][pdf_index][i]; vari[i] += weight * model->pdf[tree_index][pdf_index][i + len]; } if (msd != NULL && model->is_msd == TRUE) *msd += weight * model->pdf[tree_index][pdf_index][len + len]; } /* HTS_ModelSet_get_duration_index: get duration PDF & tree index */ void HTS_ModelSet_get_duration_index(HTS_ModelSet * ms, size_t voice_index, const char *string, size_t * tree_index, size_t * pdf_index) { HTS_Model_get_index(&ms->duration[voice_index], 2, string, tree_index, pdf_index); } /* HTS_ModelSet_get_duration: get duration using interpolation weight */ void HTS_ModelSet_get_duration(HTS_ModelSet * ms, const char *string, const double *iw, double *mean, double *vari) { size_t i; size_t len = ms->num_states; for (i = 0; i < len; i++) { mean[i] = 0.0; vari[i] = 0.0; } for (i = 0; i < ms->num_voices; i++) if (iw[i] != 0.0) HTS_Model_add_parameter(&ms->duration[i], 2, string, mean, vari, NULL, iw[i]); } /* HTS_ModelSet_get_parameter_index: get paramter PDF & tree index */ 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) { HTS_Model_get_index(&ms->stream[voice_index][stream_index], state_index, string, tree_index, pdf_index); } /* HTS_ModelSet_get_parameter: get parameter using interpolation weight */ 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) { size_t i; size_t len = ms->stream[0][stream_index].vector_length * ms->stream[0][stream_index].num_windows; for (i = 0; i < len; i++) { mean[i] = 0.0; vari[i] = 0.0; } if (msd != NULL) *msd = 0.0; for (i = 0; i < ms->num_voices; i++) if (iw[i] != 0.0) HTS_Model_add_parameter(&ms->stream[i][stream_index], state_index, string, mean, vari, msd, iw[i]); } /* HTS_ModelSet_get_gv_index: get gv PDF & tree index */ 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) { HTS_Model_get_index(&ms->gv[voice_index][stream_index], 2, string, tree_index, pdf_index); } /* HTS_ModelSet_get_gv: get GV using interpolation weight */ void HTS_ModelSet_get_gv(HTS_ModelSet * ms, size_t stream_index, const char *string, const double *iw, double *mean, double *vari) { size_t i; size_t len = ms->stream[0][stream_index].vector_length; for (i = 0; i < len; i++) { mean[i] = 0.0; vari[i] = 0.0; } for (i = 0; i < ms->num_voices; i++) if (iw[i] != 0.0) HTS_Model_add_parameter(&ms->gv[i][stream_index], 2, string, mean, vari, NULL, iw[i]); } HTS_MODEL_C_END; #endif /* !HTS_MODEL_C */