/** * Look up for a pseudo phone with the name, and return the content. * * @param hmminfo [in] %HMM information to search for. * @param cdstr [in] string of pseudo phone name to search. * * @return pointer to the pseudo phone if found, or NULL if not found. */ CD_Set * cdset_lookup(HTK_HMM_INFO *hmminfo, char *cdstr) { CD_Set *cd; cd = aptree_search_data(cdstr, hmminfo->cdset_info.cdtree); if (cd != NULL && strmatch(cdstr, cd->name)) { return cd; } else { return NULL; } }
/** * Look up logical %HMM by its name. * * @param hmminfo [in] HMM definition data * @param keyname [in] key string of %HMM name * * @return pointer to the found logical %HMM, NULL if not found. */ HMM_Logical * htk_hmmdata_lookup_logical(HTK_HMM_INFO *hmminfo, char *keyname) { HMM_Logical *tmp; tmp = aptree_search_data(keyname, hmminfo->logical_root); if (tmp != NULL && strmatch(tmp->name, keyname)) { return tmp; } else { return NULL; } }
/** * Look up a data macro by the name. * * @param hmm [in] %HMM definition data * @param keyname [in] macro name to find * * @return pointer to the found data, or NULL if not found. */ static GCODEBOOK * codebook_lookup(HTK_HMM_INFO *hmm, char *keyname) { GCODEBOOK *book; if (hmm->codebook_root == NULL) return(NULL); book = aptree_search_data(keyname, hmm->codebook_root); if (book != NULL && strmatch(book->name, keyname)) { return book; } else { return NULL; } }
/** * <JA> * @brief 単語末尾のトライフォンセット (pseudo phone set) を検索する. * * 文法認識では,各カテゴリごとに独立した pseudo phone set を用いる. * ここでは単語末用カテゴリ付き pseudo phone set を検索する. * * @param wchmm [in] 木構造化辞書 * @param hmm [in] 単語の末尾の HMM * @param category [in] 単語の属するカテゴリ * * @return 該当 set が見つかればそこへのポインタ,あるいは見つからなければ * NULL を返す. * </JA> * <EN> * Lookup a word-end triphone set (aka pseudo phone set) with * category id for grammar recognition. * * @param wchmm [in] word lexicon tree * @param hmm [in] logical HMM of word end phone * @param category [in] belonging category id of the word * * @return pointer to the corresponding phone set if found, or NULL if * not found. * </EN> * @callgraph * @callergraph */ CD_Set * lcdset_lookup_with_category(WCHMM_INFO *wchmm, HMM_Logical *hmm, WORD_ID category) { CD_Set *cd; leftcenter_name(hmm->name, wchmm->lccbuf); sprintf(wchmm->lccbuf2, "%s::%04d", wchmm->lccbuf, category); if (wchmm->lcdset_category_root != NULL) { cd = aptree_search_data(wchmm->lccbuf2, wchmm->lcdset_category_root); if (cd == NULL) return NULL; if (strmatch(wchmm->lccbuf2, cd->name)) { return cd; } } return NULL; }
/** * Add a triphone name to the missing error list in WORD_INFO. * * @param winfo [i/o] word dictionary to add the error phone to error list * @param name [in] phone name to be added */ static void add_to_error(WORD_INFO *winfo, char *name) { char *buf; char *match; buf = (char *)mymalloc(strlen(name) + 1); strcpy(buf, name); if (winfo->errph_root == NULL) { winfo->errph_root = aptree_make_root_node(buf, &(winfo->mroot)); } else { match = aptree_search_data(buf, winfo->errph_root); if (match == NULL || !strmatch(match, buf)) { aptree_add_entry(buf, buf, match, &(winfo->errph_root), &(winfo->mroot)); } } }
/** * Register a physical %HMM as a member of a pseudo phone set. * * @param root [i/o] root node of %HMM search index node. * @param d [in] a physical defined %HMM to be added. * @param cdname [in] name of the pseudo phone set. * * @return TRUE if newly registered, FALSE if the specified physical %HMM already exists in the pseudo phone. */ boolean regist_cdset(APATNODE **root, HTK_HMM_Data *d, char *cdname, BMALLOC_BASE **mroot) { boolean need_new; CD_State_Set *tmp; CD_Set *lset = NULL, *lmatch = NULL; int j,n; boolean changed = FALSE; if (strlen(cdname) >= MAX_HMMNAME_LEN) { jlog("Error: cdset: HMM name exceeds limit (%d): %s!\n", MAX_HMMNAME_LEN, cdname); jlog("Error: cdset: Please increase the value of MAX_HMMNAME_LEN (current = %d)\n", MAX_HMMNAME_LEN); exit(1); } /* check if the cdset already exist */ need_new = TRUE; if (*root != NULL) { lmatch = aptree_search_data(cdname, *root); if (lmatch != NULL && strmatch(lmatch->name, cdname)) { /* exist, add to it later */ lset = lmatch; need_new = FALSE; /* if the state num is larger than allocated, expand the lset */ if (d->state_num > lset->state_num) { lset->stateset = (CD_State_Set *)myrealloc(lset->stateset, sizeof(CD_State_Set) * d->state_num); /* 0 1 ... (lset->state_num-1) */ /* N A ... N */ /* 0 1 ... ... (d->state_num-1) */ /* N A ... A ..................... N */ /* malloc new area to expanded state (N to A above) */ for(j = lset->state_num - 1; j < d->state_num - 1; j++) { lset->stateset[j].maxnum = CD_STATE_SET_STEP; lset->stateset[j].s = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * lset->stateset[j].maxnum); lset->stateset[j].num = 0; } lset->stateset[d->state_num-1].s = NULL; lset->stateset[d->state_num-1].num = 0; lset->stateset[d->state_num-1].maxnum = 0; lset->state_num = d->state_num; /* update transition table */ lset->tr = d->tr; changed = TRUE; } } } if (need_new) { /* allocate as new with blank data */ lset = cdset_new(); lset->name = strdup(cdname); lset->state_num = d->state_num; lset->stateset = (CD_State_Set *)mymalloc(sizeof(CD_State_Set) * lset->state_num); /* assume first and last state has no outprob */ lset->stateset[0].s = lset->stateset[lset->state_num-1].s = NULL; lset->stateset[0].num = lset->stateset[lset->state_num-1].num = 0; lset->stateset[0].maxnum = lset->stateset[lset->state_num-1].maxnum = 0; for(j=1;j<lset->state_num-1; j++) { /* pre-allocate only the first step */ lset->stateset[j].maxnum = CD_STATE_SET_STEP; lset->stateset[j].s = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * lset->stateset[j].maxnum); lset->stateset[j].num = 0; } /* assign transition table of first found %HMM (ad-hoc?) */ lset->tr = d->tr; /* add to search index tree */ if (*root == NULL) { *root = aptree_make_root_node(lset, mroot); } else { aptree_add_entry(lset->name, lset, lmatch->name, root, mroot); } changed = TRUE; } /* register each HMM states to the lcdset */ for (j=1;j<d->state_num-1;j++) { tmp = &(lset->stateset[j]); /* check if the state has already registered */ for(n = 0; n < tmp->num ; n++) { if (tmp->s[n] == d->s[j]) { /* compare by pointer */ /*jlog("\tstate %d has same\n", n);*/ break; } } if (n < tmp->num ) continue; /* same state found, cancel regist. */ /* expand storage area if necessary */ if (tmp->num >= tmp->maxnum) { tmp->maxnum += CD_STATE_SET_STEP; tmp->s = (HTK_HMM_State **)myrealloc(tmp->s, sizeof(HTK_HMM_State *) * tmp->maxnum); } tmp->s[tmp->num] = d->s[j]; tmp->num++; changed = TRUE; } return(changed); }