libjulius/src/m_fusion.c

Go to the documentation of this file.
00001 
00026 /*
00027  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00028  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00029  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00030  * All rights reserved
00031  */
00032 
00033 #include <julius/julius.h>
00034 
00072 static HTK_HMM_INFO *
00073 initialize_HMM(JCONF_AM *amconf, Jconf *jconf)
00074 {
00075   HTK_HMM_INFO *hmminfo;
00076 
00077   /* at here, global variable "para" holds values specified by user or
00078      by user-specified HTK config file */
00079   if (amconf->analysis.para_hmm.loaded == 1) {
00080     jlog("Warning: you seems to read more than one acoustic model for recognition, but\n");
00081     jlog("Warning: previous one already has header-embedded acoustic parameters\n");
00082     jlog("Warning: if you have different parameters, result may be wrong!\n");
00083   }
00084   
00085   /* allocate new hmminfo */
00086   hmminfo = hmminfo_new();
00087   /* load hmmdefs */
00088   if (init_hmminfo(hmminfo, amconf->hmmfilename, amconf->mapfilename, &(amconf->analysis.para_hmm)) == FALSE) {
00089     hmminfo_free(hmminfo);
00090     return NULL;
00091   }
00092 
00093   /* set multipath mode flag */
00094   if (amconf->force_multipath) {
00095     jlog("STAT: m_fusion: force multipath HMM handling by user request\n");
00096     hmminfo->multipath = TRUE;
00097   } else {
00098     hmminfo->multipath = hmminfo->need_multipath;
00099   }
00100 
00101   /* only MFCC is supported for audio input */
00102   /* MFCC_{0|E}[_D][_A][_Z][_N] is supported */
00103   /* check parameter type of this acoustic HMM */
00104   if (jconf->input.speech_input != SP_MFCFILE) {
00105     /* Decode parameter extraction type according to the training
00106        parameter type in the header of the given acoustic HMM */
00107     if ((hmminfo->opt.param_type & F_BASEMASK) != F_MFCC) {
00108       jlog("ERROR: m_fusion: for direct speech input, only HMM trained by MFCC is supported\n");
00109       hmminfo_free(hmminfo);
00110       return NULL;
00111     }
00112     /* set acoustic analysis parameters from HMM header */
00113     calc_para_from_header(&(amconf->analysis.para), hmminfo->opt.param_type, hmminfo->opt.vec_size);
00114   }
00115   /* check if tied_mixture */
00116   if (hmminfo->is_tied_mixture && hmminfo->codebooknum <= 0) {
00117     jlog("ERROR: m_fusion: this tied-mixture model has no codebook!?\n");
00118     hmminfo_free(hmminfo);
00119     return NULL;
00120   }
00121 
00122 #ifdef PASS1_IWCD
00123   /* make state clusters of same context for inter-word triphone approx. */
00124   if (hmminfo->is_triphone) {
00125     jlog("STAT: making pseudo bi/mono-phone for IW-triphone\n");
00126     if (make_cdset(hmminfo) == FALSE) {
00127       jlog("ERROR: m_fusion: failed to make context-dependent state set\n");
00128       hmminfo_free(hmminfo);
00129       return NULL;
00130     }
00131     /* add those `pseudo' biphone and monophone to the logical HMM names */
00132     /* they points not to the defined HMM, but to the CD_Set structure */
00133     hmm_add_pseudo_phones(hmminfo);
00134   }
00135 #endif
00136 
00137   /* find short pause model and set to hmminfo->sp */
00138   htk_hmm_set_pause_model(hmminfo, amconf->spmodel_name);
00139 
00140 
00141   hmminfo->cdset_method = amconf->iwcdmethod;
00142   hmminfo->cdmax_num = amconf->iwcdmaxn;
00143 
00144   if (amconf->analysis.para_htk.loaded == 1) apply_para(&(amconf->analysis.para), &(amconf->analysis.para_htk));
00145   if (amconf->analysis.para_hmm.loaded == 1) apply_para(&(amconf->analysis.para), &(amconf->analysis.para_hmm));
00146   apply_para(&(amconf->analysis.para), &(amconf->analysis.para_default));
00147 
00148   return(hmminfo);
00149   
00150 }
00151 
00165 static HTK_HMM_INFO *
00166 initialize_GSHMM(JCONF_AM *amconf)
00167 {
00168   HTK_HMM_INFO *hmm_gs;
00169   Value para_dummy;
00170 
00171   jlog("STAT: Reading GS HMMs:\n");
00172   hmm_gs = hmminfo_new();
00173   undef_para(&para_dummy);
00174   if (init_hmminfo(hmm_gs, amconf->hmm_gs_filename, NULL, &para_dummy) == FALSE) {
00175     hmminfo_free(hmm_gs);
00176     return NULL;
00177   }
00178   return(hmm_gs);
00179 }
00180 
00197 static HTK_HMM_INFO *
00198 initialize_GMM(Jconf *jconf)
00199 {
00200   HTK_HMM_INFO *gmm;
00201   
00202   jlog("STAT: reading GMM: %s\n", jconf->reject.gmm_filename);
00203   gmm = hmminfo_new();
00204   if (init_hmminfo(gmm, jconf->reject.gmm_filename, NULL, &(jconf->gmm->analysis.para_hmm)) == FALSE) {
00205     hmminfo_free(gmm);
00206     return NULL;
00207   }
00208   /* check parameter type of this acoustic HMM */
00209   if (jconf->input.speech_input != SP_MFCFILE) {
00210     /* Decode parameter extraction type according to the training
00211        parameter type in the header of the given acoustic HMM */
00212     if ((gmm->opt.param_type & F_BASEMASK) != F_MFCC) {
00213       jlog("ERROR: m_fusion: for direct speech input, only GMM trained by MFCC is supported\n");
00214       hmminfo_free(gmm);
00215       return NULL;
00216     }
00217   }
00218 
00219   /* set acoustic analysis parameters from HMM header */
00220   calc_para_from_header(&(jconf->gmm->analysis.para), gmm->opt.param_type, gmm->opt.vec_size);
00221 
00222   if (jconf->gmm->analysis.para_htk.loaded == 1) apply_para(&(jconf->gmm->analysis.para), &(jconf->gmm->analysis.para_htk));
00223   if (jconf->gmm->analysis.para_hmm.loaded == 1) apply_para(&(jconf->gmm->analysis.para), &(jconf->gmm->analysis.para_hmm));
00224   apply_para(&(jconf->gmm->analysis.para), &(jconf->gmm->analysis.para_default));
00225 
00226   return(gmm);
00227 }
00228 
00262 static WORD_INFO *
00263 initialize_dict(JCONF_LM *lmconf, HTK_HMM_INFO *hmminfo)
00264 {
00265   WORD_INFO *winfo;
00266 
00267   /* allocate new word dictionary */
00268   winfo = word_info_new();
00269   /* read in dictinary from file */
00270   if ( ! 
00271 #ifdef MONOTREE
00272       /* leave winfo monophone for 1st pass lexicon tree */
00273        init_voca(winfo, lmconf->dictfilename, hmminfo, TRUE, lmconf->forcedict_flag)
00274 #else 
00275        init_voca(winfo, lmconf->dictfilename, hmminfo, FALSE, lmconf->forcedict_flag)
00276 #endif
00277        ) {
00278     jlog("ERROR: m_fusion: failed to read dictionary, terminated\n");
00279     word_info_free(winfo);
00280     return NULL;
00281   }
00282 
00283   if (lmconf->lmtype == LM_PROB) {
00284     /* if necessary, append a IW-sp word to the dict if "-iwspword" specified */
00285     if (lmconf->enable_iwspword) {
00286       if (
00287 #ifdef MONOTREE
00288           voca_append_htkdict(lmconf->iwspentry, winfo, hmminfo, TRUE)
00289 #else 
00290           voca_append_htkdict(lmconf->iwspentry, winfo, hmminfo, FALSE)
00291 #endif
00292           == FALSE) {
00293         jlog("ERROR: m_fusion: failed to make IW-sp word entry \"%s\"\n", lmconf->iwspentry);
00294         word_info_free(winfo);
00295         return NULL;
00296       } else {
00297         jlog("STAT: 1 IW-sp word entry added\n");
00298       }
00299     }
00300     /* set {head,tail}_silwid */
00301     winfo->head_silwid = voca_lookup_wid(lmconf->head_silname, winfo);
00302     if (winfo->head_silwid == WORD_INVALID) { /* not exist */
00303       jlog("ERROR: m_fusion: head sil word \"%s\" not exist in voca\n", lmconf->head_silname);
00304       word_info_free(winfo);
00305       return NULL;
00306     }
00307     winfo->tail_silwid = voca_lookup_wid(lmconf->tail_silname, winfo);
00308     if (winfo->tail_silwid == WORD_INVALID) { /* not exist */
00309       jlog("ERROR: m_fusion: tail sil word \"%s\" not exist in voca\n", lmconf->tail_silname);
00310       word_info_free(winfo);
00311       return NULL;
00312     }
00313   }
00314   
00315   return(winfo);
00316   
00317 }
00318 
00319 
00352 static NGRAM_INFO *
00353 initialize_ngram(JCONF_LM *lmconf, WORD_INFO *winfo)
00354 {
00355   NGRAM_INFO *ngram;
00356   boolean ret;
00357 
00358   /* allocate new */
00359   ngram = ngram_info_new();
00360   /* load LM */
00361   if (lmconf->ngram_filename != NULL) { /* binary format */
00362     ret = init_ngram_bin(ngram, lmconf->ngram_filename);
00363   } else {                      /* ARPA format */
00364     /* if either forward or backward N-gram is specified, read it */
00365     /* if both specified, use backward N-gram as main and
00366        use forward 2-gram only for 1st pass (this is an old behavior) */
00367     if (lmconf->ngram_filename_rl_arpa) {
00368       ret = init_ngram_arpa(ngram, lmconf->ngram_filename_rl_arpa, DIR_RL);
00369       if (ret == FALSE) {
00370         ngram_info_free(ngram);
00371         return NULL;
00372       }
00373       if (lmconf->ngram_filename_lr_arpa) {
00374         ret = init_ngram_arpa_additional(ngram, lmconf->ngram_filename_lr_arpa);
00375         if (ret == FALSE) {
00376           ngram_info_free(ngram);
00377           return NULL;
00378         }
00379       }
00380     } else if (lmconf->ngram_filename_lr_arpa) {
00381       ret = init_ngram_arpa(ngram, lmconf->ngram_filename_lr_arpa, DIR_LR);
00382     }
00383   }
00384   if (ret == FALSE) {
00385     ngram_info_free(ngram);
00386     return NULL;
00387   }
00388 
00389   /* map dict item to N-gram entry */
00390   make_voca_ref(ngram, winfo);
00391 
00392   return(ngram);
00393 }
00394 
00427 boolean
00428 j_load_am(Recog *recog, JCONF_AM *amconf)
00429 {
00430   PROCESS_AM *am;
00431 
00432   jlog("STAT: *** loading AM%02d %s\n", amconf->id, amconf->name);
00433 
00434   /* create AM process instance */
00435   am = j_process_am_new(recog, amconf);
00436   
00437   /* HMM */
00438   if ((am->hmminfo = initialize_HMM(amconf, recog->jconf)) == NULL) {
00439     jlog("ERROR: m_fusion: failed to initialize AM\n");
00440     return FALSE;
00441   }
00442   if (amconf->hmm_gs_filename != NULL) {
00443     if ((am->hmm_gs = initialize_GSHMM(amconf)) == NULL) {
00444       jlog("ERROR: m_fusion: failed to initialize GS HMM\n");
00445       return FALSE;
00446     }
00447   }
00448 
00449   /* fixate model-specific params */
00450   /* set params whose default will change by models and not specified in arg */
00451   /* select Gaussian pruning function */
00452   if (am->config->gprune_method == GPRUNE_SEL_UNDEF) {/* set default if not specified */
00453     if (am->hmminfo->is_tied_mixture) {
00454       /* enabled by default for tied-mixture models */
00455 #ifdef GPRUNE_DEFAULT_SAFE
00456       am->config->gprune_method = GPRUNE_SEL_SAFE;
00457 #elif GPRUNE_DEFAULT_HEURISTIC
00458       am->config->gprune_method = GPRUNE_SEL_HEURISTIC;
00459 #elif GPRUNE_DEFAULT_BEAM
00460       am->config->gprune_method = GPRUNE_SEL_BEAM;
00461 #endif
00462     } else {
00463       /* disabled by default for non tied-mixture model */
00464       am->config->gprune_method = GPRUNE_SEL_NONE;
00465     }
00466   }
00467   
00468   /* fixated analysis.para not uses loaded flag any more, so
00469      reset it for binary matching */
00470   amconf->analysis.para.loaded = 0;
00471 
00472   jlog("STAT: *** AM%02d %s loaded\n", amconf->id, amconf->name);
00473 
00474   return TRUE;
00475 }
00476 
00516 boolean
00517 j_load_lm(Recog *recog, JCONF_LM *lmconf)
00518 {
00519   JCONF_SEARCH *sh;
00520   PROCESS_LM *lm;
00521   PROCESS_AM *am, *atmp;
00522 
00523   jlog("STAT: *** loading LM%02d %s\n", lmconf->id, lmconf->name);
00524 
00525   /* find which am process instance to assign to each LM */
00526   am = NULL;
00527   for(sh=recog->jconf->search_root;sh;sh=sh->next) {
00528     if (sh->lmconf == lmconf) {
00529       for(atmp=recog->amlist;atmp;atmp=atmp->next) {
00530         if (sh->amconf == atmp->config) {
00531           am = atmp;
00532         }
00533       }
00534     }
00535   }
00536   if (am == NULL) {
00537     jlog("ERROR: cannot find corresponding AM for LM%02d %s\n", lmconf->id, lmconf->name);
00538     jlog("ERROR: you should write all AM/LM combinations to be used for recognition with \"-SR\"\n");
00539     return FALSE;
00540   }
00541 
00542   /* create LM process instance */
00543   lm = j_process_lm_new(recog, lmconf);
00544 
00545   /* assign AM process instance to the LM instance */
00546   lm->am = am;
00547 
00548   /* load language model */
00549   if (lm->lmtype == LM_PROB) {
00550     /* LM (N-gram) */
00551     if ((lm->winfo = initialize_dict(lm->config, lm->am->hmminfo)) == NULL) {
00552       jlog("ERROR: m_fusion: failed to initialize dictionary\n");
00553       return FALSE;
00554     }
00555     if (lm->config->ngram_filename_lr_arpa || lm->config->ngram_filename_rl_arpa || lm->config->ngram_filename) {
00556       if ((lm->ngram = initialize_ngram(lm->config, lm->winfo)) == NULL) {
00557         jlog("ERROR: m_fusion: failed to initialize N-gram\n");
00558         return FALSE;
00559       }
00560     }
00561   }
00562   if (lm->lmtype == LM_DFA) {
00563     /* DFA */
00564     if (lm->config->dfa_filename != NULL && lm->config->dictfilename != NULL) {
00565       /* here add grammar specified by "-dfa" and "-v" to grammar list */
00566       multigram_add_gramlist(lm->config->dfa_filename, lm->config->dictfilename, lm->config, LM_DFA_GRAMMAR);
00567     }
00568     /* load all the specified grammars */
00569     if (multigram_load_all_gramlist(lm) == FALSE) {
00570       jlog("ERROR: m_fusion: some error occured in reading grammars\n");
00571       return FALSE;
00572     }
00573     /* setup for later wchmm building */
00574     multigram_update(lm);
00575     /* the whole lexicon will be forced to built in the boot sequence,
00576        so reset the global modification flag here */
00577     lm->global_modified = FALSE;
00578   }
00579   
00580   jlog("STAT: *** LM%02d %s loaded\n", lmconf->id, lmconf->name);
00581 
00582   return TRUE;
00583 }
00584 
00585 /**********************************************************************/
00614 boolean
00615 j_load_all(Recog *recog, Jconf *jconf)
00616 {
00617   JCONF_AM *amconf;
00618   JCONF_LM *lmconf;
00619   JCONF_SEARCH *sh;
00620   PROCESS_AM *am;
00621   PROCESS_LM *lm;
00622 
00623   /* set global jconf */
00624   recog->jconf = jconf;
00625 
00626   /* load acoustic models */
00627   for(amconf=jconf->am_root;amconf;amconf=amconf->next) {
00628     if (j_load_am(recog, amconf) == FALSE) return FALSE;
00629   }
00630 
00631   /* load language models */
00632   for(lmconf=jconf->lm_root;lmconf;lmconf=lmconf->next) {
00633     if (j_load_lm(recog, lmconf) == FALSE) return FALSE;
00634   }
00635 
00636   /* GMM */
00637   if (jconf->reject.gmm_filename != NULL) {
00638     jlog("STAT: loading GMM\n");
00639     if ((recog->gmm = initialize_GMM(jconf)) == NULL) {
00640       jlog("ERROR: m_fusion: failed to initialize GMM\n");
00641       return FALSE;
00642     }
00643   }
00644 
00645   /* check sampling rate requirement on AMs and set it to global jconf */
00646   {
00647     boolean ok_p;
00648 
00649     /* set input sampling rate from an AM */
00650     jconf->input.sfreq = jconf->am_root->analysis.para.smp_freq;
00651     jconf->input.period = jconf->am_root->analysis.para.smp_period;
00652     jconf->input.frameshift = jconf->am_root->analysis.para.frameshift;
00653     jconf->input.framesize = jconf->am_root->analysis.para.framesize;
00654     /* check if the value is equal at all AMs */
00655     ok_p = TRUE;
00656     for(amconf = jconf->am_root; amconf; amconf = amconf->next) {
00657       if (jconf->input.sfreq != amconf->analysis.para.smp_freq) ok_p = FALSE;
00658     }
00659     if (!ok_p) {
00660       jlog("ERROR: required sampling rate differs in AMs!\n");
00661       for(amconf = jconf->am_root; amconf; amconf = amconf->next) {
00662         jlog("ERROR: AM%02d %s: %dHz\n", amconf->analysis.para.smp_freq);
00663       }
00664       return FALSE;
00665     }
00666     for(amconf = jconf->am_root; amconf; amconf = amconf->next) {
00667       if (jconf->input.frameshift != amconf->analysis.para.frameshift) ok_p = FALSE;
00668     }
00669     if (!ok_p) {
00670       jlog("ERROR: requested frame shift differs in AMs!\n");
00671       for(amconf = jconf->am_root; amconf; amconf = amconf->next) {
00672         jlog("ERROR: AM%02d %s: %d samples\n", amconf->analysis.para.frameshift);
00673       }
00674       return FALSE;
00675     }
00676     for(amconf = jconf->am_root; amconf; amconf = amconf->next) {
00677       if (jconf->input.framesize != amconf->analysis.para.framesize) ok_p = FALSE;
00678     }
00679     if (!ok_p) {
00680       jlog("ERROR: requested frame size (window length) differs in AMs!\n");
00681       for(amconf = jconf->am_root; amconf; amconf = amconf->next) {
00682         jlog("ERROR: AM%02d %s: %d samples\n", amconf->analysis.para.framesize);
00683       }
00684       return FALSE;
00685     }
00686   }
00687 
00688   return TRUE;
00689 }
00690 
00708 static boolean
00709 mfcc_config_is_same(JCONF_AM *amconf, MFCCCalc *mfcc)
00710 {
00711   char *s1, *s2;
00712 
00713   /* parameter extraction conditions are the same */
00714   /* check exact match in amconf->analysis.* */
00715   if (&(amconf->analysis.para) == mfcc->para || memcmp(&(amconf->analysis.para), mfcc->para, sizeof(Value)) == 0) {
00716     s1 = amconf->analysis.cmnload_filename;
00717     s2 = mfcc->cmn.load_filename;
00718     if (s1 == s2 || (s1 && s2 && strmatch(s1, s2))) {
00719       s1 = amconf->analysis.cmnsave_filename;
00720       s2 = mfcc->cmn.save_filename;
00721       if (s1 == s2 || (s1 && s2 && strmatch(s1, s2))) {
00722         if (amconf->analysis.cmn_update == mfcc->cmn.update
00723             && amconf->analysis.cmn_map_weight == mfcc->cmn.map_weight) {
00724           if (amconf->frontend.ss_alpha == mfcc->frontend.ss_alpha
00725               && amconf->frontend.ss_floor == mfcc->frontend.ss_floor
00726               && amconf->frontend.sscalc == mfcc->frontend.sscalc
00727               && amconf->frontend.sscalc_len == mfcc->frontend.sscalc_len) {
00728             s1 = amconf->frontend.ssload_filename;
00729             s2 = mfcc->frontend.ssload_filename;
00730             if (s1 == s2 || (s1 && s2 && strmatch(s1, s2))) {
00731               return TRUE;
00732             }
00733           }
00734         }
00735       }
00736     }
00737   }
00738 
00739   return FALSE;
00740 }
00741 
00742 /***************************************************/
00743 /* create MFCC calculation instance from AM config */
00744 /* according to the fixated parameter information  */
00745 /***************************************************/
00770 void
00771 create_mfcc_calc_instances(Recog *recog)
00772 {
00773   PROCESS_AM *am;
00774   MFCCCalc *mfcc;
00775   int count;
00776   
00777   jlog("STAT: *** create MFCC calculation modules from AM\n");
00778   count = 0;
00779   for(am=recog->amlist;am;am=am->next) {
00780     for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00781       if (mfcc_config_is_same(am->config, mfcc)) {
00782         /* the same */
00783         jlog("STAT: AM%02d %s: share MFCC%02d\n", am->config->id, am->config->name, mfcc->id);
00784         am->mfcc = mfcc;
00785         break;
00786       }
00787     }
00788     if (!mfcc) {                /* the same not found */
00789       /* initialize MFCC calculation work area */
00790       count++;
00791       /* create new mfcc instance */
00792       mfcc = j_mfcccalc_new(am->config);
00793       mfcc->id = count;
00794       /* assign to the am */
00795       am->mfcc = mfcc;
00796       /* add to the list of all MFCCCalc */
00797       mfcc->next = recog->mfcclist;
00798       recog->mfcclist = mfcc;
00799       jlog("STAT: AM%2d %s: create a new module MFCC%02d\n", am->config->id, am->config->name, mfcc->id);
00800     }
00801   }
00802 
00803   /* for GMM */
00804   if (recog->gmm) {
00805     /* if GMM calculation config found, make MFCC instance for that. */
00806     for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00807       if (mfcc_config_is_same(recog->jconf->gmm, mfcc)) {
00808         /* the same */
00809         jlog("STAT: GMM: share MFCC%02d\n", mfcc->id);
00810         recog->gmmmfcc = mfcc;
00811         break;
00812         }
00813     }
00814     if (!mfcc) {                /* the same not found */
00815       /* initialize MFCC calculation work area */
00816       count++;
00817       /* create new mfcc instance */
00818       mfcc = j_mfcccalc_new(recog->jconf->gmm);
00819       mfcc->id = count;
00820       /* assign to gmm */
00821       recog->gmmmfcc = mfcc;
00822       /* add to the list of all MFCCCalc */
00823       mfcc->next = recog->mfcclist;
00824       recog->mfcclist = mfcc;
00825       jlog("STAT: GMM: create a new module MFCC%02d\n", mfcc->id);
00826     }
00827   }
00828   
00829   jlog("STAT: %d MFCC modules created\n", count);
00830 }
00831 
00864 boolean
00865 j_launch_recognition_instance(Recog *recog, JCONF_SEARCH *sconf)
00866 {
00867   RecogProcess *p;
00868   PROCESS_AM *am;
00869   PROCESS_LM *lm;
00870 
00871   jlog("STAT: *** composing recognizer instance SR%02d %s (AM%02d %s, LM%02d %s)\n", sconf->id, sconf->name, sconf->amconf->id, sconf->amconf->name, sconf->lmconf->id, sconf->lmconf->name);
00872 
00873   /* allocate recognition instance */
00874   p = j_recogprocess_new(recog, sconf);
00875 
00876   /* assign corresponding AM instance and LM instance to use */
00877   for(lm=recog->lmlist;lm;lm=lm->next) {
00878     if (sconf->lmconf == lm->config) {
00879       for(am=recog->amlist;am;am=am->next) {
00880         if (sconf->amconf == am->config) {
00881           p->am = am;
00882           p->lm = lm;
00883         }
00884       }
00885     }
00886   }
00887   
00888   if (p->config->sw.triphone_check_flag && p->am->hmminfo->is_triphone) {
00889     /* go into interactive triphone HMM check mode */
00890     hmm_check(p);
00891   }
00892   
00893   /******************************************/
00894   /******** set work area and flags *********/
00895   /******************************************/
00896 
00897   /* set flag for context dependent handling */
00898   if (p->config->force_ccd_handling) {
00899     p->ccd_flag = p->config->ccd_handling;
00900   } else {
00901     if (p->am->hmminfo->is_triphone) {
00902       p->ccd_flag = TRUE;
00903     } else {
00904       p->ccd_flag = FALSE;
00905     }
00906   }
00907 
00908   /* iwsp prepare */
00909   if (p->lm->config->enable_iwsp) {
00910     if (p->am->hmminfo->multipath) {
00911       /* find short-pause model */
00912       if (p->am->hmminfo->sp == NULL) {
00913         jlog("ERROR: iwsp enabled but no short pause model \"%s\" in hmmdefs\n", p->am->config->spmodel_name);
00914         return FALSE;
00915       }
00916       p->am->hmminfo->iwsp_penalty = p->am->config->iwsp_penalty;
00917     } else {
00918       jlog("Warning: \"-iwsp\" is supported on multi-path mode, ignored\n");
00919     }
00920   }
00921 
00922   /* for short-pause segmentation  */
00923   if (p->config->successive.enabled) {
00924     if (p->config->successive.pausemodelname) {
00925       /* pause model name string specified, divide it and store to p */
00926       char *s;
00927       int n;
00928       p->pass1.pausemodelnames = (char*)mymalloc(strlen(p->config->successive.pausemodelname)+1);
00929       strcpy(p->pass1.pausemodelnames, p->config->successive.pausemodelname);
00930       n = 0;
00931       for (s = strtok(p->pass1.pausemodelnames, " ,"); s; s = strtok(NULL, " ,")) {
00932         n++;
00933       }
00934       p->pass1.pausemodelnum = n;
00935       p->pass1.pausemodel = (char **)mymalloc(sizeof(char *) * n);
00936       strcpy(p->pass1.pausemodelnames, p->config->successive.pausemodelname);
00937       n = 0;
00938       for (s = strtok(p->pass1.pausemodelnames, " ,"); s; s = strtok(NULL, " ,")) {
00939         p->pass1.pausemodel[n++] = s;
00940       }
00941     } else {
00942       p->pass1.pausemodel = NULL;
00943     }
00944   }
00945 
00946   /* copy values of sub instances for handly access during recognition */
00947   /* set lm type */
00948   p->lmtype = p->lm->lmtype;
00949   p->lmvar  = p->lm->lmvar;
00950   p->graphout = p->config->graph.enabled;
00951 
00952   /**********************************************/
00953   /******** set model-specific defaults *********/
00954   /**********************************************/
00955   if (p->lmtype == LM_PROB) {
00956     /* set default lm parameter if not specified */
00957     if (!p->config->lmp.lmp_specified) {
00958       if (p->am->hmminfo->is_triphone) {
00959         p->config->lmp.lm_weight = DEFAULT_LM_WEIGHT_TRI_PASS1;
00960         p->config->lmp.lm_penalty = DEFAULT_LM_PENALTY_TRI_PASS1;
00961       } else {
00962         p->config->lmp.lm_weight = DEFAULT_LM_WEIGHT_MONO_PASS1;
00963         p->config->lmp.lm_penalty = DEFAULT_LM_PENALTY_MONO_PASS1;
00964       }
00965     }
00966     if (!p->config->lmp.lmp2_specified) {
00967       if (p->am->hmminfo->is_triphone) {
00968         p->config->lmp.lm_weight2 = DEFAULT_LM_WEIGHT_TRI_PASS2;
00969         p->config->lmp.lm_penalty2 = DEFAULT_LM_PENALTY_TRI_PASS2;
00970       } else {
00971         p->config->lmp.lm_weight2 = DEFAULT_LM_WEIGHT_MONO_PASS2;
00972         p->config->lmp.lm_penalty2 = DEFAULT_LM_PENALTY_MONO_PASS2;
00973       }
00974     }
00975     if (p->config->lmp.lmp_specified != p->config->lmp.lmp2_specified) {
00976       jlog("WARNING: m_fusion: only -lmp or -lmp2 specified, LM weights may be unbalanced\n");
00977     }
00978   }
00979 
00980   /****************************/
00981   /******* build wchmm ********/
00982   /****************************/
00983   if (p->lmtype == LM_DFA) {
00984     /* execute generation of global grammar and build of wchmm */
00985     multigram_build(p); /* some modification occured if return TRUE */
00986   }
00987 
00988   if (p->lmtype == LM_PROB) {
00989     /* build wchmm with N-gram */
00990     p->wchmm = wchmm_new();
00991     p->wchmm->lmtype = p->lmtype;
00992     p->wchmm->lmvar  = p->lmvar;
00993     p->wchmm->ccd_flag = p->ccd_flag;
00994     p->wchmm->category_tree = FALSE;
00995     p->wchmm->hmmwrk = &(p->am->hmmwrk);
00996     /* assign models */
00997     p->wchmm->ngram = p->lm->ngram;
00998     if (p->lmvar == LM_NGRAM_USER) {
00999       /* register LM functions for 1st pass here */
01000       p->wchmm->uni_prob_user = p->lm->lmfunc.uniprob;
01001       p->wchmm->bi_prob_user = p->lm->lmfunc.biprob;
01002     }
01003     p->wchmm->winfo = p->lm->winfo;
01004     p->wchmm->hmminfo = p->am->hmminfo;
01005     if (p->wchmm->category_tree) {
01006       if (p->config->pass1.old_tree_function_flag) {
01007         if (build_wchmm(p->wchmm, p->lm->config) == FALSE) {
01008           jlog("ERROR: m_fusion: error in bulding wchmm\n");
01009           return FALSE;
01010         }
01011       } else {
01012         if (build_wchmm2(p->wchmm, p->lm->config) == FALSE) {
01013           jlog("ERROR: m_fusion: error in bulding wchmm\n");
01014           return FALSE;
01015         }
01016       }
01017     } else {
01018       if (build_wchmm2(p->wchmm, p->lm->config) == FALSE) {
01019         jlog("ERROR: m_fusion: error in bulding wchmm\n");
01020         return FALSE;
01021       }
01022     }
01023 
01024     /* 起動時 -check でチェックモードへ */
01025     if (p->config->sw.wchmm_check_flag) {
01026       wchmm_check_interactive(p->wchmm);
01027     }
01028 
01029     /* set beam width */
01030     /* guess beam width from models, when not specified */
01031     p->trellis_beam_width = set_beam_width(p->wchmm, p->config->pass1.specified_trellis_beam_width);
01032   }
01033 
01034   /* backtrellis initialization */
01035   p->backtrellis = (BACKTRELLIS *)mymalloc(sizeof(BACKTRELLIS));
01036   bt_init(p->backtrellis);
01037 
01038   /* initialize cache for factoring */
01039   if (p->lmtype == LM_PROB) {
01040     max_successor_cache_init(p->wchmm);
01041   }
01042 
01043   jlog("STAT: *** SR%02d %s composed\n", sconf->id, sconf->name);
01044 
01045   if (sconf->sw.start_inactive) {
01046     /* start inactive */
01047     p->active = -1;
01048   } else {
01049     /* book activation for the recognition */
01050     p->active = 1;
01051   }
01052 
01053   return TRUE;
01054 }
01055 
01056 
01110 boolean
01111 j_final_fusion(Recog *recog)
01112 {
01113   RecogProcess *p;
01114   MFCCCalc *mfcc;
01115   JCONF_SEARCH *sconf;
01116   PROCESS_AM *am;
01117   PROCESS_LM *lm;
01118 
01119   jlog("STAT: now all modules into fire for fusion...\n");
01120   
01121   if (recog->jconf->input.speech_input != SP_MFCFILE) {
01122     /***************************************************/
01123     /* create MFCC calculation instance from AM config */
01124     /* according to the fixated parameter information  */
01125     /***************************************************/
01126     create_mfcc_calc_instances(recog);
01127   }
01128 
01129   /****************************************/
01130   /* create recognition process instances */
01131   /****************************************/
01132   for(sconf=recog->jconf->search_root;sconf;sconf=sconf->next) {
01133     if (j_launch_recognition_instance(recog, sconf) == FALSE) return FALSE;
01134   }
01135 
01136   /****************************/
01137   /****** initialize GMM ******/
01138   /****************************/
01139   if (recog->gmm != NULL) {
01140     if (gmm_init(recog) == FALSE) {
01141       jlog("ERROR: m_fusion: error in initializing GMM\n");
01142       return FALSE;
01143     }
01144   }
01145 
01146   /* stage 4: setup output probability function for each AM */
01147   for(am=recog->amlist;am;am=am->next) {
01148     if (am->config->hmm_gs_filename != NULL) {/* with GMS */
01149       outprob_init(&(am->hmmwrk), am->hmminfo, am->hmm_gs, am->config->gs_statenum, am->config->gprune_method, am->config->mixnum_thres);
01150     } else {
01151       outprob_init(&(am->hmmwrk), am->hmminfo, NULL, 0, am->config->gprune_method, am->config->mixnum_thres);
01152     }
01153   }
01154 
01155   /* stage 5: initialize work area for input and realtime decoding */
01156 
01157   if (recog->jconf->input.speech_input == SP_MFCFILE) {
01158     /* create an MFCC instance for MFCC input */
01159     /* create new mfcc instance */
01160     recog->mfcclist = j_mfcccalc_new(NULL);
01161     recog->mfcclist->id = 1;
01162     /* assign to the am */
01163     for(am=recog->amlist;am;am=am->next) {
01164       am->mfcc = recog->mfcclist;
01165     }
01166     if (recog->gmm) recog->gmmmfcc = recog->mfcclist;
01167   }
01168   /* allocate parameter holders */
01169   for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
01170     mfcc->param = new_param();
01171   }
01172   
01173   /* initialize SS calculation work area */
01174   if (recog->jconf->input.speech_input != SP_MFCFILE) {
01175     for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
01176       if (mfcc->frontend.sscalc) {
01177         mfcc->frontend.mfccwrk_ss = WMP_work_new(mfcc->para);
01178         if (mfcc->frontend.mfccwrk_ss == NULL) {
01179           jlog("ERROR: m_fusion: failed to initialize MFCC computation for SS\n");
01180           return -1;
01181         }
01182       }
01183     }
01184   }
01185 
01186   if (recog->jconf->decodeopt.realtime_flag) {
01187     /* prepare for 1st pass pipeline processing */
01188     if (RealTimeInit(recog) == FALSE) {
01189       jlog("ERROR: m_fusion: failed to initialize recognition process\n");
01190       return FALSE;
01191     }
01192   }
01193 
01194   /* finished! */
01195   jlog("STAT: All init successfully done\n\n");
01196 
01197   return TRUE;
01198 }
01199 
01200 /* end of file */

Generated on Tue Dec 18 15:59:52 2007 for Julius by  doxygen 1.5.4