sumom****@users*****
sumom****@users*****
2008年 11月 16日 (日) 21:28:04 JST
Index: julius4/libjulius/src/recogmain.c diff -u julius4/libjulius/src/recogmain.c:1.7 julius4/libjulius/src/recogmain.c:1.8 --- julius4/libjulius/src/recogmain.c:1.7 Thu Sep 25 14:00:06 2008 +++ julius4/libjulius/src/recogmain.c Sun Nov 16 21:28:04 2008 @@ -12,7 +12,7 @@ * @author Akinobu Lee * @date Wed Aug 8 14:53:53 2007 * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * */ @@ -576,6 +576,7 @@ boolean ok_p; boolean process_segment_last; boolean on_the_fly; + boolean pass2_p; jconf = recog->jconf; @@ -1050,9 +1051,38 @@ } } + /* for instances with "-1pass", copy 1st pass result as final */ + /* execute stack-decoding search */ + /* they will be skipepd in the next pass */ + for(r=recog->process_list;r;r=r->next) { + if (!r->live) continue; + /* skip if 1st pass was failed */ + if (r->result.status < 0) continue; + if (r->config->compute_only_1pass) { + if (verbose_flag) { + jlog("%02d %s: \"-1pass\" specified, output 1st pass result as a final result\n", r->config->id, r->config->name); + } + /* prepare result storage */ + result_sentence_malloc(r, 1); + /* finalize result when no hypothesis was obtained */ + pass2_finalize_on_no_result(r, TRUE); + } + } + /***********************************************/ /* 2nd-pass --- forward search with heuristics */ /***********************************************/ + pass2_p = FALSE; + for(r=recog->process_list;r;r=r->next) { + if (!r->live) continue; + /* if [-1pass] is specified, skip 2nd pass */ + if (r->config->compute_only_1pass) continue; + /* if search already failed on 1st pass, skip 2nd pass */ + if (r->result.status < 0) continue; + pass2_p = TRUE; + } + if (pass2_p) callback_exec(CALLBACK_EVENT_PASS2_BEGIN, recog); + #if !defined(PASS2_STRICT_IWCD) || defined(FIX_35_PASS2_STRICT_SCORE) /* adjust trellis score not to contain outprob of the last frames */ for(r=recog->process_list;r;r=r->next) { @@ -1073,11 +1103,9 @@ #endif /* execute stack-decoding search */ - callback_exec(CALLBACK_EVENT_PASS2_BEGIN, recog); - for(r=recog->process_list;r;r=r->next) { if (!r->live) continue; - /* if [-1pass] is specified, skip 2nd pass */ + /* if [-1pass] is specified, just copy from 1st pass result */ if (r->config->compute_only_1pass) continue; /* if search already failed on 1st pass, skip 2nd pass */ if (r->result.status < 0) continue; @@ -1113,6 +1141,15 @@ } } + /* do forced alignment if needed */ + for(r=recog->process_list;r;r=r->next) { + if (!r->live) continue; + /* if search failed on 2nd pass, skip this */ + if (r->result.status < 0) continue; + /* do needed alignment */ + do_alignment_all(r, r->am->mfcc->param); + } + /* output result */ callback_exec(CALLBACK_RESULT, recog); #ifdef ENABLE_PLUGIN @@ -1123,6 +1160,8 @@ ok_p = FALSE; for(r=recog->process_list;r;r=r->next) { if (!r->live) continue; + if (r->config->compute_only_1pass) continue; + if (r->result.status < 0) continue; if (r->config->graph.lattice) ok_p = TRUE; } if (ok_p) callback_exec(CALLBACK_RESULT_GRAPH, recog); @@ -1131,6 +1170,8 @@ ok_p = FALSE; for(r=recog->process_list;r;r=r->next) { if (!r->live) continue; + if (r->config->compute_only_1pass) continue; + if (r->result.status < 0) continue; if (r->config->graph.confnet) ok_p = TRUE; } if (ok_p) callback_exec(CALLBACK_RESULT_CONFNET, recog); @@ -1142,7 +1183,7 @@ } /* output end of 2nd pass */ - callback_exec(CALLBACK_EVENT_PASS2_END, recog); + if (pass2_p) callback_exec(CALLBACK_EVENT_PASS2_END, recog); #ifdef DEBUG_VTLN_ALPHA_TEST if (r->am->mfcc->para->vtln_alpha == 1.0) { Index: julius4/libjulius/src/search_bestfirst_main.c diff -u julius4/libjulius/src/search_bestfirst_main.c:1.7 julius4/libjulius/src/search_bestfirst_main.c:1.8 --- julius4/libjulius/src/search_bestfirst_main.c:1.7 Thu Aug 7 18:27:35 2008 +++ julius4/libjulius/src/search_bestfirst_main.c Sun Nov 16 21:28:04 2008 @@ -35,7 +35,7 @@ * @author Akinobu Lee * @date Thu Sep 08 11:51:12 2005 * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * */ /* @@ -1099,19 +1099,96 @@ /* if in sp segmentation mode, */ /* set the last context-aware word for next recognition */ if (r->lmtype == LM_PROB && r->config->successive.enabled && num == 1) segment_set_last_nword(now, r); - /* do forced alignment if needed */ - if (r->config->annotate.align_result_word_flag) word_rev_align(now->seq, now->seqnum, param, &(r->result.sent[r->result.sentnum-1]), r); - if (r->config->annotate.align_result_phoneme_flag) phoneme_rev_align(now->seq, now->seqnum, param, &(r->result.sent[r->result.sentnum-1]), r); - if (r->config->annotate.align_result_state_flag) state_rev_align(now->seq, now->seqnum, param, &(r->result.sent[r->result.sentnum-1]), r); free_node(now); } - r->result.status = J_RESULT_STATUS_SUCCESS; /* free the rest */ if (now != NULL) free_node(now); free_all_nodes(*r_start); } +/** + * <EN> + * @brief Post-process of 2nd pass when no result is obtained. + * + * This is a post-process for the 2nd pass which should be called when + * the 2nd pass has no result. This will occur when the 2nd pass was + * executed but failed with no sentence candidate, or skipped by + * an option. + * + * When the 2nd argument is set to TRUE, the result of the 1st pass + * will be copied as final result of 2nd pass and the recognition + * status flag is set to SUCCESS. If FALSE, recognition status will + * be set to FAILED. On sp-segment decoding, the initial hypothesis + * marker for the next input segment will be set up from the 1st pass + * result also. + * + * @param r [in] recognition process instance + * @param use_1pass_as_final [in] when TRUE the 1st pass result will be used as final recognition result of 2nd pass. + * + * </EN> + * <JA> + * @brief 第2パスの解が得られない場合の終了処理 + * + * 第2パスが失敗した場合や第2パスが実行されない設定の場合の + * 認識終了処理を行う.use_1pass_as_final が TRUE のとき, + * 第1パスの結果を第2パスの結果としてコピーして格納し,認識成功とする. + * FALSE時は認識失敗とする. + * また,sp-segment 時は,次の認識区間用の初期仮説設定も第1パスの + * 結果から行う. + * + * @param r [in] 認識処理インスタンス + * @param use_1pass_as_final [in] TRUE 時第1パスの結果を第2パス結果に格納する + * + * </JA> + */ +void +pass2_finalize_on_no_result(RecogProcess *r, boolean use_1pass_as_final) +{ + NODE *now; + int i, j; + + /* 探索失敗 */ + /* search failed */ + + /* make temporal hypothesis data from the result of previous 1st pass */ + now = newnode(r); + for (i=0;i<r->pass1_wnum;i++) { + now->seq[i] = r->pass1_wseq[r->pass1_wnum-1-i]; + } + now->seqnum = r->pass1_wnum; + now->score = r->pass1_score; +#ifdef CONFIDENCE_MEASURE + /* fill in null values */ +#ifdef CM_MULTIPLE_ALPHA + for(j=0;j<jconf->annotate.cm_alpha_num;j++) { + for(i=0;i<now->seqnum;i++) now->cmscore[i][j] = 0.0; + } +#else + for(i=0;i<now->seqnum;i++) now->cmscore[i] = 0.0; +#endif +#endif /* CONFIDENCE_MEASURE */ + + if (r->lmtype == LM_PROB && r->config->successive.enabled) { + /* if in sp segment mode, */ + /* find segment restart words from 1st pass result */ + segment_set_last_nword(now, r); + } + + if (use_1pass_as_final) { + /* 第1パスの結果をそのまま出力する */ + /* output the result of the previous 1st pass as a final result. */ + store_result_pass2(now, r); + r->result.status = J_RESULT_STATUS_SUCCESS; + } else { + /* store output as failure */ + r->result.status = J_RESULT_STATUS_FAIL; + //callback_exec(CALLBACK_RESULT, r); + } + + free_node(now); +} + /**********************************************************************/ /********* Main stack decoding function *******************************/ @@ -2052,58 +2129,16 @@ /* output */ if (dwrk->finishnum == 0) { /* if search failed */ - /* 探索失敗 */ - /* search failed */ - /* make temporal hypothesis data from the result of previous 1st pass */ - now = newnode(r); - for (i=0;i<r->pass1_wnum;i++) { - now->seq[i] = r->pass1_wseq[r->pass1_wnum-1-i]; - } - now->seqnum = r->pass1_wnum; - now->score = r->pass1_score; -#ifdef CONFIDENCE_MEASURE - /* fill in null values */ -#ifdef CM_MULTIPLE_ALPHA - for(j=0;j<jconf->annotate.cm_alpha_num;j++) { - for(i=0;i<now->seqnum;i++) now->cmscore[i][j] = 0.0; - } -#else - for(i=0;i<now->seqnum;i++) now->cmscore[i] = 0.0; -#endif -#endif /* CONFIDENCE_MEASURE */ - - if (r->lmtype == LM_PROB && r->config->successive.enabled) { - /* if in sp segment mode, */ - /* find segment restart words from 1st pass result */ - segment_set_last_nword(now, r); - } - - if (r->config->sw.fallback_pass1_flag) { - /* 第1パスの結果をそのまま出力する */ - /* output the result of the previous 1st pass as a final result. */ - if (verbose_flag) { - jlog("%02d %s: got no candidates, output 1st pass result as a final result\n", r->config->id, r->config->name); - } - /* do forced alignment if needed */ - if (jconf->annotate.align_result_word_flag) word_rev_align(now->seq, now->seqnum, param, &(r->result.pass1), r); - if (jconf->annotate.align_result_phoneme_flag) phoneme_rev_align(now->seq, now->seqnum, param, &(r->result.pass1), r); - if (jconf->annotate.align_result_state_flag) state_rev_align(now->seq, now->seqnum, param, &(r->result.pass1), r); - - /* store output as final result */ - store_result_pass2(now, r); - - } else { - /* store output as failure */ - if (verbose_flag) { + /* finalize result when no hypothesis was obtained */ + if (verbose_flag) { + if (r->config->sw.fallback_pass1_flag) { + jlog("%02d %s: got no candidates, output 1st pass result as a final result\n", r->config->id, r->config->name); + } else { jlog("WARNING: %02d %s: got no candidates, search failed\n", r->config->id, r->config->name); } - - r->result.status = J_RESULT_STATUS_FAIL; - //callback_exec(CALLBACK_RESULT, r); } - - free_node(now); + pass2_finalize_on_no_result(r, r->config->sw.fallback_pass1_flag); } else { /* if at least 1 candidate found */ @@ -2116,6 +2151,8 @@ and output them here */ if (debug2_flag) jlog("DEBUG: done\n"); result_reorder_and_output(&r_start, &r_bottom, &r_stacknum, jconf->output.output_hypo_maxnum, r, param); + + r->result.status = J_RESULT_STATUS_SUCCESS; //callback_exec(CALLBACK_RESULT, r); //callback_exec(CALLBACK_EVENT_PASS2_END, r); } Index: julius4/libjulius/src/word_align.c diff -u julius4/libjulius/src/word_align.c:1.3 julius4/libjulius/src/word_align.c:1.4 --- julius4/libjulius/src/word_align.c:1.3 Fri Feb 15 03:25:14 2008 +++ julius4/libjulius/src/word_align.c Sun Nov 16 21:28:04 2008 @@ -33,7 +33,7 @@ * @author Akinobu Lee * @date Sat Sep 24 16:09:46 2005 * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * */ /* @@ -529,4 +529,38 @@ free(words); } +/** + * <JA> + * 認識結果に対して必要なアラインメントを全て実行する. + * + * @param r [i/o] 認識処理インスタンス + * @param param [in] 入力特徴ベクトル列 + * </JA> + * <EN> + * Do required forced alignment for the recognition results + * + * @param r [i/o] recognition process instance + * @param param [in] input parameter vectors + * </EN> + * @callgraph + * @callergraph + */ +void +do_alignment_all(RecogProcess *r, HTK_Param *param) +{ + int n; + Sentence *s; + + for(n = 0; n < r->result.sentnum; n++) { + s = &(r->result.sent[n]); + /* do forced alignment if needed */ + if (r->config->annotate.align_result_word_flag) + word_align(s->word, s->word_num, param, s, r); + if (r->config->annotate.align_result_phoneme_flag) + phoneme_align(s->word, s->word_num, param, s, r); + if (r->config->annotate.align_result_state_flag) + state_align(s->word, s->word_num, param, s, r); + } +} + /* end of file */