/** * @file rdhmmlist.c * * * @brief HMMListファイルを読み込む * * HMMList ファイルは,辞書上の音素表記(トライフォン表記)から * 実際に定義されている %HMM へのマッピングを行なうファイルです. * * HMMListファイルでは,登場しうる音素について,対応する * HMM 定義の名前を記述します.一行に1つづつ,第1カラムに音素名, * スペースで区切って第2カラムに定義されている実際の %HMM 名を指定します. * 第1カラムと第2カラムが全く同じ場合,すなわちその音素名のモデルが直接 * %HMM として定義されている場合は,第2カラムは省略することができます. * * トライフォン使用時は,HMMListファイルで登場しうる全てのトライフォンに * ついて記述する必要がある点に注意して下さい.もし与えられた認識辞書 * 上で登場しうるトライフォンがHMMListに記述されていない場合, * エラーとなります. * * * * @brief Read in HMMList file * * HMMList file specifies how the phones as described in word dictionary, * or their context-dependent form, should be mapped to actual defined %HMM. * * In HMMList file, the possible phone names and their corresponding %HMM * name should be specified one per line. The phone name should be put on * the first column, and its corresponding %HMM name in the HTK %HMM definition * file should be defined on the second column. If the two strings are * the same, which occurs when a %HMM of the phone name is directly defined, * the second column can be omitted. * * When using a triphone model, ALL the possible triphones that can appear * on the given word dictionary should be specified in the HMMList file. * If some possible triphone are not specified in the HMMList, Julius * produces error. * * * @author Akinobu LEE * @date Wed Feb 16 04:04:23 2005 * * $Revision: 1.5 $ * */ /* * Copyright (c) 1991-2012 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology * All rights reserved */ #include #include #include #define MAXLINEINHMMLIST 256 ///< Maximum line length in HMMList /** * Read a HMMList file and build initial logical triphone list. * * @param fp [in] file pointer * @param hmminfo [i/o] %HMM definition data to store the logical phone list * * @return TRUE on success, FALSE on failure. */ boolean rdhmmlist(FILE *fp, HTK_HMM_INFO *hmminfo) { char *buf, *lname, *pname; HMM_Logical *new, *match; HTK_HMM_Data *mapped; boolean ok_flag = TRUE; int n; /* 1 column ... define HMM_Logical of the name as referring to HMM of the same name */ /* 2 column ... define HMM_Logical of the name "$1" which has pointer to $2 */ buf = (char *)mymalloc(MAXLINEINHMMLIST); n = 0; while (getl(buf, MAXLINEINHMMLIST, fp) != NULL) { n++; if ((lname = strtok(buf, DELM)) == NULL) { jlog("Error: rdhmmlist: failed to parse, corrupted or invalid data?\n"); return FALSE; } if (strlen(lname) >= MAX_HMMNAME_LEN) { jlog("Error: rdhmmlist: %d: name too long: \"%s\"\n", n, lname); jlog("Error: rdhmmlist: try increase value of MAX_HMMNAME_LEN\n"); return FALSE; } pname = strtok(NULL, DELM); if (pname == NULL) { /* 1 column */ mapped = htk_hmmdata_lookup_physical(hmminfo, lname); if (mapped == NULL) { jlog("Error: rdhmmlist: line %d: physical HMM \"%s\" not found\n", n, lname); ok_flag = FALSE; continue; } } else { /* 2 column */ mapped = htk_hmmdata_lookup_physical(hmminfo, pname); if (strlen(pname) >= MAX_HMMNAME_LEN) { jlog("Error: rdhmmlist: %d: name too long: \"%s\"\n", n, pname); jlog("Error: rdhmmlist: please increase MAX_HMMNAME_LEN (%d) and re-compile\n", MAX_HMMNAME_LEN); return FALSE; } if (mapped == NULL) { jlog("Error: rdhmmlist: line %d: physical HMM \"%s\" not found\n", n, pname); ok_flag = FALSE; continue; } } /* create new HMM_Logical */ new = (HMM_Logical *)mybmalloc2(sizeof(HMM_Logical), &(hmminfo->lroot)); new->name = mybstrdup2(lname, &(hmminfo->lroot)); new->is_pseudo = FALSE; new->body.defined = mapped; new->next = hmminfo->lgstart; hmminfo->lgstart = new; /* add index to search index tree */ if (hmminfo->logical_root == NULL) { hmminfo->logical_root = aptree_make_root_node(new, &(hmminfo->lroot)); } else { match = aptree_search_data(new->name, hmminfo->logical_root); if (match != NULL && strmatch(match->name, new->name)) { jlog("Error: rdhmmlist: line %d: logical HMM \"%s\" duplicated\n", n, new->name); ok_flag = FALSE; } else { aptree_add_entry(new->name, new, match->name, &(hmminfo->logical_root), &(hmminfo->lroot)); } } } hmminfo->totallogicalnum = n; free(buf); return(ok_flag); }