Julius 4.2
|
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 /* $Id: write_binhmm.c,v 1.5 2011/04/29 05:09:16 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 00057 if (unitnum == 0) return TRUE; 00058 00059 #ifndef WORDS_BIGENDIAN 00060 if (unitbyte != 1) { 00061 swap_bytes((char *)buf, unitbyte, unitnum); 00062 } 00063 #endif 00064 if (myfwrite(buf, unitbyte, unitnum, fp) < unitnum) { 00065 jlog("Error: write_binhmm: failed to write %d bytes", unitbyte * unitnum); 00066 return FALSE; 00067 } 00068 #ifndef WORDS_BIGENDIAN 00069 if (unitbyte != 1) { 00070 swap_bytes((char *)buf, unitbyte, unitnum); 00071 } 00072 #endif 00073 return TRUE; 00074 } 00075 00082 static boolean 00083 wrt_strfunc(FILE *fp, char *str) 00084 { 00085 static char noname = '\0'; 00086 boolean ret; 00087 00088 if (str) { 00089 ret = wrtfunc(fp, str, sizeof(char), strlen(str)+1); 00090 } else { 00091 ret = wrtfunc(fp, &noname, sizeof(char), 1); 00092 } 00093 return ret; 00094 } 00095 00096 00097 static char *binhmm_header_v2 = BINHMM_HEADER_V2; 00098 00107 static boolean 00108 wt_header(FILE *fp, boolean emp, boolean inv, boolean mpdfmacro) 00109 { 00110 char buf[50]; 00111 char *p; 00112 00113 wrt_str(fp, binhmm_header_v2); 00114 p = &(buf[0]); 00115 if (emp) { 00116 *p++ = '_'; 00117 *p++ = BINHMM_HEADER_V2_EMBEDPARA; 00118 } 00119 if (inv) { 00120 *p++ = '_'; 00121 *p++ = BINHMM_HEADER_V2_VARINV; 00122 } 00123 if (mpdfmacro) { 00124 *p++ = '_'; 00125 *p++ = BINHMM_HEADER_V2_MPDFMACRO; 00126 } 00127 *p = '\0'; 00128 wrt_str(fp, buf); 00129 jlog("Stat: write_binhmm: written header: \"%s%s\"\n", binhmm_header_v2, buf); 00130 00131 return TRUE; 00132 } 00133 00134 00141 static boolean 00142 wt_para(FILE *fp, Value *para) 00143 { 00144 short version; 00145 00146 version = VALUE_VERSION; 00147 wrt(fp, &version, sizeof(short), 1); 00148 00149 wrt(fp, &(para->smp_period), sizeof(long), 1); 00150 wrt(fp, &(para->smp_freq), sizeof(long), 1); 00151 wrt(fp, &(para->framesize), sizeof(int), 1); 00152 wrt(fp, &(para->frameshift), sizeof(int), 1); 00153 wrt(fp, &(para->preEmph), sizeof(float), 1); 00154 wrt(fp, &(para->lifter), sizeof(int), 1); 00155 wrt(fp, &(para->fbank_num), sizeof(int), 1); 00156 wrt(fp, &(para->delWin), sizeof(int), 1); 00157 wrt(fp, &(para->accWin), sizeof(int), 1); 00158 wrt(fp, &(para->silFloor), sizeof(float), 1); 00159 wrt(fp, &(para->escale), sizeof(float), 1); 00160 wrt(fp, &(para->hipass), sizeof(int), 1); 00161 wrt(fp, &(para->lopass), sizeof(int), 1); 00162 wrt(fp, &(para->enormal), sizeof(int), 1); 00163 wrt(fp, &(para->raw_e), sizeof(int), 1); 00164 wrt(fp, &(para->zmeanframe), sizeof(int), 1); 00165 wrt(fp, &(para->usepower), sizeof(int), 1); 00166 00167 return TRUE; 00168 } 00169 00170 00177 static boolean 00178 wt_opt(FILE *fp, HTK_HMM_Options *opt) 00179 { 00180 wrt(fp, &(opt->stream_info.num), sizeof(short), 1); 00181 wrt(fp, opt->stream_info.vsize, sizeof(short), MAXSTREAMNUM); 00182 wrt(fp, &(opt->vec_size), sizeof(short), 1); 00183 wrt(fp, &(opt->cov_type), sizeof(short), 1); 00184 wrt(fp, &(opt->dur_type), sizeof(short), 1); 00185 wrt(fp, &(opt->param_type), sizeof(short), 1); 00186 return TRUE; 00187 } 00188 00195 static boolean 00196 wt_type(FILE *fp, HTK_HMM_INFO *hmm) 00197 { 00198 wrt(fp, &(hmm->is_tied_mixture), sizeof(boolean), 1); 00199 wrt(fp, &(hmm->maxmixturenum), sizeof(int), 1); 00200 return TRUE; 00201 } 00202 00203 00204 /* write transition data */ 00205 static HTK_HMM_Trans **tr_index; 00206 static unsigned int tr_num; 00207 00217 static int 00218 qsort_tr_index(HTK_HMM_Trans **t1, HTK_HMM_Trans **t2) 00219 { 00220 if (*t1 > *t2) return 1; 00221 else if (*t1 < *t2) return -1; 00222 else return 0; 00223 } 00224 00236 static boolean 00237 wt_trans(FILE *fp, HTK_HMM_INFO *hmm) 00238 { 00239 HTK_HMM_Trans *t; 00240 unsigned int idx; 00241 int i; 00242 00243 tr_num = 0; 00244 for(t = hmm->trstart; t; t = t->next) tr_num++; 00245 tr_index = (HTK_HMM_Trans **)mymalloc(sizeof(HTK_HMM_Trans *) * tr_num); 00246 idx = 0; 00247 for(t = hmm->trstart; t; t = t->next) tr_index[idx++] = t; 00248 qsort(tr_index, tr_num, sizeof(HTK_HMM_Trans *), (int (*)(const void *, const void *))qsort_tr_index); 00249 00250 wrt(fp, &tr_num, sizeof(unsigned int), 1); 00251 for (idx = 0; idx < tr_num; idx++) { 00252 t = tr_index[idx]; 00253 wrt_str(fp, t->name); 00254 wrt(fp, &(t->statenum), sizeof(short), 1); 00255 for(i=0;i<t->statenum;i++) { 00256 wrt(fp, t->a[i], sizeof(PROB), t->statenum); 00257 } 00258 } 00259 00260 jlog("Stat: write_binhmm: %d transition maxtix written\n", tr_num); 00261 00262 return TRUE; 00263 } 00264 00272 static unsigned int 00273 search_trid(HTK_HMM_Trans *t) 00274 { 00275 unsigned int left = 0; 00276 unsigned int right = tr_num - 1; 00277 unsigned int mid; 00278 00279 while (left < right) { 00280 mid = (left + right) / 2; 00281 if (tr_index[mid] < t) { 00282 left = mid + 1; 00283 } else { 00284 right = mid; 00285 } 00286 } 00287 return(left); 00288 } 00289 00290 00291 /* write variance data */ 00292 static HTK_HMM_Var **vr_index; 00293 static unsigned int vr_num; 00294 00304 static int 00305 qsort_vr_index(HTK_HMM_Var **v1, HTK_HMM_Var **v2) 00306 { 00307 if (*v1 > *v2) return 1; 00308 else if (*v1 < *v2) return -1; 00309 else return 0; 00310 } 00311 00323 static boolean 00324 wt_var(FILE *fp, HTK_HMM_INFO *hmm) 00325 { 00326 HTK_HMM_Var *v; 00327 unsigned int idx; 00328 00329 vr_num = 0; 00330 for(v = hmm->vrstart; v; v = v->next) vr_num++; 00331 vr_index = (HTK_HMM_Var **)mymalloc(sizeof(HTK_HMM_Var *) * vr_num); 00332 idx = 0; 00333 for(v = hmm->vrstart; v; v = v->next) vr_index[idx++] = v; 00334 qsort(vr_index, vr_num, sizeof(HTK_HMM_Var *), (int (*)(const void *, const void *))qsort_vr_index); 00335 00336 wrt(fp, &vr_num, sizeof(unsigned int), 1); 00337 for (idx = 0; idx < vr_num; idx++) { 00338 v = vr_index[idx]; 00339 wrt_str(fp, v->name); 00340 wrt(fp, &(v->len), sizeof(short), 1); 00341 wrt(fp, v->vec, sizeof(VECT), v->len); 00342 } 00343 jlog("Stat: write_binhmm: %d variance written\n", vr_num); 00344 00345 return TRUE; 00346 } 00347 00355 static unsigned int 00356 search_vid(HTK_HMM_Var *v) 00357 { 00358 unsigned int left = 0; 00359 unsigned int right = vr_num - 1; 00360 unsigned int mid; 00361 00362 while (left < right) { 00363 mid = (left + right) / 2; 00364 if (vr_index[mid] < v) { 00365 left = mid + 1; 00366 } else { 00367 right = mid; 00368 } 00369 } 00370 return(left); 00371 } 00372 00373 00374 /* write density data */ 00375 static HTK_HMM_Dens **dens_index; 00376 static unsigned int dens_num; 00377 00387 static int 00388 qsort_dens_index(HTK_HMM_Dens **d1, HTK_HMM_Dens **d2) 00389 { 00390 if (*d1 > *d2) return 1; 00391 else if (*d1 < *d2) return -1; 00392 else return 0; 00393 } 00394 00408 static boolean 00409 wt_dens(FILE *fp, HTK_HMM_INFO *hmm) 00410 { 00411 HTK_HMM_Dens *d; 00412 unsigned int idx; 00413 unsigned int vid; 00414 00415 dens_num = hmm->totalmixnum; 00416 dens_index = (HTK_HMM_Dens **)mymalloc(sizeof(HTK_HMM_Dens *) * dens_num); 00417 idx = 0; 00418 for(d = hmm->dnstart; d; d = d->next) dens_index[idx++] = d; 00419 qsort(dens_index, dens_num, sizeof(HTK_HMM_Dens *), (int (*)(const void *, const void *))qsort_dens_index); 00420 00421 wrt(fp, &dens_num, sizeof(unsigned int), 1); 00422 for (idx = 0; idx < dens_num; idx++) { 00423 d = dens_index[idx]; 00424 wrt_str(fp, d->name); 00425 wrt(fp, &(d->meanlen), sizeof(short), 1); 00426 wrt(fp, d->mean, sizeof(VECT), d->meanlen); 00427 vid = search_vid(d->var); 00428 /* for debug */ 00429 if (d->var != vr_index[vid]) { 00430 jlog("Error: write_binhmm: index not match!!!\n"); 00431 return FALSE; 00432 } 00433 wrt(fp, &vid, sizeof(unsigned int), 1); 00434 wrt(fp, &(d->gconst), sizeof(LOGPROB), 1); 00435 } 00436 jlog("Stat: write_binhmm: %d gaussian densities written\n", dens_num); 00437 00438 return TRUE; 00439 } 00440 00448 static unsigned int 00449 search_did(HTK_HMM_Dens *d) 00450 { 00451 unsigned int left = 0; 00452 unsigned int right = dens_num - 1; 00453 unsigned int mid; 00454 00455 while (left < right) { 00456 mid = (left + right) / 2; 00457 if (dens_index[mid] < d) { 00458 left = mid + 1; 00459 } else { 00460 right = mid; 00461 } 00462 } 00463 return(left); 00464 } 00465 00466 /* write stream weight data */ 00467 static HTK_HMM_StreamWeight **streamweight_index; 00468 static unsigned int streamweight_num; 00469 00479 static int 00480 qsort_streamweight_index(HTK_HMM_StreamWeight **d1, HTK_HMM_StreamWeight **d2) 00481 { 00482 if (*d1 > *d2) return 1; 00483 else if (*d1 < *d2) return -1; 00484 else return 0; 00485 } 00486 00500 static boolean 00501 wt_streamweight(FILE *fp, HTK_HMM_INFO *hmm) 00502 { 00503 HTK_HMM_StreamWeight *sw; 00504 unsigned int idx; 00505 00506 streamweight_num = 0; 00507 for(sw=hmm->swstart;sw;sw=sw->next) streamweight_num++; 00508 streamweight_index = (HTK_HMM_StreamWeight **)mymalloc(sizeof(HTK_HMM_StreamWeight *) * streamweight_num); 00509 idx = 0; 00510 for(sw = hmm->swstart; sw; sw = sw->next) streamweight_index[idx++] = sw; 00511 qsort(streamweight_index, streamweight_num, sizeof(HTK_HMM_StreamWeight *), (int (*)(const void *, const void *))qsort_streamweight_index); 00512 00513 wrt(fp, &streamweight_num, sizeof(unsigned int), 1); 00514 for (idx = 0; idx < streamweight_num; idx++) { 00515 sw = streamweight_index[idx]; 00516 wrt_str(fp, sw->name); 00517 wrt(fp, &(sw->len), sizeof(short), 1); 00518 wrt(fp, sw->weight, sizeof(VECT), sw->len); 00519 } 00520 jlog("Stat: write_binhmm: %d stream weights written\n", streamweight_num); 00521 00522 return TRUE; 00523 } 00524 00532 static unsigned int 00533 search_swid(HTK_HMM_StreamWeight *sw) 00534 { 00535 unsigned int left = 0; 00536 unsigned int right = streamweight_num - 1; 00537 unsigned int mid; 00538 00539 while (left < right) { 00540 mid = (left + right) / 2; 00541 if (streamweight_index[mid] < sw) { 00542 left = mid + 1; 00543 } else { 00544 right = mid; 00545 } 00546 } 00547 return(left); 00548 } 00549 00550 00551 /* write tmix data */ 00552 static GCODEBOOK **tm_index; 00553 static unsigned int tm_num; 00554 static unsigned int tm_idx; 00555 00561 static void 00562 tmix_list_callback(void *p) 00563 { 00564 GCODEBOOK *tm; 00565 tm = p; 00566 tm_index[tm_idx++] = tm; 00567 } 00568 00578 static int 00579 qsort_tm_index(GCODEBOOK **tm1, GCODEBOOK **tm2) 00580 { 00581 if (*tm1 > *tm2) return 1; 00582 else if (*tm1 < *tm2) return -1; 00583 else return 0; 00584 } 00585 00599 static boolean 00600 wt_tmix(FILE *fp, HTK_HMM_INFO *hmm) 00601 { 00602 GCODEBOOK *tm; 00603 unsigned int idx; 00604 unsigned int did; 00605 int i; 00606 00607 tm_num = hmm->codebooknum; 00608 tm_index = (GCODEBOOK **)mymalloc(sizeof(GCODEBOOK *) * tm_num); 00609 tm_idx = 0; 00610 aptree_traverse_and_do(hmm->codebook_root, tmix_list_callback); 00611 qsort(tm_index, tm_num, sizeof(GCODEBOOK *), (int (*)(const void *, const void *))qsort_tm_index); 00612 00613 wrt(fp, &tm_num, sizeof(unsigned int), 1); 00614 for (idx = 0; idx < tm_num; idx++) { 00615 tm = tm_index[idx]; 00616 wrt_str(fp, tm->name); 00617 wrt(fp, &(tm->num), sizeof(int), 1); 00618 for(i=0;i<tm->num;i++) { 00619 if (tm->d[i] == NULL) { 00620 did = dens_num; 00621 } else { 00622 did = search_did(tm->d[i]); 00623 /* for debug */ 00624 if (tm->d[i] != dens_index[did]) { 00625 jlog("Error: write_binhmm: index not match!!!\n"); 00626 return FALSE; 00627 } 00628 } 00629 wrt(fp, &did, sizeof(unsigned int), 1); 00630 } 00631 } 00632 jlog("Stat: write_binhmm: %d tied-mixture codebooks written\n", tm_num); 00633 00634 return TRUE; 00635 } 00636 00644 static unsigned int 00645 search_tmid(GCODEBOOK *tm) 00646 { 00647 unsigned int left = 0; 00648 unsigned int right = tm_num - 1; 00649 unsigned int mid; 00650 00651 while (left < right) { 00652 mid = (left + right) / 2; 00653 if (tm_index[mid] < tm) { 00654 left = mid + 1; 00655 } else { 00656 right = mid; 00657 } 00658 } 00659 return(left); 00660 } 00661 00662 00663 /* write mixture pdf data */ 00664 static HTK_HMM_PDF **mpdf_index; 00665 static unsigned int mpdf_num; 00666 00676 static int 00677 qsort_mpdf_index(HTK_HMM_PDF **d1, HTK_HMM_PDF **d2) 00678 { 00679 if (*d1 > *d2) return 1; 00680 else if (*d1 < *d2) return -1; 00681 else return 0; 00682 } 00683 00694 static boolean 00695 wt_pdf_sub(FILE *fp, HTK_HMM_INFO *hmm, HTK_HMM_PDF *m) 00696 { 00697 unsigned int did; 00698 int i; 00699 short dummy; 00700 00701 if (hmm->is_tied_mixture) { 00702 /* try tmix */ 00703 did = search_tmid((GCODEBOOK *)(m->b)); 00704 if ((GCODEBOOK *)m->b == tm_index[did]) { 00705 /* tmix */ 00706 dummy = -1; 00707 wrt(fp, &dummy, sizeof(short), 1); 00708 wrt(fp, &did, sizeof(unsigned int), 1); 00709 } else { 00710 /* tmix failed -> normal mixture */ 00711 wrt(fp, &(m->mix_num), sizeof(short), 1); 00712 for (i=0;i<m->mix_num;i++) { 00713 if (m->b[i] == NULL) { 00714 did = dens_num; 00715 } else { 00716 did = search_did(m->b[i]); 00717 if (m->b[i] != dens_index[did]) { 00718 jlog("Error: write_binhmm: index not match!!!\n"); 00719 return FALSE; 00720 } 00721 } 00722 wrt(fp, &did, sizeof(unsigned int), 1); 00723 } 00724 } 00725 } else { /* not tied mixture */ 00726 wrt(fp, &(m->mix_num), sizeof(short), 1); 00727 for (i=0;i<m->mix_num;i++) { 00728 if (m->b[i] == NULL) { 00729 did = dens_num; 00730 } else { 00731 did = search_did(m->b[i]); 00732 if (m->b[i] != dens_index[did]) { 00733 jlog("Error: write_binhmm: index not match!!!\n"); 00734 return FALSE; 00735 } 00736 } 00737 wrt(fp, &did, sizeof(unsigned int), 1); 00738 } 00739 } 00740 wrt(fp, m->bweight, sizeof(PROB), m->mix_num); 00741 00742 return TRUE; 00743 } 00744 00758 static boolean 00759 wt_mpdf(FILE *fp, HTK_HMM_INFO *hmm) 00760 { 00761 HTK_HMM_PDF *m; 00762 unsigned int idx; 00763 00764 mpdf_num = 0; 00765 for(m=hmm->pdfstart;m;m=m->next) mpdf_num++; 00766 mpdf_index = (HTK_HMM_PDF **)mymalloc(sizeof(HTK_HMM_PDF *) * mpdf_num); 00767 idx = 0; 00768 for(m=hmm->pdfstart;m;m=m->next) mpdf_index[idx++] = m; 00769 qsort(mpdf_index, mpdf_num, sizeof(HTK_HMM_PDF *), (int (*)(const void *, const void *))qsort_mpdf_index); 00770 00771 wrt(fp, &mpdf_num, sizeof(unsigned int), 1); 00772 for (idx = 0; idx < mpdf_num; idx++) { 00773 m = mpdf_index[idx]; 00774 wrt_str(fp, m->name); 00775 wrt(fp, &(m->stream_id), sizeof(short), 1); 00776 if (wt_pdf_sub(fp, hmm, m) == FALSE) return FALSE; 00777 } 00778 00779 jlog("Stat: write_binhmm: %d mixture PDF written\n", mpdf_num); 00780 00781 return TRUE; 00782 } 00783 00791 static unsigned int 00792 search_mpdfid(HTK_HMM_PDF *m) 00793 { 00794 unsigned int left = 0; 00795 unsigned int right = mpdf_num - 1; 00796 unsigned int mid; 00797 00798 while (left < right) { 00799 mid = (left + right) / 2; 00800 if (mpdf_index[mid] < m) { 00801 left = mid + 1; 00802 } else { 00803 right = mid; 00804 } 00805 } 00806 return(left); 00807 } 00808 00809 00810 /* write state data */ 00811 static HTK_HMM_State **st_index; 00812 static unsigned int st_num; 00813 00823 static int 00824 qsort_st_index(HTK_HMM_State **s1, HTK_HMM_State **s2) 00825 { 00826 if (*s1 > *s2) return 1; 00827 else if (*s1 < *s2) return -1; 00828 else return 0; 00829 } 00830 00845 static boolean 00846 wt_state(FILE *fp, HTK_HMM_INFO *hmm, boolean mpdf_macro) 00847 { 00848 HTK_HMM_State *s; 00849 unsigned int idx; 00850 unsigned int mid; 00851 unsigned int swid; 00852 int m; 00853 00854 st_num = hmm->totalstatenum; 00855 st_index = (HTK_HMM_State **)mymalloc(sizeof(HTK_HMM_State *) * st_num); 00856 idx = 0; 00857 for(s = hmm->ststart; s; s = s->next) st_index[idx++] = s; 00858 qsort(st_index, st_num, sizeof(HTK_HMM_State *), (int (*)(const void *, const void *))qsort_st_index); 00859 00860 wrt(fp, &st_num, sizeof(unsigned int), 1); 00861 for (idx = 0; idx < st_num; idx++) { 00862 s = st_index[idx]; 00863 wrt_str(fp, s->name); 00864 if (mpdf_macro) { 00865 /* mpdf are already written, so write index */ 00866 for(m=0;m<s->nstream;m++) { 00867 if (s->pdf[m] == NULL) { 00868 mid = mpdf_num; 00869 } else { 00870 mid = search_mpdfid(s->pdf[m]); 00871 if (s->pdf[m] != mpdf_index[mid]) { 00872 jlog("Error: write_binhmm: index not match!!!\n"); 00873 return FALSE; 00874 } 00875 } 00876 wrt(fp, &mid, sizeof(unsigned int), 1); 00877 } 00878 } else { 00879 /* mpdf should be written here */ 00880 for(m=0;m<s->nstream;m++) { 00881 /* stream_id will not be written */ 00882 if (wt_pdf_sub(fp, hmm, s->pdf[m]) == FALSE) return FALSE; 00883 } 00884 } 00885 if (hmm->opt.stream_info.num > 1) { 00886 /* write steam weight */ 00887 if (s->w == NULL) { 00888 swid = streamweight_num; 00889 } else { 00890 swid = search_swid(s->w); 00891 if (s->w != streamweight_index[swid]) { 00892 jlog("Error: write_binhmm: index not match!!!\n"); 00893 return FALSE; 00894 } 00895 } 00896 wrt(fp, &swid, sizeof(unsigned int), 1); 00897 } 00898 } 00899 00900 jlog("Stat: write_binhmm: %d states written\n", st_num); 00901 00902 return TRUE; 00903 } 00904 00912 static unsigned int 00913 search_stid(HTK_HMM_State *s) 00914 { 00915 unsigned int left = 0; 00916 unsigned int right = st_num - 1; 00917 unsigned int mid; 00918 00919 while (left < right) { 00920 mid = (left + right) / 2; 00921 if (st_index[mid] < s) { 00922 left = mid + 1; 00923 } else { 00924 right = mid; 00925 } 00926 } 00927 return(left); 00928 } 00929 00930 00942 static boolean 00943 wt_data(FILE *fp, HTK_HMM_INFO *hmm) 00944 { 00945 HTK_HMM_Data *d; 00946 unsigned int md_num; 00947 unsigned int sid, tid; 00948 int i; 00949 00950 md_num = hmm->totalhmmnum; 00951 00952 wrt(fp, &(md_num), sizeof(unsigned int), 1); 00953 for(d = hmm->start; d; d = d->next) { 00954 wrt_str(fp, d->name); 00955 wrt(fp, &(d->state_num), sizeof(short), 1); 00956 for (i=0;i<d->state_num;i++) { 00957 if (d->s[i] != NULL) { 00958 sid = search_stid(d->s[i]); 00959 /* for debug */ 00960 if (d->s[i] != st_index[sid]) { 00961 jlog("Error: write_binhmm: index not match!!!\n"); 00962 return FALSE; 00963 } 00964 } else { 00965 sid = hmm->totalstatenum + 1; /* error value */ 00966 } 00967 wrt(fp, &sid, sizeof(unsigned int), 1); 00968 } 00969 tid = search_trid(d->tr); 00970 /* for debug */ 00971 if (d->tr != tr_index[tid]) { 00972 jlog("Error: write_binhmm: index not match!!!\n"); 00973 return FALSE; 00974 } 00975 wrt(fp, &tid, sizeof(unsigned int), 1); 00976 } 00977 jlog("Stat: write_binhmm: %d HMM model definition written\n", md_num); 00978 return TRUE; 00979 } 00980 00981 00991 boolean 00992 write_binhmm(FILE *fp, HTK_HMM_INFO *hmm, Value *para) 00993 { 00994 boolean mpdf_macro; 00995 00996 if (hmm->pdf_root != NULL) { 00997 /* "~p" macro definition exist */ 00998 /* save mixture pdf separatedly from state definition */ 00999 mpdf_macro = TRUE; 01000 jlog("Stat: write_binhmm: mixture PDF macro \"~p\" used, use qualifier \'M\'\n"); 01001 } else { 01002 mpdf_macro = FALSE; 01003 } 01004 01005 /* write header */ 01006 if (wt_header(fp, (para ? TRUE : FALSE), hmm->variance_inversed, mpdf_macro) == FALSE) { 01007 jlog("Error: write_binhmm: failed to write header\n"); 01008 return FALSE; 01009 } 01010 01011 if (para) { 01012 /* write acoustic analysis parameter info */ 01013 if (wt_para(fp, para) == FALSE) { 01014 jlog("Error: write_binhmm: failed to write acoustic analysis parameters\n"); 01015 return FALSE; 01016 } 01017 } 01018 01019 /* write option data */ 01020 if (wt_opt(fp, &(hmm->opt)) == FALSE) { 01021 jlog("Error: write_binhmm: failed to write option data\n"); 01022 return FALSE; 01023 } 01024 01025 /* write type data */ 01026 if (wt_type(fp, hmm) == FALSE) { 01027 jlog("Error: write_binhmm: failed to write HMM type data\n"); 01028 return FALSE; 01029 } 01030 01031 /* write transition data */ 01032 if (wt_trans(fp, hmm) == FALSE) { 01033 jlog("Error: write_binhmm: failed to write HMM transition data\n"); 01034 return FALSE; 01035 } 01036 01037 /* write variance data */ 01038 if (wt_var(fp, hmm) == FALSE) { 01039 jlog("Error: write_binhmm: failed to write HMM variance data\n"); 01040 return FALSE; 01041 } 01042 01043 /* write density data */ 01044 if (wt_dens(fp, hmm) == FALSE) { 01045 jlog("Error: write_binhmm: failed to write density data\n"); 01046 return FALSE; 01047 } 01048 01049 /* write stream weight data */ 01050 if (hmm->opt.stream_info.num > 1) { 01051 if (wt_streamweight(fp, hmm) == FALSE) { 01052 jlog("Error: write_binhmm: failed to write stream weights data\n"); 01053 return FALSE; 01054 } 01055 } 01056 01057 /* write tmix data */ 01058 if (hmm->is_tied_mixture) { 01059 if (wt_tmix(fp, hmm) == FALSE) { 01060 jlog("Error: write_binhmm: failed to write tied-mixture codebook data\n"); 01061 return FALSE; 01062 } 01063 } 01064 01065 /* write mixture pdf data */ 01066 if (mpdf_macro) { 01067 if (wt_mpdf(fp, hmm) == FALSE) { 01068 jlog("Error: write_binhmm: failed to write mixture pdf data\n"); 01069 return FALSE; 01070 } 01071 } 01072 01073 /* write state data */ 01074 if (wt_state(fp, hmm, mpdf_macro) == FALSE) { 01075 jlog("Error: write_binhmm: failed to write HMM state data\n"); 01076 return FALSE; 01077 } 01078 01079 /* write model data */ 01080 if (wt_data(fp, hmm) == FALSE) { 01081 jlog("Error: write_binhmm: failed to write HMM data\n"); 01082 return FALSE; 01083 } 01084 01085 /* free pointer->index work area */ 01086 if (mpdf_macro) free(mpdf_index); 01087 free(tr_index); 01088 free(vr_index); 01089 if (hmm->opt.stream_info.num > 1) free(streamweight_index); 01090 free(dens_index); 01091 if (hmm->is_tied_mixture) free(tm_index); 01092 free(st_index); 01093 01094 return (TRUE); 01095 }