メインページ | モジュール | データ構造 | Directories | ファイル一覧 | データフィールド | グローバル | 関連ページ

write_binhmm.c

説明を見る。
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, Nagoya Institute of Technology
00030  * All rights reserved
00031  */
00032 
00033 /* $Id: write_binhmm.c,v 1.1.1.1 2005/11/17 11:11:49 sumomo Exp $ */
00034 
00035 #include <sent/stddefs.h>
00036 #include <sent/htk_param.h>
00037 #include <sent/htk_hmm.h>
00038 
00039 
00048 static void
00049 wrt(FILE *fp, void *buf, size_t unitbyte, int unitnum)
00050 {
00051 #ifndef WORDS_BIGENDIAN
00052   if (unitbyte != 1) {
00053     swap_bytes((char *)buf, unitbyte, unitnum);
00054   }
00055 #endif
00056   if (myfwrite(buf, unitbyte, unitnum, fp) < unitnum) {
00057     perror("write_binhmm: wrt");
00058     j_error("write failed\n");
00059   }
00060 #ifndef WORDS_BIGENDIAN
00061   if (unitbyte != 1) {
00062     swap_bytes((char *)buf, unitbyte, unitnum);
00063   }
00064 #endif
00065 }
00066 
00073 static void
00074 wrt_str(FILE *fp, char *str)
00075 {
00076   static char noname = '\0';
00077   
00078   if (str) {
00079     wrt(fp, str, sizeof(char), strlen(str)+1);
00080   } else {
00081     wrt(fp, &noname, sizeof(char), 1);
00082   }
00083 }
00084 
00085 
00086 static char *binhmm_header = BINHMM_HEADER; 
00087 
00092 static void
00093 wt_header(FILE *fp)
00094 {
00095   wrt_str(fp, binhmm_header);
00096 }
00097 
00098 
00105 static void
00106 wt_opt(FILE *fp, HTK_HMM_Options *opt)
00107 {
00108   wrt(fp, &(opt->stream_info.num), sizeof(short), 1);
00109   wrt(fp, opt->stream_info.vsize, sizeof(short), 50);
00110   wrt(fp, &(opt->vec_size), sizeof(short), 1);
00111   wrt(fp, &(opt->cov_type), sizeof(short), 1);
00112   wrt(fp, &(opt->dur_type), sizeof(short), 1);
00113   wrt(fp, &(opt->param_type), sizeof(short), 1);
00114 }
00115 
00122 static void
00123 wt_type(FILE *fp, HTK_HMM_INFO *hmm)
00124 {
00125   wrt(fp, &(hmm->is_tied_mixture), sizeof(boolean), 1);
00126   wrt(fp, &(hmm->maxmixturenum), sizeof(int), 1);
00127 }
00128 
00129 
00130 /* write transition data */
00131 static HTK_HMM_Trans **tr_index; 
00132 static unsigned int tr_num;     
00133 
00143 static int
00144 qsort_tr_index(HTK_HMM_Trans **t1, HTK_HMM_Trans **t2)
00145 {
00146   if (*t1 > *t2) return 1;
00147   else if (*t1 < *t2) return -1;
00148   else return 0;
00149 }
00150 
00162 static void
00163 wt_trans(FILE *fp, HTK_HMM_INFO *hmm)
00164 {
00165   HTK_HMM_Trans *t;
00166   unsigned int idx;
00167   int i;
00168 
00169   tr_num = 0;
00170   for(t = hmm->trstart; t; t = t->next) tr_num++;
00171   tr_index = (HTK_HMM_Trans **)mymalloc(sizeof(HTK_HMM_Trans *) * tr_num);
00172   idx = 0;
00173   for(t = hmm->trstart; t; t = t->next) tr_index[idx++] = t;
00174   qsort(tr_index, tr_num, sizeof(HTK_HMM_Trans *), (int (*)(const void *, const void *))qsort_tr_index);
00175   
00176   wrt(fp, &tr_num, sizeof(unsigned int), 1);
00177   for (idx = 0; idx < tr_num; idx++) {
00178     t = tr_index[idx];
00179     wrt_str(fp, t->name);
00180     wrt(fp, &(t->statenum), sizeof(short), 1);
00181     for(i=0;i<t->statenum;i++) {
00182       wrt(fp, t->a[i], sizeof(PROB), t->statenum);
00183     }
00184   }
00185 
00186   j_printf("%d transition maxtix written\n", tr_num);
00187 }
00188 
00196 static unsigned int
00197 search_trid(HTK_HMM_Trans *t)
00198 {
00199   unsigned int left = 0;
00200   unsigned int right = tr_num - 1;
00201   unsigned int mid;
00202 
00203   while (left < right) {
00204     mid = (left + right) / 2;
00205     if (tr_index[mid] < t) {
00206       left = mid + 1;
00207     } else {
00208       right = mid;
00209     }
00210   }
00211   return(left);
00212 }
00213 
00214 
00215 /* write variance data */
00216 static HTK_HMM_Var **vr_index;  
00217 static unsigned int vr_num;     
00218 
00228 static int
00229 qsort_vr_index(HTK_HMM_Var **v1, HTK_HMM_Var **v2)
00230 {
00231   if (*v1 > *v2) return 1;
00232   else if (*v1 < *v2) return -1;
00233   else return 0;
00234 }
00235 
00247 static void
00248 wt_var(FILE *fp, HTK_HMM_INFO *hmm)
00249 {
00250   HTK_HMM_Var *v;
00251   unsigned int idx;
00252 
00253   vr_num = 0;
00254   for(v = hmm->vrstart; v; v = v->next) vr_num++;
00255   vr_index = (HTK_HMM_Var **)mymalloc(sizeof(HTK_HMM_Var *) * vr_num);
00256   idx = 0;
00257   for(v = hmm->vrstart; v; v = v->next) vr_index[idx++] = v;
00258   qsort(vr_index, vr_num, sizeof(HTK_HMM_Var *), (int (*)(const void *, const void *))qsort_vr_index);  
00259 
00260   wrt(fp, &vr_num, sizeof(unsigned int), 1);
00261   for (idx = 0; idx < vr_num; idx++) {
00262     v = vr_index[idx];
00263     wrt_str(fp, v->name);
00264     wrt(fp, &(v->len), sizeof(short), 1);
00265     wrt(fp, v->vec, sizeof(VECT), v->len);
00266   }
00267   j_printf("%d variance written\n", vr_num);
00268 }
00269 
00277 static unsigned int
00278 search_vid(HTK_HMM_Var *v)
00279 {
00280   unsigned int left = 0;
00281   unsigned int right = vr_num - 1;
00282   unsigned int mid;
00283 
00284   while (left < right) {
00285     mid = (left + right) / 2;
00286     if (vr_index[mid] < v) {
00287       left = mid + 1;
00288     } else {
00289       right = mid;
00290     }
00291   }
00292   return(left);
00293 }
00294 
00295 
00296 /* write density data */
00297 static HTK_HMM_Dens **dens_index; 
00298 static unsigned int dens_num;   
00299 
00309 static int
00310 qsort_dens_index(HTK_HMM_Dens **d1, HTK_HMM_Dens **d2)
00311 {
00312   if (*d1 > *d2) return 1;
00313   else if (*d1 < *d2) return -1;
00314   else return 0;
00315 }
00316 
00330 static void
00331 wt_dens(FILE *fp, HTK_HMM_INFO *hmm)
00332 {
00333   HTK_HMM_Dens *d;
00334   unsigned int idx;
00335   unsigned int vid;
00336 
00337   dens_num = hmm->totalmixnum;
00338   dens_index = (HTK_HMM_Dens **)mymalloc(sizeof(HTK_HMM_Dens *) * dens_num);
00339   idx = 0;
00340   for(d = hmm->dnstart; d; d = d->next) dens_index[idx++] = d;
00341   qsort(dens_index, dens_num, sizeof(HTK_HMM_Dens *), (int (*)(const void *, const void *))qsort_dens_index);
00342   
00343   wrt(fp, &dens_num, sizeof(unsigned int), 1);
00344   for (idx = 0; idx < dens_num; idx++) {
00345     d = dens_index[idx];
00346     wrt_str(fp, d->name);
00347     wrt(fp, &(d->meanlen), sizeof(short), 1);
00348     wrt(fp, d->mean, sizeof(VECT), d->meanlen);
00349     vid = search_vid(d->var);
00350     /* for debug */
00351     if (d->var != vr_index[vid]) j_error("index not match!!! dens\n");
00352     wrt(fp, &vid, sizeof(unsigned int), 1);
00353     wrt(fp, &(d->gconst), sizeof(LOGPROB), 1);
00354   }
00355   j_printf("%d gaussian densities written\n", dens_num);
00356 }
00357 
00365 static unsigned int
00366 search_did(HTK_HMM_Dens *d)
00367 {
00368   unsigned int left = 0;
00369   unsigned int right = dens_num - 1;
00370   unsigned int mid;
00371 
00372   while (left < right) {
00373     mid = (left + right) / 2;
00374     if (dens_index[mid] < d) {
00375       left = mid + 1;
00376     } else {
00377       right = mid;
00378     }
00379   }
00380   return(left);
00381 }
00382 
00383 
00384 /* write tmix data */
00385 static GCODEBOOK **tm_index; 
00386 static unsigned int tm_num;     
00387 static unsigned int tm_idx;     
00388 
00394 static void
00395 tmix_list_callback(void *p)
00396 {
00397   GCODEBOOK *tm;
00398   tm = p;
00399   tm_index[tm_idx++] = tm;
00400 }
00401 
00411 static int
00412 qsort_tm_index(GCODEBOOK **tm1, GCODEBOOK **tm2)
00413 {
00414   if (*tm1 > *tm2) return 1;
00415   else if (*tm1 < *tm2) return -1;
00416   else return 0;
00417 }
00418 
00432 static void
00433 wt_tmix(FILE *fp, HTK_HMM_INFO *hmm)
00434 {
00435   GCODEBOOK *tm;
00436   unsigned int idx;
00437   unsigned int did;
00438   int i;
00439 
00440   tm_num = hmm->codebooknum;
00441   tm_index = (GCODEBOOK **)mymalloc(sizeof(GCODEBOOK *) * tm_num);
00442   tm_idx = 0;
00443   aptree_traverse_and_do(hmm->codebook_root, tmix_list_callback);
00444   qsort(tm_index, tm_num, sizeof(GCODEBOOK *), (int (*)(const void *, const void *))qsort_tm_index);  
00445 
00446   wrt(fp, &tm_num, sizeof(unsigned int), 1);
00447   for (idx = 0; idx < tm_num; idx++) {
00448     tm = tm_index[idx];
00449     wrt_str(fp, tm->name);
00450     wrt(fp, &(tm->num), sizeof(int), 1);
00451     for(i=0;i<tm->num;i++) {
00452       if (tm->d[i] == NULL) {
00453         did = dens_num;
00454       } else {
00455         did = search_did(tm->d[i]);
00456         /* for debug */
00457         if (tm->d[i] != dens_index[did]) j_error("index not match!!! dens\n");
00458       }
00459       wrt(fp, &did, sizeof(unsigned int), 1);
00460     }
00461   }
00462   j_printf("%d tied-mixture codebooks written\n", tm_num);
00463 }
00464 
00472 static unsigned int
00473 search_tmid(GCODEBOOK *tm)
00474 {
00475   unsigned int left = 0;
00476   unsigned int right = tm_num - 1;
00477   unsigned int mid;
00478 
00479   while (left < right) {
00480     mid = (left + right) / 2;
00481     if (tm_index[mid] < tm) {
00482       left = mid + 1;
00483     } else {
00484       right = mid;
00485     }
00486   }
00487   return(left);
00488 }
00489 
00490 
00491 /* write state data */
00492 static HTK_HMM_State **st_index; 
00493 static unsigned int st_num;     
00494 
00504 static int
00505 qsort_st_index(HTK_HMM_State **s1, HTK_HMM_State **s2)
00506 {
00507   if (*s1 > *s2) return 1;
00508   else if (*s1 < *s2) return -1;
00509   else return 0;
00510 }
00511 
00525 static void
00526 wt_state(FILE *fp, HTK_HMM_INFO *hmm)
00527 {
00528   HTK_HMM_State *s;
00529   unsigned int idx;
00530   unsigned int did;
00531   int i;
00532   short dummy;
00533 
00534   st_num = hmm->totalstatenum;
00535   st_index = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * st_num);
00536   idx = 0;
00537   for(s = hmm->ststart; s; s = s->next) st_index[idx++] = s;
00538   qsort(st_index, st_num, sizeof(HTK_HMM_State *), (int (*)(const void *, const void *))qsort_st_index);
00539   
00540   wrt(fp, &st_num, sizeof(unsigned int), 1);
00541   for (idx = 0; idx < st_num; idx++) {
00542     s = st_index[idx];
00543     wrt_str(fp, s->name);
00544     if (hmm->is_tied_mixture) {
00545       /* try tmix */
00546       did = search_tmid((GCODEBOOK *)(s->b));
00547       if ((GCODEBOOK *)s->b == tm_index[did]) {
00548         /* tmix */
00549         dummy = -1;
00550         wrt(fp, &dummy, sizeof(short), 1);
00551         wrt(fp, &did, sizeof(unsigned int), 1);
00552       } else {
00553         /* tmix failed -> normal mixture */
00554         wrt(fp, &(s->mix_num), sizeof(short), 1);
00555         for (i=0;i<s->mix_num;i++) {
00556           if (s->b[i] == NULL) {
00557             did = dens_num;
00558           } else {
00559             did = search_did(s->b[i]);
00560             if (s->b[i] != dens_index[did]) {
00561               j_error("index not match!!!");
00562             }
00563           }
00564           wrt(fp, &did, sizeof(unsigned int), 1);
00565         }
00566       }
00567     } else {                    /* not tied mixture */
00568       wrt(fp, &(s->mix_num), sizeof(short), 1);
00569       for (i=0;i<s->mix_num;i++) {
00570         if (s->b[i] == NULL) {
00571           did = dens_num;
00572         } else {
00573           did = search_did(s->b[i]);
00574           if (s->b[i] != dens_index[did]) {
00575             j_error("index not match!!!");
00576           }
00577         }
00578         wrt(fp, &did, sizeof(unsigned int), 1);
00579       }
00580     }
00581     wrt(fp, s->bweight, sizeof(PROB), s->mix_num);
00582   }
00583   j_printf("%d states written\n", st_num);
00584 }
00585 
00593 static unsigned int
00594 search_stid(HTK_HMM_State *s)
00595 {
00596   unsigned int left = 0;
00597   unsigned int right = st_num - 1;
00598   unsigned int mid;
00599 
00600   while (left < right) {
00601     mid = (left + right) / 2;
00602     if (st_index[mid] < s) {
00603       left = mid + 1;
00604     } else {
00605       right = mid;
00606     }
00607   }
00608   return(left);
00609 }
00610 
00611 
00623 static void
00624 wt_data(FILE *fp, HTK_HMM_INFO *hmm)
00625 {
00626   HTK_HMM_Data *d;
00627   unsigned int md_num;
00628   unsigned int sid, tid;
00629   int i;
00630 
00631   md_num = hmm->totalhmmnum;
00632 
00633   wrt(fp, &(md_num), sizeof(unsigned int), 1);
00634   for(d = hmm->start; d; d = d->next) {
00635     wrt_str(fp, d->name);
00636     wrt(fp, &(d->state_num), sizeof(short), 1);
00637     for (i=0;i<d->state_num;i++) {
00638       if (d->s[i] != NULL) {
00639         sid = search_stid(d->s[i]);
00640         /* for debug */
00641         if (d->s[i] != st_index[sid]) j_error("index not match!!! data state\n");
00642       } else {
00643         sid = hmm->totalstatenum + 1; /* error value */
00644       }
00645       wrt(fp, &sid, sizeof(unsigned int), 1);
00646     }
00647     tid = search_trid(d->tr);
00648     /* for debug */
00649     if (d->tr != tr_index[tid]) j_error("index not match!!! data trans\n");
00650     wrt(fp, &tid, sizeof(unsigned int), 1);
00651   }
00652   j_printf("%d HMM model definition written\n", md_num);
00653 }
00654 
00655 
00664 boolean
00665 write_binhmm(FILE *fp, HTK_HMM_INFO *hmm)
00666 {
00667   /* write header */
00668   wt_header(fp);
00669   
00670   /* write option data */
00671   wt_opt(fp, &(hmm->opt));
00672 
00673   /* write type data */
00674   wt_type(fp, hmm);
00675 
00676   /* write transition data */
00677   wt_trans(fp, hmm);
00678 
00679   /* write variance data */
00680   wt_var(fp, hmm);
00681 
00682   /* write density data */
00683   wt_dens(fp, hmm);
00684 
00685   /* write tmix data */
00686   if (hmm->is_tied_mixture) {
00687     wt_tmix(fp, hmm);
00688   }
00689 
00690   /* write state data */
00691   wt_state(fp, hmm);
00692 
00693   /* write model data */
00694   wt_data(fp, hmm);
00695 
00696   /* free pointer->index work area */
00697   free(tr_index);
00698   free(vr_index);
00699   free(dens_index);
00700   if (hmm->is_tied_mixture) free(tm_index);
00701   free(st_index);
00702 
00703   return (TRUE);
00704 }

Juliusに対してTue Mar 28 16:04:43 2006に生成されました。  doxygen 1.4.2