Julius 4.2
|
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