📄 multi-gram.c
字号:
* <JA> * 矢恕を铜跟步する. ここでは肌搀构糠箕に * 瓤鼻されるようにマ〖クをつけるのみである. * * @param gid [in] 铜跟步したい矢恕の ID * @param lm [i/o] 咐胳借妄インスタンス * </JA> * <EN> * Activate a grammar in the grammar list. The specified grammar * will only be marked as to be activated in the next grammar update timing. * * @param gid [in] grammar ID to be activated * @param lm [i/o] LM processing instance * * @return 0 on success, -1 on error (when specified grammar not found), * of 1 if already active * </EN> * @callgraph * @callergraph * @ingroup grammar */intmultigram_activate(int gid, PROCESS_LM *lm) /* only mark */{ MULTIGRAM *m; int ret; for(m=lm->grammars;m;m=m->next) { if (m->id == gid) { if (m->hook & MULTIGRAM_DEACTIVATE) { ret = 0; m->hook &= ~(MULTIGRAM_DEACTIVATE); m->hook |= MULTIGRAM_ACTIVATE; jlog("STAT: Gram #%d %s: marked active, superceding deactivate\n", m->id, m->name); } else { if (m->hook & MULTIGRAM_ACTIVATE) { jlog("STAT: Gram #%d %s: already marked active\n", m->id, m->name); ret = 1; } else { ret = 0; m->hook |= MULTIGRAM_ACTIVATE; jlog("STAT: Gram #%d %s: marked activate\n", m->id, m->name); } } break; } } if (! m) { jlog("WARNING: Gram #%d: not found, activation ignored\n", gid); ret = -1; } return(ret);}/** * <JA> * 矢恕を痰跟步する. 痰跟步された矢恕は * 千急において簿棱鸥倡されない. これによって·グロ〖バル辑今を * 浩菇蜜することなく·办箕弄に改」の矢恕をON/OFFできる. 痰跟步した * 矢恕は multigram_activate() で浩び铜跟步できる. なおここでは * 肌搀の矢恕构糠タイミングで瓤鼻されるようにマ〖クをつけるのみである. * * @param gid [in] 痰跟步したい矢恕のID * @param lm [i/o] 咐胳借妄インスタンス * </JA> * <EN> * Deactivate a grammar in the grammar list. The words of the de-activated * grammar will not be expanded in the recognition process. This feature * enables rapid switching of grammars without re-building tree lexicon. * The de-activated grammar will again be activated by calling * multigram_activate(). * * @param gid [in] grammar ID to be de-activated * @param lm [i/o] LM processing instance * * @return 0 on success, -1 on error (when specified grammar not found), * of 1 if already inactive * </EN> * @callgraph * @callergraph * @ingroup grammar */intmultigram_deactivate(int gid, PROCESS_LM *lm) /* only mark */{ MULTIGRAM *m; int ret; for(m=lm->grammars;m;m=m->next) { if (m->id == gid) { if (m->hook & MULTIGRAM_ACTIVATE) { ret = 0; m->hook &= ~(MULTIGRAM_ACTIVATE); m->hook |= MULTIGRAM_DEACTIVATE; jlog("STAT: Gram #%d %s: marked deactivate, superceding activate\n", m->id, m->name); } else { if (m->hook & MULTIGRAM_DEACTIVATE) { jlog("STAT: Gram #%d %s: already marked deactivate\n", m->id, m->name); ret = 1; } else { ret = 0; m->hook |= MULTIGRAM_DEACTIVATE; jlog("STAT: Gram #%d %s: marked deactivate\n", m->id, m->name); } } break; } } if (! m) { jlog("WARNING: - Gram #%d: not found, deactivation ignored\n", gid); ret = -1; } return(ret);}/** * <JA> * 矢恕の铜跟步ˇ痰跟步を悸乖する. * * @param lm [i/o] 咐胳借妄インスタンス * * @return 痰跟から铜跟へ·あるいは铜跟から痰跟へ觉轮が恃步した矢恕が办つでも * あればTRUE, 觉轮が链く恃步しなかった眷圭は FALSE を手す. * </JA> * <EN> * Execute (de)activation of grammars. * * @param lm [i/o] LM processing instance * * @return TRUE if at least one grammar has been changed, or FALSE if no * grammar has changed its status. * </EN> */static booleanmultigram_exec_activate(PROCESS_LM *lm){ MULTIGRAM *m; boolean modified; modified = FALSE; for(m=lm->grammars;m;m=m->next) { if (m->hook & MULTIGRAM_ACTIVATE) { m->hook &= ~(MULTIGRAM_ACTIVATE); if (!m->active) { jlog("STAT: Gram #%d %s: turn on active\n", m->id, m->name); } m->active = TRUE; modified = TRUE; } else if (m->hook & MULTIGRAM_DEACTIVATE) { m->hook &= ~(MULTIGRAM_DEACTIVATE); if (m->active) { jlog("STAT: Gram #%d %s: turn off inactive\n", m->id, m->name); } m->active = FALSE; modified = TRUE; } } return(modified);} /** * <JA> * @brief グロ〖バル矢恕の构糠 * * 涟搀钙叫しからの矢恕リストの恃构をチェックする. * リスト面に猴近マ〖クがつけられた矢恕がある眷圭は·その矢恕を猴近し· * グロ〖バル辑今を浩菇蜜する. 糠たに纳裁された矢恕がある眷圭は· * その矢恕を附哼のグロ〖バル辑今の琐萨に纳裁する. * * @param lm [i/o] 咐胳借妄インスタンス * * @return 撅に TRUE を手す. * </JA> * <EN> * @brief Update global grammar if needed. * * This function checks for any modification in the grammar list from * previous call, and update the global grammar if needed. * * If there are grammars marked to be deleted in the grammar list, * they will be actually deleted from memory. Then the global grammar is * built from scratch using the rest grammars. * If there are new grammars, they are appended to the current global grammar. * * @param lm [i/o] LM processing instance * * @return TRUE when any of add/delete/active/inactive occurs, or FALSE if * nothing modified. * </EN> * @callgraph * @callergraph * @ingroup grammar */boolean /* return FALSE if no gram */multigram_update(PROCESS_LM *lm){ MULTIGRAM *m; boolean active_changed = FALSE; boolean rebuild_flag; if (lm->lmvar == LM_DFA_GRAMMAR) { /* setup additional grammar info of new ones */ for(m=lm->grammars;m;m=m->next) { if (m->newbie) { jlog("STAT: Gram #%d %s: new grammar loaded, now mash it up for recognition\n", m->id, m->name); /* map dict item to dfa terminal symbols */ if (make_dfa_voca_ref(m->dfa, m->winfo) == FALSE) { jlog("ERROR: failed to map dict <-> DFA. This grammar will be deleted\n"); /* mark as to be deleted */ m->hook |= MULTIGRAM_DELETE; continue; } /* set dfa->sp_id and dfa->is_sp */ dfa_find_pause_word(m->dfa, m->winfo, lm->am->hmminfo); /* build catergory-pair information */ jlog("STAT: Gram #%d %s: extracting category-pair constraint for the 1st pass\n", m->id, m->name); if (extract_cpair(m->dfa) == FALSE) { jlog("ERROR: failed to extract category pair. This grammar will be deleted\n"); /* mark as to be deleted */ m->hook |= MULTIGRAM_DELETE; } } } } rebuild_flag = FALSE; /* delete grammars marked as "delete" */ if (multigram_exec_delete(lm)) { /* some built grammars deleted */ rebuild_flag = TRUE; /* needs rebuilding global grammar */ } /* find modified grammar */ for(m=lm->grammars;m;m=m->next) { if (m->hook & MULTIGRAM_MODIFIED) { rebuild_flag = TRUE; /* needs rebuilding global grammar */ m->hook &= ~(MULTIGRAM_MODIFIED); } } if (rebuild_flag) { /* rebuild global grammar from scratch (including new) */ /* active status not changed here (inactive grammar will also included) */ /* activate/deactivate hook will be handled later, so just keep it here */#ifdef MDEBUG jlog("STAT: re-build whole global grammar...\n");#endif /* free old if not yet */ if (lm->dfa != NULL) { dfa_info_free(lm->dfa); lm->dfa = NULL; } if (lm->winfo != NULL) { word_info_free(lm->winfo); lm->winfo = NULL; } /* concatinate all existing grammars to global */ for(m=lm->grammars;m;m=m->next) { if (lm->lmvar == LM_DFA_GRAMMAR && lm->dfa == NULL) { lm->dfa = dfa_info_new(); dfa_state_init(lm->dfa); } if (lm->winfo == NULL) { lm->winfo = word_info_new(); winfo_init(lm->winfo); } if (m->newbie) m->newbie = FALSE; if (lm->lmvar == LM_DFA_WORD) { /* just append dictionaty */ m->word_begin = lm->winfo->num; if (voca_append(lm->winfo, m->winfo, m->id, m->word_begin) == FALSE) { jlog("ERROR: multi-gram: failed to add dictionary #%d to recognition network\n", m->id); /* mark as delete */ m->hook |= MULTIGRAM_DELETE; } } else { if (multigram_append_to_global(lm->dfa, lm->winfo, m) == FALSE) { jlog("ERROR: multi-gram: failed to add grammar #%d to recognition network\n", m->id); /* mark as delete */ m->hook |= MULTIGRAM_DELETE; } } } /* delete the error grammars if exist */ if (multigram_exec_delete(lm)) { jlog("ERROR: errorous grammar deleted\n"); } lm->global_modified = TRUE; } else { /* global not need changed by the deletion */ /* append only new grammars */ for(m=lm->grammars;m;m=m->next) { if (m->newbie) { if (lm->lmvar == LM_DFA_GRAMMAR && lm->dfa == NULL) { lm->dfa = dfa_info_new(); dfa_state_init(lm->dfa); } if (lm->winfo == NULL) { lm->winfo = word_info_new(); winfo_init(lm->winfo); } if (m->newbie) m->newbie = FALSE; if (lm->lmvar == LM_DFA_WORD) { /* just append dictionaty */ m->word_begin = lm->winfo->num; if (voca_append(lm->winfo, m->winfo, m->id, m->word_begin) == FALSE) { jlog("ERROR: multi-gram: failed to add dictionary #%d to recognition network\n", m->id); /* mark as delete */ m->hook |= MULTIGRAM_DELETE; } } else { if (multigram_append_to_global(lm->dfa, lm->winfo, m) == FALSE) { jlog("ERROR: multi-gram: failed to add grammar #%d to recognition network\n", m->id); /* mark as delete */ m->hook |= MULTIGRAM_DELETE; } } lm->global_modified = TRUE; } } } /* process activate/deactivate hook */ active_changed = multigram_exec_activate(lm); if (lm->global_modified) { /* if global lexicon has changed */ /* now global grammar info has been updated */ /* check if no grammar */ if (lm->lmvar == LM_DFA_GRAMMAR) { if (lm->dfa == NULL || lm->winfo == NULL) { if (lm->dfa != NULL) { dfa_info_free(lm->dfa); lm->dfa = NULL; } if (lm->winfo != NULL) { word_info_free(lm->winfo); lm->winfo = NULL; } } }#ifdef MDEBUG jlog("STAT: grammar update completed\n");#endif } if (lm->global_modified || active_changed) { return (TRUE); } return FALSE;}/** * <JA> * dfaファイルとdictファイルを粕み哈んで矢恕リストに纳裁する. * * @param dfa_file [in] dfa ファイル叹 * @param dict_file [in] dict ファイル叹 * @param lm [i/o] 咐胳借妄インスタンス * </JA> * <EN> * Add grammar to the grammar list specified by dfa file and dict file. * * @param dfa_file [in] dfa file name * @param dict_file [in] dict file name * @param lm [i/o] LM processing instance * </EN> */static booleanmultigram_read_file_and_add(char *dfa_file, char *dict_file, PROCESS_LM *lm){ WORD_INFO *new_winfo; DFA_INFO *new_dfa; char buf[MAXGRAMNAMELEN], *p, *q; boolean ret; if (dfa_file != NULL) { jlog("STAT: reading [%s] and [%s]...\n", dfa_file, dict_file); } else { jlog("STAT: reading [%s]...\n", dict_file); } /* read dict*/ new_winfo = word_info_new(); if (lm->lmvar == LM_DFA_GRAMMAR) { ret = init_voca(new_winfo, dict_file, lm->am->hmminfo, #ifdef MONOTREE TRUE,#else FALSE,#endif lm->config->forcedict_flag); if ( ! ret ) { jlog("ERROR: failed to read dictionary \"%s\"\n", dict_file); word_info_free(new_winfo); return FALSE; } } else if (lm->lmvar == LM_DFA_WORD) { ret = init_wordlist(new_winfo, dict_file, lm->am->hmminfo, lm->config->wordrecog_head_silence_model_name, lm->config->wordrecog_tail_silence_model_name, (lm->config->wordrecog_silence_context_name[0] == '\0') ? NULL : lm->config->wordrecog_silence_context_name, lm->config->forcedict_flag); if ( ! ret ) { jlog("ERROR: failed to read word list \"%s\"\n", dict_file); word_info_free(new_winfo); return FALSE; } } new_dfa = NULL; if (lm->lmvar == LM_DFA_GRAMMAR) { /* read dfa */ new_dfa = dfa_info_new(); if (init_dfa(new_dfa, dfa_file) == FALSE) { jlog("ERROR: multi-gram: error in reading DFA\n"); word_info_free(new_winfo); dfa_info_free(new_dfa); return FALSE; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -