📄 search_bestfirst_v1.c
字号:
maxwn = r->lm->winfo->maxwn + 10; dwrk = &(r->pass2); dwrk->wordtrellis[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn); dwrk->wordtrellis[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn); dwrk->g = (LOGPROB *)mymalloc(sizeof(LOGPROB) * r->peseqlen); dwrk->phmmlen_max = r->lm->winfo->maxwlen + 2; dwrk->phmmseq = (HMM_Logical **)mymalloc(sizeof(HMM_Logical *) * dwrk->phmmlen_max); if (r->lm->config->enable_iwsp && r->am->hmminfo->multipath) { dwrk->has_sp = (boolean *)mymalloc(sizeof(boolean) * dwrk->phmmlen_max); } else { dwrk->has_sp = NULL; } dwrk->wend_token_frame[0] = NULL; dwrk->wend_token_frame[1] = NULL; dwrk->wend_token_gscore[0] = NULL; dwrk->wend_token_gscore[1] = NULL;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { dwrk->wend_token_frame[0] = (short *)mymalloc(sizeof(short) * maxwn); dwrk->wend_token_frame[1] = (short *)mymalloc(sizeof(short) * maxwn); dwrk->wend_token_gscore[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn); dwrk->wend_token_gscore[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn); }#endif }/** * <JA> * 1帽胳尸のトレリス纷换脱のワ〖クエアリアを豺庶 * * </JA> * <EN> * Free the work area for trellis computation of a word. * * </EN> * @callgraph * @callergraph */voidfree_wordtrellis(StackDecode *dwrk){ int i; free(dwrk->wordtrellis[0]); free(dwrk->wordtrellis[1]); free(dwrk->g); free(dwrk->phmmseq); if (dwrk->has_sp) { free(dwrk->has_sp); dwrk->has_sp = NULL; }#ifdef GRAPHOUT_PRECISE_BOUNDARY for(i=0;i<2;i++) { if (dwrk->wend_token_frame[i]) { free(dwrk->wend_token_frame[i]); dwrk->wend_token_frame[i] = NULL; } if (dwrk->wend_token_gscore[i]) { free(dwrk->wend_token_gscore[i]); dwrk->wend_token_gscore[i] = NULL; } }#endif}/**********************************************************************//************ 簿棱の涟羹き锑刨纷换 *******************//************ Compute forward score of a hypothesis *******************//**********************************************************************//** * <JA> * 呵姜觉轮への莲败澄唯の呵络猛を滇める (multipath) * * @param tr [in] 莲败乖误 * @param state_num [in] 觉轮眶 * * @return 呵姜觉轮への莲败澄唯への呵络猛を手す. * </JA> * <EN> * Get the maximum transition log probability to final state. (multipath) * * @param tr [in] transition matrix * @param state_num [in] number of states * * @return the maximum log probability of transition to the final state. * </EN> */static LOGPROBget_max_out_arc(HTK_HMM_Trans *tr, int state_num){ LOGPROB max_a; int afrom; LOGPROB a; max_a = LOG_ZERO; for (afrom = 0; afrom < state_num - 1; afrom++) { a = tr->a[afrom][state_num-1]; if (max_a < a) max_a = a; } return(max_a);}/** * <JA> * 不燎の叫蜗觉轮への莲败澄唯の呵络猛を滇める. (multipath) * * @param l [in] 不燎 * * @return 叫蜗觉轮への莲败澄唯の呵络猛を手す. * </JA> * <EN> * Get the maximum transition log probability outside a phone. (multipath) * * @param l [in] phone * * @return the maximum transition log probability outside a phone. * </EN> */static LOGPROBmax_out_arc(HMM_Logical *l){ return(get_max_out_arc(hmm_logical_trans(l), hmm_logical_state_num(l)));}/** * <JA> * 呵稿の1帽胳の涟羹きトレリスを纷换して·矢簿棱の涟羹き锑刨を构糠する. * * @param now [i/o] 矢簿棱 * @param param [in] 掐蜗パラメ〖タ误 * @param r [in] 千急借妄インスタンス * * </JA> * <EN> * Compute the forward viterbi for the last word to update forward scores * and ready for word connection. * * @param now [i/o] hypothesis * @param param [in] input parameter vectors * @param r [in] recognition process instance * * </EN> * @callgraph * @callergraph */voidscan_word(NODE *now, HTK_Param *param, RecogProcess *r){ int i,t, j; HMM *whmm; A_CELL *ac; WORD_ID word; LOGPROB tmpmax, tmptmp, score1; int startt = 0, endt; int wordhmmnum; LOGPROB tmpmax_store, store_point_maxarc; /* multipath */ LOGPROB tmpmax2 = LOG_ZERO; int phmmlen; HMM_Logical *ret, *wend; int store_point; int crossword_point = 0; boolean back_rescan = FALSE; boolean node_exist_p; int tn; ///< Temporal pointer to current buffer int tl; ///< Temporal pointer to previous buffer /* store global values to local for rapid access */ WORD_INFO *winfo; HTK_HMM_INFO *hmminfo; LOGPROB *framemaxscore; int peseqlen; boolean ccd_flag; boolean enable_iwsp;#ifdef SCAN_BEAM LOGPROB scan_beam_thres;#endif StackDecode *dwrk; winfo = r->lm->winfo; hmminfo = r->am->hmminfo; dwrk = &(r->pass2); peseqlen = r->peseqlen; framemaxscore = r->pass2.framemaxscore; ccd_flag = r->ccd_flag; enable_iwsp = r->lm->config->enable_iwsp; /* multipath */#ifdef SCAN_BEAM scan_beam_thres = r->config->pass2.scan_beam_thres;#endif if (hmminfo->multipath) { store_point = -1; } else { store_point = 0; } /* ----------------------- prepare HMM ----------------------- */ if (ccd_flag) { /* 木涟の不燎があれば·そこまでさかのぼって scan する */ /* if there are any last phone, enable backscan */ if (now->last_ph == NULL) { /* initial score: now->g[] */ /* scan range: phones in now->seq[now->seqnum-1] */ back_rescan = FALSE; } else { /* initial score: now->g_prev[] (1-phone before)*/ /* scan range: phones in now->seq[now->seqnum-1] + now->last_ph */ back_rescan = TRUE; } }#ifdef TCD if (now->last_ph != NULL) { jlog("DEBUG: inherited last_ph: %s\n", (now->last_ph)->name); if (now->last_ph_sp_attached) jlog("DEBUG: (sp attached)\n"); /* multipath */ } else { jlog("DEBUG: no last_ph inherited\n"); }#endif /* scan 认跋尸のHMMを洁洒 */ /* prepare HMM of the scan range */ word = now->seq[now->seqnum-1]; if (ccd_flag) { if (back_rescan) { /* scan range: phones in now->seq[now->seqnum-1] + now->last_ph */ phmmlen = winfo->wlen[word] + 1; if (phmmlen > dwrk->phmmlen_max) { j_internal_error("scan_word: num of phonemes in a word exceed phmmlenmax (%d) ?\n", dwrk->phmmlen_max); } for (i=0;i<phmmlen - 2;i++) dwrk->phmmseq[i] = winfo->wseq[word][i]; if (enable_iwsp && hmminfo->multipath) { for (i=0;i<phmmlen - 2;i++) dwrk->has_sp[i] = FALSE; } /* 呵姜帽胳と last_ph 粗の帽胳粗triphoneを雇胃 */ /* consider cross-word context dependency between the last word and now->last_ph */ wend = winfo->wseq[word][winfo->wlen[word]-1]; ret = get_right_context_HMM(wend, now->last_ph->name, hmminfo); if (ret == NULL) { /* triphone not found */ /* fallback to the original bi/mono-phone */ /* error if the original is pseudo phone (not explicitly defined in hmmdefs/hmmlist) */ /* exception: word with 1 phone (triphone may exist in the next expansion */ if (winfo->wlen[word] > 1 && wend->is_pseudo) { error_missing_right_triphone(wend, now->last_ph->name); } dwrk->phmmseq[phmmlen-2] = wend; } else { dwrk->phmmseq[phmmlen-2] = ret; } ret = get_left_context_HMM(now->last_ph, wend->name, hmminfo); if (ret == NULL) { /* fallback to the original bi/mono-phone */ /* error if the original is pseudo phone (not explicitly defined in hmmdefs/hmmlist) */ if (now->last_ph->is_pseudo) { error_missing_left_triphone(now->last_ph, wend->name); } dwrk->phmmseq[phmmlen-1] = now->last_ph; } else { dwrk->phmmseq[phmmlen-1] = ret; } if (enable_iwsp && hmminfo->multipath) { dwrk->has_sp[phmmlen-2] = TRUE; dwrk->has_sp[phmmlen-1] = now->last_ph_sp_attached; } #ifdef TCD jlog("DEBUG: w="); for(i=0;i<winfo->wlen[word];i++) { jlog(" %s",(winfo->wseq[word][i])->name); if (enable_iwsp && hmminfo->multipath && dwrk->has_sp[i]) jlog("(sp)"); } jlog(" | %s\n", (now->last_ph)->name); if (hmminfo->multipath && now->last_ph_sp_attached) jlog("DEBUG: (sp)\n"); jlog("DEBUG: scan for:"); for (i=0;i<phmmlen;i++) { jlog(" %s", dwrk->phmmseq[i]->name); if (enable_iwsp && hmminfo->multipath && dwrk->has_sp[i]) jlog("(sp)"); } jlog("\n");#endif /* 帽胳HMMを侯る */ /* make word HMM */ whmm = new_make_word_hmm(hmminfo, dwrk->phmmseq, phmmlen, (enable_iwsp && hmminfo->multipath) ? dwrk->has_sp : NULL); if (whmm == NULL) { j_internal_error("Error: failed to make word hmm for word #%d \"%s [%s]\"\n", word, winfo->wname[word], winfo->woutput[word]); } /* backscan なので·纷换涟の g[] 介袋猛は now->g_prev[] を蝗脱 */ /* As backscan enabled, the initial forward score g[] is set by now->g_prev[] */ for (t=0;t<peseqlen;t++) { dwrk->g[t]=now->g_prev[t]; } /* 肌檬脱のg_prevを呈羌するノ〖ド疤弥を肋年 */ /* set where to store scores as new g_prev[] for the next backscan in the HMM */ if (hmminfo->multipath) { store_point = hmm_logical_state_num(dwrk->phmmseq[0]) - 2; store_point_maxarc = max_out_arc(dwrk->phmmseq[0]); if (enable_iwsp && dwrk->has_sp[0]) { store_point += hmm_logical_state_num(hmminfo->sp) - 2; if (store_point_maxarc < max_out_arc(hmminfo->sp)) { store_point_maxarc = max_out_arc(hmminfo->sp); } } } else { store_point = hmm_logical_state_num(dwrk->phmmseq[0]) - 2 - 1; } /* scan面に木涟帽胳とこの帽胳をまたぐ眷疥を肋年 */ /* set where is the connection point of the last word in the HMM */ if (hmminfo->multipath) { crossword_point = whmm->len - hmm_logical_state_num(dwrk->phmmseq[phmmlen-1]); if (enable_iwsp && dwrk->has_sp[phmmlen-1]) { crossword_point -= hmm_logical_state_num(hmminfo->sp) - 2; } } else { crossword_point = whmm->len - (hmm_logical_state_num(dwrk->phmmseq[phmmlen-1]) - 2) - 1; } } else { /* not backscan mode */ /* scan range: phones in now->seq[now->seqnum-1] */ #ifdef TCD jlog("DEBUG: scan(org):"); for (i=0;i<winfo->wlen[word];i++) { jlog(" %s", (winfo->wseq[word][i])->name); } jlog("\n");#endif if (enable_iwsp && hmminfo->multipath) { /* 涩妥ならばショ〖トポ〖ズを洞み哈む疤弥を回年する */ for(i=0;i<winfo->wlen[word];i++) { dwrk->has_sp[i] = FALSE; } dwrk->has_sp[winfo->wlen[word]-1] = TRUE; } /* 帽胳HMMを侯る */ /* make word HMM */ whmm = new_make_word_hmm(hmminfo, winfo->wseq[word], winfo->wlen[word], (enable_iwsp && hmminfo->multipath) ? dwrk->has_sp : NULL); if (whmm == NULL) { j_internal_error("Error: failed to make word hmm for word #%d \"%s [%s]\"\n", word, winfo->wname[word], winfo->woutput[word]); } /* 纷换涟の g[] 介袋猛は now->g[] を蝗脱 */ /* the initial forward score g[] is set by now->g[] */ for (t=0;t<peseqlen;t++) { dwrk->g[t]=now->g[t]; } /* 肌檬脱のg_prevを呈羌するノ〖ド疤弥を肋年 */ /* set where to store scores as new g_prev[] for the next backscan in the HMM */ if (hmminfo->multipath) { store_point = hmm_logical_state_num(winfo->wseq[word][0]) - 2; store_point_maxarc = max_out_arc(winfo->wseq[word][0]); if (enable_iwsp && dwrk->has_sp[0]) { store_point += hmm_logical_state_num(hmminfo->sp) - 2; if (store_point_maxarc < max_out_arc(hmminfo->sp)) { store_point_maxarc = max_out_arc(hmminfo->sp); } } } else { store_point = hmm_logical_state_num(winfo->wseq[word][0]) - 2 - 1; } /* scan面に木涟帽胳とこの帽胳をまたぐ眷疥は·なし */ /* the connection point of the last word is not exist in the HMM */ crossword_point = -1; } } else { /* ccd_flag == FALSE */ if (enable_iwsp && hmminfo->multipath) { /* 涩妥ならばショ〖トポ〖ズを洞み哈む疤弥を回年する */ for(i=0;i<winfo->wlen[word];i++) { dwrk->has_sp[i] = FALSE; } dwrk->has_sp[winfo->wlen[word]-1] = TRUE; } /* 不燎茨董润巴赂の眷圭は帽姐に呵姜帽胳尸の HMM を侯喇 */ /* for monophone: simple make HMM for the last word */ whmm = new_make_word_hmm(hmminfo, winfo->wseq[word], winfo->wlen[word], (enable_iwsp && hmminfo->multipath) ? dwrk->has_sp : NULL); if (whmm == NULL) { j_internal_error("Error: failed to make word hmm for word #%d \"%s [%s]\"\n", word, winfo->wname[word], winfo->woutput[word]); } /* 纷换涟の g[] 介袋猛は now->g[] を蝗脱 */ /* the initial forward score g[] is set by now->g[] */ for (t=0;t<peseqlen;t++) { dwrk->g[t]=now->g[t]; } }#ifdef TCD jlog("DEBUG: whmm len = %d\n",whmm->len); jlog("DEBUG: crossword_point = %d\n", crossword_point); jlog("DEBUG: g[] store point = %d\n", store_point);#endif wordhmmnum = whmm->len; if (wordhmmnum >= winfo->maxwn + 10) { j_internal_error("scan_word: word too long (>%d)\n", winfo->maxwn + 10); }#ifndef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -