Julius 4.2
libsent/src/hmminfo/read_binhmm.c
説明を見る。
00001 
00028 /*
00029  * Copyright (c) 2003-2005 Shikano Lab., Nara Institute of Science and Technology
00030  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00031  * All rights reserved
00032  */
00033 
00034 #include <sent/stddefs.h>
00035 #include <sent/htk_param.h>
00036 #include <sent/htk_hmm.h>
00037 
00038 #undef DMES                     /* define to enable debug message */
00039 
00040 static boolean gzfile;        
00041 
00042 #define rdn(A,B,C,D) if (rdnfunc(A,B,C,D) == FALSE) return FALSE
00043 #define rdn_str(A,B,C) if ((C = rdn_strfunc(A,B)) == NULL) return FALSE
00044 
00053 static boolean
00054 rdnfunc(FILE *fp, void *buf, size_t unitbyte, int unitnum)
00055 {
00056   size_t tmp;
00057 
00058   if (unitnum == 0) return TRUE;
00059 
00060   if (gzfile) {
00061     tmp = myfread(buf, unitbyte, unitnum, fp);
00062   } else {
00063     tmp = fread(buf, unitbyte, unitnum, fp);
00064   }
00065   if (tmp < (size_t)unitnum) {
00066     jlog("Error: read_binhmm: failed to read %d bytes\n", unitbyte * unitnum);
00067     return FALSE;
00068   }
00069 #ifndef WORDS_BIGENDIAN
00070   if (unitbyte != 1) {
00071     swap_bytes(buf, unitbyte, unitnum);
00072   }
00073 #endif
00074   return TRUE;
00075 }
00076 
00077 static char buf[MAXLINELEN];    
00078 static char nostr = '\0';
00087 static char *
00088 rdn_strfunc(FILE *fp, HTK_HMM_INFO *hmm)
00089 {
00090   int c;
00091   int len;
00092   char *p;
00093 
00094   len = 0;
00095   while ((c = gzfile ? myfgetc(fp) : fgetc(fp)) != -1) {
00096     if (len >= MAXLINELEN) {
00097       jlog("Error: read_binhmm: string len exceeded %d bytes\n", MAXLINELEN);
00098       jlog("Error: read_binhmm: please check the value of MAXLINELEN\n");
00099       return NULL;
00100     }
00101     buf[len++] = c;
00102     if (c == '\0') break;
00103   }
00104   if (len == 0) return NULL;
00105   if (len == 1) {
00106     p = &nostr;
00107   } else {
00108     p = (char *)mybmalloc2(len, &(hmm->mroot));
00109     strcpy(p, buf);
00110   }
00111   return(p);
00112 }
00113 
00114 
00115 static char *binhmm_header = BINHMM_HEADER; 
00116 static char *binhmm_header_v2 = BINHMM_HEADER_V2; 
00117 
00124 static boolean
00125 rd_para(FILE *fp, Value *para)
00126 {
00127   short version;
00128   float dummy;
00129 
00130   /* read version */
00131   rdn(fp, &version, sizeof(short), 1);
00132 
00133   if (version > VALUE_VERSION) {
00134     jlog("Error: read_binhmm: unknown embedded parameter format version: %d\n", version);
00135     return FALSE;
00136   }
00137   jlog("Stat: rd_para: found embedded acoutic parameter (ver.%d)\n", version);
00138 
00139   /* read parameters */
00140   rdn(fp, &(para->smp_period), sizeof(long), 1);      
00141   rdn(fp, &(para->smp_freq), sizeof(long), 1);  
00142   rdn(fp, &(para->framesize), sizeof(int), 1);        
00143   rdn(fp, &(para->frameshift), sizeof(int), 1);       
00144   rdn(fp, &(para->preEmph), sizeof(float), 1);        
00145   rdn(fp, &(para->lifter), sizeof(int), 1);           
00146   rdn(fp, &(para->fbank_num), sizeof(int), 1);        
00147   rdn(fp, &(para->delWin), sizeof(int), 1);           
00148   rdn(fp, &(para->accWin), sizeof(int), 1);           
00149   rdn(fp, &(para->silFloor), sizeof(float), 1);       
00150   rdn(fp, &(para->escale), sizeof(float), 1);         
00151   rdn(fp, &(para->hipass), sizeof(int), 1);             
00152   rdn(fp, &(para->lopass), sizeof(int), 1);             
00153   rdn(fp, &(para->enormal), sizeof(int), 1);          
00154   rdn(fp, &(para->raw_e), sizeof(int), 1);            
00155   if (version == 1) {
00156     /* version 1 has ss related parameters, but version 2 and later not */
00157     /* skip ss related parameters (ss_alpha and ss_floor) */
00158     rdn(fp, &dummy, sizeof(float), 1);
00159     rdn(fp, &dummy, sizeof(float), 1);
00160   }
00161   rdn(fp, &(para->zmeanframe), sizeof(int), 1); 
00162   if (version >= 3) {
00163     rdn(fp, &(para->usepower), sizeof(int), 1);
00164   }
00165 
00166   return(TRUE);
00167 }
00168 
00180 static boolean
00181 rd_header(FILE *fp, HTK_HMM_INFO *hmm, Value *para, boolean *mpdf_macro_ret)
00182 {
00183   char *p, *q;
00184   boolean emp, inv;
00185   
00186   rdn_str(fp, hmm, p);
00187   if (strmatch(p, binhmm_header)) {
00188     /* version 1 */
00189     hmm->variance_inversed = FALSE;
00190   } else if (strmatch(p, binhmm_header_v2)) {
00191     /* version 2 */
00192     emp = inv = FALSE;
00193     rdn_str(fp, hmm, q);
00194     if (*q != '\0') {
00195       while(*q == '_') {
00196         q++;
00197         switch (*q) {
00198         case BINHMM_HEADER_V2_EMBEDPARA:
00199           /* read in embedded acoutic condition parameters */
00200           emp = TRUE;
00201           jlog("Stat: binhmm-header: analysis parameter embedded\n");
00202           break;
00203         case BINHMM_HEADER_V2_VARINV:
00204           inv = TRUE;
00205           jlog("Stat: binhmm-header: variance inversed\n");
00206           break;
00207         case BINHMM_HEADER_V2_MPDFMACRO:
00208           *mpdf_macro_ret = TRUE;
00209           jlog("Stat: binhmm-header: mixture PDF macro used\n");
00210           break;
00211         default:
00212           jlog("Error: unknown format qualifier in header: \"%c\"\n", *q);
00213           return FALSE;
00214         }
00215         q++;
00216       }
00217     }
00218     if (emp) {
00219       para->loaded = 1;
00220       if (rd_para(fp, para) == FALSE) {
00221         jlog("Error: read_binhmm: failed to read embeded parameter\n");
00222         return FALSE;
00223       }
00224       jlog("Stat: read_binhmm: has acoutic analysis configurations in its header\n");
00225     }
00226     if (inv) {
00227       hmm->variance_inversed = TRUE;
00228       jlog("Stat: read_binhmm: has inversed variances\n");
00229     } else {
00230       hmm->variance_inversed = FALSE;
00231     }
00232   } else {
00233     /* failed to read header */
00234     return FALSE;
00235   }
00236   return TRUE;
00237 }
00238 
00239 
00240 
00248 static boolean
00249 rd_opt(FILE *fp, HTK_HMM_Options *opt)
00250 {
00251   rdn(fp, &(opt->stream_info.num), sizeof(short), 1);
00252   rdn(fp, opt->stream_info.vsize, sizeof(short), MAXSTREAMNUM);
00253   rdn(fp, &(opt->vec_size), sizeof(short), 1);
00254   rdn(fp, &(opt->cov_type), sizeof(short), 1);
00255   rdn(fp, &(opt->dur_type), sizeof(short), 1);
00256   rdn(fp, &(opt->param_type), sizeof(short), 1);
00257 
00258   return(TRUE);
00259 }
00260 
00267 static boolean
00268 rd_type(FILE *fp, HTK_HMM_INFO *hmm)
00269 {
00270   rdn(fp, &(hmm->is_tied_mixture), sizeof(boolean), 1);
00271   rdn(fp, &(hmm->maxmixturenum), sizeof(int), 1);
00272   return TRUE;
00273 }
00274 
00275 
00276 /* read transition data */
00277 static HTK_HMM_Trans **tr_index; 
00278 static unsigned int tr_num;     
00279 
00290 static boolean
00291 rd_trans(FILE *fp, HTK_HMM_INFO *hmm)
00292 {
00293   HTK_HMM_Trans *t;
00294   unsigned int idx;
00295   int i;
00296   PROB *atmp;
00297   char *p;
00298 
00299   rdn(fp, &tr_num, sizeof(unsigned int), 1);
00300   tr_index = (HTK_HMM_Trans **)mymalloc(sizeof(HTK_HMM_Trans *) * tr_num);
00301 
00302   hmm->trstart = NULL;
00303   hmm->tr_root = NULL;
00304   for (idx = 0; idx < tr_num; idx++) {
00305     t = (HTK_HMM_Trans *)mybmalloc2(sizeof(HTK_HMM_Trans), &(hmm->mroot));
00306     rdn_str(fp, hmm, p);
00307     t->name = (*p == '\0') ? NULL : p;
00308     rdn(fp, &(t->statenum), sizeof(short), 1);
00309     t->a = (PROB **)mybmalloc2(sizeof(PROB *) * t->statenum, &(hmm->mroot));
00310     atmp = (PROB *)mybmalloc2(sizeof(PROB) * t->statenum * t->statenum, &(hmm->mroot));
00311     for (i=0;i<t->statenum;i++) {
00312       t->a[i] = &(atmp[i*t->statenum]);
00313       rdn(fp, t->a[i], sizeof(PROB), t->statenum);
00314     }
00315     trans_add(hmm, t);
00316     tr_index[idx] = t;
00317   }
00318 
00319 #ifdef DMES
00320   jlog("Stat: read_binhmm: %d transition maxtix read\n", tr_num);
00321 #endif
00322   return TRUE;
00323 }
00324 
00325 
00326 static HTK_HMM_Var **vr_index;  
00327 static unsigned int vr_num;     
00328 
00339 static boolean
00340 rd_var(FILE *fp, HTK_HMM_INFO *hmm)
00341 {
00342   HTK_HMM_Var *v;
00343   unsigned int idx;
00344   char *p;
00345 
00346   rdn(fp, &vr_num, sizeof(unsigned int), 1);
00347   vr_index = (HTK_HMM_Var **)mymalloc(sizeof(HTK_HMM_Var *) * vr_num);
00348   
00349   hmm->vrstart = NULL;
00350   hmm->vr_root = NULL;
00351   for (idx = 0; idx < vr_num; idx++) {
00352     v = (HTK_HMM_Var *)mybmalloc2(sizeof(HTK_HMM_Var), &(hmm->mroot));
00353     rdn_str(fp, hmm, p);
00354     v->name = (*p == '\0') ? NULL : p;
00355     rdn(fp, &(v->len), sizeof(short), 1);
00356     v->vec = (VECT *)mybmalloc2(sizeof(VECT) * v->len, &(hmm->mroot));
00357     rdn(fp, v->vec, sizeof(VECT), v->len);
00358     vr_index[idx] = v;
00359     var_add(hmm, v);
00360   }
00361 #ifdef DMES
00362   jlog("Stat: read_binhmm: %d variance read\n", vr_num);
00363 #endif
00364   return TRUE;
00365 }
00366 
00367 
00368 /* read density data */
00369 static HTK_HMM_Dens **dens_index; 
00370 static unsigned int dens_num;   
00371 
00383 static boolean
00384 rd_dens(FILE *fp, HTK_HMM_INFO *hmm)
00385 {
00386   HTK_HMM_Dens *d;
00387   unsigned int idx;
00388   unsigned int vid;
00389   char *p;
00390 
00391   rdn(fp, &dens_num, sizeof(unsigned int), 1);
00392   hmm->totalmixnum = dens_num;
00393   dens_index = (HTK_HMM_Dens **)mymalloc(sizeof(HTK_HMM_Dens *) * dens_num);
00394 
00395   hmm->dnstart = NULL;
00396   hmm->dn_root = NULL;
00397   for (idx = 0; idx < dens_num; idx++) {
00398     d = (HTK_HMM_Dens *)mybmalloc2(sizeof(HTK_HMM_Dens), &(hmm->mroot));
00399     rdn_str(fp, hmm, p);
00400     d->name = (*p == '\0') ? NULL : p;
00401     rdn(fp, &(d->meanlen), sizeof(short), 1);
00402     d->mean = (VECT *)mybmalloc2(sizeof(VECT) * d->meanlen, &(hmm->mroot));
00403     rdn(fp, d->mean, sizeof(VECT), d->meanlen);
00404     rdn(fp, &vid, sizeof(unsigned int), 1);
00405     d->var = vr_index[vid];
00406     rdn(fp, &(d->gconst), sizeof(LOGPROB), 1);
00407     dens_index[idx] = d;
00408     dens_add(hmm, d);
00409   }
00410 #ifdef DMES
00411   jlog("Stat: read_binhmm: %d gaussian densities read\n", dens_num);
00412 #endif
00413   return TRUE;
00414 }
00415 
00416 
00417 /* read stream weight data */
00418 static HTK_HMM_StreamWeight **streamweight_index; 
00419 static unsigned int streamweight_num;   
00420 
00432 static boolean
00433 rd_streamweight(FILE *fp, HTK_HMM_INFO *hmm)
00434 {
00435   HTK_HMM_StreamWeight *sw;
00436   unsigned int idx;
00437   char *p;
00438 
00439   rdn(fp, &streamweight_num, sizeof(unsigned int), 1);
00440   streamweight_index = (HTK_HMM_StreamWeight **)mymalloc(sizeof(HTK_HMM_StreamWeight *) * streamweight_num);
00441 
00442   hmm->swstart = NULL;
00443   hmm->sw_root = NULL;
00444   for (idx = 0; idx < streamweight_num; idx++) {
00445     sw = (HTK_HMM_StreamWeight *)mybmalloc2(sizeof(HTK_HMM_StreamWeight), &(hmm->mroot));
00446     rdn_str(fp, hmm, p);
00447     sw->name = (*p == '\0') ? NULL : p;
00448     rdn(fp, &(sw->len), sizeof(short), 1);
00449     sw->weight = (VECT *)mybmalloc2(sizeof(VECT) * sw->len, &(hmm->mroot));
00450     rdn(fp, sw->weight, sizeof(VECT), sw->len);
00451     streamweight_index[idx] = sw;
00452     sw_add(hmm, sw);
00453   }
00454 #ifdef DMES
00455   jlog("Stat: read_binhmm: %d stream weights read\n", streamweight_num);
00456 #endif
00457   return TRUE;
00458 }
00459 
00460 
00461 /* read tmix data */
00462 static GCODEBOOK **tm_index;    
00463 static unsigned int tm_num;     
00464 
00476 static boolean
00477 rd_tmix(FILE *fp, HTK_HMM_INFO *hmm)
00478 {
00479   GCODEBOOK *tm;
00480   unsigned int idx;
00481   unsigned int did;
00482   int i;
00483   char *p;
00484 
00485   rdn(fp, &tm_num, sizeof(unsigned int), 1);
00486   hmm->codebooknum = tm_num;
00487   tm_index = (GCODEBOOK **)mymalloc(sizeof(GCODEBOOK *) * tm_num);
00488   hmm->maxcodebooksize = 0;
00489 
00490   hmm->codebook_root = NULL;
00491   for (idx = 0; idx < tm_num; idx++) {
00492     tm = (GCODEBOOK *)mybmalloc2(sizeof(GCODEBOOK), &(hmm->mroot));
00493     rdn_str(fp, hmm, p);
00494     tm->name = (*p == '\0') ? NULL : p;
00495     rdn(fp, &(tm->num), sizeof(int), 1);
00496     if (hmm->maxcodebooksize < tm->num) hmm->maxcodebooksize = tm->num;
00497     tm->d = (HTK_HMM_Dens **)mybmalloc2(sizeof(HTK_HMM_Dens *) * tm->num, &(hmm->mroot));
00498     for(i=0;i<tm->num;i++) {
00499       rdn(fp, &did, sizeof(unsigned int), 1);
00500       if (did >= dens_num) {
00501         tm->d[i] = NULL;
00502       } else {
00503         tm->d[i] = dens_index[did];
00504       }
00505     }
00506     tm->id = idx;
00507     tm_index[idx] = tm;
00508     codebook_add(hmm, tm);
00509   }
00510 #ifdef DMES
00511   jlog("Stat: read_binhmm: %d tied-mixture codebooks read\n", tm_num);
00512 #endif  
00513   return TRUE;
00514 }
00515 
00516 
00517 /* read mpdf data */
00518 static HTK_HMM_PDF **mpdf_index; 
00519 static unsigned int mpdf_num;   
00520 
00531 static boolean
00532 rd_pdf_sub(FILE *fp, HTK_HMM_INFO *hmm, HTK_HMM_PDF *m)
00533 {
00534   int i;
00535   unsigned int did;
00536 
00537   rdn(fp, &(m->mix_num), sizeof(short), 1);
00538   if (m->mix_num == -1) {
00539     /* tmix */
00540     rdn(fp, &did, sizeof(unsigned int), 1);
00541     m->b = (HTK_HMM_Dens **)tm_index[did];
00542     m->mix_num = (tm_index[did])->num;
00543     m->tmix = TRUE;
00544   } else {
00545     /* mixture */
00546     m->b = (HTK_HMM_Dens **)mybmalloc2(sizeof(HTK_HMM_Dens *) * m->mix_num, &(hmm->mroot));
00547     for (i=0;i<m->mix_num;i++) {
00548       rdn(fp, &did, sizeof(unsigned int), 1);
00549       if (did >= dens_num) {
00550         m->b[i] = NULL;
00551       } else {
00552         m->b[i] = dens_index[did];
00553       }
00554     }
00555     m->tmix = FALSE;
00556   }
00557   m->bweight = (PROB *)mybmalloc2(sizeof(PROB) * m->mix_num, &(hmm->mroot));
00558   rdn(fp, m->bweight, sizeof(PROB), m->mix_num);
00559 
00560   return TRUE;
00561 }
00562 
00563 
00575 static boolean
00576 rd_mpdf(FILE *fp, HTK_HMM_INFO *hmm)
00577 {
00578   HTK_HMM_PDF *m;
00579   unsigned int idx;
00580   char *p;
00581 
00582   rdn(fp, &mpdf_num, sizeof(unsigned int), 1);
00583   mpdf_index = (HTK_HMM_PDF **)mymalloc(sizeof(HTK_HMM_PDF *) * mpdf_num);
00584 
00585   hmm->pdfstart = NULL;
00586   hmm->pdf_root = NULL;
00587   for (idx = 0; idx < mpdf_num; idx++) {
00588     m = (HTK_HMM_PDF *)mybmalloc2(sizeof(HTK_HMM_PDF), &(hmm->mroot));
00589     rdn_str(fp, hmm, p);
00590     m->name = (*p == '\0') ? NULL : p;
00591     rdn(fp, &(m->stream_id), sizeof(short), 1);
00592     if (rd_pdf_sub(fp, hmm, m) == FALSE) return FALSE;
00593     mpdf_index[idx] = m;
00594     mpdf_add(hmm, m);
00595   }
00596 #ifdef DMES
00597   jlog("Stat: read_binhmm: %d mixture PDFs read\n", mpdf_num);
00598 #endif
00599   return TRUE;
00600 }
00601 
00602 
00603 /* read state data */
00604 static HTK_HMM_State **st_index; 
00605 static unsigned int st_num;     
00606 
00620 static boolean
00621 rd_state(FILE *fp, HTK_HMM_INFO *hmm, boolean mpdf_macro)
00622 {
00623   HTK_HMM_State *s;
00624   unsigned int idx;
00625   unsigned int mid, swid;
00626   int m;
00627   char *buf;
00628 
00629   rdn(fp, &st_num, sizeof(unsigned int), 1);
00630   hmm->totalstatenum = st_num;
00631   st_index = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * st_num);
00632 
00633   hmm->ststart = NULL;
00634   hmm->st_root = NULL;
00635   for (idx = 0; idx < st_num; idx++) {
00636     s = (HTK_HMM_State *)mybmalloc2(sizeof(HTK_HMM_State), &(hmm->mroot));
00637     rdn_str(fp, hmm, buf);
00638     s->name = (*buf == '\0') ? NULL : buf;
00639     s->nstream = hmm->opt.stream_info.num;
00640     s->pdf = (HTK_HMM_PDF **)mybmalloc2(sizeof(HTK_HMM_PDF *) * s->nstream, &(hmm->mroot));
00641     if (mpdf_macro) {
00642       /* mpdf are stored separatedly, so read index */
00643       for(m=0;m<s->nstream;m++) {
00644         rdn(fp, &mid, sizeof(unsigned int), 1);
00645         if (mid >= mpdf_num) {
00646           s->pdf[m] = NULL;
00647         } else {
00648           s->pdf[m] = mpdf_index[mid];
00649         }
00650       }
00651     } else {
00652       /* mpdf are stored sequencially, so read the content here */
00653       for(m=0;m<s->nstream;m++) {
00654         s->pdf[m] = (HTK_HMM_PDF *)mybmalloc2(sizeof(HTK_HMM_PDF), &(hmm->mroot));
00655         s->pdf[m]->name = NULL;
00656         if (rd_pdf_sub(fp, hmm, s->pdf[m]) == FALSE) return FALSE;
00657         s->pdf[m]->stream_id = m;
00658         mpdf_add(hmm, s->pdf[m]);
00659       }
00660     }
00661     if (hmm->opt.stream_info.num > 1) {
00662       /* read steam weight info */
00663       rdn(fp, &swid, sizeof(unsigned int), 1);
00664       if (swid >= streamweight_num) {
00665         s->w = NULL;
00666       } else {
00667         s->w = streamweight_index[swid];
00668       }
00669     } else {
00670       s->w = NULL;
00671     }
00672     s->id = idx;
00673     st_index[idx] = s;
00674     state_add(hmm, s);
00675   }
00676 #ifdef DMES
00677   jlog("Stat: read_binhmm: %d states read\n", st_num);
00678 #endif
00679   return TRUE;
00680 }
00681 
00693 static boolean
00694 rd_data(FILE *fp, HTK_HMM_INFO *hmm)
00695 {
00696   HTK_HMM_Data *d;
00697   unsigned int md_num;
00698   unsigned int sid, tid;
00699   unsigned int idx;
00700   int i;
00701   char *p;
00702 
00703   rdn(fp, &(md_num), sizeof(unsigned int), 1);
00704   hmm->totalhmmnum = md_num;
00705 
00706   hmm->start = NULL;
00707   hmm->physical_root = NULL;
00708   for (idx = 0; idx < md_num; idx++) {
00709     d = (HTK_HMM_Data *)mybmalloc2(sizeof(HTK_HMM_Data), &(hmm->mroot));
00710     rdn_str(fp, hmm, p);
00711     d->name = (*p == '\0') ? NULL : p;
00712     rdn(fp, &(d->state_num), sizeof(short), 1);
00713     d->s = (HTK_HMM_State **)mybmalloc2(sizeof(HTK_HMM_State *) * d->state_num, &(hmm->mroot));
00714     for (i=0;i<d->state_num;i++) {
00715       rdn(fp, &sid, sizeof(unsigned int), 1);
00716       if (sid > (unsigned int)hmm->totalstatenum) {
00717         d->s[i] = NULL;
00718       } else {
00719         d->s[i] = st_index[sid];
00720       }
00721     }
00722     rdn(fp, &tid, sizeof(unsigned int), 1);
00723     d->tr = tr_index[tid];
00724     htk_hmmdata_add(hmm, d);
00725   }
00726 #ifdef DMES
00727   jlog("Stat: read_binhmm: %d HMM model definition read\n", md_num);
00728 #endif
00729   return TRUE;
00730 }
00731 
00732 
00733 
00744 boolean
00745 read_binhmm(FILE *fp, HTK_HMM_INFO *hmm, boolean gzfile_p, Value *para)
00746 {
00747   boolean mpdf_macro = FALSE;
00748 
00749   gzfile = gzfile_p;
00750 
00751   /* read header */
00752   if (rd_header(fp, hmm, para, &mpdf_macro) == FALSE) {
00753     return FALSE;
00754   }
00755 
00756   jlog("Stat: read_binhmm: binary format HMM definition\n");
00757   
00758   /* read option data */
00759   if (rd_opt(fp, &(hmm->opt)) == FALSE) {
00760     jlog("Error: read_binhmm: failed to read HMM options\n");
00761     return FALSE;
00762   }
00763 
00764   /* read type data */
00765   if (rd_type(fp, hmm) == FALSE) {
00766     jlog("Error: read_binhmm: failed to read HMM type of mixture tying\n");
00767     return FALSE;
00768   }
00769 
00770   /* read transition data */
00771   if (rd_trans(fp, hmm) == FALSE) {
00772     jlog("Error: read_binhmm: failed to read HMM transition data\n");
00773     return FALSE;
00774   }
00775 
00776   /* read variance data */
00777   if (rd_var(fp, hmm) == FALSE) {
00778     jlog("Error: read_binhmm: failed to read HMM variance data\n");
00779     return FALSE;
00780   }
00781 
00782   /* read density data */
00783   if (rd_dens(fp, hmm) == FALSE) {
00784     jlog("Error: read_binhmm: failed to read HMM density data\n");
00785     return FALSE;
00786   }
00787 
00788   /* read stream weight data */
00789   if (hmm->opt.stream_info.num > 1) {
00790     if (rd_streamweight(fp, hmm) == FALSE) {
00791       jlog("Error: read_binhmm: failed to read stream weights data\n");
00792       return FALSE;
00793     }
00794   }
00795 
00796   /* read tmix data */
00797   if (hmm->is_tied_mixture) {
00798     if (rd_tmix(fp, hmm) == FALSE) {
00799       jlog("Error: read_binhmm: failed to read HMM tied-mixture codebook data\n");
00800       return FALSE;
00801     }
00802   }
00803 
00804   /* read mixture pdf data */
00805   if (mpdf_macro) {
00806     if (rd_mpdf(fp, hmm) == FALSE) {
00807       jlog("Error: read_binhmm: failed to read mixture PDF data\n");
00808       return FALSE;
00809     }
00810   }
00811 
00812   /* read state data */
00813   if (rd_state(fp, hmm, mpdf_macro) == FALSE) {
00814     jlog("Error: read_binhmm: failed to read HMM state data\n");
00815     return FALSE;
00816   }
00817 
00818   /* read model data */
00819   if (rd_data(fp, hmm) == FALSE) {
00820     jlog("Error: read_binhmm: failed to read HMM data\n");
00821     return FALSE;
00822   }
00823 
00824   /* free pointer->index work area */
00825   if (mpdf_macro) free(mpdf_index);
00826   free(tr_index);
00827   free(vr_index);
00828   if (hmm->opt.stream_info.num > 1) free(streamweight_index);
00829   free(dens_index);
00830   if (hmm->is_tied_mixture) free(tm_index);
00831   free(st_index);
00832 
00833   /* count maximum state num (it is not stored in binhmm... */
00834   {
00835     HTK_HMM_Data *dtmp;
00836     int maxlen = 0;
00837     for (dtmp = hmm->start; dtmp; dtmp = dtmp->next) {
00838       if (maxlen < dtmp->state_num) maxlen = dtmp->state_num;
00839     }
00840     hmm->maxstatenum = maxlen;
00841   }
00842 
00843   /* compute total number of mixture PDFs */
00844   {
00845     HTK_HMM_PDF *p;
00846     int n = 0;
00847     for (p = hmm->pdfstart; p; p = p->next) {
00848       n++;
00849     }
00850     hmm->totalpdfnum = n;
00851   }
00852 
00853   /* re-number state id */
00854   {
00855     HTK_HMM_State *stmp;
00856     int n = 0;
00857     for (stmp = hmm->ststart; stmp; stmp = stmp->next) {
00858       stmp->id = n++;
00859     }
00860   }
00861   /* assign ID number for all HTK_HMM_Trans */
00862   {
00863     HTK_HMM_Trans *ttmp;
00864     int n = 0;
00865     for (ttmp = hmm->trstart; ttmp; ttmp = ttmp->next) {
00866       ttmp->id = n++;
00867     }
00868     hmm->totaltransnum = n;
00869   }
00870 
00871   /* determine whether this model needs multi-path handling */
00872   hmm->need_multipath = htk_hmm_has_several_arc_on_edge(hmm);
00873   if (hmm->need_multipath) {
00874     jlog("Stat: read_binhmm: this HMM requires multipath handling at decoding\n");
00875   } else {
00876     jlog("Stat: read_binhmm: this HMM does not need multipath handling\n");
00877   }
00878   
00879   if (! hmm->variance_inversed) {
00880     /* inverse all variance values for faster computation */
00881     htk_hmm_inverse_variances(hmm);
00882     hmm->variance_inversed = TRUE;
00883   }
00884 
00885 #ifdef ENABLE_MSD
00886   /* check if MSD-HMM */
00887   htk_hmm_check_msd(hmm);
00888 #endif
00889 
00890   return (TRUE);
00891 }