libsent/src/hmminfo/write_binhmm.c

Go to the documentation of this file.
00001 
00028 /*
00029  * Copyright (c) 2003-2005 Shikano Lab., Nara Institute of Science and Technology
00030  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00031  * All rights reserved
00032  */
00033 
00034 /* $Id: write_binhmm.c,v 1.1.1.1 2007/09/28 02:50:56 sumomo Exp $ */
00035 
00036 #include <sent/stddefs.h>
00037 #include <sent/htk_param.h>
00038 #include <sent/htk_hmm.h>
00039 #include <sent/mfcc.h>
00040 
00041 #define wrt(A,B,C,D) if (wrtfunc(A,B,C,D) == FALSE) return FALSE
00042 #define wrt_str(A,B) if (wrt_strfunc(A,B) == FALSE) return FALSE
00043 
00044 
00053 static boolean
00054 wrtfunc(FILE *fp, void *buf, size_t unitbyte, size_t unitnum)
00055 {
00056 #ifndef WORDS_BIGENDIAN
00057   if (unitbyte != 1) {
00058     swap_bytes((char *)buf, unitbyte, unitnum);
00059   }
00060 #endif
00061   if (myfwrite(buf, unitbyte, unitnum, fp) < unitnum) {
00062     jlog("Error: write_binhmm: failed to write %d bytes", unitbyte * unitnum);
00063     return FALSE;
00064   }
00065 #ifndef WORDS_BIGENDIAN
00066   if (unitbyte != 1) {
00067     swap_bytes((char *)buf, unitbyte, unitnum);
00068   }
00069 #endif
00070   return TRUE;
00071 }
00072 
00079 static boolean
00080 wrt_strfunc(FILE *fp, char *str)
00081 {
00082   static char noname = '\0';
00083   boolean ret;
00084   
00085   if (str) {
00086     ret = wrtfunc(fp, str, sizeof(char), strlen(str)+1);
00087   } else {
00088     ret = wrtfunc(fp, &noname, sizeof(char), 1);
00089   }
00090   return ret;
00091 }
00092 
00093 
00094 static char *binhmm_header_v2 = BINHMM_HEADER_V2; 
00095 
00101 static boolean
00102 wt_header(FILE *fp, boolean emp, boolean inv)
00103 {
00104   char buf[50];
00105   char *p;
00106 
00107   wrt_str(fp, binhmm_header_v2);
00108   p = &(buf[0]);
00109   if (emp) {
00110     *p++ = '_';
00111     *p++ = BINHMM_HEADER_V2_EMBEDPARA;
00112   }
00113   if (inv) {
00114     *p++ = '_';
00115     *p++ = BINHMM_HEADER_V2_VARINV;
00116   }
00117   *p = '\0';
00118   wrt_str(fp, buf);
00119 
00120   return TRUE;
00121 }
00122 
00123 
00130 static boolean
00131 wt_para(FILE *fp, Value *para)
00132 {
00133   short version;
00134 
00135   version = VALUE_VERSION;
00136   wrt(fp, &version, sizeof(short), 1);
00137 
00138   wrt(fp, &(para->smp_period), sizeof(long), 1);      
00139   wrt(fp, &(para->smp_freq), sizeof(long), 1);  
00140   wrt(fp, &(para->framesize), sizeof(int), 1);        
00141   wrt(fp, &(para->frameshift), sizeof(int), 1);       
00142   wrt(fp, &(para->preEmph), sizeof(float), 1);        
00143   wrt(fp, &(para->lifter), sizeof(int), 1);           
00144   wrt(fp, &(para->fbank_num), sizeof(int), 1);        
00145   wrt(fp, &(para->delWin), sizeof(int), 1);           
00146   wrt(fp, &(para->accWin), sizeof(int), 1);           
00147   wrt(fp, &(para->silFloor), sizeof(float), 1);       
00148   wrt(fp, &(para->escale), sizeof(float), 1);         
00149   wrt(fp, &(para->hipass), sizeof(int), 1);             
00150   wrt(fp, &(para->lopass), sizeof(int), 1);             
00151   wrt(fp, &(para->enormal), sizeof(int), 1);          
00152   wrt(fp, &(para->raw_e), sizeof(int), 1);            
00153   wrt(fp, &(para->zmeanframe), sizeof(int), 1); 
00154 
00155   return TRUE;
00156 }
00157 
00158 
00165 static boolean
00166 wt_opt(FILE *fp, HTK_HMM_Options *opt)
00167 {
00168   wrt(fp, &(opt->stream_info.num), sizeof(short), 1);
00169   wrt(fp, opt->stream_info.vsize, sizeof(short), 50);
00170   wrt(fp, &(opt->vec_size), sizeof(short), 1);
00171   wrt(fp, &(opt->cov_type), sizeof(short), 1);
00172   wrt(fp, &(opt->dur_type), sizeof(short), 1);
00173   wrt(fp, &(opt->param_type), sizeof(short), 1);
00174   return TRUE;
00175 }
00176 
00183 static boolean
00184 wt_type(FILE *fp, HTK_HMM_INFO *hmm)
00185 {
00186   wrt(fp, &(hmm->is_tied_mixture), sizeof(boolean), 1);
00187   wrt(fp, &(hmm->maxmixturenum), sizeof(int), 1);
00188   return TRUE;
00189 }
00190 
00191 
00192 /* write transition data */
00193 static HTK_HMM_Trans **tr_index; 
00194 static unsigned int tr_num;     
00195 
00205 static int
00206 qsort_tr_index(HTK_HMM_Trans **t1, HTK_HMM_Trans **t2)
00207 {
00208   if (*t1 > *t2) return 1;
00209   else if (*t1 < *t2) return -1;
00210   else return 0;
00211 }
00212 
00224 static boolean
00225 wt_trans(FILE *fp, HTK_HMM_INFO *hmm)
00226 {
00227   HTK_HMM_Trans *t;
00228   unsigned int idx;
00229   int i;
00230 
00231   tr_num = 0;
00232   for(t = hmm->trstart; t; t = t->next) tr_num++;
00233   tr_index = (HTK_HMM_Trans **)mymalloc(sizeof(HTK_HMM_Trans *) * tr_num);
00234   idx = 0;
00235   for(t = hmm->trstart; t; t = t->next) tr_index[idx++] = t;
00236   qsort(tr_index, tr_num, sizeof(HTK_HMM_Trans *), (int (*)(const void *, const void *))qsort_tr_index);
00237   
00238   wrt(fp, &tr_num, sizeof(unsigned int), 1);
00239   for (idx = 0; idx < tr_num; idx++) {
00240     t = tr_index[idx];
00241     wrt_str(fp, t->name);
00242     wrt(fp, &(t->statenum), sizeof(short), 1);
00243     for(i=0;i<t->statenum;i++) {
00244       wrt(fp, t->a[i], sizeof(PROB), t->statenum);
00245     }
00246   }
00247 
00248   jlog("Stat: write_binhmm: %d transition maxtix written\n", tr_num);
00249 
00250   return TRUE;
00251 }
00252 
00260 static unsigned int
00261 search_trid(HTK_HMM_Trans *t)
00262 {
00263   unsigned int left = 0;
00264   unsigned int right = tr_num - 1;
00265   unsigned int mid;
00266 
00267   while (left < right) {
00268     mid = (left + right) / 2;
00269     if (tr_index[mid] < t) {
00270       left = mid + 1;
00271     } else {
00272       right = mid;
00273     }
00274   }
00275   return(left);
00276 }
00277 
00278 
00279 /* write variance data */
00280 static HTK_HMM_Var **vr_index;  
00281 static unsigned int vr_num;     
00282 
00292 static int
00293 qsort_vr_index(HTK_HMM_Var **v1, HTK_HMM_Var **v2)
00294 {
00295   if (*v1 > *v2) return 1;
00296   else if (*v1 < *v2) return -1;
00297   else return 0;
00298 }
00299 
00311 static boolean
00312 wt_var(FILE *fp, HTK_HMM_INFO *hmm)
00313 {
00314   HTK_HMM_Var *v;
00315   unsigned int idx;
00316 
00317   vr_num = 0;
00318   for(v = hmm->vrstart; v; v = v->next) vr_num++;
00319   vr_index = (HTK_HMM_Var **)mymalloc(sizeof(HTK_HMM_Var *) * vr_num);
00320   idx = 0;
00321   for(v = hmm->vrstart; v; v = v->next) vr_index[idx++] = v;
00322   qsort(vr_index, vr_num, sizeof(HTK_HMM_Var *), (int (*)(const void *, const void *))qsort_vr_index);  
00323 
00324   wrt(fp, &vr_num, sizeof(unsigned int), 1);
00325   for (idx = 0; idx < vr_num; idx++) {
00326     v = vr_index[idx];
00327     wrt_str(fp, v->name);
00328     wrt(fp, &(v->len), sizeof(short), 1);
00329     wrt(fp, v->vec, sizeof(VECT), v->len);
00330   }
00331   jlog("Stat: write_binhmm: %d variance written\n", vr_num);
00332 
00333   return TRUE;
00334 }
00335 
00343 static unsigned int
00344 search_vid(HTK_HMM_Var *v)
00345 {
00346   unsigned int left = 0;
00347   unsigned int right = vr_num - 1;
00348   unsigned int mid;
00349 
00350   while (left < right) {
00351     mid = (left + right) / 2;
00352     if (vr_index[mid] < v) {
00353       left = mid + 1;
00354     } else {
00355       right = mid;
00356     }
00357   }
00358   return(left);
00359 }
00360 
00361 
00362 /* write density data */
00363 static HTK_HMM_Dens **dens_index; 
00364 static unsigned int dens_num;   
00365 
00375 static int
00376 qsort_dens_index(HTK_HMM_Dens **d1, HTK_HMM_Dens **d2)
00377 {
00378   if (*d1 > *d2) return 1;
00379   else if (*d1 < *d2) return -1;
00380   else return 0;
00381 }
00382 
00396 static boolean
00397 wt_dens(FILE *fp, HTK_HMM_INFO *hmm)
00398 {
00399   HTK_HMM_Dens *d;
00400   unsigned int idx;
00401   unsigned int vid;
00402 
00403   dens_num = hmm->totalmixnum;
00404   dens_index = (HTK_HMM_Dens **)mymalloc(sizeof(HTK_HMM_Dens *) * dens_num);
00405   idx = 0;
00406   for(d = hmm->dnstart; d; d = d->next) dens_index[idx++] = d;
00407   qsort(dens_index, dens_num, sizeof(HTK_HMM_Dens *), (int (*)(const void *, const void *))qsort_dens_index);
00408   
00409   wrt(fp, &dens_num, sizeof(unsigned int), 1);
00410   for (idx = 0; idx < dens_num; idx++) {
00411     d = dens_index[idx];
00412     wrt_str(fp, d->name);
00413     wrt(fp, &(d->meanlen), sizeof(short), 1);
00414     wrt(fp, d->mean, sizeof(VECT), d->meanlen);
00415     vid = search_vid(d->var);
00416     /* for debug */
00417     if (d->var != vr_index[vid]) {
00418       jlog("Error: write_binhmm: index not match!!!\n");
00419       return FALSE;
00420     }
00421     wrt(fp, &vid, sizeof(unsigned int), 1);
00422     wrt(fp, &(d->gconst), sizeof(LOGPROB), 1);
00423   }
00424   jlog("Stat: write_binhmm: %d gaussian densities written\n", dens_num);
00425 
00426   return TRUE;
00427 }
00428 
00436 static unsigned int
00437 search_did(HTK_HMM_Dens *d)
00438 {
00439   unsigned int left = 0;
00440   unsigned int right = dens_num - 1;
00441   unsigned int mid;
00442 
00443   while (left < right) {
00444     mid = (left + right) / 2;
00445     if (dens_index[mid] < d) {
00446       left = mid + 1;
00447     } else {
00448       right = mid;
00449     }
00450   }
00451   return(left);
00452 }
00453 
00454 
00455 /* write tmix data */
00456 static GCODEBOOK **tm_index; 
00457 static unsigned int tm_num;     
00458 static unsigned int tm_idx;     
00459 
00465 static void
00466 tmix_list_callback(void *p)
00467 {
00468   GCODEBOOK *tm;
00469   tm = p;
00470   tm_index[tm_idx++] = tm;
00471 }
00472 
00482 static int
00483 qsort_tm_index(GCODEBOOK **tm1, GCODEBOOK **tm2)
00484 {
00485   if (*tm1 > *tm2) return 1;
00486   else if (*tm1 < *tm2) return -1;
00487   else return 0;
00488 }
00489 
00503 static boolean
00504 wt_tmix(FILE *fp, HTK_HMM_INFO *hmm)
00505 {
00506   GCODEBOOK *tm;
00507   unsigned int idx;
00508   unsigned int did;
00509   int i;
00510 
00511   tm_num = hmm->codebooknum;
00512   tm_index = (GCODEBOOK **)mymalloc(sizeof(GCODEBOOK *) * tm_num);
00513   tm_idx = 0;
00514   aptree_traverse_and_do(hmm->codebook_root, tmix_list_callback);
00515   qsort(tm_index, tm_num, sizeof(GCODEBOOK *), (int (*)(const void *, const void *))qsort_tm_index);  
00516 
00517   wrt(fp, &tm_num, sizeof(unsigned int), 1);
00518   for (idx = 0; idx < tm_num; idx++) {
00519     tm = tm_index[idx];
00520     wrt_str(fp, tm->name);
00521     wrt(fp, &(tm->num), sizeof(int), 1);
00522     for(i=0;i<tm->num;i++) {
00523       if (tm->d[i] == NULL) {
00524         did = dens_num;
00525       } else {
00526         did = search_did(tm->d[i]);
00527         /* for debug */
00528         if (tm->d[i] != dens_index[did]) {
00529           jlog("Error: write_binhmm: index not match!!!\n");
00530           return FALSE;
00531         }
00532       }
00533       wrt(fp, &did, sizeof(unsigned int), 1);
00534     }
00535   }
00536   jlog("Stat: write_binhmm: %d tied-mixture codebooks written\n", tm_num);
00537 
00538   return TRUE;
00539 }
00540 
00548 static unsigned int
00549 search_tmid(GCODEBOOK *tm)
00550 {
00551   unsigned int left = 0;
00552   unsigned int right = tm_num - 1;
00553   unsigned int mid;
00554 
00555   while (left < right) {
00556     mid = (left + right) / 2;
00557     if (tm_index[mid] < tm) {
00558       left = mid + 1;
00559     } else {
00560       right = mid;
00561     }
00562   }
00563   return(left);
00564 }
00565 
00566 
00567 /* write state data */
00568 static HTK_HMM_State **st_index; 
00569 static unsigned int st_num;     
00570 
00580 static int
00581 qsort_st_index(HTK_HMM_State **s1, HTK_HMM_State **s2)
00582 {
00583   if (*s1 > *s2) return 1;
00584   else if (*s1 < *s2) return -1;
00585   else return 0;
00586 }
00587 
00601 static boolean
00602 wt_state(FILE *fp, HTK_HMM_INFO *hmm)
00603 {
00604   HTK_HMM_State *s;
00605   unsigned int idx;
00606   unsigned int did;
00607   int i;
00608   short dummy;
00609 
00610   st_num = hmm->totalstatenum;
00611   st_index = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * st_num);
00612   idx = 0;
00613   for(s = hmm->ststart; s; s = s->next) st_index[idx++] = s;
00614   qsort(st_index, st_num, sizeof(HTK_HMM_State *), (int (*)(const void *, const void *))qsort_st_index);
00615   
00616   wrt(fp, &st_num, sizeof(unsigned int), 1);
00617   for (idx = 0; idx < st_num; idx++) {
00618     s = st_index[idx];
00619     wrt_str(fp, s->name);
00620     if (hmm->is_tied_mixture) {
00621       /* try tmix */
00622       did = search_tmid((GCODEBOOK *)(s->b));
00623       if ((GCODEBOOK *)s->b == tm_index[did]) {
00624         /* tmix */
00625         dummy = -1;
00626         wrt(fp, &dummy, sizeof(short), 1);
00627         wrt(fp, &did, sizeof(unsigned int), 1);
00628       } else {
00629         /* tmix failed -> normal mixture */
00630         wrt(fp, &(s->mix_num), sizeof(short), 1);
00631         for (i=0;i<s->mix_num;i++) {
00632           if (s->b[i] == NULL) {
00633             did = dens_num;
00634           } else {
00635             did = search_did(s->b[i]);
00636             if (s->b[i] != dens_index[did]) {
00637               jlog("Error: write_binhmm: index not match!!!\n");
00638               return FALSE;
00639             }
00640           }
00641           wrt(fp, &did, sizeof(unsigned int), 1);
00642         }
00643       }
00644     } else {                    /* not tied mixture */
00645       wrt(fp, &(s->mix_num), sizeof(short), 1);
00646       for (i=0;i<s->mix_num;i++) {
00647         if (s->b[i] == NULL) {
00648           did = dens_num;
00649         } else {
00650           did = search_did(s->b[i]);
00651           if (s->b[i] != dens_index[did]) {
00652             jlog("Error: write_binhmm: index not match!!!\n");
00653             return FALSE;
00654           }
00655         }
00656         wrt(fp, &did, sizeof(unsigned int), 1);
00657       }
00658     }
00659     wrt(fp, s->bweight, sizeof(PROB), s->mix_num);
00660   }
00661   jlog("Stat: write_binhmm: %d states written\n", st_num);
00662 
00663   return TRUE;
00664 }
00665 
00673 static unsigned int
00674 search_stid(HTK_HMM_State *s)
00675 {
00676   unsigned int left = 0;
00677   unsigned int right = st_num - 1;
00678   unsigned int mid;
00679 
00680   while (left < right) {
00681     mid = (left + right) / 2;
00682     if (st_index[mid] < s) {
00683       left = mid + 1;
00684     } else {
00685       right = mid;
00686     }
00687   }
00688   return(left);
00689 }
00690 
00691 
00703 static boolean
00704 wt_data(FILE *fp, HTK_HMM_INFO *hmm)
00705 {
00706   HTK_HMM_Data *d;
00707   unsigned int md_num;
00708   unsigned int sid, tid;
00709   int i;
00710 
00711   md_num = hmm->totalhmmnum;
00712 
00713   wrt(fp, &(md_num), sizeof(unsigned int), 1);
00714   for(d = hmm->start; d; d = d->next) {
00715     wrt_str(fp, d->name);
00716     wrt(fp, &(d->state_num), sizeof(short), 1);
00717     for (i=0;i<d->state_num;i++) {
00718       if (d->s[i] != NULL) {
00719         sid = search_stid(d->s[i]);
00720         /* for debug */
00721         if (d->s[i] != st_index[sid]) {
00722           jlog("Error: write_binhmm: index not match!!!\n");
00723           return FALSE;
00724         }
00725       } else {
00726         sid = hmm->totalstatenum + 1; /* error value */
00727       }
00728       wrt(fp, &sid, sizeof(unsigned int), 1);
00729     }
00730     tid = search_trid(d->tr);
00731     /* for debug */
00732     if (d->tr != tr_index[tid]) {
00733       jlog("Error: write_binhmm: index not match!!!\n");
00734       return FALSE;
00735     }
00736     wrt(fp, &tid, sizeof(unsigned int), 1);
00737   }
00738   jlog("Stat: write_binhmm: %d HMM model definition written\n", md_num);
00739   return TRUE;
00740 }
00741 
00742 
00752 boolean
00753 write_binhmm(FILE *fp, HTK_HMM_INFO *hmm, Value *para)
00754 {
00755 
00756   /* write header */
00757   if (wt_header(fp, (para ? TRUE : FALSE), hmm->variance_inversed) == FALSE) {
00758     jlog("Error: write_binhmm: failed to write header\n");
00759     return FALSE;
00760   }
00761 
00762   if (para) {
00763     /* write acoustic analysis parameter info */
00764     if (wt_para(fp, para) == FALSE) {
00765       jlog("Error: write_binhmm: failed to write acoustic analysis parameters\n");
00766       return FALSE;
00767     }
00768   }
00769   
00770   /* write option data */
00771   if (wt_opt(fp, &(hmm->opt)) == FALSE) {
00772     jlog("Error: write_binhmm: failed to write option data\n");
00773     return FALSE;
00774   }
00775 
00776   /* write type data */
00777   if (wt_type(fp, hmm) == FALSE) {
00778     jlog("Error: write_binhmm: failed to write HMM type data\n");
00779     return FALSE;
00780   }
00781 
00782   /* write transition data */
00783   if (wt_trans(fp, hmm) == FALSE) {
00784     jlog("Error: write_binhmm: failed to write HMM transition data\n");
00785     return FALSE;
00786   }
00787 
00788   /* write variance data */
00789   if (wt_var(fp, hmm) == FALSE) {
00790     jlog("Error: write_binhmm: failed to write HMM variance data\n");
00791     return FALSE;
00792   }
00793 
00794   /* write density data */
00795   if (wt_dens(fp, hmm) == FALSE) {
00796     jlog("Error: write_binhmm: failed to write density data\n");
00797     return FALSE;
00798   }
00799 
00800   /* write tmix data */
00801   if (hmm->is_tied_mixture) {
00802     if (wt_tmix(fp, hmm) == FALSE) {
00803       jlog("Error: write_binhmm: failed to write tied-mixture codebook data\n");
00804       return FALSE;
00805     }
00806   }
00807 
00808   /* write state data */
00809   if (wt_state(fp, hmm) == FALSE) {
00810     jlog("Error: write_binhmm: failed to write HMM state data\n");
00811     return FALSE;
00812   }
00813 
00814   /* write model data */
00815   if (wt_data(fp, hmm) == FALSE) {
00816     jlog("Error: write_binhmm: failed to write HMM data\n");
00817     return FALSE;
00818   }
00819 
00820   /* free pointer->index work area */
00821   free(tr_index);
00822   free(vr_index);
00823   free(dens_index);
00824   if (hmm->is_tied_mixture) free(tm_index);
00825   free(st_index);
00826 
00827   return (TRUE);
00828 }

Generated on Tue Dec 18 15:59:55 2007 for Julius by  doxygen 1.5.4