Julius 4.2
libsent/src/hmminfo/cdset.c
説明を見る。
00001 
00066 /*
00067  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00068  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00069  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00070  * All rights reserved
00071  */
00072 
00073 #include <sent/stddefs.h>
00074 #include <sent/htk_param.h>
00075 #include <sent/htk_hmm.h>
00076 
00078 
00079 
00080 #define CD_STATE_SET_STEP 10    ///< CD_State_Set memory allocation step
00081 
00087 static void
00088 cdset_init(HTK_HMM_INFO *hmminfo)
00089 {
00090   hmminfo->cdset_info.binary_malloc = FALSE;
00091   hmminfo->cdset_info.cdtree = NULL;
00092 }
00093 
00099 static CD_Set *
00100 cdset_new()
00101 {
00102   return((CD_Set *)mymalloc(sizeof(CD_Set)));
00103 }
00104 
00113 CD_Set *
00114 cdset_lookup(HTK_HMM_INFO *hmminfo, char *cdstr)
00115 {
00116   CD_Set *cd;
00117   cd = aptree_search_data(cdstr, hmminfo->cdset_info.cdtree);
00118   if (cd != NULL && strmatch(cdstr, cd->name)) {
00119     return cd;
00120   } else {
00121     return NULL;
00122   }
00123 }
00124 
00133 CD_Set *
00134 lcdset_lookup_by_hmmname(HTK_HMM_INFO *hmminfo, char *hmmname)
00135 {
00136   char buf[MAX_HMMNAME_LEN];
00137 
00138   return(cdset_lookup(hmminfo, leftcenter_name(hmmname, buf)));
00139 }
00140 
00149 CD_Set *
00150 rcdset_lookup_by_hmmname(HTK_HMM_INFO *hmminfo, char *hmmname)
00151 {
00152   char buf[MAX_HMMNAME_LEN];
00153 
00154   return(cdset_lookup(hmminfo, rightcenter_name(hmmname, buf)));
00155 }
00156 
00157 
00163 static void
00164 put_cdset(void *ptr)
00165 {
00166   int i;
00167   CD_Set *a;
00168   int j;
00169 
00170   a = ptr;
00171   printf("name: %s\n", a->name);
00172   /* printf("state_num: %d\n", a->state_num); */
00173   for(i=0;i<a->state_num;i++) {
00174     if (a->stateset[i].num == 0) {
00175       printf("\t[state %d]  not exist\n", i);
00176     } else {
00177       printf("\t[state %d]  %d variants\n", i, a->stateset[i].num);
00178     }
00179     for(j=0;j<a->stateset[i].num;j++) {
00180       if (a->stateset[i].s[j]->name) {
00181         printf("\t\t%s %d\n", a->stateset[i].s[j]->name, a->stateset[i].s[j]->id);
00182       } else {
00183         printf("\t\t(NULL) %d\n", a->stateset[i].s[j]->id);
00184       }
00185     }
00186   }
00187 }
00188 
00194 void
00195 put_all_cdinfo(HTK_HMM_INFO *hmminfo)
00196 {
00197   aptree_traverse_and_do(hmminfo->cdset_info.cdtree, put_cdset);
00198 }
00199 
00200 
00210 boolean
00211 regist_cdset(APATNODE **root, HTK_HMM_Data *d, char *cdname, BMALLOC_BASE **mroot)
00212 {
00213   boolean need_new;
00214   CD_State_Set *tmp;
00215   CD_Set *lset = NULL, *lmatch = NULL;
00216   int j,n;
00217   boolean changed = FALSE;
00218 
00219   if (strlen(cdname) >= MAX_HMMNAME_LEN) {
00220     jlog("Error: cdset: HMM name exceeds limit (%d): %s!\n", MAX_HMMNAME_LEN, cdname);
00221     jlog("Error: cdset: Please increase the value of MAX_HMMNAME_LEN (current = %d)\n", MAX_HMMNAME_LEN);
00222     exit(1);
00223   }
00224   
00225   /* check if the cdset already exist */
00226   need_new = TRUE;
00227   if (*root != NULL) {
00228     lmatch = aptree_search_data(cdname, *root);
00229     if (lmatch != NULL && strmatch(lmatch->name, cdname)) {
00230       /* exist, add to it later */
00231       lset = lmatch;
00232       need_new = FALSE;
00233       /* if the state num is larger than allocated, expand the lset */
00234       if (d->state_num > lset->state_num) {
00235         lset->stateset = (CD_State_Set *)myrealloc(lset->stateset, sizeof(CD_State_Set) * d->state_num);
00236         /* 0 1 ... (lset->state_num-1) */
00237         /* N A ... N                   */
00238         /* 0 1 ...                     ... (d->state_num-1) */
00239         /* N A ... A ..................... N                */
00240         /* malloc new area to expanded state (N to A above) */
00241         for(j = lset->state_num - 1; j < d->state_num - 1; j++) {
00242           lset->stateset[j].maxnum = CD_STATE_SET_STEP;
00243           lset->stateset[j].s = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * lset->stateset[j].maxnum);
00244           lset->stateset[j].num = 0;
00245         }
00246         lset->stateset[d->state_num-1].s = NULL;
00247         lset->stateset[d->state_num-1].num = 0;
00248         lset->stateset[d->state_num-1].maxnum = 0;
00249         
00250         lset->state_num = d->state_num;
00251 
00252         /* update transition table */
00253         lset->tr = d->tr;
00254 
00255         changed = TRUE;
00256       }
00257     }
00258   }
00259 
00260   if (need_new) {
00261     /* allocate as new with blank data */
00262     lset = cdset_new();
00263     lset->name = strdup(cdname);
00264     lset->state_num = d->state_num;
00265     lset->stateset = (CD_State_Set *)mymalloc(sizeof(CD_State_Set) * lset->state_num);
00266     /* assume first and last state has no outprob */
00267     lset->stateset[0].s = lset->stateset[lset->state_num-1].s = NULL;
00268     lset->stateset[0].num = lset->stateset[lset->state_num-1].num = 0;
00269     lset->stateset[0].maxnum = lset->stateset[lset->state_num-1].maxnum = 0;
00270     for(j=1;j<lset->state_num-1; j++) {
00271       /* pre-allocate only the first step */
00272       lset->stateset[j].maxnum = CD_STATE_SET_STEP;
00273       lset->stateset[j].s = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * lset->stateset[j].maxnum);
00274       lset->stateset[j].num = 0;
00275     }
00276     /* assign transition table of first found %HMM (ad-hoc?) */
00277     lset->tr = d->tr;
00278     /* add to search index tree */
00279     if (*root == NULL) {
00280       *root = aptree_make_root_node(lset, mroot);
00281     } else {
00282       aptree_add_entry(lset->name, lset, lmatch->name, root, mroot);
00283     }
00284 
00285     changed = TRUE;
00286   }
00287     
00288   /* register each HMM states to the lcdset */
00289   for (j=1;j<d->state_num-1;j++) {
00290     tmp = &(lset->stateset[j]);
00291     /* check if the state has already registered */
00292     for(n = 0; n < tmp->num ; n++) {
00293       if (tmp->s[n] == d->s[j]) { /* compare by pointer */
00294         /*jlog("\tstate %d has same\n", n);*/
00295         break;
00296       }
00297     }
00298     if (n < tmp->num ) continue;        /* same state found, cancel regist. */
00299     
00300     /* expand storage area if necessary */
00301     if (tmp->num >= tmp->maxnum) {
00302       tmp->maxnum += CD_STATE_SET_STEP;
00303       tmp->s = (HTK_HMM_State **)myrealloc(tmp->s, sizeof(HTK_HMM_State *) * tmp->maxnum);
00304     }
00305     
00306     tmp->s[tmp->num] = d->s[j];
00307     tmp->num++;
00308 
00309     changed = TRUE;
00310   }
00311 
00312   return(changed);
00313 }
00314 
00323 boolean
00324 make_cdset(HTK_HMM_INFO *hmminfo)
00325 {
00326   HMM_Logical *lg;
00327   char buf[MAX_HMMNAME_LEN];
00328 
00329   cdset_init(hmminfo);
00330   /* make cdset name from logical HMM name */
00331   /* left-context set: "a-k" for /a-k+i/, /a-k+o/, ...
00332      for 1st pass (word end) */
00333   for(lg = hmminfo->lgstart; lg; lg = lg->next) {
00334     if (lg->is_pseudo) continue;
00335     regist_cdset(&(hmminfo->cdset_info.cdtree), lg->body.defined, leftcenter_name(lg->name, buf), &(hmminfo->cdset_root));
00336   }
00337   /* right-context set: "a+o" for /b-a+o/, /t-a+o/, ...
00338      for 2nd pass (word beginning) */
00339   for(lg = hmminfo->lgstart; lg; lg = lg->next) {
00340     if (lg->is_pseudo) continue;
00341     regist_cdset(&(hmminfo->cdset_info.cdtree), lg->body.defined, rightcenter_name(lg->name, buf), &(hmminfo->cdset_root));
00342   }
00343   /* both-context set: "a" for all triphone with same base phone "a"
00344      for 1st pass (1 phoneme word, with no previous word hypo.) */
00345   for(lg = hmminfo->lgstart; lg; lg = lg->next) {
00346     if (lg->is_pseudo) continue;
00347     regist_cdset(&(hmminfo->cdset_info.cdtree), lg->body.defined, center_name(lg->name, buf), &(hmminfo->cdset_root));
00348   }
00349 
00350   /* now that cdset is completely built */
00351   hmminfo->cdset_info.binary_malloc = FALSE;
00352   
00353   return(TRUE);
00354 }
00355 
00361 static void
00362 callback_free_lcdset_content(void *arg)
00363 {
00364   CD_Set *d;
00365   int j;
00366 
00367   d = arg;
00368   for(j=0;j<d->state_num;j++) {
00369     if (d->stateset[j].s != NULL) free(d->stateset[j].s);
00370   }
00371   free(d->stateset);
00372   free(d->name);
00373   free(d);
00374 }
00375 
00383 void
00384 free_cdset(APATNODE **root, BMALLOC_BASE **mroot)
00385 {
00386   if (*root != NULL) {
00387     aptree_traverse_and_do(*root, callback_free_lcdset_content);
00388     mybfree2(mroot);
00389     *root = NULL;
00390   }
00391 }
00392