📄 pass1.c
字号:
/** * @file pass1.c * * <JA> * @brief 妈1パス¨フレ〖ム票袋ビ〖ム玫瑚 * * 琅弄腾菇陇辑今を脱いて·掐蜗泼魔翁ベクトル误に滦して·Juliusの妈1パス * であるフレ〖ム票袋ビ〖ム玫瑚を乖います. * * 掐蜗デ〖タ链挛があらかじめ评られている眷圭は·办崇で纷换を * 乖う簇眶 get_back_trellis() がメインから钙ばれます. オンライン千急 * の眷圭は realtime_1stpass.c から·介袋步·フレ〖ムごとの纷换· * 姜位借妄のそれぞれが掐蜗の渴乖にあわせて改侍に钙ばれます. * * 悸狠の改」の千急借妄インスタンスごとの借妄は beam.c に淡揭されています. * * </JA> * * <EN> * @brief The first pass: frame-synchronous beam search * * These functions perform a frame-synchronous beam search using a static * lexicon tree, as the first pass of Julius/Julian. * * When the whole input is already obtained, get_back_trellis() simply * does all the processing of the 1st pass. When performing online * real-time recognition with concurrent speech input, each function * will be called separately from realtime_1stpass.c according on the * basis of input processing. * * The core recognition processing functions for each recognition * process instances are written in beam.c. * * </EN> * * @author Akinobu Lee * @date Fri Oct 12 23:14:13 2007 * * $Revision: 1.7 $ * *//* * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology * All rights reserved */#include <julius/julius.h>/********************************************************************//* 妈1パスを悸乖するメイン簇眶 *//* 掐蜗をパイプライン借妄する眷圭は realtime_1stpass.c を徊救のこと *//* main function to execute 1st pass *//* the pipeline processing is not here: see realtime_1stpass.c *//********************************************************************//** * <EN> * @brief Process one input frame for all recognition process instance. * * This function proceeds the recognition for one frame. All * recognition process instance will be processed synchronously. * The input frame for each instance is stored in mfcc->f, where mfcc * is the MFCC calculation instance assigned to each process instance. * * If an instance's mfcc->invalid is set to TRUE, its processing will * be skipped. * * When using GMM, GMM computation will also be executed here. * If GMM_VAD is defined, GMM-based voice detection will be performed * inside this function, by using a scheme of short-pause segmentation. * * This function also handles segmentation of recognition process. A * segmentation will occur when end of speech is detected by level-based * sound detection or GMM-based / decoder-based VAD, or by request from * application. When segmented, it stores current frame and return with * that status. * * The frame-wise callbacks will be executed inside this function, * when at least one valid recognition process instances exists. * * </EN> * <JA> * @brief 链ての千急借妄インスタンス借妄を1フレ〖ム尸渴める. * * 链ての千急借妄インスタンスについて·充り烧けられているMFCC纷换インスタンス * の mfcc->f をカレントフレ〖ムとして借妄を1フレ〖ム渴める. * * なお·mfcc->invalid が TRUE となっている借妄インスタンスの借妄はスキップ * される. * * GMMの纷换もここで钙び叫される. GMM_VAD 年盗箕は·GMM による * 券厦惰粗倡幌ˇ姜位の浮叫がここで乖われる. また·GMMの纷换冯蔡· * あるいは千急借妄柒のショ〖トポ〖ズセグメンテ〖ション冉年やデバイスˇ嘲婶 * からの妥滇によりセグメンテ〖ションが妥滇されたかどうかの冉年も乖う. * * フレ〖ム帽疤で钙び叫されるコ〖ルバックが判峡されている眷圭は·それらの * 钙叫しも乖う. * </JA> * * @param recog [in] engine instance * * @return 0 on success, -1 on error, or 1 when an input segmentation * occured/requested inside this function. * * @callgraph * @callergraph * */intdecode_proceed(Recog *recog){ MFCCCalc *mfcc; boolean break_flag; boolean break_decode; RecogProcess *p; boolean ok_p;#ifdef GMM_VAD GMMCalc *gmm; boolean break_gmm;#endif break_decode = FALSE; for(p = recog->process_list; p; p = p->next) {#ifdef DETERMINE p->have_determine = FALSE;#endif p->have_interim = FALSE; } for (mfcc = recog->mfcclist; mfcc; mfcc = mfcc->next) { mfcc->segmented = FALSE; }#ifdef POWER_REJECT for (mfcc = recog->mfcclist; mfcc; mfcc = mfcc->next) { if (!mfcc->valid) continue; if (mfcc->f == 0) { mfcc->avg_power = 0.0; if (debug2_flag) jlog("STAT: power_reject: reset\n"); } }#endif#ifdef GMM_VAD if (recog->gmm != NULL) { /* reset flags */ break_gmm = FALSE; recog->gc->want_rewind = FALSE; }#endif if (recog->gmm != NULL && recog->gmmmfcc->valid) { /* GMM 纷换を乖う */ if (recog->gmmmfcc->f == 0) { /* GMM 纷换の介袋步 */ gmm_prepare(recog); } /* このフレ〖ムに滦するGMMの锑刨を纷换 */ gmm_proceed(recog);#ifdef GMM_VAD /* Check for GMM-based VAD */ gmm = recog->gc; gmm_check_trigger(recog); if (gmm->after_trigger) { /* after trigger, in speech area */ if (gmm->down_trigger) { /* down trigger, end segment */#ifdef GMM_VAD_DEBUG printf("GMM_VAD: %d: down trigger\n", recog->gmmmfcc->f);#endif recog->gmmmfcc->sparea_start = recog->gmmmfcc->f + 1 - recog->jconf->detect.gmm_margin; if (recog->gmmmfcc->sparea_start < 0) recog->gmmmfcc->sparea_start = 0; gmm->after_trigger = FALSE; recog->gmmmfcc->segmented = TRUE; break_gmm = TRUE; } else { /* keep recognition */ } } else { /* before trigger, in noise area */ if (gmm->up_trigger) { /* start recognition */ /* request caller to rewind to the backstep point and re-start with normal search */ if (recog->gmmmfcc->f + 1 < recog->jconf->detect.gmm_margin) { gmm->rewind_frame = 0; } else { gmm->rewind_frame = recog->gmmmfcc->f + 1 - recog->jconf->detect.gmm_margin; }#ifdef GMM_VAD_DEBUG printf("GMM_VAD: %d: up trigger, start recognition with %d frame rewind\n", recog->gmmmfcc->f, recog->gmmmfcc->f - gmm->rewind_frame);#endif gmm->want_rewind = TRUE; gmm->want_rewind_reprocess = TRUE; gmm->after_trigger = TRUE; return 0; } else { /* before trigger, noise continues */ /* if noise goes more than a certain frame, shrink the noise area to avoid unlimited memory usage */ if (recog->gmmmfcc->f + 1 > GMM_VAD_AUTOSHRINK_LIMIT) { gmm->want_rewind = TRUE; gmm->want_rewind_reprocess = FALSE; gmm->rewind_frame = recog->gmmmfcc->f + 1 - recog->jconf->detect.gmm_margin; if (debug2_flag) { jlog("DEBUG: GMM_VAD: pause exceeded %d, rewind\n", GMM_VAD_AUTOSHRINK_LIMIT); } } /* skip recognition processing */ return 0; } }#endif /* GMM_VAD */ } for(p = recog->process_list; p; p = p->next) { if (!p->live) continue; mfcc = p->am->mfcc; if (!mfcc->valid) { /* このフレ〖ムの借妄をスキップ */ /* skip processing the frame */ continue; } /* mfcc-f のフレ〖ムについて千急借妄(フレ〖ム票袋ビ〖ム玫瑚)を渴める */ /* proceed beam search for mfcc->f */ if (mfcc->f == 0) { /* 呵介のフレ〖ム: 玫瑚借妄を介袋步 */ /* initial frame: initialize search process */ if (get_back_trellis_init(mfcc->param, p) == FALSE) { jlog("ERROR: %02d %s: failed to initialize the 1st pass\n", p->config->id, p->config->name); return -1; } } if (mfcc->f > 0 || p->am->hmminfo->multipath) { /* 1フレ〖ム玫瑚を渴める */ /* proceed search for 1 frame */ if (get_back_trellis_proceed(mfcc->f, mfcc->param, p, FALSE) == FALSE) { mfcc->segmented = TRUE; break_decode = TRUE; } if (p->config->successive.enabled) { if (detect_end_of_segment(p, mfcc->f - 1)) { /* セグメント姜位浮梦: 妈1パスここで面们 */ mfcc->segmented = TRUE; break_decode = TRUE; } } } } /* セグメントすべきかどうか呵姜弄な冉年を乖うˉ デコ〖ダベ〖スVADあるいは spsegment の眷圭·剩眶インスタンス粗で OR を艰るˉまた·GMMなど剩眶答洁がある眷圭は答洁粗で AND を艰るˉ*/ /* determine whether to segment at here If multiple segmenter exists, take their AND */ break_flag = FALSE; if (break_decode#ifdef GMM_VAD || (recog->gmm != NULL && break_gmm)#endif ) { break_flag = TRUE; } if (break_flag) { /* 玫瑚借妄の姜位が券栏したのでここで千急を姜える. 呵介のフレ〖ムから [f-1] 戎誊までが千急されたことになる */ /* the recognition process tells us to stop recognition, so recognition should be terminated here. the recognized data are [0..f-1] */ /* 呵姜フレ〖ムを last_time にセット */ /* set the last frame to last_time */ for (mfcc = recog->mfcclist; mfcc; mfcc = mfcc->next) { mfcc->last_time = mfcc->f - 1; } if (! recog->jconf->decodeopt.segment) { /* ショ〖トポ〖ズ笆嘲で磊れた眷圭·荒りのサンプルは千急せずに嘉てる */ /* drop rest inputs if segmented by error */ for (mfcc = recog->mfcclist; mfcc; mfcc = mfcc->next) { mfcc->param->header.samplenum = mfcc->f; mfcc->param->samplenum = mfcc->f; } } return 1; } /* call frame-wise callback for the processing results if any */#ifdef DETERMINE ok_p = FALSE; for(p=recog->process_list;p;p=p->next) { if (!p->live) continue; if (p->have_determine) { ok_p = TRUE; } } if (ok_p) callback_exec(CALLBACK_RESULT_PASS1_DETERMINED, recog);#endif ok_p = FALSE; for(p=recog->process_list;p;p=p->next) { if (!p->live) continue; if (p->have_interim) { ok_p = TRUE; } } if (ok_p) callback_exec(CALLBACK_RESULT_PASS1_INTERIM, recog); return 0;}#ifdef POWER_REJECTbooleanpower_reject(Recog *recog){ MFCCCalc *mfcc; for (mfcc = recog->mfcclist; mfcc; mfcc = mfcc->next) { /* skip if not realtime and raw file processing */ if (mfcc->avg_power == 0.0) continue; if (debug2_flag) jlog("STAT: power_reject: MFCC%02d: avg_power = %f\n", mfcc->id, mfcc->avg_power / mfcc->param->samplenum); if (mfcc->avg_power / mfcc->param->samplenum < recog->jconf->reject.powerthres) return TRUE; } return FALSE;}#endif/** * <EN> * @brief End procedure of the first pass (when segmented) * * This function do things for ending the first pass and prepare for * the next recognition, when the input was segmented at the middle of * recognition by some reason. * * First, the best path at each recognition process instance will be parsed * and stored. In case of recognition error or input rejection, the error * status will be set. * * Then, the last pause segment of the processed input will be cut and saved * to be processed at first in the recognition of the next or remaining input. * * </EN> * <JA> * @brief 妈1パスの姜位借妄∈セグメント箕∷ * * 掐蜗が部らかの祸统によって庞面でセグメントされた箕に·妈1パスの千急借妄を * 姜位して肌搀浩倡するための借妄を乖う. * * まず·称千急借妄インスタンスに滦して·呵锑帽胳废误を斧烧け·妈1パスの * 千急冯蔡として呈羌する. また·千急己窃ˇ掐蜗逮笛の箕はエラ〖ステ〖タスをそ * れぞれセットする. * * そして·肌搀の千急で·肌のセグメントの千急を·浮叫された琐萨花不 * 惰粗から浩倡するために·その琐萨花不惰粗を磊り叫しておく借妄を钙ぶ. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -