00001 
00026 
00027 
00028 
00029 
00030 
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   
00078 
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   
00086   hmminfo = hmminfo_new();
00087   
00088   if (init_hmminfo(hmminfo, amconf->hmmfilename, amconf->mapfilename, &(amconf->analysis.para_hmm)) == FALSE) {
00089     hmminfo_free(hmminfo);
00090     return NULL;
00091   }
00092 
00093   
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   
00102   
00103   
00104   if (jconf->input.speech_input != SP_MFCFILE) {
00105     
00106 
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     
00113     calc_para_from_header(&(amconf->analysis.para), hmminfo->opt.param_type, hmminfo->opt.vec_size);
00114   }
00115   
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   
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     
00132     
00133     hmm_add_pseudo_phones(hmminfo);
00134   }
00135 #endif
00136 
00137   
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(¶_dummy);
00174   if (init_hmminfo(hmm_gs, amconf->hmm_gs_filename, NULL, ¶_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   
00209   if (jconf->input.speech_input != SP_MFCFILE) {
00210     
00211 
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   
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   
00268   winfo = word_info_new();
00269   
00270   if ( ! 
00271 #ifdef MONOTREE
00272       
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     
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     
00301     winfo->head_silwid = voca_lookup_wid(lmconf->head_silname, winfo);
00302     if (winfo->head_silwid == WORD_INVALID) { 
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) { 
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   
00359   ngram = ngram_info_new();
00360   
00361   if (lmconf->ngram_filename != NULL) { 
00362     ret = init_ngram_bin(ngram, lmconf->ngram_filename);
00363   } else {                      
00364     
00365     
00366 
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   
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   
00435   am = j_process_am_new(recog, amconf);
00436   
00437   
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   
00450   
00451   
00452   if (am->config->gprune_method == GPRUNE_SEL_UNDEF) {
00453     if (am->hmminfo->is_tied_mixture) {
00454       
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       
00464       am->config->gprune_method = GPRUNE_SEL_NONE;
00465     }
00466   }
00467   
00468   
00469 
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   
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   
00543   lm = j_process_lm_new(recog, lmconf);
00544 
00545   
00546   lm->am = am;
00547 
00548   
00549   if (lm->lmtype == LM_PROB) {
00550     
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     
00564     if (lm->config->dfa_filename != NULL && lm->config->dictfilename != NULL) {
00565       
00566       multigram_add_gramlist(lm->config->dfa_filename, lm->config->dictfilename, lm->config, LM_DFA_GRAMMAR);
00567     }
00568     
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     
00574     multigram_update(lm);
00575     
00576 
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   
00624   recog->jconf = jconf;
00625 
00626   
00627   for(amconf=jconf->am_root;amconf;amconf=amconf->next) {
00628     if (j_load_am(recog, amconf) == FALSE) return FALSE;
00629   }
00630 
00631   
00632   for(lmconf=jconf->lm_root;lmconf;lmconf=lmconf->next) {
00633     if (j_load_lm(recog, lmconf) == FALSE) return FALSE;
00634   }
00635 
00636   
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   
00646   {
00647     boolean ok_p;
00648 
00649     
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     
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   
00714   
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 
00744 
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         
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) {                
00789       
00790       count++;
00791       
00792       mfcc = j_mfcccalc_new(am->config);
00793       mfcc->id = count;
00794       
00795       am->mfcc = mfcc;
00796       
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   
00804   if (recog->gmm) {
00805     
00806     for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00807       if (mfcc_config_is_same(recog->jconf->gmm, mfcc)) {
00808         
00809         jlog("STAT: GMM: share MFCC%02d\n", mfcc->id);
00810         recog->gmmmfcc = mfcc;
00811         break;
00812         }
00813     }
00814     if (!mfcc) {                
00815       
00816       count++;
00817       
00818       mfcc = j_mfcccalc_new(recog->jconf->gmm);
00819       mfcc->id = count;
00820       
00821       recog->gmmmfcc = mfcc;
00822       
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   
00874   p = j_recogprocess_new(recog, sconf);
00875 
00876   
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     
00890     hmm_check(p);
00891   }
00892   
00893   
00894   
00895   
00896 
00897   
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   
00909   if (p->lm->config->enable_iwsp) {
00910     if (p->am->hmminfo->multipath) {
00911       
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   
00923   if (p->config->successive.enabled) {
00924     if (p->config->successive.pausemodelname) {
00925       
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   
00947   
00948   p->lmtype = p->lm->lmtype;
00949   p->lmvar  = p->lm->lmvar;
00950   p->graphout = p->config->graph.enabled;
00951 
00952   
00953   
00954   
00955   if (p->lmtype == LM_PROB) {
00956     
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   
00982   
00983   if (p->lmtype == LM_DFA) {
00984     
00985     multigram_build(p); 
00986   }
00987 
00988   if (p->lmtype == LM_PROB) {
00989     
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     
00997     p->wchmm->ngram = p->lm->ngram;
00998     if (p->lmvar == LM_NGRAM_USER) {
00999       
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     
01025     if (p->config->sw.wchmm_check_flag) {
01026       wchmm_check_interactive(p->wchmm);
01027     }
01028 
01029     
01030     
01031     p->trellis_beam_width = set_beam_width(p->wchmm, p->config->pass1.specified_trellis_beam_width);
01032   }
01033 
01034   
01035   p->backtrellis = (BACKTRELLIS *)mymalloc(sizeof(BACKTRELLIS));
01036   bt_init(p->backtrellis);
01037 
01038   
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     
01047     p->active = -1;
01048   } else {
01049     
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     
01124     
01125     
01126     create_mfcc_calc_instances(recog);
01127   }
01128 
01129   
01130   
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   
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   
01147   for(am=recog->amlist;am;am=am->next) {
01148     if (am->config->hmm_gs_filename != NULL) {
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   
01156 
01157   if (recog->jconf->input.speech_input == SP_MFCFILE) {
01158     
01159     
01160     recog->mfcclist = j_mfcccalc_new(NULL);
01161     recog->mfcclist->id = 1;
01162     
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   
01169   for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
01170     mfcc->param = new_param();
01171   }
01172   
01173   
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     
01188     if (RealTimeInit(recog) == FALSE) {
01189       jlog("ERROR: m_fusion: failed to initialize recognition process\n");
01190       return FALSE;
01191     }
01192   }
01193 
01194   
01195   jlog("STAT: All init successfully done\n\n");
01196 
01197   return TRUE;
01198 }
01199 
01200