libsent/src/hmminfo/write_binhmm.c

Go to the documentation of this file.
00001 
00027 /*
00028  * Copyright (c) 2003-2005 Shikano Lab., Nara Institute of Science and Technology
00029  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00030  * All rights reserved
00031  */
00032 
00033 /* $Id: write_binhmm.c,v 1.5 2006/12/14 08:18:36 sumomo Exp $ */
00034 
00035 #include <sent/stddefs.h>
00036 #include <sent/htk_param.h>
00037 #include <sent/htk_hmm.h>
00038 #include <sent/mfcc.h>
00039 
00040 
00049 static void
00050 wrt(FILE *fp, void *buf, size_t unitbyte, int unitnum)
00051 {
00052 #ifndef WORDS_BIGENDIAN
00053   if (unitbyte != 1) {
00054     swap_bytes((char *)buf, unitbyte, unitnum);
00055   }
00056 #endif
00057   if (myfwrite(buf, unitbyte, unitnum, fp) < unitnum) {
00058     perror("write_binhmm: wrt");
00059     j_error("write failed\n");
00060   }
00061 #ifndef WORDS_BIGENDIAN
00062   if (unitbyte != 1) {
00063     swap_bytes((char *)buf, unitbyte, unitnum);
00064   }
00065 #endif
00066 }
00067 
00074 static void
00075 wrt_str(FILE *fp, char *str)
00076 {
00077   static char noname = '\0';
00078   
00079   if (str) {
00080     wrt(fp, str, sizeof(char), strlen(str)+1);
00081   } else {
00082     wrt(fp, &noname, sizeof(char), 1);
00083   }
00084 }
00085 
00086 
00087 static char *binhmm_header_v2 = BINHMM_HEADER_V2; 
00088 
00094 static void
00095 wt_header(FILE *fp, boolean emp, boolean inv)
00096 {
00097   char buf[50];
00098   char *p;
00099 
00100   wrt_str(fp, binhmm_header_v2);
00101   p = &(buf[0]);
00102   if (emp) {
00103     *p++ = '_';
00104     *p++ = BINHMM_HEADER_V2_EMBEDPARA;
00105   }
00106   if (inv) {
00107     *p++ = '_';
00108     *p++ = BINHMM_HEADER_V2_VARINV;
00109   }
00110   *p = '\0';
00111   wrt_str(fp, buf);
00112 }
00113 
00114 
00121 static void
00122 wt_para(FILE *fp, Value *para)
00123 {
00124   short version;
00125 
00126   version = VALUE_VERSION;
00127   wrt(fp, &version, sizeof(short), 1);
00128 
00129   wrt(fp, &(para->smp_period), sizeof(long), 1);      
00130   wrt(fp, &(para->smp_freq), sizeof(long), 1);  
00131   wrt(fp, &(para->framesize), sizeof(int), 1);        
00132   wrt(fp, &(para->frameshift), sizeof(int), 1);       
00133   wrt(fp, &(para->preEmph), sizeof(float), 1);        
00134   wrt(fp, &(para->lifter), sizeof(int), 1);           
00135   wrt(fp, &(para->fbank_num), sizeof(int), 1);        
00136   wrt(fp, &(para->delWin), sizeof(int), 1);           
00137   wrt(fp, &(para->accWin), sizeof(int), 1);           
00138   wrt(fp, &(para->silFloor), sizeof(float), 1);       
00139   wrt(fp, &(para->escale), sizeof(float), 1);         
00140   wrt(fp, &(para->hipass), sizeof(int), 1);             
00141   wrt(fp, &(para->lopass), sizeof(int), 1);             
00142   wrt(fp, &(para->enormal), sizeof(int), 1);          
00143   wrt(fp, &(para->raw_e), sizeof(int), 1);            
00144   wrt(fp, &(para->ss_alpha), sizeof(float), 1); 
00145   wrt(fp, &(para->ss_floor), sizeof(float), 1); 
00146   wrt(fp, &(para->zmeanframe), sizeof(int), 1); 
00147 }
00148 
00149 
00156 static void
00157 wt_opt(FILE *fp, HTK_HMM_Options *opt)
00158 {
00159   wrt(fp, &(opt->stream_info.num), sizeof(short), 1);
00160   wrt(fp, opt->stream_info.vsize, sizeof(short), 50);
00161   wrt(fp, &(opt->vec_size), sizeof(short), 1);
00162   wrt(fp, &(opt->cov_type), sizeof(short), 1);
00163   wrt(fp, &(opt->dur_type), sizeof(short), 1);
00164   wrt(fp, &(opt->param_type), sizeof(short), 1);
00165 }
00166 
00173 static void
00174 wt_type(FILE *fp, HTK_HMM_INFO *hmm)
00175 {
00176   wrt(fp, &(hmm->is_tied_mixture), sizeof(boolean), 1);
00177   wrt(fp, &(hmm->maxmixturenum), sizeof(int), 1);
00178 }
00179 
00180 
00181 /* write transition data */
00182 static HTK_HMM_Trans **tr_index; 
00183 static unsigned int tr_num;     
00184 
00194 static int
00195 qsort_tr_index(HTK_HMM_Trans **t1, HTK_HMM_Trans **t2)
00196 {
00197   if (*t1 > *t2) return 1;
00198   else if (*t1 < *t2) return -1;
00199   else return 0;
00200 }
00201 
00213 static void
00214 wt_trans(FILE *fp, HTK_HMM_INFO *hmm)
00215 {
00216   HTK_HMM_Trans *t;
00217   unsigned int idx;
00218   int i;
00219 
00220   tr_num = 0;
00221   for(t = hmm->trstart; t; t = t->next) tr_num++;
00222   tr_index = (HTK_HMM_Trans **)mymalloc(sizeof(HTK_HMM_Trans *) * tr_num);
00223   idx = 0;
00224   for(t = hmm->trstart; t; t = t->next) tr_index[idx++] = t;
00225   qsort(tr_index, tr_num, sizeof(HTK_HMM_Trans *), (int (*)(const void *, const void *))qsort_tr_index);
00226   
00227   wrt(fp, &tr_num, sizeof(unsigned int), 1);
00228   for (idx = 0; idx < tr_num; idx++) {
00229     t = tr_index[idx];
00230     wrt_str(fp, t->name);
00231     wrt(fp, &(t->statenum), sizeof(short), 1);
00232     for(i=0;i<t->statenum;i++) {
00233       wrt(fp, t->a[i], sizeof(PROB), t->statenum);
00234     }
00235   }
00236 
00237   j_printf("%d transition maxtix written\n", tr_num);
00238 }
00239 
00247 static unsigned int
00248 search_trid(HTK_HMM_Trans *t)
00249 {
00250   unsigned int left = 0;
00251   unsigned int right = tr_num - 1;
00252   unsigned int mid;
00253 
00254   while (left < right) {
00255     mid = (left + right) / 2;
00256     if (tr_index[mid] < t) {
00257       left = mid + 1;
00258     } else {
00259       right = mid;
00260     }
00261   }
00262   return(left);
00263 }
00264 
00265 
00266 /* write variance data */
00267 static HTK_HMM_Var **vr_index;  
00268 static unsigned int vr_num;     
00269 
00279 static int
00280 qsort_vr_index(HTK_HMM_Var **v1, HTK_HMM_Var **v2)
00281 {
00282   if (*v1 > *v2) return 1;
00283   else if (*v1 < *v2) return -1;
00284   else return 0;
00285 }
00286 
00298 static void
00299 wt_var(FILE *fp, HTK_HMM_INFO *hmm)
00300 {
00301   HTK_HMM_Var *v;
00302   unsigned int idx;
00303 
00304   vr_num = 0;
00305   for(v = hmm->vrstart; v; v = v->next) vr_num++;
00306   vr_index = (HTK_HMM_Var **)mymalloc(sizeof(HTK_HMM_Var *) * vr_num);
00307   idx = 0;
00308   for(v = hmm->vrstart; v; v = v->next) vr_index[idx++] = v;
00309   qsort(vr_index, vr_num, sizeof(HTK_HMM_Var *), (int (*)(const void *, const void *))qsort_vr_index);  
00310 
00311   wrt(fp, &vr_num, sizeof(unsigned int), 1);
00312   for (idx = 0; idx < vr_num; idx++) {
00313     v = vr_index[idx];
00314     wrt_str(fp, v->name);
00315     wrt(fp, &(v->len), sizeof(short), 1);
00316     wrt(fp, v->vec, sizeof(VECT), v->len);
00317   }
00318   j_printf("%d variance written\n", vr_num);
00319 }
00320 
00328 static unsigned int
00329 search_vid(HTK_HMM_Var *v)
00330 {
00331   unsigned int left = 0;
00332   unsigned int right = vr_num - 1;
00333   unsigned int mid;
00334 
00335   while (left < right) {
00336     mid = (left + right) / 2;
00337     if (vr_index[mid] < v) {
00338       left = mid + 1;
00339     } else {
00340       right = mid;
00341     }
00342   }
00343   return(left);
00344 }
00345 
00346 
00347 /* write density data */
00348 static HTK_HMM_Dens **dens_index; 
00349 static unsigned int dens_num;   
00350 
00360 static int
00361 qsort_dens_index(HTK_HMM_Dens **d1, HTK_HMM_Dens **d2)
00362 {
00363   if (*d1 > *d2) return 1;
00364   else if (*d1 < *d2) return -1;
00365   else return 0;
00366 }
00367 
00381 static void
00382 wt_dens(FILE *fp, HTK_HMM_INFO *hmm)
00383 {
00384   HTK_HMM_Dens *d;
00385   unsigned int idx;
00386   unsigned int vid;
00387 
00388   dens_num = hmm->totalmixnum;
00389   dens_index = (HTK_HMM_Dens **)mymalloc(sizeof(HTK_HMM_Dens *) * dens_num);
00390   idx = 0;
00391   for(d = hmm->dnstart; d; d = d->next) dens_index[idx++] = d;
00392   qsort(dens_index, dens_num, sizeof(HTK_HMM_Dens *), (int (*)(const void *, const void *))qsort_dens_index);
00393   
00394   wrt(fp, &dens_num, sizeof(unsigned int), 1);
00395   for (idx = 0; idx < dens_num; idx++) {
00396     d = dens_index[idx];
00397     wrt_str(fp, d->name);
00398     wrt(fp, &(d->meanlen), sizeof(short), 1);
00399     wrt(fp, d->mean, sizeof(VECT), d->meanlen);
00400     vid = search_vid(d->var);
00401     /* for debug */
00402     if (d->var != vr_index[vid]) j_error("index not match!!! dens\n");
00403     wrt(fp, &vid, sizeof(unsigned int), 1);
00404     wrt(fp, &(d->gconst), sizeof(LOGPROB), 1);
00405   }
00406   j_printf("%d gaussian densities written\n", dens_num);
00407 }
00408 
00416 static unsigned int
00417 search_did(HTK_HMM_Dens *d)
00418 {
00419   unsigned int left = 0;
00420   unsigned int right = dens_num - 1;
00421   unsigned int mid;
00422 
00423   while (left < right) {
00424     mid = (left + right) / 2;
00425     if (dens_index[mid] < d) {
00426       left = mid + 1;
00427     } else {
00428       right = mid;
00429     }
00430   }
00431   return(left);
00432 }
00433 
00434 
00435 /* write tmix data */
00436 static GCODEBOOK **tm_index; 
00437 static unsigned int tm_num;     
00438 static unsigned int tm_idx;     
00439 
00445 static void
00446 tmix_list_callback(void *p)
00447 {
00448   GCODEBOOK *tm;
00449   tm = p;
00450   tm_index[tm_idx++] = tm;
00451 }
00452 
00462 static int
00463 qsort_tm_index(GCODEBOOK **tm1, GCODEBOOK **tm2)
00464 {
00465   if (*tm1 > *tm2) return 1;
00466   else if (*tm1 < *tm2) return -1;
00467   else return 0;
00468 }
00469 
00483 static void
00484 wt_tmix(FILE *fp, HTK_HMM_INFO *hmm)
00485 {
00486   GCODEBOOK *tm;
00487   unsigned int idx;
00488   unsigned int did;
00489   int i;
00490 
00491   tm_num = hmm->codebooknum;
00492   tm_index = (GCODEBOOK **)mymalloc(sizeof(GCODEBOOK *) * tm_num);
00493   tm_idx = 0;
00494   aptree_traverse_and_do(hmm->codebook_root, tmix_list_callback);
00495   qsort(tm_index, tm_num, sizeof(GCODEBOOK *), (int (*)(const void *, const void *))qsort_tm_index);  
00496 
00497   wrt(fp, &tm_num, sizeof(unsigned int), 1);
00498   for (idx = 0; idx < tm_num; idx++) {
00499     tm = tm_index[idx];
00500     wrt_str(fp, tm->name);
00501     wrt(fp, &(tm->num), sizeof(int), 1);
00502     for(i=0;i<tm->num;i++) {
00503       if (tm->d[i] == NULL) {
00504         did = dens_num;
00505       } else {
00506         did = search_did(tm->d[i]);
00507         /* for debug */
00508         if (tm->d[i] != dens_index[did]) j_error("index not match!!! dens\n");
00509       }
00510       wrt(fp, &did, sizeof(unsigned int), 1);
00511     }
00512   }
00513   j_printf("%d tied-mixture codebooks written\n", tm_num);
00514 }
00515 
00523 static unsigned int
00524 search_tmid(GCODEBOOK *tm)
00525 {
00526   unsigned int left = 0;
00527   unsigned int right = tm_num - 1;
00528   unsigned int mid;
00529 
00530   while (left < right) {
00531     mid = (left + right) / 2;
00532     if (tm_index[mid] < tm) {
00533       left = mid + 1;
00534     } else {
00535       right = mid;
00536     }
00537   }
00538   return(left);
00539 }
00540 
00541 
00542 /* write state data */
00543 static HTK_HMM_State **st_index; 
00544 static unsigned int st_num;     
00545 
00555 static int
00556 qsort_st_index(HTK_HMM_State **s1, HTK_HMM_State **s2)
00557 {
00558   if (*s1 > *s2) return 1;
00559   else if (*s1 < *s2) return -1;
00560   else return 0;
00561 }
00562 
00576 static void
00577 wt_state(FILE *fp, HTK_HMM_INFO *hmm)
00578 {
00579   HTK_HMM_State *s;
00580   unsigned int idx;
00581   unsigned int did;
00582   int i;
00583   short dummy;
00584 
00585   st_num = hmm->totalstatenum;
00586   st_index = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * st_num);
00587   idx = 0;
00588   for(s = hmm->ststart; s; s = s->next) st_index[idx++] = s;
00589   qsort(st_index, st_num, sizeof(HTK_HMM_State *), (int (*)(const void *, const void *))qsort_st_index);
00590   
00591   wrt(fp, &st_num, sizeof(unsigned int), 1);
00592   for (idx = 0; idx < st_num; idx++) {
00593     s = st_index[idx];
00594     wrt_str(fp, s->name);
00595     if (hmm->is_tied_mixture) {
00596       /* try tmix */
00597       did = search_tmid((GCODEBOOK *)(s->b));
00598       if ((GCODEBOOK *)s->b == tm_index[did]) {
00599         /* tmix */
00600         dummy = -1;
00601         wrt(fp, &dummy, sizeof(short), 1);
00602         wrt(fp, &did, sizeof(unsigned int), 1);
00603       } else {
00604         /* tmix failed -> normal mixture */
00605         wrt(fp, &(s->mix_num), sizeof(short), 1);
00606         for (i=0;i<s->mix_num;i++) {
00607           if (s->b[i] == NULL) {
00608             did = dens_num;
00609           } else {
00610             did = search_did(s->b[i]);
00611             if (s->b[i] != dens_index[did]) {
00612               j_error("index not match!!!");
00613             }
00614           }
00615           wrt(fp, &did, sizeof(unsigned int), 1);
00616         }
00617       }
00618     } else {                    /* not tied mixture */
00619       wrt(fp, &(s->mix_num), sizeof(short), 1);
00620       for (i=0;i<s->mix_num;i++) {
00621         if (s->b[i] == NULL) {
00622           did = dens_num;
00623         } else {
00624           did = search_did(s->b[i]);
00625           if (s->b[i] != dens_index[did]) {
00626             j_error("index not match!!!");
00627           }
00628         }
00629         wrt(fp, &did, sizeof(unsigned int), 1);
00630       }
00631     }
00632     wrt(fp, s->bweight, sizeof(PROB), s->mix_num);
00633   }
00634   j_printf("%d states written\n", st_num);
00635 }
00636 
00644 static unsigned int
00645 search_stid(HTK_HMM_State *s)
00646 {
00647   unsigned int left = 0;
00648   unsigned int right = st_num - 1;
00649   unsigned int mid;
00650 
00651   while (left < right) {
00652     mid = (left + right) / 2;
00653     if (st_index[mid] < s) {
00654       left = mid + 1;
00655     } else {
00656       right = mid;
00657     }
00658   }
00659   return(left);
00660 }
00661 
00662 
00674 static void
00675 wt_data(FILE *fp, HTK_HMM_INFO *hmm)
00676 {
00677   HTK_HMM_Data *d;
00678   unsigned int md_num;
00679   unsigned int sid, tid;
00680   int i;
00681 
00682   md_num = hmm->totalhmmnum;
00683 
00684   wrt(fp, &(md_num), sizeof(unsigned int), 1);
00685   for(d = hmm->start; d; d = d->next) {
00686     wrt_str(fp, d->name);
00687     wrt(fp, &(d->state_num), sizeof(short), 1);
00688     for (i=0;i<d->state_num;i++) {
00689       if (d->s[i] != NULL) {
00690         sid = search_stid(d->s[i]);
00691         /* for debug */
00692         if (d->s[i] != st_index[sid]) j_error("index not match!!! data state\n");
00693       } else {
00694         sid = hmm->totalstatenum + 1; /* error value */
00695       }
00696       wrt(fp, &sid, sizeof(unsigned int), 1);
00697     }
00698     tid = search_trid(d->tr);
00699     /* for debug */
00700     if (d->tr != tr_index[tid]) j_error("index not match!!! data trans\n");
00701     wrt(fp, &tid, sizeof(unsigned int), 1);
00702   }
00703   j_printf("%d HMM model definition written\n", md_num);
00704 }
00705 
00706 
00716 boolean
00717 write_binhmm(FILE *fp, HTK_HMM_INFO *hmm, Value *para)
00718 {
00719 
00720   /* write header */
00721   wt_header(fp, (para ? TRUE : FALSE), hmm->variance_inversed);
00722 
00723   if (para) {
00724     /* write acoustic analysis parameter info */
00725     wt_para(fp, para);
00726   }
00727   
00728   /* write option data */
00729   wt_opt(fp, &(hmm->opt));
00730 
00731   /* write type data */
00732   wt_type(fp, hmm);
00733 
00734   /* write transition data */
00735   wt_trans(fp, hmm);
00736 
00737   /* write variance data */
00738   wt_var(fp, hmm);
00739 
00740   /* write density data */
00741   wt_dens(fp, hmm);
00742 
00743   /* write tmix data */
00744   if (hmm->is_tied_mixture) {
00745     wt_tmix(fp, hmm);
00746   }
00747 
00748   /* write state data */
00749   wt_state(fp, hmm);
00750 
00751   /* write model data */
00752   wt_data(fp, hmm);
00753 
00754   /* free pointer->index work area */
00755   free(tr_index);
00756   free(vr_index);
00757   free(dens_index);
00758   if (hmm->is_tied_mixture) free(tm_index);
00759   free(st_index);
00760 
00761   return (TRUE);
00762 }

Generated on Tue Dec 26 12:53:22 2006 for Julian by  doxygen 1.5.0