julius/main.c

Go to the documentation of this file.
00001 
00017 /*
00018  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00019  * Copyright (c) 1997-2000 Information-technology Promotion Agency, Japan
00020  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00021  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00022  * All rights reserved
00023  */
00024 
00025 #define GLOBAL_VARIABLE_DEFINE  
00026 #include <julius.h>
00027 #include <signal.h>
00028 #if defined(_WIN32) && !defined(__CYGWIN32__)
00029 #include <mbctype.h>
00030 #include <mbstring.h>
00031 #endif
00032 
00033 
00034 /* ---------- utility functions -----------------------------------------*/
00035 #ifdef REPORT_MEMORY_USAGE
00036 
00046 static void
00047 print_mem()
00048 {
00049   char buf[200];
00050   sprintf(buf,"ps -o vsz,rss -p %d",getpid());
00051   system(buf);
00052   j_flushprint();
00053   fflush(stderr);
00054 }
00055 #endif
00056           
00057 
00058 /* --------------------- speech buffering ------------------ */
00066 static SP16 *overflowed_samples = NULL;
00071 static int overflowed_samplenum;
00102 int
00103 adin_cut_callback_store_buffer(SP16 *now, int len)
00104 {
00105   if (module_mode) {
00106     /* poll the command buffer for each input fragment */
00107     msock_check_and_process_command();
00108   }
00109   if (speechlen == 0) {         /* first part of a segment */
00110     /* output start recording/processing message */
00111     status_recstart();
00112     if (module_mode) {
00113       /* module termination check */
00114       if (module_wants_terminate() ||/* TERMINATE ... force termination */
00115           !module_is_active()) { /* PAUSE ... keep recording when *triggering */
00116         return(-2);
00117       }
00118     }
00119     if (overflowed_samples) {   /* last input was overflowed */
00120       /* restore last overflowed samples */
00121       memcpy(&(speech[0]), overflowed_samples, sizeof(SP16)*overflowed_samplenum);
00122       speechlen += overflowed_samplenum;
00123       free(overflowed_samples);
00124       overflowed_samples = NULL;
00125     }
00126   }
00127   if (speechlen + len > MAXSPEECHLEN) {
00128     /*j_printerr("Error: too long input (> %d samples)\n", MAXSPEECHLEN);*/
00129     j_printerr("Warning: too long input (> %d samples), segmented now\n", MAXSPEECHLEN);
00130     /* store the overflowed samples for next segment, and end segment */
00131     {
00132       int getlen, restlen;
00133       getlen = MAXSPEECHLEN - speechlen;
00134       restlen = len - getlen;
00135       overflowed_samples = (SP16 *)mymalloc(sizeof(SP16)*restlen);
00136       memcpy(overflowed_samples, &(now[getlen]), restlen * sizeof(SP16));
00137       if (record_dirname != NULL) {
00138         record_sample_write(&(now[getlen]), restlen);
00139       }
00140       overflowed_samplenum = restlen;
00141       memcpy(&(speech[speechlen]), now, getlen * sizeof(SP16));
00142       if (record_dirname != NULL) {
00143         record_sample_write(now, getlen);
00144       }
00145       speechlen += getlen;
00146     }
00147     return(1);                  /* tell adin_go to end segment */
00148   }
00149   if (module_mode) {
00150     /* poll module command and terminate here if requested */
00151     if (module_wants_terminate()) {/* TERMINATE ... force termination */
00152       speechlen = 0;
00153       return(-2);
00154     }
00155   }
00156   /* store now[0..len] to speech[speechlen] */
00157   memcpy(&(speech[speechlen]), now, len * sizeof(SP16));
00158   if (record_dirname != NULL) {
00159     record_sample_write(now, len);
00160   }
00161   speechlen += len;
00162   return(0);                    /* tell adin_go to continue reading */
00163 }
00164 
00165 /* return malloced next file name from inputlist (return NULL on error) */
00201 static char *
00202 mfcfilelist_nextfile()
00203 {
00204   static FILE *mfclist = NULL;  /* current filelist of MFC file (-filelist) */
00205   static char *buf;
00206   
00207   if (mfclist == NULL) {        /* not opened yet */
00208     if ((mfclist = fopen(inputlist_filename, "r")) == NULL) { /* open error */
00209       j_error("inputlist open error\n");
00210     }
00211   }
00212   buf = mymalloc(MAXLINELEN);
00213   while(getl_fp(buf, MAXLINELEN, mfclist) != NULL) {
00214     if (buf[0] == '\0') continue; /* skip blank line */
00215     if (buf[0] == '#') continue; /* skip commented-out line */
00216     /* read a filename */
00217     return buf;
00218   }
00219   /* end of inputfile list */
00220   free(buf);
00221   fclose(mfclist);
00222   mfclist = NULL;
00223   return NULL;
00224 }
00225 
00226                                       
00227 /* ------------------------------------------------------------------- */
00228 /* ------------- Main Recognition Loop ------------------------------- */
00229 /* ------------------------------------------------------------------- */
00230 
00252 void
00253 main_recognition_loop()
00254 {
00255   char *speechfilename; /* pathname of speech file or MFCC file */
00256   HTK_Param *param = NULL;              /* parameter vector */
00257   HTK_Param *selected_param;
00258   int ret;
00259   int file_counter;
00260   float seclen, mseclen;
00261   boolean process_online = FALSE; /* TRUE if audio stream is now open and engine is either listening audio stream or recognizing a speech.  FALSE on startup or when in pause specified by a module command. */
00262 
00263   /***************************/
00264   /* Model/IO initialization */
00265   /***************************/
00266   /* initialize all models, work area, parameters to bootup system */
00267   final_fusion();
00268 
00269   /* initialize and standby audio input device */
00270   adin_initialize();
00271   
00272   /* print out system information */
00273   print_info();
00274 
00275   /* reset file count */
00276   file_counter = 0;
00277 
00278 #ifdef VISUALIZE
00279   /* Visualize: initialize GTK */
00280   visual_init();
00281 #endif
00282 
00283   /***************************/
00284   /***************************/
00286   /***************************/
00287   /***************************/
00288   for (;;) {
00289 
00290     j_printf("\n");
00291     if (verbose_flag) j_printf("------\n");
00292     j_flushprint();
00293 
00294     /*********************/
00295     /* open input stream */
00296     /*********************/
00297     if (speech_input == SP_MFCFILE) {
00298       /************************************/
00299       /* read pre-analyzed parameter file */
00300       /************************************/
00301       VERMES("### read analyzed parameter\n");
00302       /* from MFCC parameter file (in HTK format) */
00303       if (inputlist_filename != NULL) { /* has filename list */
00304         speechfilename = mfcfilelist_nextfile();
00305       } else {
00306         speechfilename = get_line("enter MFCC filename->");
00307       }
00308       if (speechfilename == NULL) {
00309         /* end */
00310         j_printerr("%d files processed\n", file_counter);
00311 #ifdef REPORT_MEMORY_USAGE
00312         print_mem();
00313 #endif
00314         j_exit();
00315       }
00316       if (verbose_flag) j_printf("\ninput MFCC file: %s\n",speechfilename);
00317       /* read parameter file */
00318       param = new_param();
00319       if (rdparam(speechfilename, param) == FALSE) {
00320         j_printerr("error in reading parameter file: %s\n",speechfilename);
00321         free(speechfilename);
00322         free_param(param);
00323         continue;
00324       }
00325       /* check and strip invalid frames */
00326       if (strip_zero_sample) {
00327         param_strip_zero(param);
00328       }
00329       free(speechfilename);
00330       /* output frame length */
00331       status_param(param);
00332       /* count number of processed files */
00333       file_counter++;
00334     } else {                    /* raw speech input */
00335       /********************************/
00336       /* ready to read waveform input */
00337       /********************************/
00338       VERMES("### read waveform input\n");
00339       /* begin A/D input */
00340       if (adin_begin() == FALSE) {
00341         /* failed to begin stream, terminate */
00342         if (speech_input == SP_RAWFILE) {
00343           j_printerr("%d files processed\n", file_counter);
00344           j_exit();  /* end of file list */
00345         } else if (speech_input == SP_STDIN) {
00346           j_exit();  /* end of input */
00347         } else {
00348           j_error("failed to begin input stream\n");
00349         }
00350       }
00351       /* count number of processed files */
00352       if (speech_input == SP_RAWFILE) {
00353         file_counter++;
00354       }
00355     }
00356     
00357 #ifdef USE_DFA
00358     /* if no grammar specified on startup, start with pause status */
00359     if (module_mode) {
00360       if (dfa == NULL || winfo == NULL) { /* stop when no grammar found */
00361         msock_exec_command("PAUSE");
00362       }
00363     }
00364 #endif
00365 
00366     if (!module_mode) {
00367       /* if not module mode, process becomes online after all initialize done */
00368       process_online = TRUE;
00369       status_process_online();
00370     }
00371   
00372     /******************************************************************/
00373     /* do recognition for each incoming segment from the input stream */
00374     /******************************************************************/
00375     while (1) {
00376 
00377     start_recog:
00378 
00379       if (module_mode) {
00380         /*****************************/
00381         /* module command processing */
00382         /*****************************/
00383         /* If recognition is running (active), commands are polled only once
00384            here, and if any, process the command, and continue the recognition.
00385            If recognition is sleeping (inactive), wait here for any command to
00386            come, and process them until recognition is activated by the
00387            commands
00388          */
00389         /* Output process status when status change occured by module command */
00390         if (process_online != module_is_active()) {
00391           process_online = module_is_active();
00392           if (process_online) status_process_online();
00393           else status_process_offline();
00394         }
00395         if (module_is_active()) {
00396           /* process is now active: check a command in buffer and process if any */
00397           msock_check_and_process_command();
00398         }
00399         module_reset_reload();  /* reset reload flag here */
00400         while (! module_is_active()) {    
00401           /* now sleeping, wait for another command */
00402           /* we will stop here and wait for another command */
00403           /* until status turns to active */
00404           msock_process_command();
00405         }
00406         /* update process status */
00407         if (process_online != module_is_active()) {
00408           process_online = module_is_active();
00409           if (process_online) status_process_online();
00410           else status_process_offline();
00411         }
00412 #ifdef USE_DFA
00413         /*********************************************************/
00414         /* check for grammar to change, and rebuild if necessary */
00415         /*********************************************************/
00416         multigram_exec();
00417         if (dfa == NULL || winfo == NULL) { /* stop when no grammar found */
00418           msock_exec_command("PAUSE");
00419           goto start_recog;
00420         }
00421 #endif
00422       }
00423 
00424       if (speech_input == SP_MFCFILE) {
00425         /************************/
00426         /* parameter file input */
00427         /************************/
00428         /********************************/
00429         /* check the analized parameter */
00430         /********************************/
00431         /* parameter type check --- compare the type to that of HMM,
00432            and adjust them if necessary */
00433         if (paramtype_check_flag) {
00434           /* return param itself or new malloced param */
00435           selected_param = new_param_check_and_adjust(hmminfo, param, verbose_flag);
00436           if (selected_param == NULL) { /* failed */
00437             free_param(param);
00438             param = NULL;
00439             goto end_recog;
00440           }
00441           param = selected_param;
00442         }
00443         /* whole input is already read, so set input status to end of stream */
00444         /* and jump to the start point of 1st pass */
00445         ret = 0;
00446       } else {
00447         /****************************************************/
00448         /* raw wave data input (mic, file, adinnet, etc...) */
00449         /****************************************************/
00450         if (realtime_flag) {
00451           /********************************************/
00452           /* REALTIME ON-THE-FLY DECODING OF 1ST-PASS */
00453           /********************************************/
00454           /* store, analysis and search in a pipeline  */
00455           /* main function is RealTimePipeLine() at realtime-1stpass.c, and
00456              it will be periodically called for each incoming input segment
00457              from the AD-in function adin_go().  RealTimePipeLine() will be
00458              called as a callback function from adin_go() */
00459           /* after this part, directly jump to the beginning of the 2nd pass */
00460 #ifdef SP_BREAK_CURRENT_FRAME
00461           if (rest_param) {
00462             /*****************************************************************/
00463             /* short-pause segmentation: process last remaining frames first */
00464             /*****************************************************************/
00465             /* last was segmented by short pause */
00466             /* the margin segment in the last input should be re-processed first */
00467             /* process the last remaining parameters */
00468             ret = RealTimeResume();
00469             if (ret < 0) {              /* error end in the margin */
00470               j_error("error in resuming last fragment\n"); /* exit now! */
00471             }
00472             if (ret != 1) {     /* if segmented again in the margin, not process the rest */
00473               /* last parameters has been processed, so continue with the
00474                  current input as normal */
00475               /* output listening start message */
00476               status_recready();
00477               if (module_mode) {
00478                 /* tell module to start recording, and command check in adin */
00479                 ret = adin_go(RealTimePipeLine, msock_check_in_adin);
00480               } else {
00481                 /* process the incoming input as normal */
00482                 ret = adin_go(RealTimePipeLine, NULL);
00483               }
00484               if (ret < 0) {            /* error end in adin_go */
00485                 if (module_mode && (ret == -2 || module_wants_terminate())) {   /* terminated by module */
00486                   RealTimeTerminate();
00487                   param = NULL;
00488                   goto end_recog; /* cancel this recognition */
00489                 }
00490                 j_error("error in adin_go\n");          /* exit now! */
00491               }
00492             }
00493             
00494           } else {
00495             /* last was not segmented, process the incoming input  */
00496 #endif
00497             /**********************************/
00498             /* process incoming speech stream */
00499             /**********************************/
00500             /* end of this input will be determined by either end of stream
00501                (in case of file input), or silence detection by adin_go(), or
00502                'TERMINATE' command from module (if module mode) */
00503             /* prepare work area for on-the-fly processing */
00504             RealTimePipeLinePrepare();
00505             /* output 'listening start' message */
00506             status_recready();
00507             /* process the incoming input */
00508             if (module_mode) {
00509               ret = adin_go(RealTimePipeLine, msock_check_in_adin);
00510             } else {
00511               ret = adin_go(RealTimePipeLine, NULL); 
00512             }
00513             if (ret < 0) {              /* error end in adin_go */
00514               if (module_mode && (ret == -2 || module_wants_terminate())) {     /* terminated by module */
00515                 RealTimeTerminate();
00516                 param = NULL;
00517                 goto end_recog;
00518               }
00519               j_error("error in adin_go\n");            /* exit now! */
00520             }
00521 #ifdef SP_BREAK_CURRENT_FRAME
00522           }
00523 #endif
00524           /******************************************************************/
00525           /* speech stream has been processed on-the-fly, and 1st pass ends */
00526           /******************************************************************/
00527           /* last procedure of 1st-pass */
00528           param = RealTimeParam(&backmax);
00529           /* output stopped recording message */
00530           status_recend();
00531           /* output frame length */
00532           status_param(param);
00533           if (module_mode) {
00534             /* if terminate signal has been received, discard this input */
00535             if (module_wants_terminate()) goto end_recog;
00536           }
00537           /* end of 1st pass, jump to 2nd pass */
00538           goto end_1pass;
00539           
00540         } /* end of realtime_flag && speech stream input */
00541         
00542         /******************************************/
00543         /* buffered speech input (not on-the-fly) */
00544         /******************************************/
00545 #ifdef SP_BREAK_CURRENT_FRAME
00546         if (rest_param == NULL) { /* no segment left */
00547 #endif
00548           /****************************************/
00549           /* store raw speech samples to speech[] */
00550           /****************************************/
00551           speechlen = 0;
00552           param = NULL;
00553           /* if needed, begin recording the incoming speech data to a file */
00554           if (record_dirname != NULL) {
00555             record_sample_open();
00556           }
00557           /* output 'listening start' message */
00558           status_recready();
00559           if (module_mode) {
00560             /* tell module to start recording */
00561             /* the "adin_cut_callback_store_buffer" simply stores
00562                the input speech to a buffer "speech[]" */
00563             /* end of this input will be determined by either end of stream
00564                (in case of file input), or silence detection by adin_go(), or
00565                'TERMINATE' command from module (if module mode) */
00566             ret = adin_go(adin_cut_callback_store_buffer, msock_check_in_adin);
00567           } else {
00568             ret = adin_go(adin_cut_callback_store_buffer, NULL);
00569           }
00570           if (ret < 0) {                /* error end in adin_go */
00571             if (module_mode && (ret == -2 || module_wants_terminate())) {       /* terminated by module */
00572               goto end_recog;
00573             }
00574             j_error("error in adin_go\n");              /* exit now! */
00575           }
00576           /* output stopped recording message */
00577           status_recend();
00578 
00579           /* output recorded length */
00580           seclen = (float)speechlen / (float)para.smp_freq;
00581           j_printf("%d samples (%.2f sec.)\n", speechlen, seclen);
00582 
00583           /* -rejectshort 指定時, 入力が指定時間以下であれば
00584              ここで入力を棄却する */
00585           /* when using "-rejectshort", and input was shorter than
00586              specified, reject the input here */
00587           if (rejectshortlen > 0) {
00588             if (seclen * 1000.0 < rejectshortlen) {
00589               result_rejected("too short input");
00590               goto end_recog;
00591             }
00592           }
00593       
00594           /**********************************************/
00595           /* acoustic analysis and encoding of speech[] */
00596           /**********************************************/
00597           VERMES("### speech analysis (waveform -> MFCC)\n");
00598           /* CMN will be computed for the whole buffered input */
00599           param = new_wav2mfcc(speech, speechlen);
00600           if (param == NULL) {
00601             ret = -1;
00602             goto end_recog;
00603           }
00604 
00605           /* if terminate signal has been received, cancel this input */
00606           if (module_mode && module_wants_terminate()) goto end_recog;
00607 
00608           /* output frame length */
00609           status_param(param);
00610 
00611 #ifdef SP_BREAK_CURRENT_FRAME
00612         }
00613 #endif
00614       } /* end of data input */
00615       /* parameter has been got in 'param' */
00616 
00617       /******************************************************/
00618       /* 1st-pass --- backward search to compute heuristics */
00619       /******************************************************/
00620       /* (for buffered speech input and HTK parameter file input) */
00621 #ifdef USE_NGRAM
00622       VERMES("### Recognition: 1st pass (LR beam with 2-gram)\n");
00623 #else
00624       VERMES("### Recognition: 1st pass (LR beam with word-pair grammar)\n");
00625 #endif
00626 /* 
00627  * #ifdef WPAIR
00628  *     VERMES("with word-pair approx. ");
00629  * #else
00630  *     VERMES("with 1-best approx. ");
00631  * #endif
00632  *     VERMES("generating ");
00633  * #ifdef WORD_GRAPH
00634  *     VERMES("word graph\n");
00635  * #else
00636  *     VERMES("back trellis\n");
00637  * #endif
00638  */
00639 
00640       if (!realtime_flag) {
00641         /* prepare for outprob cache for each HMM state and time frame */
00642         outprob_prepare(param->samplenum);
00643       }
00644 
00645       if (module_mode) {
00646         /* if terminate signal has been received, cancel this input */
00647         if (module_wants_terminate()) goto end_recog;
00648       }
00649 
00650       /* execute computation of left-to-right backtrellis */
00651       get_back_trellis(param, wchmm, &backtrellis, &backmax);
00652 
00653     end_1pass:
00654 
00655       /**********************************/
00656       /* end processing of the 1st-pass */
00657       /**********************************/
00658       /* on-the-fly 1st pass processing will join here */
00659       
00660       /* -rejectshort 指定時, 入力が指定時間以下であれば探索失敗として */
00661       /* 第2パスを実行せずにここで終了する */
00662       /* when using "-rejectshort", and input was shorter than the specified
00663          length, terminate search here and output recognition failure */
00664       if (rejectshortlen > 0) {
00665         mseclen = (float)param->samplenum * (float)para.smp_period * (float)para.frameshift / 10000.0;
00666         if (mseclen < rejectshortlen) {
00667           result_rejected("too short input");
00668           goto end_recog;
00669         }
00670       }
00671   
00672       /* if [-1pass] is specified, terminate search here */
00673       if (compute_only_1pass) {
00674         goto end_recog;
00675       }
00676 
00677       /* if backtrellis function returns with bad status, terminate search */
00678       if (backmax == LOG_ZERO) {
00679         /* j_printerr("Terminate 2nd pass.\n"); */
00680         result_pass2_failed(wchmm->winfo);
00681         ret = -1;
00682         goto end_recog;
00683       }
00684 
00685       /* if terminate signal has been received, cancel this input */
00686       if (module_mode && module_wants_terminate()) goto end_recog;
00687 
00688       /* if GMM is specified and result are to be rejected, terminate search here */
00689       if (gmm_reject_cmn_string != NULL) {
00690         if (! gmm_valid_input()) {
00691           result_rejected("by GMM");
00692           goto end_recog;
00693         }
00694       }
00695       /***********************************************/
00696       /* 2nd-pass --- forward search with heuristics */
00697       /***********************************************/
00698 #if !defined(PASS2_STRICT_IWCD) || defined(FIX_35_PASS2_STRICT_SCORE)    
00699       /* adjust trellis score not to contain outprob of the last frames */
00700       bt_discount_pescore(wchmm, &backtrellis, param);
00701 #endif
00702 
00703 #ifdef USE_NGRAM
00704       VERMES("### Recognition: 2nd pass (RL heuristic best-first with 3-gram)\n");
00705 #else
00706       VERMES("### Recognition: 2nd pass (RL heuristic best-first with DFA)\n");
00707 #endif
00708 
00709       /* execute stack-decoding search */
00710 #ifdef USE_NGRAM
00711       wchmm_fbs(param, &backtrellis, backmax, stack_size, nbest, hypo_overflow, 0, 0);
00712 #else  /* USE_DFA */
00713       if (multigramout_flag) {
00714         /* execute 2nd pass multiple times for each grammar sequencially */
00715         /* to output result for each grammar */
00716         MULTIGRAM *m;
00717         for(m = gramlist; m; m = m->next) {
00718           if (m->active) {
00719             j_printf("## search for gram #%d\n", m->id);
00720             wchmm_fbs(param, &backtrellis, backmax, stack_size, nbest, hypo_overflow, m->cate_begin, m->dfa->term_num);
00721           }
00722         }
00723       } else {
00724         /* only the best among all grammar will be output */
00725         wchmm_fbs(param, &backtrellis, backmax, stack_size, nbest, hypo_overflow, 0, dfa->term_num);
00726       }
00727 #endif
00728 
00729     end_recog:
00730       /**********************/
00731       /* end of recognition */
00732       /**********************/
00733 
00734       /* update CMN info for next input (in case of realtime wave input) */
00735       if (speech_input != SP_MFCFILE && realtime_flag && param != NULL) {
00736         RealTimeCMNUpdate(param);
00737       }
00738 
00739 #ifdef VISUALIZE
00740       /* execute visualization */
00741       visual_show(&backtrellis);
00742 #endif
00743 
00744       /* free parameter work area */
00745       if (param != NULL) free_param(param);
00746 
00747       /* if needed, close the recording files */
00748       if (record_dirname != NULL) {
00749         record_sample_close();
00750       }
00751 
00752       VERMES("\n");
00753 
00754 #ifdef SP_BREAK_CURRENT_FRAME
00755       /* param is now shrinked to hold only the processed input, and */
00756       /* the rests are holded in (newly allocated) "rest_param" */
00757       /* if this is the last segment, rest_param is NULL */
00758       if (rest_param != NULL) {
00759         /* process the rest parameters in the next loop */
00760         VERMES("<<<restart the rest>>>\n\n");
00761         param = rest_param;
00762       } else {
00763         /* input has reached end of stream, terminate program */
00764         if (ret <= 0 && ret != -2) break;
00765       }
00766 #else
00767       /* input has reached end of stream, terminate program */
00768       if (ret <= 0 && ret != -2) break;
00769 #endif
00770 
00771       /* recognition continues for next (silence-aparted) segment */
00772       
00773     } /* END OF STREAM LOOP */
00774     
00775     /* input stream ended. it will happen when
00776        - input speech file has reached the end of file, 
00777        - adinnet input has received end of segment mark from client,
00778        - adinnet input has received end of input from client,
00779        - adinnet client disconnected.
00780     */
00781 
00782     if (speech_input != SP_MFCFILE) {
00783       /* close the stream */
00784       adin_end();
00785     }
00786     /* return to the opening of input stream */
00787   }
00788 
00789 }
00790 
00791 
00792 /* ------------------------------------------------------------------- */
00793 /* ------------- The Main Routine ------------------------------------ */
00794 /* ------------------------------------------------------------------- */
00821 int
00822 main(int argc, char *argv[])
00823 {
00824   /*************************/
00825   /* System initialization */
00826   /*************************/
00827   /* initialize, set some default parameter before all */
00828   system_bootup();
00829   /* parse options and set variables */
00830   opt_parse(argc,argv,NULL);
00831 
00832 #ifdef CHARACTER_CONVERSION
00833   if (j_printf_set_charconv(from_code, to_code) == FALSE) {
00834     j_error("Error: character set conversion setup failed\n");
00835   }
00836 #endif /* CHARACTER_CONVERSION */
00837 
00838   /* check option values */
00839   check_specs();
00840 
00841   /*********************/
00842   /* Server/Standalone */
00843   /*********************/
00844   if (module_mode) {
00845     /* server mode */
00846     /* main_recognition_loop() will be called in main_module_loop() */
00847     main_module_loop();
00848   } else {
00849     /* standalone mode */
00850     main_recognition_loop();
00851   }
00852 
00853   /* release global variables allocated when parsing options */
00854   opt_release();
00855 
00856   return 0;
00857 }

Generated on Tue Dec 26 12:53:21 2006 for Julian by  doxygen 1.5.0