📄 m_fusion.c
字号:
* 糠たにエンジンインスタンスに判峡されますˉAM肋年はこの簇眶を * 钙ぶ涟にあらかじめ链挛肋年recog->jconfに判峡されている涩妥がありますˉ * * </JA> * * @param recog [i/o] engine instance * @param amconf [in] AM configuration to load * * @return TRUE on success, or FALSE on error. * * @callgraph * @callergraph * @ingroup instance * */booleanj_load_am(Recog *recog, JCONF_AM *amconf){ PROCESS_AM *am; jlog("STAT: *** loading AM%02d %s\n", amconf->id, amconf->name); /* create AM process instance */ am = j_process_am_new(recog, amconf); /* HMM */ if ((am->hmminfo = initialize_HMM(amconf, recog->jconf)) == NULL) { jlog("ERROR: m_fusion: failed to initialize AM\n"); return FALSE; } if (amconf->hmm_gs_filename != NULL) { if ((am->hmm_gs = initialize_GSHMM(amconf)) == NULL) { jlog("ERROR: m_fusion: failed to initialize GS HMM\n"); return FALSE; } } /* fixate model-specific params */ /* set params whose default will change by models and not specified in arg */ /* select Gaussian pruning function */ if (am->config->gprune_method == GPRUNE_SEL_UNDEF) {/* set default if not specified */ if (am->hmminfo->is_tied_mixture) { /* enabled by default for tied-mixture models */#if defined(GPRUNE_DEFAULT_SAFE) am->config->gprune_method = GPRUNE_SEL_SAFE;#elif defined(GPRUNE_DEFAULT_HEURISTIC) am->config->gprune_method = GPRUNE_SEL_HEURISTIC;#elif defined(GPRUNE_DEFAULT_BEAM) am->config->gprune_method = GPRUNE_SEL_BEAM;#endif } else { /* disabled by default for non tied-mixture model */ am->config->gprune_method = GPRUNE_SEL_NONE; } } /* fixated analysis.para not uses loaded flag any more, so reset it for binary matching */ amconf->analysis.para.loaded = 0; jlog("STAT: *** AM%02d %s loaded\n", amconf->id, amconf->name); return TRUE;}/** * <EN> * @brief Load a language model. * * This function will create an LM process instance using the given LM * configuration, and load models specified in the configuration into * the instance. Then the created instance will be installed to the * engine instance. The lmconf should be registered to the * recog->jconf before calling this function. * * To convert phoneme sequence to triphone at loading, you should * specify which AM to use with this LM by the argument am. * * </EN> * * <JA> * @brief 咐胳モデルを粕み哈むˉ * * この簇眶は·涂えられた LM 肋年に骄って LM 借妄インスタンスを栏喇し· * その面に咐胳モデルをロ〖ドしますˉその稿·そのLM借妄インスタンスは * 糠たにエンジンインスタンスに判峡されますˉLM肋年はこの簇眶を * 钙ぶ涟にあらかじめ链挛肋年recog->jconfに判峡されている涩妥がありますˉ * * 辑今の粕み哈み箕にトライフォンへの恃垂および不读モデルとのリンクが * 票箕に乖われますˉこのため·この咐胳モデルが蝗脱する不读モデルの * インスタンスを苞眶 am として回年する涩妥がありますˉ * * </JA> * * @param recog [i/o] engine instance * @param lmconf [in] LM configuration to load * * @return TRUE on success, or FALSE on error. * * @callgraph * @callergraph * @ingroup instance * */booleanj_load_lm(Recog *recog, JCONF_LM *lmconf){ JCONF_SEARCH *sh; PROCESS_LM *lm; PROCESS_AM *am, *atmp; jlog("STAT: *** loading LM%02d %s\n", lmconf->id, lmconf->name); /* find which am process instance to assign to each LM */ am = NULL; for(sh=recog->jconf->search_root;sh;sh=sh->next) { if (sh->lmconf == lmconf) { for(atmp=recog->amlist;atmp;atmp=atmp->next) { if (sh->amconf == atmp->config) { am = atmp; } } } } if (am == NULL) { jlog("ERROR: cannot find corresponding AM for LM%02d %s\n", lmconf->id, lmconf->name); jlog("ERROR: you should write all AM/LM combinations to be used for recognition with \"-SR\"\n"); return FALSE; } /* create LM process instance */ lm = j_process_lm_new(recog, lmconf); /* assign AM process instance to the LM instance */ lm->am = am; /* load language model */ if (lm->lmtype == LM_PROB) { /* LM (N-gram) */ if ((lm->winfo = initialize_dict(lm->config, lm->am->hmminfo)) == NULL) { jlog("ERROR: m_fusion: failed to initialize dictionary\n"); return FALSE; } if (lm->config->ngram_filename_lr_arpa || lm->config->ngram_filename_rl_arpa || lm->config->ngram_filename) { if ((lm->ngram = initialize_ngram(lm->config, lm->winfo)) == NULL) { jlog("ERROR: m_fusion: failed to initialize N-gram\n"); return FALSE; } } } if (lm->lmtype == LM_DFA) { /* DFA */ if (lm->config->dfa_filename != NULL && lm->config->dictfilename != NULL) { /* here add grammar specified by "-dfa" and "-v" to grammar list */ multigram_add_gramlist(lm->config->dfa_filename, lm->config->dictfilename, lm->config, LM_DFA_GRAMMAR); } /* load all the specified grammars */ if (multigram_load_all_gramlist(lm) == FALSE) { jlog("ERROR: m_fusion: some error occured in reading grammars\n"); return FALSE; } /* setup for later wchmm building */ multigram_update(lm); /* the whole lexicon will be forced to built in the boot sequence, so reset the global modification flag here */ lm->global_modified = FALSE; } jlog("STAT: *** LM%02d %s loaded\n", lmconf->id, lmconf->name); return TRUE;}/**********************************************************************//** * <JA> * @brief 链てのモデルを粕み哈み·千急の洁洒を乖なう. * * この簇眶では·jconf 柒にある∈剩眶の∷ AM 肋年パラメ〖タ菇陇挛やLM * 肋年パラメ〖タ菇陇挛のそれぞれに滦して·AM/LM借妄インスタンスを栏喇 * する. そしてそれぞれのインスタンスについてその面にモデルを粕み哈み· * 千急脱にセットアップする. GMMもここで粕み哈まれる. * * </JA> * <EN> * @brief Read in all models for recognition. * * This function create AM/LM processing instance for each AM/LM * configurations in jconf. Then the model for each instance will be loaded * into memory and set up for recognition. GMM will also be read here. * * </EN> * * @param recog [i/o] engine instance * @param jconf [in] global configuration variables * * @return TRUE on success, FALSE on failure. * * @callgraph * @callergraph * @ingroup instance */booleanj_load_all(Recog *recog, Jconf *jconf){ JCONF_AM *amconf; JCONF_LM *lmconf; /* set global jconf */ recog->jconf = jconf; /* load acoustic models */ for(amconf=jconf->am_root;amconf;amconf=amconf->next) { if (j_load_am(recog, amconf) == FALSE) return FALSE; } /* load language models */ for(lmconf=jconf->lm_root;lmconf;lmconf=lmconf->next) { if (j_load_lm(recog, lmconf) == FALSE) return FALSE; } /* GMM */ if (jconf->reject.gmm_filename != NULL) { jlog("STAT: loading GMM\n"); if ((recog->gmm = initialize_GMM(jconf)) == NULL) { jlog("ERROR: m_fusion: failed to initialize GMM\n"); return FALSE; } } /* check sampling rate requirement on AMs and set it to global jconf */ { boolean ok_p; /* set input sampling rate from an AM */ jconf->input.sfreq = jconf->am_root->analysis.para.smp_freq; jconf->input.period = jconf->am_root->analysis.para.smp_period; jconf->input.frameshift = jconf->am_root->analysis.para.frameshift; jconf->input.framesize = jconf->am_root->analysis.para.framesize; /* check if the value is equal at all AMs */ ok_p = TRUE; for(amconf = jconf->am_root; amconf; amconf = amconf->next) { if (jconf->input.sfreq != amconf->analysis.para.smp_freq) ok_p = FALSE; } if (!ok_p) { jlog("ERROR: required sampling rate differs in AMs!\n"); for(amconf = jconf->am_root; amconf; amconf = amconf->next) { jlog("ERROR: AM%02d %s: %dHz\n", amconf->analysis.para.smp_freq); } return FALSE; } /* also check equality for GMM */ if (recog->gmm) { if (jconf->input.sfreq != jconf->gmm->analysis.para.smp_freq) { jlog("ERROR: required sampling rate differs between AM and GMM!\n"); jlog("ERROR: AM : %dHz\n", jconf->input.sfreq); jlog("ERROR: GMM: %dHz\n", jconf->gmm->analysis.para.smp_freq); return FALSE; } } for(amconf = jconf->am_root; amconf; amconf = amconf->next) { if (jconf->input.frameshift != amconf->analysis.para.frameshift) ok_p = FALSE; } if (!ok_p) { jlog("ERROR: requested frame shift differs in AMs!\n"); for(amconf = jconf->am_root; amconf; amconf = amconf->next) { jlog("ERROR: AM%02d %s: %d samples\n", amconf->analysis.para.frameshift); } return FALSE; } /* also check equality for GMM */ if (recog->gmm) { if (jconf->input.frameshift != jconf->gmm->analysis.para.frameshift) { jlog("ERROR: required frameshift differs between AM and GMM!\n"); jlog("ERROR: AM : %d samples\n", jconf->input.frameshift); jlog("ERROR: GMM: %d samples\n", jconf->gmm->analysis.para.frameshift); return FALSE; } } for(amconf = jconf->am_root; amconf; amconf = amconf->next) { if (jconf->input.framesize != amconf->analysis.para.framesize) ok_p = FALSE; } if (!ok_p) { jlog("ERROR: requested frame size (window length) differs in AMs!\n"); for(amconf = jconf->am_root; amconf; amconf = amconf->next) { jlog("ERROR: AM%02d %s: %d samples\n", amconf->analysis.para.framesize); } return FALSE; } /* also check equality for GMM */ if (recog->gmm) { if (jconf->input.framesize != jconf->gmm->analysis.para.framesize) { jlog("ERROR: requested frame size differs between AM and GMM!\n"); jlog("ERROR: AM : %d samples\n", jconf->input.framesize); jlog("ERROR: GMM: %d samples\n", jconf->gmm->analysis.para.framesize); return FALSE; } } } return TRUE;}/** * <EN> * Check if parameter extraction configuration is the same between an AM * configuration and a MFCC instance. * </EN> * <JA> * AM肋年パラメ〖タと贷に侯られたMFCC纷换インスタンス粗で·パラメ〖タ藐叫の * 肋年が票办であるかどうかをチェックする. * * </JA> * * @param amconf [in] AM configuration parameters * @param mfcc [in] MFCC calculation instance. * * @return TRUE if exactly the same, or FALSE if not. * */static booleanmfcc_config_is_same(JCONF_AM *amconf, MFCCCalc *mfcc){ char *s1, *s2; /* parameter extraction conditions are the same */ /* check exact match in amconf->analysis.* */ if (&(amconf->analysis.para) == mfcc->para || memcmp(&(amconf->analysis.para), mfcc->para, sizeof(Value)) == 0) { s1 = amconf->analysis.cmnload_filename; s2 = mfcc->cmn.load_filename; if (s1 == s2 || (s1 && s2 && strmatch(s1, s2))) { s1 = amconf->analysis.cmnsave_filename; s2 = mfcc->cmn.save_filename; if (s1 == s2 || (s1 && s2 && strmatch(s1, s2))) { if (amconf->analysis.cmn_update == mfcc->cmn.update && amconf->analysis.cmn_map_weight == mfcc->cmn.map_weight) { if (amconf->frontend.ss_alpha == mfcc->frontend.ss_alpha && amconf->frontend.ss_floor == mfcc->frontend.ss_floor && amconf->frontend.sscalc == mfcc->frontend.sscalc && amconf->frontend.sscalc_len == mfcc->frontend.sscalc_len) { s1 = amconf->frontend.ssload_filename; s2 = mfcc->frontend.ssload_filename; if (s1 == s2 || (s1 && s2 && strmatch(s1, s2))) { return TRUE; } } } } } } return FALSE;}/***************************************************//* create MFCC calculation instance from AM config *//* according to the fixated parameter information *//***************************************************//** * <EN> * * @brief Create MFCC calculation instance for AM processing instances and GMM * * If more than one AM processing instance (or GMM) has the same configuration, * the same MFCC calculation instance will be shared among them. * * </EN> * <JA> * * @brief 链てのAM借妄インスタンスおよびGMM脱に·MFCC纷换インスタンスを栏喇する. * * 2つ笆惧のAM借妄インスタンス∈およびGMM∷が票办の泼魔翁纷换掘凤を积 * つ眷圭·それらのインスタンスはひとつの MFCC 纷换インスタンスを鼎铜する. * * </JA> * * @param recog [i/o] engine instance * * @callgraph * @callergraph * */voidcreate_mfcc_calc_instances(Recog *recog){ PROCESS_AM *am; MFCCCalc *mfcc; int count; jlog("STAT: *** create MFCC calculation modules from AM\n"); count = 0; for(am=recog->amlist;am;am=am->next) { for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) { if (mfcc_config_is_same(am->config, mfcc)) { /* the same */ jlog("STAT: AM%02d %s: share MFCC%02d\n", am->config->id, am->config->name, mfcc->id); am->mfcc = mfcc; break; } } if (!mfcc) { /* the same not found */ /* initialize MFCC calculation work area */ count++; /* create new mfcc instance */ mfcc = j_mfcccalc_new(am->config); mfcc->id = count; /* assign to the am */ am->mfcc = mfcc; /* add to the list of all MFCCCalc */ mfcc->next = recog->mfcclist; recog->mfcclist = mfcc; jlog("STAT: AM%2d %s: create a new module MFCC%02d\n", am->config->id, am->config->name, mfcc->id); } } /* for GMM */ if (recog->gmm) { /* if GMM calculation config found, make MFCC instance for that. */ for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) { if (mfcc_config_is_same(recog->jconf->gmm, mfcc)) { /* the same */ jlog("STAT: GMM: share MFCC%02d\n", mfcc->id); recog->gmmmfcc = mfcc; break; } } if (!mfcc) { /* the same not found */ /* initialize MFCC calculation work area */ count++; /* create new mfcc instance */ mfcc = j_mfcccalc_new(recog->jconf->gmm); mfcc->id = count; /* assign to gmm */ recog->gmmmfcc = mfcc; /* add to the list of all MFCCCalc */ mfcc->next = recog->mfcclist; recog->mfcclist = mfcc; jlog("STAT: GMM: create a new module MFCC%02d\n", mfcc->id); } } jlog("STAT: %d MFCC modules created\n", count);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -