00001
00028
00029
00030
00031
00032
00033
00034
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
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
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
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
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
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
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
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
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
00703 did = search_tmid((GCODEBOOK *)(m->b));
00704 if ((GCODEBOOK *)m->b == tm_index[did]) {
00705
00706 dummy = -1;
00707 wrt(fp, &dummy, sizeof(short), 1);
00708 wrt(fp, &did, sizeof(unsigned int), 1);
00709 } else {
00710
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 {
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
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
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
00880 for(m=0;m<s->nstream;m++) {
00881
00882 if (wt_pdf_sub(fp, hmm, s->pdf[m]) == FALSE) return FALSE;
00883 }
00884 }
00885 if (hmm->opt.stream_info.num > 1) {
00886
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
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;
00966 }
00967 wrt(fp, &sid, sizeof(unsigned int), 1);
00968 }
00969 tid = search_trid(d->tr);
00970
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
00998
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
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
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
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
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
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
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
01044 if (wt_dens(fp, hmm) == FALSE) {
01045 jlog("Error: write_binhmm: failed to write density data\n");
01046 return FALSE;
01047 }
01048
01049
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
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
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
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
01080 if (wt_data(fp, hmm) == FALSE) {
01081 jlog("Error: write_binhmm: failed to write HMM data\n");
01082 return FALSE;
01083 }
01084
01085
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 }