📄 rdhmmdef.c
字号:
/** * @file rdhmmdef.c * * <JA> * @brief HTK %HMM 年盗ファイルの粕み哈み¨メイン * * ここには HTK 妨及の %HMM 年盗ファイルを粕み哈むための簇眶凡を钙び叫す * メイン簇眶が箭められていますˉ * * このファイルはまた·粕み哈み簇眶凡で鼎奶して脱いられるト〖クン帽疤の * ファイル粕み哈み簇眶を捏丁しますˉ * %HMM 年盗ファイルは read_token() によってト〖クン帽疤で界肌粕み哈まれ· * グロ〖バル恃眶 rdhmmdef_token に呈羌されますˉ称簇眶凡はこの * rdhmmdef_token を徊救して附哼のト〖クンを评ますˉ * </JA> * * <EN> * @brief Read HTK %HMM definition file: the main * * This file includes the main routine to read the %HMM definition file in * HTK format. * * This file also contains functions and global variables for per-token * reading tailored for reading HTK %HMM definition file. The read_token() * will read the file per token, and the read token is stored in a global * variable rdhmmdef_token. The other reading function will refer to this * variable to read the current token. * </EN> * * @author Akinobu LEE * @date Wed Feb 16 00:17:18 2005 * * $Revision: 1.3 $ * *//* * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology * All rights reserved */#include <sent/stddefs.h>#include <sent/htk_param.h>#include <sent/htk_hmm.h>#define MAXBUFLEN 4096 ///< Maximum length of a line in the inputchar *rdhmmdef_token; ///< Current token string (GLOBAL)static char *buf = NULL; ///< Local work area for token readingstatic int line; ///< Input Line count/* global functions for rdhmmdef_*.c *//** * Output error message, with current reading status, and terminate * * @param str [in] error string */voidrderr(char *str){ if (rdhmmdef_token == NULL) { /* end of file */ jlog("Error: rdhmmdef: %s on end of file\n", str); } else { jlog("Error: rdhmmdef: read error at line %d: %s\n", line, (str) ? str : "parse error"); } jlog_flush(); exit(1);}/** * Read next token and ste it to rdhmmdef_token. * * @param fp [in] file pointer * * @return the pointer to the read token, or NULL on end of file or error. */char *read_token(FILE *fp){ if (buf != NULL) { /* already have buffer */ if ((rdhmmdef_token = mystrtok_quote(NULL, HMMDEF_DELM)) != NULL) { /* return next token */ return rdhmmdef_token; } } else { /* init: allocate buffer for the first time */ buf = (char *)mymalloc(MAXBUFLEN); line = 1; } /* read new 1 line */ if (getl(buf, MAXBUFLEN, fp) == NULL) { rdhmmdef_token = NULL; } else { rdhmmdef_token = mystrtok_quote(buf, HMMDEF_DELM); line++; } return rdhmmdef_token;}/** * Convert all the transition probabilities to log10 scale. * * @param hmm [i/o] %HMM definition data to modify. */static voidconv_log_arc(HTK_HMM_INFO *hmm){ HTK_HMM_Trans *tr; int i,j; LOGPROB l; for (tr = hmm->trstart; tr; tr = tr->next) { for(i=0;i<tr->statenum;i++) { for(j=0;j<tr->statenum;j++) { l = tr->a[i][j]; tr->a[i][j] = (l != 0.0) ? (float)log10(l) : LOG_ZERO; } } }}/** * Invert all the variance values. * * @param hmm [i/o] %HMM definition data to modify. */voidhtk_hmm_inverse_variances(HTK_HMM_INFO *hmm){ HTK_HMM_Var *v; int i; for (v = hmm->vrstart; v; v = v->next) { for(i=0;i<v->len;i++) { v->vec[i] = 1.0 / v->vec[i]; } }}#ifdef ENABLE_MSD/** * Check if this HMM contains MSD-HMM. The status will be set to hmm->has_msd. * * @param hmm [i/o] %HMM definition data to check. */voidhtk_hmm_check_msd(HTK_HMM_INFO *hmm){ HTK_HMM_PDF *m; int vlen; int i; hmm->has_msd = FALSE; for (m = hmm->pdfstart; m; m = m->next) { /* skip tied-mixture pdf */ if (m->tmix) continue; /* check if vector length are the same */ vlen = hmm->opt.stream_info.vsize[m->stream_id]; for(i=0;i<m->mix_num;i++) { if (m->b[i]->meanlen != vlen) { jlog("Stat: rdhmmdef: assume MSD-HMM since Gaussian dimension are not consistent\n"); hmm->has_msd = TRUE; return; } } }}#endif/** * @brief Main top routine to read in HTK %HMM definition file. * * A HTK %HMM definition file will be read from @a fp. After reading, * the parameter type is checked and calculate some statistics. * * @param fp [in] file pointer * @param hmm [out] pointer to a %HMM definition structure to store data. * * @return TRUE on success, FALSE on failure. */booleanrdhmmdef(FILE *fp, HTK_HMM_INFO *hmm){ char macrosw; char *name; /* variances in htkdefs are not inversed yet */ hmm->variance_inversed = FALSE; /* read the first token */ read_token(fp); /* the toplevel loop */ while (rdhmmdef_token != NULL) {/* break on EOF */ if (rdhmmdef_token[0] != '~') { /* toplevel commands are always macro */ return FALSE; } macrosw = rdhmmdef_token[1]; read_token(fp); /* read next token after the "~.." */ switch(macrosw) { case 'o': /* global option */ if (set_global_opt(fp,hmm) == FALSE) { return FALSE; } break; case 't': /* transition macro */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_trans_macro(name, fp, hmm); break; case 's': /* state macro */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_state_macro(name, fp, hmm); break; case 'm': /* density (mixture) macro */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_dens_macro(name, fp, hmm); break; case 'h': /* HMM define */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_HMM(name, fp, hmm); break; case 'v': /* Variance macro */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_var_macro(name, fp, hmm); break; case 'w': /* Stream weight macro */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_streamweight_macro(name, fp, hmm); break; case 'r': /* Regression class macro (ignore) */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_regtree_macro(name, fp, hmm); break; case 'p': /* Mixture pdf macro (extension of HTS) */ name = mybstrdup2(rdhmmdef_token, &(hmm->mroot)); if (strlen(name) >= MAX_HMMNAME_LEN) rderr("Macro name too long"); read_token(fp); def_mpdf_macro(name, fp, hmm); break; } } /* convert transition prob to log scale */ conv_log_arc(hmm); jlog("Stat: rdhmmdef: ascii format HMM definition\n"); /* check limitation */ if (check_all_hmm_limit(hmm)) { jlog("Stat: rdhmmdef: limit check passed\n"); } else { jlog("Error: rdhmmdef: cannot handle this HMM due to system limitation\n"); return FALSE; } /* determine whether this model needs multi-path handling */ hmm->need_multipath = htk_hmm_has_several_arc_on_edge(hmm); if (hmm->need_multipath) { jlog("Stat: rdhmmdef: this HMM requires multipath handling at decoding\n"); } else { jlog("Stat: rdhmmdef: this HMM does not need multipath handling\n"); } /* inverse all variance values for faster computation */ if (! hmm->variance_inversed) { htk_hmm_inverse_variances(hmm); hmm->variance_inversed = TRUE; } /* check HMM parameter option type */ if (!check_hmm_options(hmm)) { jlog("Error: rdhmmdef: hmm options check failed\n"); return FALSE; } /* add ID number for all HTK_HMM_State */ /* also calculate the maximum number of mixture */ { HTK_HMM_State *stmp; int n, max, s, mix; n = 0; max = 0; for (stmp = hmm->ststart; stmp; stmp = stmp->next) { for(s=0;s<stmp->nstream;s++) { mix = stmp->pdf[s]->mix_num; if (max < mix) max = mix; } stmp->id = n++; if (n >= MAX_STATE_NUM) { jlog("Error: rdhmmdef: too much states in a model > %d\n", MAX_STATE_NUM); return FALSE; } } hmm->totalstatenum = n; hmm->maxmixturenum = max; } /* compute total number of HMM models and maximum length */ { HTK_HMM_Data *dtmp; int n, maxlen; n = 0; maxlen = 0; for (dtmp = hmm->start; dtmp; dtmp = dtmp->next) { if (maxlen < dtmp->state_num) maxlen = dtmp->state_num; n++; } hmm->maxstatenum = maxlen; hmm->totalhmmnum = n; } /* compute total number of Gaussians */ { HTK_HMM_Dens *dtmp; int n = 0; for (dtmp = hmm->dnstart; dtmp; dtmp = dtmp->next) { n++; } hmm->totalmixnum = n; } /* check of HMM name length exceed the maximum */ { HTK_HMM_Dens *dtmp; int n = 0; for (dtmp = hmm->dnstart; dtmp; dtmp = dtmp->next) { n++; } hmm->totalmixnum = n; } /* compute total number of mixture PDFs */ { HTK_HMM_PDF *p; int n = 0; for (p = hmm->pdfstart; p; p = p->next) { n++; } hmm->totalpdfnum = n; }#ifdef ENABLE_MSD /* check if MSD-HMM */ htk_hmm_check_msd(hmm);#endif return(TRUE); /* success */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -