search_bestfirst_main.c
来自「julius version 4.12.about sound recognit」· C语言 代码 · 共 2,134 行 · 第 1/5 页
C
2,134 行
* Initialize */ /* just for quick access */ jconf = r->config; winfo = r->lm->winfo; if (r->lmtype == LM_PROB) { ngram = r->lm->ngram; } else if (r->lmtype == LM_DFA) { gdfa = r->lm->dfa; } backtrellis = r->backtrellis; dwrk = &(r->pass2); stacksize = jconf->pass2.stack_size; ncan = jconf->pass2.nbest; maxhypo = jconf->pass2.hypo_overflow; peseqlen = backtrellis->framelen; /* store data for sub routines */ r->peseqlen = backtrellis->framelen; //recog->ccd_flag = recog->jconf->am.ccd_flag; /* 徒卢帽胳呈羌挝拌を澄瘦 */ /* malloc area for word prediction */ /* the initial maximum number of nextwords is the size of vocabulary */ nextword = nw_malloc(&maxnwnum, &nwroot, winfo->num); /* 涟羹きスコア纷换脱の挝拌を澄瘦 */ /* malloc are for forward viterbi (scan_word()) */ malloc_wordtrellis(r); /* scan_word脱挝拌 */ /* 簿棱スタック介袋步 */ /* initialize hypothesis stack */ start = bottom = NULL; stacknum = 0; /* 冯蔡呈羌スタック介袋步 */ /* initialize result stack */ r_stacksize = ncan; r_start = r_bottom = NULL; r_stacknum = 0; /* カウンタ介袋步 */ /* initialize counter */ dwrk->popctr = 0; dwrk->genectr = 0; dwrk->pushctr = 0; dwrk->finishnum = 0; #ifdef CM_SEARCH /* initialize local stack */ cm_init(dwrk, winfo->num, jconf->annotate.cm_alpha#ifdef CM_MULTIPLE_ALPHA , jconf->annotate.cm_alpha_num#endif );#endif#ifdef SCAN_BEAM /* prepare and initialize score envelope */ dwrk->framemaxscore = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen); envl_init(dwrk, peseqlen);#endif /* SCAN_BEAM */ /* エンベロ〖プ玫瑚脱の帽胳墓侍鸥倡眶カウンタを介袋步 */ /* initialize counters for envelope search */ if (jconf->pass2.enveloped_bestfirst_width >= 0) wb_init(dwrk); if (jconf->graph.enabled) { wordgraph_init(r->wchmm); } /* * 介袋簿棱(1帽胳からなる)を评, 矢簿棱スタックにいれる * get a set of initial words from LM function and push them as initial * hypotheses */ /* the first words will be stored in nextword[] */ if (r->lmtype == LM_PROB) { nwnum = ngram_firstwords(nextword, peseqlen, maxnwnum, r); } else if (r->lmtype == LM_DFA) { nwnum = dfa_firstwords(nextword, peseqlen, maxnwnum, r); /* 邦れたら、バッファを笼やして浩チャレンジ */ /* If the number of nextwords can exceed the buffer size, expand the nextword data area */ while (nwnum < 0) { nextword = nw_expand(nextword, &maxnwnum, &nwroot, winfo->num); nwnum = dfa_firstwords(nextword, peseqlen, maxnwnum, r); } } if (debug2_flag) { jlog("DEBUG: %d words in wordtrellis as first hypothesis\n", nwnum); } /* store them to stack */ for (w = 0; w < nwnum; w++) { if (r->lmtype == LM_DFA) { /* limit word hypothesis */ if (! (winfo->wton[nextword[w]->id] >= cate_bgn && winfo->wton[nextword[w]->id] < cate_bgn + cate_num)) { continue; } } /* generate new hypothesis */ new = newnode(r); start_word(new, nextword[w], param, r); if (r->lmtype == LM_DFA) { if (new->score <= LOG_ZERO) { /* not on trellis */ free_node(new); continue; } } dwrk->genectr++;#ifdef CM_SEARCH /* store the local hypothesis to temporal stack */ cm_store(dwrk, new);#else /* put to stack */ if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) { dwrk->current = new; //callback_exec(CALLBACK_DEBUG_PASS2_PUSH, r); if (jconf->graph.enabled) { new->prevgraph = NULL; new->lastcontext = NULL; } dwrk->pushctr++; }#endif }#ifdef CM_SEARCH /* compute score sum */ cm_sum_score(dwrk#ifdef CM_MULTIPLE_ALPHA , jconf->annotate.cm_alpha_bgn , jconf->annotate.cm_alpha_end , jconf->annotate.cm_alpha_step#endif ); /* compute CM and put the generated hypotheses to global stack */ while ((new = cm_get_node(dwrk)) != NULL) { cm_set_score(dwrk, new#ifdef CM_MULTIPLE_ALPHA , jconf->annotate.cm_alpha_bgn , jconf->annotate.cm_alpha_end , jconf->annotate.cm_alpha_step#endif );#ifdef CM_SEARCH_LIMIT if (new->cmscore[new->seqnum-1] < jconf->annotate.cm_cut_thres#ifdef CM_SEARCH_LIMIT_AFTER && dwrk->finishnum > 0#endif ) { free_node(new); continue; }#endif /* CM_SEARCH_LIMIT */ if (put_to_stack(new, &start, &bottom, &stacknum, stacksize) != -1) { dwrk->current = new; //callback_exec(CALLBACK_DEBUG_PASS2_PUSH, r); if (r->graphout) { new->prevgraph = NULL; new->lastcontext = NULL; } dwrk->pushctr++; } }#endif if (debug2_flag) { jlog("DEBUG: %d pushed\n", dwrk->pushctr); } /********************/ /* main search loop */ /********************/ for (;;) { /* if terminate signal has been received, cancel this input */ /* * if (recog->process_want_terminate) { * jlog("DEBUG: process terminated by request\n"); * break; * } */ /* * 簿棱スタックから呵もスコアの光い簿棱を艰り叫す * pop the top hypothesis from stack */#ifdef DEBUG jlog("DEBUG: get one hypothesis\n");#endif now = get_best_from_stack(&start,&stacknum); if (now == NULL) { /* stack empty ---> 玫瑚姜位*/ jlog("WARNING: %02d %s: hypothesis stack exhausted, terminate search now\n", r->config->id, r->config->name); jlog("STAT: %02d %s: %d sentences have been found\n", r->config->id, r->config->name, dwrk->finishnum); break; } /* (bogus score check) */ if (now->score <= LOG_ZERO) { free_node(now); continue; } /* 帽胳グラフ脱に pop 簿棱の f スコアを办箕瘦赂 */ if (r->graphout) { prev_score = now->score; } /* word envelope チェック */ /* consult word envelope */ if (jconf->pass2.enveloped_bestfirst_width >= 0) { if (!wb_ok(dwrk, now, jconf->pass2.enveloped_bestfirst_width)) { /* この簿棱墓における鸥倡傅簿棱眶の芜纷眶は贷に镧猛を臂えている. そのため·この簿棱は嘉てる. */ /* the number of popped hypotheses at the length already reaches its limit, so the current popped hypothesis should be discarded here with no expansion */ if (debug2_flag) { jlog("DEBUG: popped but pruned by word envelope:"); put_hypo_woutput(now, r->lm->winfo); } free_node(now); continue; } } #ifdef CM_SEARCH_LIMIT_POP if (now->cmscore[now->seqnum-1] < jconf->annotate.cm_cut_thres_pop) { free_node(now); continue; }#endif /* CM_SEARCH_LIMIT_POP */ dwrk->popctr++; /* (for debug) 艰り叫した簿棱とそのスコアを叫蜗 */ /* output information of the popped hypothesis to stdout */ if (debug2_flag) { jlog("DEBUG: --- pop %d:\n", dwrk->popctr); jlog("DEBUG: "); put_hypo_woutput(now, r->lm->winfo); jlog("DEBUG: "); put_hypo_wname(now, r->lm->winfo); jlog("DEBUG: %d words, f=%f, g=%f\n", now->seqnum, now->score, now->g[now->bestt]); jlog("DEBUG: last word on trellis: [%d-%d]\n", now->estimated_next_t + 1, now->bestt); } dwrk->current = now; //callback_exec(CALLBACK_DEBUG_PASS2_POP, r); if (r->graphout) {#ifdef GRAPHOUT_DYNAMIC /* merge last word in popped hypo if possible */ wtmp = wordgraph_check_merge(now->prevgraph, &wordgraph_root, now->seq[now->seqnum-1], &merged_p, jconf); if (wtmp != NULL) { /* wtmp holds merged word */ dynamic_merged_num++; lscore_prev = (now->prevgraph) ? now->prevgraph->lscore_tmp : 0.0; if (now->prevgraph != NULL) { if (now->prevgraph->saved) { j_internal_error("wchmm_fbs: already saved??\n"); } wordgraph_free(now->prevgraph); } if (now->lastcontext != NULL && now->lastcontext != wtmp /* avoid self loop */ ) { wordgraph_check_and_add_leftword(now->lastcontext, wtmp, lscore_prev);#ifdef GRAPHOUT_SEARCH_CONSIDER_RIGHT if (merged_p) { if (wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev) == FALSE) { merged_p = TRUE; } else { merged_p = FALSE; } } else { wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev); }#else wordgraph_check_and_add_rightword(wtmp, now->lastcontext, lscore_prev);#endif } now->prevgraph = wtmp; /* change word to the merged one */ /*printf("last word merged\n");*/ /* previous still remains at memory here... (will be purged later) */ } else { wordgraph_save(now->prevgraph, now->lastcontext, &wordgraph_root); }#ifdef GRAPHOUT_SEARCH /* if recent hypotheses are included in the existing graph, terminate */ if (merged_p && now->endflag == FALSE#ifdef GRAPHOUT_SEARCH_DELAY_TERMINATION /* Do not apply search termination by graph merging until the first sentence candidate is found. */ && (jconf->graph.graphout_search_delay == FALSE || dwrk->finishnum > 0)#endif ) { terminate_search_num++; free_node(now); continue; }#endif#else /* ~GRAPHOUT_DYNAMIC */ /* always save */ wordgraph_save(now->prevgraph, now->lastcontext, &wordgraph_root);#endif /* ~GRAPHOUT_DYNAMIC */ } /* 艰り叫した簿棱のスコアを傅に score envelope を构糠 */ /* update score envelope using the popped hypothesis */ envl_update(dwrk, now, peseqlen); /* * 艰り叫した簿棱の减妄フラグが贷に惟っていれば· * その簿棱は玫瑚姜位とみなし·冯蔡として叫蜗して肌のル〖プへ. * * If the popped hypothesis already reached to the end, * we can treat it as a recognition result. */#ifdef DEBUG VERMES("endflag check\n");#endif if (now->endflag) { if (debug2_flag) { jlog("DEBUG: This is a full sentence candidate\n"); } /* quick, dirty hack */ if (now->score == last_score) { free_node(now); continue; } else { last_score = now->score; } dwrk->finishnum++; if (debug2_flag) { jlog("DEBUG: %d-th sentence found\n", dwrk->finishnum); } /* 办年眶の簿棱が评られたあとスコアでソ〖トするため· 办箕弄に侍のスタックに呈羌しておく */ /* store the result to result stack after search is finished, they will be re-ordered and output */ put_to_stack(now, &r_start, &r_bottom, &r_stacknum, r_stacksize); /* 回年眶の矢簿棱が评られたなら玫瑚を姜位する */ /* finish search if specified number of results are found */ if (dwrk->finishnum >= ncan) { break; } else { continue; } } /* end of now->endflag */ /* * 玫瑚己窃を浮叫する. * 簿棱眶が maxhypo 笆惧鸥倡されたら, もうこれ笆惧は玫瑚しない * * detecting search failure: * if the number of expanded hypotheses reaches maxhypo, giveup further search */#ifdef DEBUG jlog("DEBUG: loop end check\n");#endif if (dwrk->popctr >= maxhypo) { jlog("WARNING: %02d %s: num of popped hypotheses reached the limit (%d)\n", r->config->id, r->config->name, maxhypo); /* (for debug) 玫瑚己窃箕に、スタックに荒った攫鼠を徘き叫す */ /* (for debug) output all hypothesis remaining in the stack */ if (debug2_flag) put_all_in_stack(&start, &stacknum, r->lm->winfo); free_node(now); break; /* end of search */ } /* 簿棱墓が办年猛を臂えたとき·その簿棱を撬逮する */ /* check hypothesis word length overflow */ if (now->seqnum >= MAXSEQNUM) { jlog("ERROR: sentence length exceeded system limit ( > %d)\n", MAXSEQNUM); free_node(now); continue; }#ifndef GRAPHOUT_PRECISE_BOUNDARY if (r->graphout) { /* if monophone (= no backscan), the tail g score should be kept here */ /* else, updated tail g score will be computed in scan_word() */ if(!jconf->am.ccd_flag) { now->tail_g_score = now->g[now->bestt]; } }#endif /* * 涟羹きスコアを构糠する¨ 呵稿の帽胳の婶尸の涟羹きスコアを纷换する. * update forward score: compute forward trellis for the last word */#ifdef DEBUG jlog("DEBUG: scan_word\n");#endif scan_word(now, param, r); if (now->score < LOG_ZERO) { /* another end-of-search detecter */ jlog("WARNING: too low score, ignore: score=%f",now->score); put_hypo_woutput(now, r->lm->winfo); free_node(now); continue; } /* * 艰り叫した簿棱が矢として减妄材墙であれば· * 减妄フラグを惟ててをスタックにいれ木しておく. * (肌に艰り叫されたら豺となる) * * if the current popped hypothesis is acceptable, set endflag * and return it to stack: it will become the recognition result * when popped again. */#ifdef DEBUG jlog("DEBUG: accept check\n");#endif if (r->lmtype == LM_PROB) { acc = ngram_acceptable(now, r);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?