/** * Insert a new node to the index tree. * * @param str [in] new key string * @param data [in] new data pointer * @param matchstr [in] the most matching data already exist in the index tree, * as obtained by aptree_search_data() * @param rootnode [i/o] pointer to root index node */ void aptree_add_entry(char *str, void *data, char *matchstr, APATNODE **rootnode, BMALLOC_BASE **mroot) { int bitloc; bitloc = where_the_bit_differ(str, matchstr); if (*rootnode == NULL) { *rootnode = aptree_make_root_node(data, mroot); } else { aptree_add_entry_at(str, strlen(str), bitloc, data, rootnode, mroot); } }
/** * 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); }