📄 search_bestfirst_v2.c
字号:
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->wef = NULL; dwrk->wes = 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->wef = (short *)mymalloc(sizeof(short) * r->peseqlen); dwrk->wes = (LOGPROB *)mymalloc(sizeof(LOGPROB) * r->peseqlen); 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){ 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 if (dwrk->wef) { free(dwrk->wef); free(dwrk->wes); free(dwrk->wend_token_frame[0]); free(dwrk->wend_token_frame[1]); free(dwrk->wend_token_gscore[0]); free(dwrk->wend_token_gscore[1]); dwrk->wef = NULL; }#endif}/**********************************************************************//************ 簿棱の涟羹き锑刨纷换 *******************//************ Compute forward score of a hypothesis *******************//**********************************************************************//* 涂えられた不燎のならび phmmseq[0..phmmlen-1]に滦してviterbi纷换を乖う. g[0..framelen-1] のスコアを介袋猛として g_new[0..framelen-1]に构糠猛を洛掐. 呵你 least_frame まではscanする. *//* Viterbi computation for the given phoneme sequence 'phmmseq[0..phmmlen-1]' with g[0..framelen-1] as initial values. The results are stored in g_new[0..framelen-1]. Scan should not terminate at least it reaches 'least_frame'. *//** * <JA> * 涂えられた不燎の事びに滦して Viterbi 纷换を乖い·涟羹きスコアを * 构糠する绕脱簇眶. * * @param g [in] 附哼の箕粗ごとの涟羹きスコア * @param g_new [out] 构糠稿の糠たな涟羹きスコアを呈羌するバッファ * @param phmmseq [in] 不燎HMMの事び * @param has_sp [in] short-pause location * @param phmmlen [in] @a phmmseq の墓さ * @param param [in] 掐蜗パラメ〖タ * @param framelen [in] 掐蜗フレ〖ム墓 * @param least_frame [in] ビ〖ム肋年箕·このフレ〖ム眶笆惧は Viterbi纷换する * @param final_g [in] final g scores * @param wordend_frame_src [in] 附哼の帽胳姜眉フレ〖ムト〖クン * @param wordend_frame_dst [out] 构糠稿の糠たな帽胳姜眉フレ〖ムト〖クン * @param wordend_gscore_src [in] 附哼の帽胳姜眉スコアト〖クン * @param wordend_gscore_dst [out] 构糠稿の糠たな帽胳姜眉スコアト〖クン * @param r [in] recognition process instance * </JA> * <EN> * Generic function to perform Viterbi path updates for given phoneme * sequence. * * @param g [in] current forward scores at each input frame * @param g_new [out] buffer to save the resulting score updates * @param phmmseq [in] phoneme sequence to perform Viterbi * @param has_sp [in] short-pause location * @param phmmlen [in] length of @a phmmseq. * @param param [in] input parameter vector * @param framelen [in] input frame length to compute * @param least_frame [in] Least frame length to force viterbi even with beam * @param final_g [in] final g scores * @param wordend_frame_src [in] current word-end frame tokens * @param wordend_frame_dst [out] buffer to store updated word-end frame tokens * @param wordend_gscore_src [in] current word-end score tokens * @param wordend_gscore_dst [out] buffer to store updated word-end score tokens * @param r [in] recognition process instance * * </EN> */static voiddo_viterbi(LOGPROB *g, LOGPROB *g_new, HMM_Logical **phmmseq, boolean *has_sp, int phmmlen, HTK_Param *param, int framelen, int least_frame, LOGPROB *final_g, short *wordend_frame_src, short *wordend_frame_dst, LOGPROB *wordend_gscore_src, LOGPROB *wordend_gscore_dst, RecogProcess *r) /* has_sp and final_g is for multipath only */{ HMM *whmm; /* HMM */ int wordhmmnum; /* length of above */ int startt; /* scan start frame */ LOGPROB tmpmax,tmpscore; /* variables for Viterbi process */ A_CELL *ac; int t,i,j; 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 */ StackDecode *dwrk; WORD_INFO *winfo; HTK_HMM_INFO *hmminfo; LOGPROB *framemaxscore;#ifdef SCAN_BEAM LOGPROB scan_beam_thres;#endif dwrk = &(r->pass2); winfo = r->lm->winfo; hmminfo = r->am->hmminfo; framemaxscore = r->pass2.framemaxscore;#ifdef SCAN_BEAM scan_beam_thres = r->config->pass2.scan_beam_thres;#endif#ifdef TCD jlog("DEBUG: scan for:"); for (i=0;i<phmmlen;i++) { jlog(" %s", phmmseq[i]->name); } jlog("\n");#endif /* 帽胳HMMを侯る */ /* make word HMM */ whmm = new_make_word_hmm(hmminfo, phmmseq, phmmlen, has_sp); if (whmm == NULL) { j_internal_error("Error: failed to make word hmm\n"); } wordhmmnum = whmm->len; if (wordhmmnum >= winfo->maxwn + 10) { j_internal_error("do_viterbi: word too long (>%d)\n", winfo->maxwn + 10); } /* scan倡幌爬を浮瑚 -> starttへ*/ /* search for the start frame -> set to startt */ for(t = framelen-1; t >=0 ; t--) { if (#ifdef SCAN_BEAM g[t] > framemaxscore[t] - scan_beam_thres &&#endif g[t] > LOG_ZERO) { break; } } if (t < 0) { /* no node has score > LOG_ZERO */ /* reset all scores and end */ for(t=0;t<framelen;t++) { g_new[t] = LOG_ZERO;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { wordend_frame_dst[t] = -1; wordend_gscore_dst[t] = LOG_ZERO; }#endif } free_hmm(whmm); return; } startt = t; /* 倡幌爬笆惯[startt+1..framelen-1] の g_new[] をリセット */ /* clear g_new[] for [startt+1..framelen-1] */ for(t=framelen-1;t>startt;t--) { g_new[t] = LOG_ZERO;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { wordend_frame_dst[t] = -1; wordend_gscore_dst[t] = LOG_ZERO; }#endif } /*****************/ /* viterbi start */ /*****************/ /* set initial swap buffer */ tn = 0; tl = 1;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { for(i=0;i<wordhmmnum;i++) { dwrk->wend_token_frame[tn][i] = -1; dwrk->wend_token_gscore[tn][i] = LOG_ZERO; } }#endif if (! hmminfo->multipath) { /* 箕粗 [startt] 惧の猛を介袋步 */ /* initialize scores on frame [startt] */ for(i=0;i<wordhmmnum-1;i++) dwrk->wordtrellis[tn][i] = LOG_ZERO; dwrk->wordtrellis[tn][wordhmmnum-1] = g[startt] + outprob(&(r->am->hmmwrk), startt, &(whmm->state[wordhmmnum-1]), param); g_new[startt] = dwrk->wordtrellis[tn][0];#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { dwrk->wend_token_frame[tn][wordhmmnum-1] = wordend_frame_src[startt]; dwrk->wend_token_gscore[tn][wordhmmnum-1] = wordend_gscore_src[startt]; wordend_frame_dst[startt] = dwrk->wend_token_frame[tn][0]; wordend_gscore_dst[startt] = dwrk->wend_token_gscore[tn][0]; }#endif } /* メインル〖プ: startt から幌まり 0 に羹かって Viterbi 纷换 */ /* main loop: start from [startt], and compute Viterbi toward [0] */ for(t = hmminfo->multipath ? startt : startt - 1; t >= 0; t--) { /* wordtrellisのワ〖クエリアをスワップ */ /* swap workarea of wordtrellis */ i = tn; tn = tl; tl = i; node_exist_p = FALSE; /* TRUE if there is at least 1 survived node in this frame */ if (! hmminfo->multipath) { /* 眉のノ〖ド [t][wordhmmnum-1]は·柒婶莲败 か g[]の光い数になる */ /* the edge node [t][wordhmmnum-1] is either internal transitin or g[] */ tmpscore = LOG_ZERO; for (ac=whmm->state[wordhmmnum-1].ac;ac;ac=ac->next) { if (tmpscore < dwrk->wordtrellis[tl][ac->arc] + ac->a) { j = ac->arc; tmpscore = dwrk->wordtrellis[tl][ac->arc] + ac->a; } } if (g[t] > tmpscore) { tmpmax = g[t];#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { dwrk->wend_token_frame[tn][wordhmmnum-1] = wordend_frame_src[t]; dwrk->wend_token_gscore[tn][wordhmmnum-1] = wordend_gscore_src[t]; }#endif } else { tmpmax = tmpscore;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { dwrk->wend_token_frame[tn][wordhmmnum-1] = dwrk->wend_token_frame[tl][j]; dwrk->wend_token_gscore[tn][wordhmmnum-1] = dwrk->wend_token_gscore[tl][j]; }#endif } /* 眉のノ〖ドのスコアエンベロ〖プチェック: 办年升嘲なら皖とす */ /* check if the edge node is within score envelope */ if (#ifdef SCAN_BEAM tmpmax <= framemaxscore[t] - scan_beam_thres ||#endif tmpmax <= LOG_ZERO ) { dwrk->wordtrellis[tn][wordhmmnum-1] = LOG_ZERO;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { dwrk->wend_token_frame[tn][wordhmmnum-1] = -1; dwrk->wend_token_gscore[tn][wordhmmnum-1] = LOG_ZERO; }#endif } else { node_exist_p = TRUE; dwrk->wordtrellis[tn][wordhmmnum-1] = tmpmax + outprob(&(r->am->hmmwrk), t, &(whmm->state[wordhmmnum-1]), param); } } /* node[wordhmmnum-2..0]についてトレリスを鸥倡 */ /* expand trellis for node [t][wordhmmnum-2..0] */ for(i=wordhmmnum-2;i>=0;i--) { /* 呵锑パスと呵锑スコア tmpmax を斧つける */ /* find most likely path and the max score 'tmpmax' */ tmpmax = LOG_ZERO; for (ac=whmm->state[i].ac;ac;ac=ac->next) { if (hmminfo->multipath) { if (ac->arc == wordhmmnum-1) tmpscore = g[t]; else if (t + 1 > startt) tmpscore = LOG_ZERO; else tmpscore = dwrk->wordtrellis[tl][ac->arc]; tmpscore += ac->a; } else { tmpscore = dwrk->wordtrellis[tl][ac->arc] + ac->a; } if (tmpmax < tmpscore) { tmpmax = tmpscore; j = ac->arc; } } /* スコアエンベロ〖プチェック: 办年升嘲なら皖とす */ /* check if score of this node is within the score envelope */ if (#ifdef SCAN_BEAM tmpmax <= framemaxscore[t] - scan_beam_thres ||#endif tmpmax <= LOG_ZERO ) { /* invalid node */ dwrk->wordtrellis[tn][i] = LOG_ZERO;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { dwrk->wend_token_frame[tn][i] = -1; dwrk->wend_token_gscore[tn][i] = LOG_ZERO; }#endif } else { /* survived node */ node_exist_p = TRUE; dwrk->wordtrellis[tn][i] = tmpmax; if (! hmminfo->multipath || i > 0) { dwrk->wordtrellis[tn][i] += outprob(&(r->am->hmmwrk), t, &(whmm->state[i]), param); }#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { if (hmminfo->multipath) { if (j == wordhmmnum-1) { dwrk->wend_token_frame[tn][i] = wordend_frame_src[t]; dwrk->wend_token_gscore[tn][i] = wordend_gscore_src[t]; } else { dwrk->wend_token_frame[tn][i] = dwrk->wend_token_frame[tl][j]; dwrk->wend_token_gscore[tn][i] = dwrk->wend_token_gscore[tl][j]; } } else { dwrk->wend_token_frame[tn][i] = dwrk->wend_token_frame[tl][j]; dwrk->wend_token_gscore[tn][i] = dwrk->wend_token_gscore[tl][j]; } }#endif } } /* end of node loop */ /* 箕粗 t のViterbi纷换姜位. 糠たな涟羹きスコア g_new[t] をセット */ /* Viterbi end for frame [t]. set the new forward score g_new[t] */ g_new[t] = dwrk->wordtrellis[tn][0];#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { /* new wordend */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -