00001
00019
00020
00021
00022
00023
00024
00025
00161 #define GLOBAL_VARIABLE_DEFINE
00162 #include <julius/julius.h>
00163 #include <signal.h>
00164 #if defined(_WIN32) && !defined(__CYGWIN32__)
00165 #include <mbctype.h>
00166 #include <mbstring.h>
00167 #endif
00168
00169
00170 #ifdef REPORT_MEMORY_USAGE
00171
00181 static void
00182 print_mem()
00183 {
00184 char buf[200];
00185 sprintf(buf,"ps -o vsz,rss -p %d",getpid());
00186 system(buf);
00187 fflush(stdout);
00188 fflush(stderr);
00189 }
00190 #endif
00191
00192
00208 void
00209 result_sentence_malloc(RecogProcess *r, int num)
00210 {
00211 int i;
00212 r->result.sent = (Sentence *)mymalloc(sizeof(Sentence) * num);
00213 for(i=0;i<num;i++) {
00214 r->result.sent[i].align.filled = FALSE;
00215 r->result.sent[i].align.w = NULL;
00216 r->result.sent[i].align.ph = NULL;
00217 r->result.sent[i].align.loc = NULL;
00218 r->result.sent[i].align.begin_frame = NULL;
00219 r->result.sent[i].align.end_frame = NULL;
00220 r->result.sent[i].align.avgscore = NULL;
00221 r->result.sent[i].align.is_iwsp = NULL;
00222 }
00223 r->result.sentnum = 0;
00224 }
00225
00239 void
00240 result_sentence_free(RecogProcess *r)
00241 {
00242 int i;
00243 if (r->result.sent) {
00244 for(i=0;i<r->result.sentnum;i++) {
00245 if (r->result.sent[i].align.w) free(r->result.sent[i].align.w);
00246 if (r->result.sent[i].align.ph) free(r->result.sent[i].align.ph);
00247 if (r->result.sent[i].align.loc) free(r->result.sent[i].align.loc);
00248 if (r->result.sent[i].align.begin_frame) free(r->result.sent[i].align.begin_frame);
00249 if (r->result.sent[i].align.end_frame) free(r->result.sent[i].align.end_frame);
00250 if (r->result.sent[i].align.avgscore) free(r->result.sent[i].align.avgscore);
00251 if (r->result.sent[i].align.is_iwsp) free(r->result.sent[i].align.is_iwsp);
00252 }
00253 free(r->result.sent);
00254 r->result.sent = NULL;
00255 }
00256 }
00257
00271 void
00272 clear_result(RecogProcess *r)
00273 {
00274 #ifdef WORD_GRAPH
00275
00276 wordgraph_clean(&(r->result.wg1));
00277 #endif
00278
00279 if (r->lmvar == LM_DFA_WORD) {
00280 if (r->result.status == J_RESULT_STATUS_SUCCESS) {
00281
00282 free(r->result.sent);
00283 }
00284 } else {
00285 if (r->graphout) {
00286 if (r->config->graph.confnet) {
00287
00288 cn_free_all(&(r->result.confnet));
00289 } else if (r->config->graph.lattice) {
00290 }
00291
00292 wordgraph_clean(&(r->result.wg));
00293 }
00294 result_sentence_free(r);
00295 }
00296 }
00297
00298
00299
00332 static int
00333 adin_cut_callback_store_buffer(SP16 *now, int len, Recog *recog)
00334 {
00335 if (recog->speechlen == 0) {
00336 if (!recog->process_active) {
00337 return(1);
00338 }
00339 }
00340
00341 if (recog->speechlen + len > recog->speechalloclen) {
00342 while (recog->speechlen + len > recog->speechalloclen) {
00343 recog->speechalloclen += MAX_SPEECH_ALLOC_STEP;
00344 }
00345 if (recog->speech == NULL) {
00346 recog->speech = (SP16 *)mymalloc(sizeof(SP16) * recog->speechalloclen);
00347 } else {
00348 if (debug2_flag) {
00349 jlog("STAT: expanding recog->speech to %d samples\n", recog->speechalloclen);
00350 }
00351 recog->speech = (SP16 *)myrealloc(recog->speech, sizeof(SP16) * recog->speechalloclen);
00352 }
00353 }
00354
00355
00356 memcpy(&(recog->speech[recog->speechlen]), now, len * sizeof(SP16));
00357 recog->speechlen += len;
00358 return(0);
00359 }
00360
00361
00362
00390 static int
00391 callback_check_in_adin(Recog *recog)
00392 {
00393
00394 callback_exec(CALLBACK_POLL, recog);
00395
00396
00397
00398
00399
00400
00401 #if 1
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 if (recog->process_want_terminate) {
00413 return(-2);
00414 }
00415 if (recog->process_want_reload) {
00416 return(-1);
00417 }
00418 #else
00419 if (recog->process_want_terminate
00420 && recog->jconf->input.speech_input != SP_ADINNET) {
00421 return(-2);
00422 }
00423 if (recog->process_want_reload) {
00424 return(-1);
00425 }
00426 #endif
00427 return(0);
00428 }
00429
00430
00431
00432
00450 int
00451 j_open_stream(Recog *recog, char *file_or_dev_name)
00452 {
00453 Jconf *jconf;
00454
00455 jconf = recog->jconf;
00456
00457 if (jconf->input.speech_input == SP_MFCFILE) {
00458
00459 param_init_content(recog->mfcclist->param);
00460 if (rdparam(file_or_dev_name, recog->mfcclist->param) == FALSE) {
00461 jlog("ERROR: error in reading parameter file: %s\n", file_or_dev_name);
00462 return -1;
00463 }
00464
00465 if (jconf->preprocess.strip_zero_sample) {
00466 param_strip_zero(recog->mfcclist->param);
00467 }
00468
00469
00470 callback_exec(CALLBACK_STATUS_PARAM, recog);
00471 } else {
00472
00473 if (adin_begin(recog->adin) == FALSE) {
00474 return -2;
00475 }
00476 }
00477
00478 #if 0
00479
00480 process_online = TRUE;
00481 callback_exec(CALLBACK_EVENT_PROCESS_ONLINE, recog);
00482 #endif
00483
00484 return 0;
00485
00486 }
00487
00488
00489
00490
00491
00504 static void
00505 result_error(Recog *recog, int status)
00506 {
00507 MFCCCalc *mfcc;
00508 RecogProcess *r;
00509 boolean ok_p;
00510
00511 for(r=recog->process_list;r;r=r->next) r->result.status = status;
00512
00513 ok_p = FALSE;
00514 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00515 if (mfcc->f > 0) {
00516 ok_p = TRUE;
00517 break;
00518 }
00519 }
00520 if (ok_p) {
00521
00522 callback_exec(CALLBACK_RESULT, recog);
00523 }
00524 }
00525
00561 static int
00562 j_recognize_stream_core(Recog *recog)
00563 {
00564 Jconf *jconf;
00565 int ret;
00566 float seclen, mseclen;
00567 RecogProcess *r;
00568 MFCCCalc *mfcc;
00569 PROCESS_AM *am;
00570 PROCESS_LM *lm;
00571 boolean ok_p;
00572 boolean process_segment_last;
00573
00574 jconf = recog->jconf;
00575
00576 if (jconf->input.speech_input != SP_MFCFILE) {
00577 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00578 param_init_content(mfcc->param);
00579 }
00580 }
00581
00582
00583 if (recog->process_list == NULL) {
00584 jlog("STAT: no recog process, engine inactive\n");
00585 j_request_pause(recog);
00586 }
00587
00588
00589 for(r=recog->process_list;r;r=r->next) {
00590 if (r->active > 0) {
00591 r->live = TRUE;
00592 } else if (r->active < 0) {
00593 r->live = FALSE;
00594 }
00595 r->active = 0;
00596 }
00597
00598
00599
00600
00601 while (1) {
00602
00603 start_recog:
00604
00605
00606
00607
00608 for(r=recog->process_list;r;r=r->next) {
00609 if (r->active > 0) {
00610 r->live = TRUE;
00611 jlog("STAT: SR%02d %s now active\n", r->config->id, r->config->name);
00612 } else if (r->active < 0) {
00613 r->live = FALSE;
00614 jlog("STAT: SR%02d %s now inactive\n", r->config->id, r->config->name);
00615 }
00616 r->active = 0;
00617 }
00618 if (debug2_flag) {
00619 for(r=recog->process_list;r;r=r->next) {
00620 jlog("DEBUG: %s: SR%02d %s\n", r->live ? "live" : "dead", r->config->id, r->config->name);
00621 }
00622 }
00623
00624 if (recog->process_active) {
00625 ok_p = FALSE;
00626 for(r=recog->process_list;r;r=r->next) {
00627 if (r->live) ok_p = TRUE;
00628 }
00629 if (!ok_p) {
00630
00631 jlog("STAT: all recog process inactive, pause engine now\n");
00632 j_request_pause(recog);
00633 }
00634 }
00635
00636
00637 if (recog->process_online != recog->process_active) {
00638 recog->process_online = recog->process_active;
00639 if (recog->process_online) callback_exec(CALLBACK_EVENT_PROCESS_ONLINE, recog);
00640 else callback_exec(CALLBACK_EVENT_PROCESS_OFFLINE, recog);
00641 }
00642
00643 if (recog->process_active) {
00644 callback_exec(CALLBACK_POLL, recog);
00645 }
00646
00647 j_reset_reload(recog);
00648
00649 if (!recog->process_active) {
00650
00651
00652 return 1;
00653 }
00654
00655 if (recog->process_online != recog->process_active) {
00656 recog->process_online = recog->process_active;
00657 if (recog->process_online) callback_exec(CALLBACK_EVENT_PROCESS_ONLINE, recog);
00658 else callback_exec(CALLBACK_EVENT_PROCESS_OFFLINE, recog);
00659 }
00660
00661
00662
00663
00664 for(lm=recog->lmlist;lm;lm=lm->next) {
00665 if (lm->lmtype == LM_DFA) {
00666 multigram_update(lm);
00667 }
00668 }
00669 for(r=recog->process_list;r;r=r->next) {
00670 if (!r->live) continue;
00671 if (r->lmtype == LM_DFA && r->lm->global_modified) {
00672 multigram_build(r);
00673 }
00674 }
00675 for(lm=recog->lmlist;lm;lm=lm->next) {
00676 if (lm->lmtype == LM_DFA) lm->global_modified = FALSE;
00677 }
00678
00679 ok_p = FALSE;
00680 for(r=recog->process_list;r;r=r->next) {
00681 if (!r->live) continue;
00682 if (r->lmtype == LM_DFA) {
00683 if (r->lm->winfo == NULL ||
00684 (r->lmvar == LM_DFA_GRAMMAR && r->lm->dfa == NULL)) {
00685
00686 r->active = -1;
00687 ok_p = TRUE;
00688 }
00689 }
00690 }
00691 if (ok_p) {
00692 goto start_recog;
00693 }
00694
00695
00696
00697
00698 if (jconf->input.speech_input == SP_MFCFILE) {
00699
00700
00701
00702
00703
00704
00705
00706
00707 if (jconf->input.paramtype_check_flag) {
00708 for(am=recog->amlist;am;am=am->next) {
00709
00710 if (param_check_and_adjust(am->hmminfo, am->mfcc->param, verbose_flag) == -1) {
00711
00712 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00713 param_init_content(mfcc->param);
00714 }
00715
00716 result_error(recog, J_RESULT_STATUS_FAIL);
00717 goto end_recog;
00718 }
00719 }
00720 }
00721
00722
00723 ret = 0;
00724 } else {
00725
00726
00727
00728 if (jconf->decodeopt.realtime_flag) {
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 if (recog->process_segment) {
00740
00741
00742
00743
00744
00745
00746
00747 callback_exec(CALLBACK_EVENT_SPEECH_READY, recog);
00748
00749 ret = RealTimeResume(recog);
00750 if (ret < 0) {
00751 jlog("ERROR: failed to process last remaining samples on RealTimeResume\n");
00752 return -1;
00753 }
00754 if (ret != 1) {
00755
00756
00757
00758 ret = adin_go(RealTimePipeLine, callback_check_in_adin, recog);
00759 if (ret < 0) {
00760 if (ret == -2 || recog->process_want_terminate) {
00761
00762 RealTimeTerminate(recog);
00763
00764 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00765 param_init_content(mfcc->param);
00766 }
00767
00768 if (recog->triggered) {
00769 callback_exec(CALLBACK_EVENT_PASS1_END, recog);
00770
00771 result_error(recog, J_RESULT_STATUS_TERMINATE);
00772 }
00773 goto end_recog;
00774 }
00775 jlog("ERROR: an error occured at on-the-fly 1st pass decoding\n");
00776 return(-1);
00777 }
00778 }
00779
00780 } else {
00781
00782
00783
00784
00785
00786
00787
00788
00789 if (RealTimePipeLinePrepare(recog) == FALSE) {
00790 jlog("ERROR: failed to prepare for on-the-fly 1st pass decoding");
00791 return (-1);
00792 }
00793
00794 callback_exec(CALLBACK_EVENT_SPEECH_READY, recog);
00795
00796 ret = adin_go(RealTimePipeLine, callback_check_in_adin, recog);
00797 if (ret < 0) {
00798 if (ret == -2 || recog->process_want_terminate) {
00799
00800 RealTimeTerminate(recog);
00801
00802 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00803 param_init_content(mfcc->param);
00804 }
00805
00806 if (recog->triggered) {
00807 callback_exec(CALLBACK_EVENT_PASS1_END, recog);
00808
00809 result_error(recog, J_RESULT_STATUS_TERMINATE);
00810 }
00811 goto end_recog;
00812 }
00813 jlog("ERROR: an error occured at on-the-fly 1st pass decoding\n");
00814 return(-1);
00815 }
00816 }
00817
00818
00819
00820
00821 if (RealTimeParam(recog) == FALSE) {
00822 jlog("ERROR: fatal error occured, program terminates now\n");
00823 return -1;
00824 }
00825
00826 #ifdef BACKEND_VAD
00827
00828 if (recog->jconf->decodeopt.segment && ! recog->triggered) {
00829 goto end_recog;
00830 }
00831 #endif
00832
00833
00834
00835 callback_exec(CALLBACK_RESULT_PASS1, recog);
00836 #ifdef WORD_GRAPH
00837
00838 callback_exec(CALLBACK_RESULT_PASS1_GRAPH, recog);
00839 #endif
00840
00841 callback_exec(CALLBACK_EVENT_PASS1_END, recog);
00842
00843 callback_exec(CALLBACK_STATUS_PARAM, recog);
00844
00845 if (recog->process_want_terminate) {
00846 result_error(recog, J_RESULT_STATUS_TERMINATE);
00847 goto end_recog;
00848 }
00849
00850
00851 goto end_1pass;
00852
00853 }
00854
00855
00856
00857
00858 if (!recog->process_segment) {
00859
00860
00861
00862
00863 recog->speechlen = 0;
00864 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00865 param_init_content(mfcc->param);
00866 }
00867
00868 callback_exec(CALLBACK_EVENT_SPEECH_READY, recog);
00869
00870
00871
00872
00873
00874
00875 ret = adin_go(adin_cut_callback_store_buffer, callback_check_in_adin, recog);
00876 if (ret < 0) {
00877 if (ret == -2 || recog->process_want_terminate) {
00878
00879
00880 result_error(recog, J_RESULT_STATUS_TERMINATE);
00881 goto end_recog;
00882 }
00883 jlog("ERROR: an error occured while recording input\n");
00884 return -1;
00885 }
00886
00887
00888 seclen = (float)recog->speechlen / (float)jconf->input.sfreq;
00889 jlog("STAT: %d samples (%.2f sec.)\n", recog->speechlen, seclen);
00890
00891
00892
00893
00894
00895 if (jconf->reject.rejectshortlen > 0) {
00896 if (seclen * 1000.0 < jconf->reject.rejectshortlen) {
00897 result_error(recog, J_RESULT_STATUS_REJECT_SHORT);
00898 goto end_recog;
00899 }
00900 }
00901
00902
00903
00904
00905 jlog("STAT: ### speech analysis (waveform -> MFCC)\n");
00906
00907 if (wav2mfcc(recog->speech, recog->speechlen, recog) == FALSE) {
00908
00909 ret = -1;
00910
00911 result_error(recog, J_RESULT_STATUS_FAIL);
00912 goto end_recog;
00913 }
00914
00915
00916 if (recog->process_want_terminate) {
00917 result_error(recog, J_RESULT_STATUS_TERMINATE);
00918 goto end_recog;
00919 }
00920
00921
00922 callback_exec(CALLBACK_STATUS_PARAM, recog);
00923
00924 }
00925 }
00926
00927
00928
00929
00930
00931
00932 if (!jconf->decodeopt.realtime_flag) {
00933
00934
00935 for(am=recog->amlist;am;am=am->next) {
00936 outprob_prepare(&(am->hmmwrk), am->mfcc->param->samplenum);
00937 }
00938 }
00939
00940
00941 if (recog->process_want_terminate) {
00942 result_error(recog, J_RESULT_STATUS_TERMINATE);
00943 goto end_recog;
00944 }
00945
00946
00947
00948
00949
00950 if (get_back_trellis(recog) == FALSE) {
00951 jlog("ERROR: fatal error occured, program terminates now\n");
00952 return -1;
00953 }
00954 #ifdef BACKEND_VAD
00955
00956 if (recog->jconf->decodeopt.segment && ! recog->triggered) {
00957 goto end_recog;
00958 }
00959 #endif
00960
00961
00962
00963 callback_exec(CALLBACK_RESULT_PASS1, recog);
00964 #ifdef WORD_GRAPH
00965
00966 callback_exec(CALLBACK_RESULT_PASS1_GRAPH, recog);
00967 #endif
00968
00969
00970 if (recog->triggered) {
00971 callback_exec(CALLBACK_EVENT_PASS1_END, recog);
00972 }
00973
00974 end_1pass:
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 if (jconf->reject.rejectshortlen > 0) {
00986 mseclen = (float)recog->mfcclist->param->samplenum * (float)jconf->input.period * (float)jconf->input.frameshift / 10000.0;
00987 if (mseclen < jconf->reject.rejectshortlen) {
00988 result_error(recog, J_RESULT_STATUS_REJECT_SHORT);
00989 goto end_recog;
00990 }
00991 }
00992 #ifdef POWER_REJECT
00993 if (power_reject(recog)) {
00994 result_error(recog, J_RESULT_STATUS_REJECT_POWER);
00995 goto end_recog;
00996 }
00997 #endif
00998
00999
01000 if (recog->process_want_terminate) {
01001 result_error(recog, J_RESULT_STATUS_TERMINATE);
01002 goto end_recog;
01003 }
01004
01005
01006 if (jconf->reject.gmm_reject_cmn_string != NULL) {
01007 if (! gmm_valid_input(recog)) {
01008 result_error(recog, J_RESULT_STATUS_REJECT_GMM);
01009 goto end_recog;
01010 }
01011 }
01012
01013
01014
01015
01016 #if !defined(PASS2_STRICT_IWCD) || defined(FIX_35_PASS2_STRICT_SCORE)
01017
01018 for(r=recog->process_list;r;r=r->next) {
01019 if (!r->live) continue;
01020
01021 if (r->config->compute_only_1pass) continue;
01022
01023 if (r->result.status < 0) continue;
01024 if (! r->am->hmminfo->multipath) {
01025 bt_discount_pescore(r->wchmm, r->backtrellis, r->am->mfcc->param);
01026 }
01027 #ifdef LM_FIX_DOUBLE_SCORING
01028 if (r->lmtype == LM_PROB) {
01029 bt_discount_lm(r->backtrellis);
01030 }
01031 #endif
01032 }
01033 #endif
01034
01035
01036 callback_exec(CALLBACK_EVENT_PASS2_BEGIN, recog);
01037
01038 for(r=recog->process_list;r;r=r->next) {
01039 if (!r->live) continue;
01040
01041 if (r->config->compute_only_1pass) continue;
01042
01043 if (r->result.status < 0) continue;
01044 if (r->lmtype == LM_PROB) {
01045 wchmm_fbs(r->am->mfcc->param, r, 0, 0);
01046 } else if (r->lmtype == LM_DFA) {
01047 if (r->config->output.multigramout_flag) {
01048
01049
01050 MULTIGRAM *m;
01051 for(m = r->lm->grammars; m; m = m->next) {
01052 if (m->active) {
01053 jlog("STAT: execute 2nd pass limiting words for gram #%d\n", m->id);
01054 wchmm_fbs(r->am->mfcc->param, r, m->cate_begin, m->dfa->term_num);
01055 }
01056 }
01057 } else {
01058
01059 wchmm_fbs(r->am->mfcc->param, r, 0, r->lm->dfa->term_num);
01060 }
01061 }
01062 }
01063
01064
01065 callback_exec(CALLBACK_RESULT, recog);
01066
01067
01068 ok_p = FALSE;
01069 for(r=recog->process_list;r;r=r->next) {
01070 if (!r->live) continue;
01071 if (r->config->graph.lattice) ok_p = TRUE;
01072 }
01073 if (ok_p) callback_exec(CALLBACK_RESULT_GRAPH, recog);
01074
01075
01076 ok_p = FALSE;
01077 for(r=recog->process_list;r;r=r->next) {
01078 if (!r->live) continue;
01079 if (r->config->graph.confnet) ok_p = TRUE;
01080 }
01081 if (ok_p) callback_exec(CALLBACK_RESULT_CONFNET, recog);
01082
01083
01084 for(r=recog->process_list;r;r=r->next) {
01085 if (!r->live) continue;
01086 clear_result(r);
01087 }
01088
01089
01090 callback_exec(CALLBACK_EVENT_PASS2_END, recog);
01091
01092 end_recog:
01093
01094
01095
01096
01097 process_segment_last = recog->process_segment;
01098 if (jconf->decodeopt.segment) {
01099
01100
01101
01102
01103 recog->process_segment = FALSE;
01104 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
01105 if (mfcc->rest_param != NULL) {
01106
01107 recog->process_segment = TRUE;
01108 free_param(mfcc->param);
01109 mfcc->param = mfcc->rest_param;
01110 mfcc->rest_param = NULL;
01111 }
01112 }
01113 }
01114
01115
01116 if (jconf->decodeopt.segment) {
01117 #ifdef BACKEND_VAD
01118 if (recog->triggered) callback_exec(CALLBACK_EVENT_SEGMENT_END, recog);
01119 if (process_segment_last && !recog->process_segment) callback_exec(CALLBACK_EVENT_RECOGNITION_END, recog);
01120 #else
01121 callback_exec(CALLBACK_EVENT_SEGMENT_END, recog);
01122 if (!recog->process_segment) callback_exec(CALLBACK_EVENT_RECOGNITION_END, recog);
01123 #endif
01124 } else {
01125 callback_exec(CALLBACK_EVENT_RECOGNITION_END, recog);
01126 }
01127
01128
01129
01130 if (jconf->input.speech_input != SP_MFCFILE && jconf->decodeopt.realtime_flag) {
01131 for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
01132 if (mfcc->param->samplenum > 0) {
01133 RealTimeCMNUpdate(mfcc, recog);
01134 }
01135 }
01136 }
01137
01138 if (verbose_flag) jlog("\n");
01139 jlog_flush();
01140
01141 if (jconf->decodeopt.segment) {
01142 if (recog->process_segment == TRUE) {
01143 if (verbose_flag) jlog("STAT: <<<restart the rest>>>\n\n");
01144 } else {
01145
01146 if (ret <= 0 && ret != -2) break;
01147 }
01148 } else {
01149
01150 if (ret <= 0 && ret != -2) break;
01151 }
01152
01153
01154
01155 }
01156
01157
01158
01159
01160
01161
01162
01163
01164 if (jconf->input.speech_input != SP_MFCFILE) {
01165
01166 adin_end(recog->adin);
01167 }
01168
01169
01170
01171 return(0);
01172
01173 }
01174
01219 int
01220 j_recognize_stream(Recog *recog)
01221 {
01222 int ret;
01223
01224 do {
01225
01226 ret = j_recognize_stream_core(recog);
01227
01228 switch(ret) {
01229 case 1:
01230
01231 callback_exec(CALLBACK_EVENT_PAUSE, recog);
01232
01233
01234 if (! callback_exist(recog, CALLBACK_PAUSE_FUNCTION)) {
01235 jlog("WARNING: pause requested but no pause function specified\n");
01236 jlog("WARNING: engine will resume now immediately\n");
01237 }
01238 callback_exec(CALLBACK_PAUSE_FUNCTION, recog);
01239
01240
01241 callback_exec(CALLBACK_EVENT_RESUME, recog);
01242 break;
01243 case 0:
01244
01245 break;
01246 case -1:
01247 jlog("ERROR: an error occured while recognition, terminate stream\n");
01248 return -1;
01249 }
01250 } while (ret == 1);
01251
01252 return 0;
01253 }
01254
01255