/** * Top function to compute the output probability of a HMM state. * * @param wrk [i/o] HMM computation work area * @param t [in] input frame * @param hmmstate [in] HMM state * @param param [in] input parameter data * * @return the computed log output probability. */ LOGPROB outprob(HMMWork *wrk, int t, HMM_STATE *hmmstate, HTK_Param *param) { if (hmmstate->is_pseudo_state) { return(outprob_cd(wrk, t, hmmstate->out.cdset, param)); } else { return(outprob_state(wrk, t, hmmstate->out.state, param)); } }
/** * <JA> * 木構造化辞書上の状態の出力確率を計算する. * * @param wchmm [in] 木構造化辞書情報 * @param node [in] ノード番号 * @param last_wid [in] 直前単語(単語先頭のトライフォン計算に用いる) * @param t [in] 時間フレーム * @param param [in] 特徴量パラメータ構造体 (@a t 番目のベクトルについて計算する) * * @return 出力確率の対数値を返す. * </JA> * <EN> * Calculate output probability on a tree lexion node. This function * calculates log output probability of an input vector on time frame @a t * in input paramter @a param at a node on tree lexicon. * * @param wchmm [in] tree lexicon structure * @param node [in] node ID to compute the output probability * @param last_wid [in] word ID of last word hypothesis (used when the node is * within the word beginning phone and triphone is used. * @param t [in] time frame of input vector in @a param to compute. * @param param [in] input parameter structure * * @return the computed log probability. * </EN> * @callgraph * @callergraph */ LOGPROB outprob_style(WCHMM_INFO *wchmm, int node, int last_wid, int t, HTK_Param *param) { char rbuf[MAX_HMMNAME_LEN]; ///< Local workarea for HMM name conversion #ifndef PASS1_IWCD /* if cross-word triphone handling is disabled, we simply compute the output prob of the state */ return(outprob_state(wchmm->hmmwrk, t, wchmm->state[node].out, param)); #else /* PASS1_IWCD */ /* state type and context cache is considered */ HMM_Logical *ohmm, *rhmm; RC_INFO *rset; LRC_INFO *lrset; CD_Set *lcd; WORD_INFO *winfo = wchmm->winfo; HTK_HMM_INFO *hmminfo = wchmm->hmminfo; /* the actual computation is different according to their context dependency handling */ switch(wchmm->outstyle[node]) { case AS_STATE: /* normal state (word-internal or context-independent )*/ /* compute as usual */ return(outprob_state(wchmm->hmmwrk, t, wchmm->state[node].out.state, param)); case AS_LSET: /* node in word end phone */ /* compute approximated value using the state set in pseudo phone */ return(outprob_cd(wchmm->hmmwrk, t, wchmm->state[node].out.lset, param)); case AS_RSET: /* note in the beginning phone of word */ /* depends on the last word hypothesis to compute the actual triphone */ rset = wchmm->state[node].out.rset; /* consult cache */ if (rset->cache.state == NULL || rset->lastwid_cache != last_wid) { /* cache miss...calculate */ /* rset contains either defined biphone or pseudo biphone */ if (last_wid != WORD_INVALID) { /* lookup triphone with left-context (= last phoneme) */ if ((ohmm = get_left_context_HMM(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) { rhmm = ohmm; } else { /* if triphone not found, try to use the bi-phone itself */ rhmm = rset->hmm; /* If the bi-phone is explicitly specified in hmmdefs/HMMList, use it. if both triphone and biphone not found in user-given hmmdefs/HMMList, use "pseudo" phone, as same as the end of word */ if (debug2_flag) { if (rhmm->is_pseudo) { error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name); } } } } else { /* if last word is WORD_INVALID try to use the bi-phone itself */ rhmm = rset->hmm; /* If the bi-phone is explicitly specified in hmmdefs/HMMList, use it. if not, use "pseudo" phone, as same as the end of word */ if (debug2_flag) { if (rhmm->is_pseudo) { error_missing_left_triphone(rset->hmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name); } } } /* rhmm may be a pseudo phone */ /* store to cache */ if (rhmm->is_pseudo) { rset->last_is_lset = TRUE; rset->cache.lset = &(rhmm->body.pseudo->stateset[rset->state_loc]); } else { rset->last_is_lset = FALSE; rset->cache.state = rhmm->body.defined->s[rset->state_loc]; } rset->lastwid_cache = last_wid; } /* calculate outprob and return */ if (rset->last_is_lset) { return(outprob_cd(wchmm->hmmwrk, t, rset->cache.lset, param)); } else { return(outprob_state(wchmm->hmmwrk, t, rset->cache.state, param)); } case AS_LRSET: /* node in word with only one phoneme --- both beginning and end */ lrset = wchmm->state[node].out.lrset; if (lrset->cache.state == NULL || lrset->lastwid_cache != last_wid) { /* cache miss...calculate */ rhmm = lrset->hmm; /* lookup cdset for given left context (= last phoneme) */ strcpy(rbuf, rhmm->name); if (last_wid != WORD_INVALID) { add_left_context(rbuf, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name); } if (wchmm->category_tree) { #ifdef USE_OLD_IWCD lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf); #else /* use category-indexed cdset */ if (last_wid != WORD_INVALID && (ohmm = get_left_context_HMM(rhmm, (winfo->wseq[last_wid][winfo->wlen[last_wid]-1])->name, hmminfo)) != NULL) { lcd = lcdset_lookup_with_category(wchmm, ohmm, lrset->category); } else { lcd = lcdset_lookup_with_category(wchmm, rhmm, lrset->category); } #endif } else { lcd = lcdset_lookup_by_hmmname(hmminfo, rbuf); } if (lcd != NULL) { /* found, set to cache */ lrset->last_is_lset = TRUE; lrset->cache.lset = &(lcd->stateset[lrset->state_loc]); lrset->lastwid_cache = last_wid; } else { /* no relating lcdset found, falling to normal state */ if (rhmm->is_pseudo) { lrset->last_is_lset = TRUE; lrset->cache.lset = &(rhmm->body.pseudo->stateset[lrset->state_loc]); lrset->lastwid_cache = last_wid; } else { lrset->last_is_lset = FALSE; lrset->cache.state = rhmm->body.defined->s[lrset->state_loc]; lrset->lastwid_cache = last_wid; } } /*printf("[%s->%s]\n", lrset->hmm->name, rhmm->name);*/ } /* calculate outprob and return */ if (lrset->last_is_lset) { return(outprob_cd(wchmm->hmmwrk, t, lrset->cache.lset, param)); } else { return(outprob_state(wchmm->hmmwrk, t, lrset->cache.state, param)); } default: /* should not happen */ j_internal_error("outprob_style: no outprob style??\n"); return(LOG_ZERO); } #endif /* PASS1_IWCD */ }