/**
* @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 */