/** * @file instance.c * * * @brief Allocate/free various instances * * * * @brief 各種インスタンスの割り付けおよび開放 * * * @author Akinobu Lee * @date Sun Oct 28 18:06:20 2007 * * $Revision: 1.8 $ * */ /* * Copyright (c) 1991-2012 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology * All rights reserved */ #include /** * * Allocate a new MFCC calculation instance * * * MFCC計算インスタンスを新たに割り付ける. * * * @param amconf [in] acoustic model configuration parameters * * @return the newly allocated MFCC calculation instance. * * @callgraph * @callergraph * */ MFCCCalc * j_mfcccalc_new(JCONF_AM *amconf) { MFCCCalc *mfcc; mfcc = (MFCCCalc *)mymalloc(sizeof(MFCCCalc)); memset(mfcc, 0, sizeof(MFCCCalc)); mfcc->param = NULL; mfcc->rest_param = NULL; mfcc->frontend.ssbuf = NULL; mfcc->cmn.loaded = FALSE; mfcc->plugin_source = -1; if (amconf) { mfcc->para = &(amconf->analysis.para); mfcc->hmm_loaded = (amconf->analysis.para_hmm.loaded == 1) ? TRUE : FALSE; mfcc->htk_loaded = (amconf->analysis.para_htk.loaded == 1) ? TRUE : FALSE; mfcc->wrk = WMP_work_new(mfcc->para); if (mfcc->wrk == NULL) { jlog("ERROR: j_mfcccalc_new: failed to initialize MFCC computation\n"); return NULL; } mfcc->cmn.load_filename = amconf->analysis.cmnload_filename; mfcc->cmn.update = amconf->analysis.cmn_update; mfcc->cmn.save_filename = amconf->analysis.cmnsave_filename; mfcc->cmn.map_weight = amconf->analysis.cmn_map_weight; mfcc->frontend.ss_alpha = amconf->frontend.ss_alpha; mfcc->frontend.ss_floor = amconf->frontend.ss_floor; mfcc->frontend.sscalc = amconf->frontend.sscalc; mfcc->frontend.sscalc_len = amconf->frontend.sscalc_len; mfcc->frontend.ssload_filename = amconf->frontend.ssload_filename; } mfcc->next = NULL; return mfcc; } /** * * Free an MFCC calculation instance. * * * MFCC計算インスタンスを開放する * * * @param mfcc [i/o] MFCC calculation instance * * @callgraph * @callergraph */ void j_mfcccalc_free(MFCCCalc *mfcc) { if (mfcc->rest_param) free_param(mfcc->rest_param); if (mfcc->param) free_param(mfcc->param); if (mfcc->wrk) WMP_free(mfcc->wrk); if (mfcc->tmpmfcc) free(mfcc->tmpmfcc); if (mfcc->db) WMP_deltabuf_free(mfcc->db); if (mfcc->ab) WMP_deltabuf_free(mfcc->ab); if (mfcc->cmn.wrk) CMN_realtime_free(mfcc->cmn.wrk); if (mfcc->frontend.ssbuf) free(mfcc->frontend.ssbuf); if (mfcc->frontend.mfccwrk_ss) WMP_free(mfcc->frontend.mfccwrk_ss); free(mfcc); } /** * * Allocate a new acoustic model processing instance. * * * 音響モデル計算インスタンスを新たに割り付ける. * * * @param recog [i/o] engine instance * @param amconf [in] AM configuration to assign * * @return newly allocated acoustic model processing instance. * * @callgraph * @callergraph */ PROCESS_AM * j_process_am_new(Recog *recog, JCONF_AM *amconf) { PROCESS_AM *new, *atmp; /* allocate memory */ new = (PROCESS_AM *)mymalloc(sizeof(PROCESS_AM)); memset(new, 0, sizeof(PROCESS_AM)); /* assign configuration */ new->config = amconf; /* append to last */ new->next = NULL; if (recog->amlist == NULL) { recog->amlist = new; } else { for(atmp = recog->amlist; atmp->next; atmp = atmp->next); atmp->next = new; } return new; } /** * * Free an acoustic model processing instance. * * * 音響モデル計算インスタンスを開放する. * * * @param am [i/o] AM process instance * * @callgraph * @callergraph */ void j_process_am_free(PROCESS_AM *am) { /* HMMWork hmmwrk */ outprob_free(&(am->hmmwrk)); if (am->hmminfo) hmminfo_free(am->hmminfo); if (am->hmm_gs) hmminfo_free(am->hmm_gs); /* not free am->jconf */ free(am); } /** * * Allocate a new language model processing instance. * * * 言語モデル計算インスタンスを新たに割り付ける. * * * @param recog [i/o] engine instance * @param lmconf [in] LM configuration to assign * * @return newly allocated language model processing instance. * * @callgraph * @callergraph */ PROCESS_LM * j_process_lm_new(Recog *recog, JCONF_LM *lmconf) { PROCESS_LM *new, *ltmp; /* allocate memory */ new = (PROCESS_LM *)mymalloc(sizeof(PROCESS_LM)); memset(new, 0, sizeof(PROCESS_LM)); /* assign config */ new->config = lmconf; /* initialize some values */ new->lmtype = lmconf->lmtype; new->lmvar = lmconf->lmvar; new->gram_maxid = 0; new->global_modified = FALSE; /* append to last */ new->next = NULL; if (recog->lmlist == NULL) { recog->lmlist = new; } else { for(ltmp = recog->lmlist; ltmp->next; ltmp = ltmp->next); ltmp->next = new; } return new; } /** * * Free a language model processing instance. * * * 言語モデル計算インスタンスを開放する. * * * @param lm [i/o] LM process instance * * @callgraph * @callergraph */ void j_process_lm_free(PROCESS_LM *lm) { if (lm->winfo) word_info_free(lm->winfo); if (lm->ngram) ngram_info_free(lm->ngram); if (lm->grammars) multigram_free_all(lm->grammars); if (lm->dfa) dfa_info_free(lm->dfa); /* not free lm->jconf */ free(lm); } /** * * Allocate a new recognition process instance. * * * 認識処理インスタンスを新たに生成する. * * * @param recog [i/o] engine instance * @param sconf [in] SEARCH configuration to assign * * @return the newly allocated recognition process instance. * * @callgraph * @callergraph */ RecogProcess * j_recogprocess_new(Recog *recog, JCONF_SEARCH *sconf) { RecogProcess *new, *ptmp; /* allocate memory */ new = (RecogProcess *)mymalloc(sizeof(RecogProcess)); memset(new, 0, sizeof(RecogProcess)); new->live = FALSE; new->active = 0; new->next = NULL; /* assign configuration */ new->config = sconf; /* append to last */ new->next = NULL; if (recog->process_list == NULL) { recog->process_list = new; } else { for(ptmp = recog->process_list; ptmp->next; ptmp = ptmp->next); ptmp->next = new; } return new; } /** * * Free a recognition process instance * * * 認識処理インスタンスを開放する. * * * @param process [i/o] recognition process instance * * @callgraph * @callergraph */ void j_recogprocess_free(RecogProcess *process) { /* not free jconf, am, lm here */ /* free part of StackDecode work area */ wchmm_fbs_free(process); /* free cache */ if (process->lmtype == LM_PROB) { max_successor_cache_free(process->wchmm); } /* free wchmm */ if (process->wchmm) wchmm_free(process->wchmm); /* free backtrellis */ if (process->backtrellis) bt_free(process->backtrellis); /* free pass1 work area */ fsbeam_free(&(process->pass1)); free(process); } /** * * Allocate a new acoustic model (AM) parameter structure. * Default parameter values are set to it. * * * 音響モデル(AM)パラメータ構造体を新たに割り付ける. * 内部メンバにはデフォルト値が格納される. * * * @return the newly allocated AM parameter structure * * @callgraph * @callergraph * @ingroup jconf */ JCONF_AM * j_jconf_am_new() { JCONF_AM *new; new = (JCONF_AM *)mymalloc(sizeof(JCONF_AM)); jconf_set_default_values_am(new); new->next = NULL; return new; } /** * * Release an acoustic model (AM) parameter structure * Default parameter values are set to it. * * * 音響モデル(AM)パラメータ構造体を解放する. * 内部メンバにはデフォルト値が格納される. * * * @param amconf [in] AM configuration * * @callgraph * @callergraph * @ingroup jconf * */ void j_jconf_am_free(JCONF_AM *amconf) { free(amconf); } /** * * Register AM configuration to global jconf. * Returns error if the same name already exist in the jconf. * * * 音響モデル(AM)パラメータ構造体を jconf に登録する. * jconf内に同じ名前のモジュールが既に登録されている場合はエラーとなる. * * * @param jconf [i/o] global jconf * @param amconf [in] AM configuration to register * @param name [in] module name * * @return TRUE on success, FALSE on failure * * @callgraph * @callergraph * @ingroup jconf */ boolean j_jconf_am_regist(Jconf *jconf, JCONF_AM *amconf, char *name) { JCONF_AM *atmp; if (!name) { jlog("ERROR: j_jconf_am_regist: no name specified to register an AM conf\n"); return FALSE; } for(atmp = jconf->am_root; atmp; atmp = atmp->next) { if (strmatch(atmp->name, name)) { jlog("ERROR: j_jconf_am_regist: failed to regist an AM conf: the same name \"%s\" already exist\n", atmp->name); return FALSE; } } /* set name */ strncpy(amconf->name, name, JCONF_MODULENAME_MAXLEN); /* append to last */ amconf->next = NULL; if (jconf->am_root == NULL) { amconf->id = 1; jconf->am_root = amconf; } else { for(atmp = jconf->am_root; atmp->next; atmp = atmp->next); amconf->id = atmp->id + 1; atmp->next = amconf; } return TRUE; } /** * * Allocate a new language model (LM) parameter structure. * Default parameter values are set to it. * * * 言語モデル (LM) パラメータ構造体を新たに割り付ける * 内部メンバにはデフォルト値が格納される. * * * @return the newly allocated LM parameter structure. * * @callgraph * @callergraph * @ingroup jconf */ JCONF_LM * j_jconf_lm_new() { JCONF_LM *new; new = (JCONF_LM *)mymalloc(sizeof(JCONF_LM)); jconf_set_default_values_lm(new); new->next = NULL; return new; } /** * * Release a language model (LM) parameter structure * * * 言語モデル (LM) パラメータ構造体を解放する * * * @param lmconf [in] LM parameter structure * * @callgraph * @callergraph * @ingroup jconf * */ void j_jconf_lm_free(JCONF_LM *lmconf) { JCONF_LM_NAMELIST *nl, *nltmp; nl = lmconf->additional_dict_files; while (nl) { nltmp = nl->next; free(nl->name); free(nl); nl = nltmp; } nl = lmconf->additional_dict_entries; while (nl) { nltmp = nl->next; free(nl->name); free(nl); nl = nltmp; } free(lmconf); } /** * * Register LM configuration to global jconf. * Returns error if the same name already exist in the jconf. * * * 言語モデル(LM)パラメータ構造体を jconf に登録する. * jconf内に同じ名前のモジュールが既に登録されている場合はエラーとなる. * * * @param jconf [i/o] global jconf * @param lmconf [in] LM configuration to register * @param name [in] module name * * @return TRUE on success, FALSE on failure * * @callgraph * @callergraph * @ingroup jconf */ boolean j_jconf_lm_regist(Jconf *jconf, JCONF_LM *lmconf, char *name) { JCONF_LM *ltmp; if (!name) { jlog("ERROR: j_jconf_lm_regist: no name specified to register a LM conf\n"); return FALSE; } for(ltmp = jconf->lm_root; ltmp; ltmp = ltmp->next) { if (strmatch(ltmp->name, name)) { jlog("ERROR: j_jconf_lm_regist: failed to regist a LM conf: the same name \"%s\" already exist\n", ltmp->name); return FALSE; } } /* set name */ strncpy(lmconf->name, name, JCONF_MODULENAME_MAXLEN); /* append to last */ lmconf->next = NULL; if (jconf->lm_root == NULL) { lmconf->id = 1; jconf->lm_root = lmconf; } else { for(ltmp = jconf->lm_root; ltmp->next; ltmp = ltmp->next); lmconf->id = ltmp->id + 1; ltmp->next = lmconf; } return TRUE; } /** * * Allocate a new search (SEARCH) parameter structure. * Default parameter values are set to it. * * * 探索パラメータ(SEARCH)構造体を新たに割り付ける. * 内部メンバにはデフォルト値が格納される. * * * @return the newly allocated SEARCH parameter structure. * * @callgraph * @callergraph * @ingroup jconf */ JCONF_SEARCH * j_jconf_search_new() { JCONF_SEARCH *new; new = (JCONF_SEARCH *)mymalloc(sizeof(JCONF_SEARCH)); jconf_set_default_values_search(new); new->next = NULL; return new; } /** * * Release a search (SEARCH) parameter structure * * * 探索パラメータ(SEARCH)構造体を解放する * * * @param sconf [in] SEARCH parameter structure * * @callgraph * @callergraph * @ingroup jconf * */ void j_jconf_search_free(JCONF_SEARCH *sconf) { free(sconf); } /** * * Register SEARCH configuration to global jconf. * Returns error if the same name already exist in the jconf. * * * 探索(SEARCH)パラメータ構造体を jconf に登録する. * jconf内に同じ名前のモジュールが既に登録されている場合はエラーとなる. * * * @param jconf [i/o] global jconf * @param sconf [in] SEARCH configuration to register * @param name [in] module name * * @return TRUE on success, FALSE on failure * * @callgraph * @callergraph * @ingroup jconf */ boolean j_jconf_search_regist(Jconf *jconf, JCONF_SEARCH *sconf, char *name) { JCONF_SEARCH *stmp; if (!name) { jlog("ERROR: j_jconf_search_regist: no name specified to register a SR conf\n"); return FALSE; } for(stmp = jconf->search_root; stmp; stmp = stmp->next) { if (strmatch(stmp->name, name)) { jlog("ERROR: j_jconf_search_regist: failed to regist an SR conf: the same name \"%s\" already exist\n", stmp->name); return FALSE; } } /* set name */ strncpy(sconf->name, name, JCONF_MODULENAME_MAXLEN); /* append to last */ sconf->next = NULL; if (jconf->search_root == NULL) { sconf->id = 1; jconf->search_root = sconf; } else { for(stmp = jconf->search_root; stmp->next; stmp = stmp->next); sconf->id = stmp->id + 1; stmp->next = sconf; } return TRUE; } /** * * @brief Allocate a new global configuration parameter structure. * * JCONF_AM, JCONF_LM, JCONF_SEARCH are defined one for each, and * assigned to the newly allocated structure as initial instances. * * * * @brief 全体のパラメータ構造体を新たに割り付ける. * * JCONF_AM, JCONF_LM, JCONF_SEARCHも1つづつ割り当てられる. * これらは -AM 等の指定を含まない 3.x 以前の jconf を読み込んだときに, * そのまま用いられる. * * * * @return the newly allocated global configuration parameter structure. * * @callgraph * @callergraph * @ingroup jconf */ Jconf * j_jconf_new() { Jconf *jconf; /* allocate memory */ jconf = (Jconf *)mymalloc(sizeof(Jconf)); /* set default values */ jconf_set_default_values(jconf); /* allocate first one am / lm /search instance with their name left NULL */ jconf->am_root = j_jconf_am_new(); jconf->am_root->id = 0; strcpy(jconf->am_root->name, JCONF_MODULENAME_DEFAULT); jconf->lm_root = j_jconf_lm_new(); jconf->lm_root->id = 0; strcpy(jconf->lm_root->name, JCONF_MODULENAME_DEFAULT); jconf->search_root = j_jconf_search_new(); jconf->search_root->id = 0; strcpy(jconf->search_root->name, JCONF_MODULENAME_DEFAULT); /* assign the am /lm instance to the instance */ jconf->search_root->amconf = jconf->am_root; jconf->search_root->lmconf = jconf->lm_root; /* set current */ jconf->amnow = jconf->am_root; jconf->lmnow = jconf->lm_root; jconf->searchnow = jconf->search_root; /* set gmm am jconf */ jconf->gmm = NULL; return(jconf); } /** * * @brief Free a global configuration parameter structure. * * All JCONF_AM, JCONF_LM, JCONF_SEARCH are also released. * * * * @brief 全体のパラメータ構造体を開放する. * * JCONF_AM, JCONF_LM, JCONF_SEARCHもすべて開放される. * * * * @param jconf [in] global configuration parameter structure * * @callgraph * @callergraph * @ingroup jconf */ void j_jconf_free(Jconf *jconf) { JCONF_AM *am, *amtmp; JCONF_LM *lm, *lmtmp; JCONF_SEARCH *sc, *sctmp; opt_release(jconf); am = jconf->am_root; while(am) { amtmp = am->next; j_jconf_am_free(am); am = amtmp; } lm = jconf->lm_root; while(lm) { lmtmp = lm->next; j_jconf_lm_free(lm); lm = lmtmp; } sc = jconf->search_root; while(sc) { sctmp = sc->next; j_jconf_search_free(sc); sc = sctmp; } free(jconf); } /** * * Allocate memory for a new engine instance. * * * エンジンインスタンスを新たにメモリ割り付けする. * * * @return the newly allocated engine instance. * * @callgraph * @callergraph * @ingroup instance */ Recog * j_recog_new() { Recog *recog; /* allocate memory */ recog = (Recog *)mymalloc(sizeof(Recog)); /* clear all values to 0 (NULL) */ memset(recog, 0, sizeof(Recog)); /* initialize some values */ recog->jconf = NULL; recog->amlist = NULL; recog->lmlist = NULL; recog->process_list = NULL; recog->process_online = FALSE; recog->process_active = TRUE; recog->process_want_terminate = FALSE; recog->process_want_reload = FALSE; recog->gram_switch_input_method = SM_PAUSE; recog->process_segment = FALSE; /* set default function for vector calculation to RealTimeMFCC() */ recog->calc_vector = RealTimeMFCC; /* clear callback func. */ callback_init(recog); recog->adin = (ADIn *)mymalloc(sizeof(ADIn)); memset(recog->adin, 0, sizeof(ADIn)); return(recog); } /** * * @brief Free an engine instance. * * All allocated memories in the instance will be also released. * * * @brief エンジンインスタンスを開放する * * インスタンス内でこれまでにアロケートされた全てのメモリも開放される. * * * @param recog [in] engine instance. * * @callgraph * @callergraph * @ingroup instance */ void j_recog_free(Recog *recog) { if (recog->gmm) hmminfo_free(recog->gmm); if (recog->speech) free(recog->speech); /* free adin work area */ adin_free_param(recog); /* free GMM calculation work area if any */ gmm_free(recog); /* Output result -> free just after malloced and used */ /* StackDecode pass2 -> allocate and free within search */ /* RealBeam real */ realbeam_free(recog); /* adin */ if (recog->adin) free(recog->adin); /* instances */ { RecogProcess *p, *ptmp; p = recog->process_list; while(p) { ptmp = p->next; j_recogprocess_free(p); p = ptmp; } } { PROCESS_LM *lm, *lmtmp; lm = recog->lmlist; while(lm) { lmtmp = lm->next; j_process_lm_free(lm); lm = lmtmp; } } { PROCESS_AM *am, *amtmp; am = recog->amlist; while(am) { amtmp = am->next; j_process_am_free(am); am = amtmp; } } { MFCCCalc *mfcc, *tmp; mfcc = recog->mfcclist; while(mfcc) { tmp = mfcc->next; j_mfcccalc_free(mfcc); mfcc = tmp; } } /* jconf */ if (recog->jconf) { j_jconf_free(recog->jconf); } free(recog); } /* end of file */