📄 search_bestfirst_v2.c
字号:
wordend_frame_dst[t] = dwrk->wend_token_frame[tn][0]; wordend_gscore_dst[t] = dwrk->wend_token_gscore[tn][0]; }#endif /* 回年された least_frame より黎まで t が渴んでおり·かつこの t において スコアエンベロ〖プによって栏き荒ったノ〖ドが办つも痰かった眷圭, このフレ〖ムで纷换を虑ち磊りそれ笆惧黎([0..t-1])は纷换しない */ /* if frame 't' already reached the 'least_frame' and no node was survived in this frame (all nodes pruned by score envelope), terminate computation at this frame and do not computer further frame ([0..t-1]). */ if (t < least_frame && (!node_exist_p)) { /* crear the rest scores */ for (i=t-1;i>=0;i--) { g_new[i] = LOG_ZERO;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { wordend_frame_dst[i] = -1; wordend_gscore_dst[i] = LOG_ZERO; }#endif } /* terminate loop */ break; } } /* end of time loop */ if (hmminfo->multipath) { /* 涟羹きスコアの呵姜猛を纷换 (觉轮 0 から箕粗 0 への莲败) */ /* compute the total forward score (transition from state 0 to frame 0 */ if (t < 0) { /* computed till the end */ tmpmax = LOG_ZERO; for(ac=whmm->state[0].ac;ac;ac=ac->next) { tmpscore = dwrk->wordtrellis[tn][ac->arc] + ac->a; if (tmpmax < tmpscore) tmpmax = tmpscore; } *final_g = tmpmax; } else { *final_g = LOG_ZERO; } } /* free work area */ free_hmm(whmm);}/** * <JA> * 呵稿の1不燎に滦して Viterbi 纷换を渴める. * * @param now [in] 鸥倡傅の矢簿棱. 办不燎涟の涟羹きスコアが g[] にあるとする. * @param new [out] 纷换稿の涟羹きスコアが g[] に呈羌される. * @param lastphone [in] Viterbi纷换を乖う不燎HMM * @param sp [in] short-pause insertion * @param param [in] 掐蜗ベクトル误 * @param r [in] 千急借妄インスタンス * </JA> * <EN> * Proceed Viterbi for the last one phoneme. * * @param now [in] source hypothesis where the forward scores prior to the * last one phone is stored at g[] * @param new [out] the resulting updated forward scores will be saved to g[] * @param lastphone [in] phone HMM for the Viterbi processing * @param sp [in] short-pause insertion * @param param [in] input vectors * @param r [in] recognition process instance * </EN> */static voiddo_viterbi_next_word(NODE *now, NODE *new, HMM_Logical *lastphone, boolean sp, HTK_Param *param, RecogProcess *r) /* sp is for multipath only */{ int t, n; LOGPROB a_value; /* for non multi-path */ int peseqlen; boolean multipath; StackDecode *dwrk; dwrk = &(r->pass2); multipath = r->am->hmminfo->multipath; peseqlen = r->peseqlen; if (! multipath) { /* もし鸥倡傅簿棱の呵稿の帽胳の不燎墓が 1 であれば·その不燎は 木涟の scan_word で纷换されていない. この眷圭, now->g[] に笆涟の 介袋猛が呈羌されている. もし不燎墓が1笆惧であれば·now->g[] はその缄涟まで纷换した觉轮 のスコアが掐っているので,now->g[t] から介袋猛を肋年する涩妥がある */ /* If the length of last word is 1, it means the last phone was not scanned in the last call of scan_word(). In this case, now->g[] keeps the previous initial value, so start viterbi with the old scores. If the length is more than 1, the now->g[] keeps the values of the scan result till the previous phone, so make initial value considering last transition probability. */ if (r->lm->winfo->wlen[now->seq[now->seqnum-1]] > 1) { n = hmm_logical_state_num(lastphone); a_value = (hmm_logical_trans(lastphone))->a[n-2][n-1]; for(t=0; t<peseqlen-1; t++) dwrk->g[t] = now->g[t+1] + a_value; dwrk->g[peseqlen-1] = LOG_ZERO; } else { for(t=0; t<peseqlen; t++) dwrk->g[t] = now->g[t]; } } else { for(t=0; t<peseqlen; t++) dwrk->g[t] = now->g[t]; dwrk->phmmseq[0] = lastphone; if (r->lm->config->enable_iwsp) dwrk->has_sp[0] = sp; } do_viterbi(dwrk->g, new->g, multipath ? dwrk->phmmseq : &lastphone, (r->lm->config->enable_iwsp && multipath) ? dwrk->has_sp : NULL, 1, param, peseqlen, now->estimated_next_t, &(new->final_g)#ifdef GRAPHOUT_PRECISE_BOUNDARY , now->wordend_frame, new->wordend_frame , now->wordend_gscore, new->wordend_gscore#else , NULL, NULL , NULL, NULL#endif , r );#ifdef GRAPHOUT_PRECISE_BOUNDARY if (! multipath) { if (r->graphout) { /* 肌搀の next_word 脱に董肠攫鼠を拇腊 */ /* proceed word boundary for one step for next_word */ new->wordend_frame[r->peseqlen-1] = new->wordend_frame[0]; new->wordend_gscore[r->peseqlen-1] = new->wordend_gscore[0]; for (t=0;t<r->peseqlen-1;t++) { new->wordend_frame[t] = new->wordend_frame[t+1]; new->wordend_gscore[t] = new->wordend_gscore[t+1]; } } }#endif}/** * <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; WORD_ID word; int phmmlen; HMM_Logical *tailph; /* store global values to local for rapid access */ WORD_INFO *winfo; HTK_HMM_INFO *hmminfo; int peseqlen; boolean ccd_flag; boolean enable_iwsp; /* multipath */ StackDecode *dwrk; dwrk = &(r->pass2); winfo = r->lm->winfo; hmminfo = r->am->hmminfo; peseqlen = r->peseqlen; ccd_flag = r->ccd_flag; if (hmminfo->multipath) { enable_iwsp = r->lm->config->enable_iwsp; } #ifndef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { if (ccd_flag) { now->tail_g_score = now->g[now->bestt]; } }#endif /* ----------------------- prepare phoneme sequence ------------------ */ /* triphoneなら黎片の1不燎はここでは滦据嘲(あとでnext_wordでやる) */ /* 琐萨の1不燎はコンテキストにしたがって弥垂 */ /* with triphone, modify the tail phone of the last word according to the previous word, and do not compute the head phone here (that will be computed later in next_word() */ word = now->seq[now->seqnum-1]; #ifdef TCD jlog("DEBUG: w="); for(i=0;i<winfo->wlen[word];i++) { jlog(" %s",(winfo->wseq[word][i])->name); } if (ccd_flag) { if (now->last_ph != NULL) { jlog(" | %s", (now->last_ph)->name); } } jlog("\n");#endif /* TCD */ if (ccd_flag) { /* the tail triphone of the last word varies by context */ if (now->last_ph != NULL) { tailph = get_right_context_HMM(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name, hmminfo); if (tailph == NULL) { /* 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 && winfo->wseq[word][winfo->wlen[word]-1]->is_pseudo){ error_missing_right_triphone(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name); } tailph = winfo->wseq[word][winfo->wlen[word]-1]; } } else { tailph = winfo->wseq[word][winfo->wlen[word]-1]; } /* 墓さ1の帽胳は肌のnextwordでさらに恃步するのでここではscanしない */ /* do not scan word if the length is 1, as it further varies in the following next_word() */ if (winfo->wlen[word] == 1) { now->last_ph = tailph; if (enable_iwsp && hmminfo->multipath) now->last_ph_sp_attached = TRUE;#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { /* 帽胳董肠帕嚷攫鼠を介袋步 */ /* initialize word boundary propagation info */ for (t=0;t<peseqlen;t++) { now->wordend_frame[t] = t; now->wordend_gscore[t] = now->g[t]; } }#endif#ifdef TCD jlog("DEBUG: suspended as %s\n", (now->last_ph)->name);#endif return; } /* scan认跋の不燎误を洁洒 */ /* prepare HMM of the scan range */ 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-1;i++) { dwrk->phmmseq[i] = winfo->wseq[word][i+1]; } dwrk->phmmseq[phmmlen-1] = tailph; if (enable_iwsp && hmminfo->multipath) { for (i=0;i<phmmlen-1;i++) dwrk->has_sp[i] = FALSE; dwrk->has_sp[phmmlen-1] = TRUE; } } else { /* ~ccd_flag */ phmmlen = winfo->wlen[word]; for (i=0;i<phmmlen;i++) dwrk->phmmseq[i] = winfo->wseq[word][i]; if (enable_iwsp && hmminfo->multipath) { for (i=0;i<phmmlen;i++) dwrk->has_sp[i] = FALSE; dwrk->has_sp[phmmlen-1] = TRUE; } } /* 傅のg[]をいったん略闰しておく */ /* temporally keeps the original g[] */ for (t=0;t<peseqlen;t++) dwrk->g[t] = now->g[t];#ifdef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { /* 帽胳董肠帕嚷攫鼠を介袋步 */ /* initialize word boundary propagation info */ for (t=0;t<peseqlen;t++) { dwrk->wef[t] = t; dwrk->wes[t] = now->g[t]; } }#endif /* viterbiを悸乖して g[] から now->g[] を构糠する */ /* do viterbi computation for phmmseq from g[] to now->g[] */ do_viterbi(dwrk->g, now->g, dwrk->phmmseq, (enable_iwsp && hmminfo->multipath) ? dwrk->has_sp : NULL, phmmlen, param, peseqlen, now->estimated_next_t, &(now->final_g)#ifdef GRAPHOUT_PRECISE_BOUNDARY /* 帽胳董肠攫鼠 we[] から now->wordend_frame[] を构糠する */ /* propagate word boundary info from we[] to now->wordend_frame[] */ , dwrk->wef, now->wordend_frame , dwrk->wes, now->wordend_gscore#else , NULL, NULL , NULL, NULL#endif , r );#ifdef GRAPHOUT_PRECISE_BOUNDARY if (! hmminfo->multipath) { if (r->graphout) { /* 肌搀の next_word 脱に董肠攫鼠を拇腊 */ /* proceed word boundary for one step for next_word */ now->wordend_frame[peseqlen-1] = now->wordend_frame[0]; now->wordend_gscore[peseqlen-1] = now->wordend_gscore[0]; for (t=0;t<peseqlen-1;t++) { now->wordend_frame[t] = now->wordend_frame[t+1]; now->wordend_gscore[t] = now->wordend_gscore[t+1]; } } }#endif if (ccd_flag) { /* 肌搀のために now->last_ph を构糠 */ /* update 'now->last_ph' for future scan_word() */ now->last_ph = winfo->wseq[word][0]; if (enable_iwsp && hmminfo->multipath) now->last_ph_sp_attached = FALSE; /* wlen > 1 here */#ifdef TCD jlog("DEBUG: last_ph = %s\n", (now->last_ph)->name);#endif }}/**************************************************************************//*** 糠簿棱の鸥倡とヒュ〖リスティックを芬いだ链挛スコアを纷换 ***//*** Expand new hypothesis and compute the total score (with heuristic) ***//**************************************************************************//** * <JA> * 鸥倡傅簿棱に肌帽胳を儡鲁して糠しい簿棱を栏喇する. 肌帽胳の帽胳トレリス惧の * スコアから呵锑儡鲁爬を滇め·簿棱スコアを纷换する. * * @param now [in] 鸥倡傅簿棱 * @param new [out] 糠たに栏喇された簿棱が呈羌される * @param nword [in] 儡鲁する肌帽胳の攫鼠 * @param param [in] 掐蜗パラメ〖タ误 * @param r [in] 千急借妄インスタンス * </JA> * <EN> * Connect a new word to generate a next hypothesis. The optimal connection * point and new sentence score of the new hypothesis will be estimated by * looking up the corresponding words on word trellis. * * @param now [in] source hypothesis * @param new [out] pointer to save the newly generated hypothesis * @param nword [in] next word to be connected * @param param [in] input parameter vector * @param r [in] recognition process instance * </EN> * @callgraph * @callergraph
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -