libsent/src/hmminfo/cdset.c

Go to the documentation of this file.
00001 
00065 /*
00066  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00067  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00068  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00069  * All rights reserved
00070  */
00071 
00072 #include <sent/stddefs.h>
00073 #include <sent/htk_param.h>
00074 #include <sent/htk_hmm.h>
00075 
00077 
00078 
00079 #define CD_STATE_SET_STEP 10    
00080 
00081 
00086 static void
00087 cdset_init(HTK_HMM_INFO *hmminfo)
00088 {
00089   hmminfo->cdset_info.cdtree = NULL;
00090 }
00091 
00097 static CD_Set *
00098 cdset_new()
00099 {
00100   return((CD_Set *)mymalloc(sizeof(CD_Set)));
00101 }
00102 
00111 CD_Set *
00112 cdset_lookup(HTK_HMM_INFO *hmminfo, char *cdstr)
00113 {
00114   CD_Set *cd;
00115   cd = aptree_search_data(cdstr, hmminfo->cdset_info.cdtree);
00116   if (strmatch(cdstr, cd->name)) {
00117     return cd;
00118   } else {
00119     return NULL;
00120   }
00121 }
00122 
00131 CD_Set *
00132 lcdset_lookup_by_hmmname(HTK_HMM_INFO *hmminfo, char *hmmname)
00133 {
00134   static char buf[MAX_HMMNAME_LEN];
00135 
00136   return(cdset_lookup(hmminfo, leftcenter_name(hmmname, buf)));
00137 }
00138 
00147 CD_Set *
00148 rcdset_lookup_by_hmmname(HTK_HMM_INFO *hmminfo, char *hmmname)
00149 {
00150   static char buf[MAX_HMMNAME_LEN];
00151 
00152   return(cdset_lookup(hmminfo, rightcenter_name(hmmname, buf)));
00153 }
00154 
00155 
00161 static void
00162 put_cdset(void *ptr)
00163 {
00164   int i;
00165   CD_Set *a;
00166 
00167   a = ptr;
00168   printf("name: %s\n", a->name);
00169   /* printf("state_num: %d\n", a->state_num); */
00170   for(i=0;i<a->state_num;i++) {
00171     if (a->stateset[i].num == 0) {
00172       printf("\t[state %d]  not exist\n", i);
00173     } else {
00174       printf("\t[state %d]  %d variants\n", i, a->stateset[i].num);
00175     }
00176     /*
00177       for(j=0;j<a->stateset[i].num;j++) {
00178         put_htk_state(a->stateset[i].s[j]);
00179       }
00180     */
00181   }
00182 }
00183 
00189 void
00190 put_all_cdinfo(HTK_HMM_INFO *hmminfo)
00191 {
00192   aptree_traverse_and_do(hmminfo->cdset_info.cdtree, put_cdset);
00193 }
00194 
00195 
00205 boolean
00206 regist_cdset(APATNODE **root, HTK_HMM_Data *d, char *cdname)
00207 {
00208   boolean need_new;
00209   CD_State_Set *tmp;
00210   CD_Set *lset = NULL, *lmatch = NULL;
00211   int j,n;
00212   boolean changed = FALSE;
00213 
00214   if (strlen(cdname) >= MAX_HMMNAME_LEN) {
00215     j_error("Error: HMM name exceeds limit (%d): %s!\n", MAX_HMMNAME_LEN, cdname);
00216   }
00217   
00218   /* check if the cdset already exist */
00219   need_new = TRUE;
00220   if (*root != NULL) {
00221     lmatch = aptree_search_data(cdname, *root);
00222     if (strmatch(lmatch->name, cdname)) {
00223       /* exist, add to it later */
00224       lset = lmatch;
00225       need_new = FALSE;
00226       /* if the state num is larger than allocated, expand the lset */
00227       if (d->state_num > lset->state_num) {
00228         lset->stateset = (CD_State_Set *)myrealloc(lset->stateset, sizeof(CD_State_Set) * d->state_num);
00229         /* 0 1 ... (lset->state_num-1) */
00230         /* N A ... N                   */
00231         /* 0 1 ...                     ... (d->state_num-1) */
00232         /* N A ... A ..................... N                */
00233         /* malloc new area to expanded state (N to A above) */
00234         for(j = lset->state_num - 1; j < d->state_num - 1; j++) {
00235           lset->stateset[j].maxnum = CD_STATE_SET_STEP;
00236           lset->stateset[j].s = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * lset->stateset[j].maxnum);
00237           lset->stateset[j].num = 0;
00238         }
00239         lset->stateset[d->state_num-1].s = NULL;
00240         lset->stateset[d->state_num-1].num = 0;
00241         lset->stateset[d->state_num-1].maxnum = 0;
00242         
00243         lset->state_num = d->state_num;
00244 
00245         /* update transition table */
00246         lset->tr = d->tr;
00247 
00248         changed = TRUE;
00249       }
00250     }
00251   }
00252 
00253   if (need_new) {
00254     /* allocate as new with blank data */
00255     lset = cdset_new();
00256     lset->name = strdup(cdname);
00257     lset->state_num = d->state_num;
00258     lset->stateset = (CD_State_Set *)mymalloc(sizeof(CD_State_Set) * lset->state_num);
00259     /* assume first and last state has no outprob */
00260     lset->stateset[0].s = lset->stateset[lset->state_num-1].s = NULL;
00261     lset->stateset[0].num = lset->stateset[lset->state_num-1].num = 0;
00262     lset->stateset[0].maxnum = lset->stateset[lset->state_num-1].maxnum = 0;
00263     for(j=1;j<lset->state_num-1; j++) {
00264       /* pre-allocate only the first step */
00265       lset->stateset[j].maxnum = CD_STATE_SET_STEP;
00266       lset->stateset[j].s = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * lset->stateset[j].maxnum);
00267       lset->stateset[j].num = 0;
00268     }
00269     /* assign transition table of first found %HMM (ad-hoc?) */
00270     lset->tr = d->tr;
00271     /* add to search index tree */
00272     if (*root == NULL) {
00273       *root = aptree_make_root_node(lset);
00274     } else {
00275       aptree_add_entry(lset->name, lset, lmatch->name, root);
00276     }
00277 
00278     changed = TRUE;
00279   }
00280     
00281   /*j_printerr("add to \"%s\"\n", lset->name);*/
00282   /* register each HMM states to the lcdset */
00283   for (j=1;j<d->state_num-1;j++) {
00284     tmp = &(lset->stateset[j]);
00285     /* check if the state has already registered */
00286     for(n = 0; n < tmp->num ; n++) {
00287       if (tmp->s[n] == d->s[j]) { /* compare by pointer */
00288         /*j_printerr("\tstate %d has same\n", n);*/
00289         break;
00290       }
00291     }
00292     if (n < tmp->num ) continue;        /* same state found, cancel regist. */
00293     
00294     /* expand storage area if necessary */
00295     if (tmp->num >= tmp->maxnum) {
00296       tmp->maxnum += CD_STATE_SET_STEP;
00297       tmp->s = (HTK_HMM_State **)myrealloc(tmp->s, sizeof(HTK_HMM_State *) * tmp->maxnum);
00298     }
00299     
00300     tmp->s[tmp->num] = d->s[j];
00301     tmp->num++;
00302 
00303     changed = TRUE;
00304   }
00305 
00306   return(changed);
00307 }
00308 
00317 boolean
00318 remove_cdset(HTK_HMM_INFO *hmminfo, char *cdname)
00319 {
00320   CD_Set *lmatch;
00321   
00322   if (hmminfo->cdset_info.cdtree == NULL) return TRUE;
00323 
00324   lmatch = aptree_search_data(cdname, hmminfo->cdset_info.cdtree);
00325   if (strmatch(lmatch->name, cdname)) {
00326     printf("[%s] found\n", lmatch->name);
00327     /* found */
00328     /*
00329     for(j=1;j<lmatch->state_num-1;j++) {
00330       free(lmatch->stateset[j].s);
00331     }
00332     free(lmatch->stateset);
00333     */
00334     aptree_remove_entry(cdname, &(hmminfo->cdset_info.cdtree));
00335   } else {
00336     return FALSE;
00337   }
00338   return TRUE;
00339 }
00340   
00341 
00350 boolean
00351 make_cdset(HTK_HMM_INFO *hmminfo)
00352 {
00353   HMM_Logical *lg;
00354   static char buf[MAX_HMMNAME_LEN];
00355 
00356   cdset_init(hmminfo);
00357   /* make cdset name from logical HMM name */
00358   /* left-context set: "a-k" for /a-k+i/, /a-k+o/, ...
00359      for 1st pass (word end) */
00360   for(lg = hmminfo->lgstart; lg; lg = lg->next) {
00361     if (lg->is_pseudo) continue;
00362     regist_cdset(&(hmminfo->cdset_info.cdtree), lg->body.defined, leftcenter_name(lg->name, buf));
00363   }
00364   /* right-context set: "a+o" for /b-a+o/, /t-a+o/, ...
00365      for 2nd pass (word beginning) */
00366   for(lg = hmminfo->lgstart; lg; lg = lg->next) {
00367     if (lg->is_pseudo) continue;
00368     regist_cdset(&(hmminfo->cdset_info.cdtree), lg->body.defined, rightcenter_name(lg->name, buf));
00369   }
00370   /* both-context set: "a" for all triphone with same base phone "a"
00371      for 1st pass (1 phoneme word, with no previous word hypo.) */
00372   for(lg = hmminfo->lgstart; lg; lg = lg->next) {
00373     if (lg->is_pseudo) continue;
00374     regist_cdset(&(hmminfo->cdset_info.cdtree), lg->body.defined, center_name(lg->name, buf));
00375   }
00376 
00377   /* now that cdset is completely built */
00378   
00379   return(TRUE);
00380 }
00381 
00387 static void
00388 callback_free_lcdset_content(void *arg)
00389 {
00390   CD_Set *d;
00391   int j;
00392 
00393   d = arg;
00394   for(j=0;j<d->state_num;j++) {
00395     if (d->stateset[j].s != NULL) free(d->stateset[j].s);
00396   }
00397   free(d->stateset);
00398   free(d->name);
00399   free(d);
00400 }
00401 
00409 void
00410 free_cdset(APATNODE **root)
00411 {
00412   if (*root != NULL) {
00413     aptree_traverse_and_do(*root, callback_free_lcdset_content);
00414     free_aptree(*root);
00415     *root = NULL;
00416   }
00417 }
00418 

Generated on Tue Dec 26 16:16:33 2006 for Julius by  doxygen 1.5.0