📄 recogmain.c
字号:
* @callergraph * @ingroup engine */intj_open_stream(Recog *recog, char *file_or_dev_name){ Jconf *jconf; jconf = recog->jconf; if (jconf->input.type == INPUT_WAVEFORM) { /* begin A/D input */ if (adin_begin(recog->adin) == FALSE) { return -2; } /* create A/D-in thread here */#ifdef HAVE_PTHREAD if (recog->adin->enable_thread && ! recog->adin->input_side_segment) { if (adin_thread_create(recog) == FALSE) { return -2; } }#endif } else { switch(jconf->input.speech_input) { case SP_MFCMODULE: param_init_content(recog->mfcclist->param); if (mfc_module_begin(recog->mfcclist) == FALSE) return -2; break; case SP_MFCFILE: /* read parameter file */ param_init_content(recog->mfcclist->param); if (rdparam(file_or_dev_name, recog->mfcclist->param) == FALSE) { jlog("ERROR: error in reading parameter file: %s\n", file_or_dev_name); return -1; } /* check and strip invalid frames */ if (jconf->preprocess.strip_zero_sample) { param_strip_zero(recog->mfcclist->param); } /* output frame length */ callback_exec(CALLBACK_STATUS_PARAM, recog); break; default: jlog("ERROR: j_open_stream: none of SP_MFC_*??\n"); return -1; } } return 0;}/** * <EN> * Close input stream. The main recognition loop will be stopped after * stream has been closed. * </EN> * <JA> * 不兰掐蜗ストリ〖ムを誓じるˉ千急のメインル〖プは誓じられた稿姜位するˉ * </JA> * * @param recog [i/o] engine instance * * @return 0 on success, -1 on general error, -2 on device error. * * @callgraph * @callergraph * @ingroup engine */intj_close_stream(Recog *recog){ Jconf *jconf; jconf = recog->jconf; if (jconf->input.type == INPUT_WAVEFORM) {#ifdef HAVE_PTHREAD /* close A/D-in thread here */ if (recog->adin->enable_thread && ! recog->adin->input_side_segment) { if (adin_thread_cancel(recog) == FALSE) { return -2; } }#endif /* end A/D input */ if (adin_end(recog->adin) == FALSE) { return -2; } } else { switch(jconf->input.speech_input) { case SP_MFCMODULE: if (mfc_module_end(recog->mfcclist) == FALSE) return -2; break; case SP_MFCFILE: /* nothing to do */ break; default: jlog("ERROR: j_close_stream: none of SP_MFC_*??\n"); return -1; } } return 0;}/**********************************************************************//**********************************************************************//**********************************************************************//** * <EN> * Recognition error handling. * </EN> * <JA> * エラ〖による千急姜位箕の借妄. * </JA> * * @param recog [in] engine instance * @param status [in] error status to be set * */static voidresult_error(Recog *recog, int status){ MFCCCalc *mfcc; RecogProcess *r; boolean ok_p; for(r=recog->process_list;r;r=r->next) r->result.status = status; ok_p = FALSE; for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) { if (mfcc->f > 0) { ok_p = TRUE; break; } } if (ok_p) { /* had some input */ /* output as rejected */ callback_exec(CALLBACK_RESULT, recog);#ifdef ENABLE_PLUGIN plugin_exec_process_result(recog);#endif }}/** * <EN> * @brief Execute recognition. * * This function repeats recognition sequences until the input stream * reached its end. It detects speech segment (if needed), recognize * the detected segment, output result, and go back to the first. * * This function will be stopped and exited if reached end of stream * (mostly in case of file input), some error has been occured, or * termination requested from application by calling * j_request_pause() and j_request_terminate(). * * </EN> * <JA> * @brief 不兰千急の悸乖. * * この簇眶は掐蜗ストリ〖ムが姜わるまで不兰千急を帆り手す. * 涩妥であれば掐蜗略ちを乖って惰粗を浮叫し·不兰千急を乖い·冯蔡を * 叫蜗してふたたび掐蜗略ちに提る. * * 掐蜗ストリ〖ムを姜わりまで千急するか·エラ〖が栏じたときに姜位する. * * あるいは·千急借妄面に·j_request_pause() や j_request_terminate() が * アプリから钙ばれた眷圭·千急借妄の磊れ誊で姜位する. * * </JA> * * @param recog [i/o] engine instance * * @return 1 when stopped by application request, 0 when reached end of stream, * or -1 when an error occured. Note that the input stream can still continues * when 1 is returned. * */static intj_recognize_stream_core(Recog *recog){ Jconf *jconf; int ret; float seclen, mseclen; RecogProcess *r; MFCCCalc *mfcc; PROCESS_AM *am; PROCESS_LM *lm; boolean ok_p; boolean process_segment_last; boolean on_the_fly; boolean pass2_p; jconf = recog->jconf; /* determine whether on-the-fly decoding should be done */ on_the_fly = FALSE; switch(jconf->input.type) { case INPUT_VECTOR: switch(jconf->input.speech_input) { case SP_MFCFILE: on_the_fly = FALSE; break; case SP_MFCMODULE: on_the_fly = TRUE; break; } break; case INPUT_WAVEFORM: if (jconf->decodeopt.realtime_flag) { on_the_fly = TRUE; } else { on_the_fly = FALSE; } break; } if (jconf->input.type == INPUT_WAVEFORM || jconf->input.speech_input == SP_MFCMODULE) { for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) { param_init_content(mfcc->param); } } /* if no process instance exist, start with terminated */ if (recog->process_list == NULL) { jlog("STAT: no recog process, engine inactive\n"); j_request_pause(recog); } /* update initial recognition process status */ for(r=recog->process_list;r;r=r->next) { if (r->active > 0) { r->live = TRUE; } else if (r->active < 0) { r->live = FALSE; } r->active = 0; } /******************************************************************/ /* do recognition for each incoming segment from the input stream */ /******************************************************************/ while (1) { start_recog: /*************************************/ /* Update recognition process status */ /*************************************/ for(r=recog->process_list;r;r=r->next) { if (r->active > 0) { r->live = TRUE; jlog("STAT: SR%02d %s now active\n", r->config->id, r->config->name); } else if (r->active < 0) { r->live = FALSE; jlog("STAT: SR%02d %s now inactive\n", r->config->id, r->config->name); } r->active = 0; } if (debug2_flag) { for(r=recog->process_list;r;r=r->next) { jlog("DEBUG: %s: SR%02d %s\n", r->live ? "live" : "dead", r->config->id, r->config->name); } } /* check if any process is live */ if (recog->process_active) { ok_p = FALSE; for(r=recog->process_list;r;r=r->next) { if (r->live) ok_p = TRUE; } if (!ok_p) { /* no process is alive */ /* make whole process as inactive */ jlog("STAT: all recog process inactive, pause engine now\n"); j_request_pause(recog); } } /* Check whether process status was changed while in the last run */ if (recog->process_online != recog->process_active) { recog->process_online = recog->process_active; if (recog->process_online) callback_exec(CALLBACK_EVENT_PROCESS_ONLINE, recog); else callback_exec(CALLBACK_EVENT_PROCESS_OFFLINE, recog); } /* execute poll callback */ if (recog->process_active) { callback_exec(CALLBACK_POLL, recog); } /* reset reload flag here */ j_reset_reload(recog); if (!recog->process_active) { /* now sleeping, return */ /* in the next call, we will resume from here */ return 1; } /* update process status */ if (recog->process_online != recog->process_active) { recog->process_online = recog->process_active; if (recog->process_online) callback_exec(CALLBACK_EVENT_PROCESS_ONLINE, recog); else callback_exec(CALLBACK_EVENT_PROCESS_OFFLINE, recog); } /*********************************************************/ /* check for grammar to change, and rebuild if necessary */ /*********************************************************/ for(lm=recog->lmlist;lm;lm=lm->next) { if (lm->lmtype == LM_DFA) { multigram_update(lm); /* some modification occured if return TRUE*/ } } for(r=recog->process_list;r;r=r->next) { if (!r->live) continue; if (r->lmtype == LM_DFA && r->lm->global_modified) { multigram_build(r); } } for(lm=recog->lmlist;lm;lm=lm->next) { if (lm->lmtype == LM_DFA) lm->global_modified = FALSE; } ok_p = FALSE; for(r=recog->process_list;r;r=r->next) { if (!r->live) continue; if (r->lmtype == LM_DFA) { if (r->lm->winfo == NULL || (r->lmvar == LM_DFA_GRAMMAR && r->lm->dfa == NULL)) { /* make this instance inactive */ r->active = -1; ok_p = TRUE; } } } if (ok_p) { /* at least one instance has no grammar */ goto start_recog; } /******************/ /* start 1st pass */ /******************/ if (on_the_fly) { /********************************************/ /* REALTIME ON-THE-FLY DECODING OF 1ST-PASS */ /********************************************/ /* store, analysis and search in a pipeline */ /* main function is RealTimePipeLine() at realtime-1stpass.c, and it will be periodically called for each incoming input segment from the AD-in function adin_go(). RealTimePipeLine() will be called as a callback function from adin_go() */ /* after this part, directly jump to the beginning of the 2nd pass */ if (recog->process_segment) { /*****************************************************************/ /* short-pause segmentation: process last remaining frames first */ /*****************************************************************/ /* last was segmented by short pause */ /* the margin segment in the last input will be re-processed first, and then the speech input will be processed */ /* process the last remaining parameters */ ret = RealTimeResume(recog); if (ret < 0) { /* error end in the margin */ jlog("ERROR: failed to process last remaining samples on RealTimeResume\n"); /* exit now! */ return -1; } if (ret != 1) { /* if segmented again in the margin, not process the rest */ /* last parameters has been processed, so continue with the current input as normal */ /* process the incoming input */ if (jconf->input.type == INPUT_WAVEFORM) { /* get speech and process it on real-time */ ret = adin_go(RealTimePipeLine, callback_check_in_adin, recog); } else { /* get feature vector and process it */ ret = mfcc_go(recog, callback_check_in_adin); } if (ret < 0) { /* error end in adin_go */ if (ret == -2 || recog->process_want_terminate) { /* terminated by callback */ RealTimeTerminate(recog); /* reset param */ for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) { param_init_content(mfcc->param); } /* execute callback at end of pass1 */ if (recog->triggered) { callback_exec(CALLBACK_EVENT_PASS1_END, recog); /* output result terminate */ result_error(recog, J_RESULT_STATUS_TERMINATE); } goto end_recog; /* cancel this recognition */ } jlog("ERROR: an error occured at on-the-fly 1st pass decoding\n"); /* exit now! */ return(-1); } } } else { /***********************************************************/ /* last was not segmented, process the new incoming input */ /***********************************************************/ /* end of this input will be determined by either end of stream (in case of file input), or silence detection by adin_go(), or 'TERMINATE' command from module (if module mode) */ /* prepare work area for on-the-fly processing */ if (RealTimePipeLinePrepare(recog) == FALSE) { jlog("ERROR: failed to prepare for on-the-fly 1st pass decoding\n"); return (-1); } /* process the incoming input */ if (jconf->input.type == INPUT_WAVEFORM) { /* get speech and process it on real-time */ ret = adin_go(RealTimePipeLine, callback_check_in_adin, recog); } else { /* get feature vector and process it */ ret = mfcc_go(recog, callback_check_in_adin); } if (ret < 0) { /* error end in adin_go */ if (ret == -2 || recog->process_want_terminate) { /* terminated by callback */ RealTimeTerminate(recog); /* reset param */ for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) { param_init_content(mfcc->param); } /* execute callback at end of pass1 */ if (recog->triggered) { callback_exec(CALLBACK_EVENT_PASS1_END, recog); /* output result terminate */ result_error(recog, J_RESULT_STATUS_TERMINATE); } goto end_recog; } jlog("ERROR: an error occured at on-the-fly 1st pass decoding\n"); /* exit now! */ return(-1); } } /******************************************************************/ /* speech stream has been processed on-the-fly, and 1st pass ends */ /******************************************************************/ /* last procedure of 1st-pass */ if (RealTimeParam(recog) == FALSE) { jlog("ERROR: fatal error occured, program terminates now\n"); return -1; } #ifdef BACKEND_VAD /* if not triggered, skip this segment */ if (recog->jconf->decodeopt.segment && ! recog->triggered) { goto end_recog; }#endif /* execute callback for 1st pass result */ /* result.status <0 must be skipped inside callback */ callback_exec(CALLBACK_RESULT_PASS1, recog);#ifdef WORD_GRAPH /* result.wg1 == NULL should be skipped inside callback */ callback_exec(CALLBACK_RESULT_PASS1_GRAPH, recog);#endif /* execute callback at end of pass1 */ callback_exec(CALLBACK_EVENT_PASS1_END, recog); /* output frame length */ callback_exec(CALLBACK_STATUS_PARAM, recog); /* if terminate signal has been received, discard this input */ if (recog->process_want_terminate) { result_error(recog, J_RESULT_STATUS_TERMINATE); goto end_recog; } /* END OF ON-THE-FLY INPUT AND DECODING OF 1ST PASS */ } else { /******************/ /* buffered input */ /******************/ if (jconf->input.type == INPUT_VECTOR) { /***********************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -