/** * <JA> * @brief グローバル文法から木構造化辞書を構築する. * * 与えられた文法で認識を行うために,認識処理インスタンスが現在持つ * グローバル文法から木構造化辞書を(再)構築します. また, * 起動時にビーム幅が明示的に指示されていない場合やフルサーチの場合, * ビーム幅の再設定も行います. * * @param r [i/o] 認識処理インスタンス * </JA> * <EN> * @brief Build tree lexicon from global grammar. * * This function will re-construct the tree lexicon using the global grammar * in the recognition process instance. If the beam width was not explicitly * specified on startup, the the beam width will be guessed * according to the size of the new lexicon. * * @param r [i/o] recognition process instance * </EN> */ static boolean multigram_rebuild_wchmm(RecogProcess *r) { boolean ret; /* re-build wchmm */ if (r->wchmm != NULL) { wchmm_free(r->wchmm); } r->wchmm = wchmm_new(); r->wchmm->lmtype = r->lmtype; r->wchmm->lmvar = r->lmvar; r->wchmm->ccd_flag = r->ccd_flag; r->wchmm->category_tree = TRUE; r->wchmm->hmmwrk = &(r->am->hmmwrk); /* assign models */ r->wchmm->dfa = r->lm->dfa; r->wchmm->winfo = r->lm->winfo; r->wchmm->hmminfo = r->am->hmminfo; if (r->wchmm->category_tree) { if (r->config->pass1.old_tree_function_flag) { ret = build_wchmm(r->wchmm, r->lm->config); } else { ret = build_wchmm2(r->wchmm, r->lm->config); } } else { ret = build_wchmm2(r->wchmm, r->lm->config); } /* 起動時 -check でチェックモードへ */ if (r->config->sw.wchmm_check_flag) { wchmm_check_interactive(r->wchmm); } if (ret == FALSE) { jlog("ERROR: multi-gram: failed to build (global) lexicon tree for recognition\n"); return FALSE; } /* guess beam width from models, when not specified */ r->trellis_beam_width = set_beam_width(r->wchmm, r->config->pass1.specified_trellis_beam_width); switch(r->config->pass1.specified_trellis_beam_width) { case 0: jlog("STAT: multi-gram: beam width set to %d (full) by lexicon change\n", r->trellis_beam_width); break; case -1: jlog("STAT: multi-gram: beam width set to %d (guess) by lexicon change\n", r->trellis_beam_width); } /* re-allocate factoring cache for the tree lexicon*/ /* for n-gram only?? */ //max_successor_cache_free(recog->wchmm); //max_successor_cache_init(recog->wchmm); /* finished! */ return TRUE; }
/** * <EN> * @brief Launch a recognition process instance. * * This function will create an recognition process instance * using the given SEARCH configuration, and launch recognizer for * the search. Then the created instance will be installed to the * engine instance. The sconf should be registered to the global * jconf before calling this function. * * </EN> * * <JA> * @brief 認識処理インスタンスを立ち上げる. * * この関数は,与えられた SEARCH 設定に従って 認識処理インスタンスを生成し, * 対応する音声認識器を構築します.その後,その生成された認識処理インスタンスは * 新たにエンジンインスタンスに登録されます.SEARCH設定はこの関数を * 呼ぶ前にあらかじめ全体設定jconfに登録されている必要があります. * * </JA> * * @param recog [i/o] engine instance * @param sconf [in] SEARCH configuration to launch * * @return TRUE on success, or FALSE on error. * * @callgraph * @callergraph * @ingroup instance * */ boolean j_launch_recognition_instance(Recog *recog, JCONF_SEARCH *sconf) { RecogProcess *p; PROCESS_AM *am; PROCESS_LM *lm; 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); /* allocate recognition instance */ p = j_recogprocess_new(recog, sconf); /* assign corresponding AM instance and LM instance to use */ for(lm=recog->lmlist;lm;lm=lm->next) { if (sconf->lmconf == lm->config) { for(am=recog->amlist;am;am=am->next) { if (sconf->amconf == am->config) { p->am = am; p->lm = lm; } } } } if (p->config->sw.triphone_check_flag && p->am->hmminfo->is_triphone) { /* go into interactive triphone HMM check mode */ hmm_check(p); } /******************************************/ /******** set work area and flags *********/ /******************************************/ /* copy values of sub instances for handly access during recognition */ /* set lm type */ p->lmtype = p->lm->lmtype; p->lmvar = p->lm->lmvar; p->graphout = p->config->graph.enabled; /* set flag for context dependent handling */ if (p->config->force_ccd_handling) { p->ccd_flag = p->config->ccd_handling; } else { if (p->am->hmminfo->is_triphone) { p->ccd_flag = TRUE; } else { p->ccd_flag = FALSE; } } /* iwsp prepare */ if (p->lm->config->enable_iwsp) { if (p->am->hmminfo->multipath) { /* find short-pause model */ if (p->am->hmminfo->sp == NULL) { jlog("ERROR: iwsp enabled but no short pause model \"%s\" in hmmdefs\n", p->am->config->spmodel_name); return FALSE; } p->am->hmminfo->iwsp_penalty = p->am->config->iwsp_penalty; } else { jlog("ERROR: \"-iwsp\" needs multi-path mode\n"); jlog("ERROR: you should use multi-path AM, or specify \"-multipath\" with \"-iwsp\"\n"); return FALSE; } } /* for short-pause segmentation */ if (p->config->successive.enabled) { if (p->config->successive.pausemodelname) { /* pause model name string specified, divide it and store to p */ char *s; int n; p->pass1.pausemodelnames = (char*)mymalloc(strlen(p->config->successive.pausemodelname)+1); strcpy(p->pass1.pausemodelnames, p->config->successive.pausemodelname); n = 0; for (s = strtok(p->pass1.pausemodelnames, " ,"); s; s = strtok(NULL, " ,")) { n++; } p->pass1.pausemodelnum = n; p->pass1.pausemodel = (char **)mymalloc(sizeof(char *) * n); strcpy(p->pass1.pausemodelnames, p->config->successive.pausemodelname); n = 0; for (s = strtok(p->pass1.pausemodelnames, " ,"); s; s = strtok(NULL, " ,")) { p->pass1.pausemodel[n++] = s; } } else { p->pass1.pausemodel = NULL; } /* check if pause word exists on dictionary */ { WORD_ID w; boolean ok_p; ok_p = FALSE; for(w=0;w<p->lm->winfo->num;w++) { if (is_sil(w, p)) { ok_p = TRUE; break; } } if (!ok_p) { #ifdef SPSEGMENT_NAIST jlog("Error: no pause word in dictionary needed for decoder-based VAD\n"); #else jlog("Error: no pause word in dictionary needed for short-pause segmentation\n"); #endif jlog("Error: you should have at least one pause word in dictionary\n"); jlog("Error: you can specify pause model names by \"-pausemodels\"\n"); return FALSE; } } } /**********************************************/ /******** set model-specific defaults *********/ /**********************************************/ if (p->lmtype == LM_PROB) { /* set default lm parameter if not specified */ if (!p->config->lmp.lmp_specified) { if (p->am->hmminfo->is_triphone) { p->config->lmp.lm_weight = DEFAULT_LM_WEIGHT_TRI_PASS1; p->config->lmp.lm_penalty = DEFAULT_LM_PENALTY_TRI_PASS1; } else { p->config->lmp.lm_weight = DEFAULT_LM_WEIGHT_MONO_PASS1; p->config->lmp.lm_penalty = DEFAULT_LM_PENALTY_MONO_PASS1; } } if (!p->config->lmp.lmp2_specified) { if (p->am->hmminfo->is_triphone) { p->config->lmp.lm_weight2 = DEFAULT_LM_WEIGHT_TRI_PASS2; p->config->lmp.lm_penalty2 = DEFAULT_LM_PENALTY_TRI_PASS2; } else { p->config->lmp.lm_weight2 = DEFAULT_LM_WEIGHT_MONO_PASS2; p->config->lmp.lm_penalty2 = DEFAULT_LM_PENALTY_MONO_PASS2; } } if (p->config->lmp.lmp_specified != p->config->lmp.lmp2_specified) { jlog("WARNING: m_fusion: only -lmp or -lmp2 specified, LM weights may be unbalanced\n"); } } /****************************/ /******* build wchmm ********/ /****************************/ if (p->lmtype == LM_DFA) { /* execute generation of global grammar and build of wchmm */ multigram_build(p); /* some modification occured if return TRUE */ } if (p->lmtype == LM_PROB) { /* build wchmm with N-gram */ p->wchmm = wchmm_new(); p->wchmm->lmtype = p->lmtype; p->wchmm->lmvar = p->lmvar; p->wchmm->ccd_flag = p->ccd_flag; p->wchmm->category_tree = FALSE; p->wchmm->hmmwrk = &(p->am->hmmwrk); /* assign models */ p->wchmm->ngram = p->lm->ngram; if (p->lmvar == LM_NGRAM_USER) { /* register LM functions for 1st pass here */ p->wchmm->uni_prob_user = p->lm->lmfunc.uniprob; p->wchmm->bi_prob_user = p->lm->lmfunc.biprob; } p->wchmm->winfo = p->lm->winfo; p->wchmm->hmminfo = p->am->hmminfo; if (p->wchmm->category_tree) { if (p->config->pass1.old_tree_function_flag) { if (build_wchmm(p->wchmm, p->lm->config) == FALSE) { jlog("ERROR: m_fusion: error in bulding wchmm\n"); return FALSE; } } else { if (build_wchmm2(p->wchmm, p->lm->config) == FALSE) { jlog("ERROR: m_fusion: error in bulding wchmm\n"); return FALSE; } } } else { if (build_wchmm2(p->wchmm, p->lm->config) == FALSE) { jlog("ERROR: m_fusion: error in bulding wchmm\n"); return FALSE; } } /* 起動時 -check でチェックモードへ */ if (p->config->sw.wchmm_check_flag) { wchmm_check_interactive(p->wchmm); } /* set beam width */ /* guess beam width from models, when not specified */ p->trellis_beam_width = set_beam_width(p->wchmm, p->config->pass1.specified_trellis_beam_width); /* initialize cache for factoring */ max_successor_cache_init(p->wchmm); } /* backtrellis initialization */ p->backtrellis = (BACKTRELLIS *)mymalloc(sizeof(BACKTRELLIS)); bt_init(p->backtrellis); /* prepare work area for 2nd pass */ wchmm_fbs_prepare(p); jlog("STAT: SR%02d %s composed\n", sconf->id, sconf->name); if (sconf->sw.start_inactive) { /* start inactive */ p->active = -1; } else { /* book activation for the recognition */ p->active = 1; } if (p->lmtype == LM_DFA) { if (p->lm->winfo == NULL || (p->lmvar == LM_DFA_GRAMMAR && p->lm->dfa == NULL)) { /* make this instance inactive */ p->active = -1; } } return TRUE; }