00001
00018
00019
00020
00021
00022
00023
00024
00025 #include <sent/stddefs.h>
00026 #include <sent/htk_hmm.h>
00027 #include <sent/htk_param.h>
00028 #include <sent/hmm.h>
00029 #include <sent/hmm_calc.h>
00030
00031 static char buf[512];
00032
00033
00040 void
00041 put_htk_trans(FILE *fp, HTK_HMM_Trans *t)
00042 {
00043 int i,j;
00044
00045 if (fp == NULL) return;
00046 if (t == NULL) {
00047 fprintf(fp, "no transition\n");
00048 } else {
00049 for (i=0;i<t->statenum;i++) {
00050 for (j=0;j<t->statenum;j++) {
00051 fprintf(fp, " %e", t->a[i][j]);
00052 }
00053 fprintf(fp, "\n");
00054 }
00055 }
00056 }
00057
00064 void
00065 put_htk_var(FILE *fp, HTK_HMM_Var *v)
00066 {
00067 int i;
00068
00069 if (fp == NULL) return;
00070 if (v == NULL) {
00071 fprintf(fp, "no covariance\n");
00072 } else {
00073 fprintf(fp, "variance(%d): (may be inversed)", v->len);
00074 for (i=0;i<v->len;i++) {
00075 fprintf(fp, " %e", v->vec[i]);
00076 }
00077 fprintf(fp, "\n");
00078 }
00079 }
00080
00087 void
00088 put_htk_dens(FILE *fp, HTK_HMM_Dens *d)
00089 {
00090 int i;
00091
00092 if (fp == NULL) return;
00093 if (d == NULL) {
00094 fprintf(fp, "no dens\n");
00095 } else {
00096 fprintf(fp, "mean(%d):", d->meanlen);
00097 for (i=0;i<d->meanlen;i++) {
00098 fprintf(fp, " %e", d->mean[i]);
00099 }
00100 fprintf(fp, "\n");
00101 put_htk_var(fp, d->var);
00102 fprintf(fp, "gconst: %e\n", d->gconst);
00103 }
00104 }
00105
00112 void
00113 put_htk_state(FILE *fp, HTK_HMM_State *s)
00114 {
00115 int i;
00116
00117 if (fp == NULL) return;
00118 if (s == NULL) {
00119 fprintf(fp, "no output state\n");
00120 } else {
00121 fprintf(fp, "mixture num: %d\n", s->mix_num);
00122 for (i=0;i<s->mix_num;i++) {
00123 fprintf(fp, "-- d%d (weight=%f)--\n",i+1,pow(10.0, s->bweight[i]));
00124 put_htk_dens(fp, s->b[i]);
00125 }
00126 }
00127 }
00128
00135 void
00136 put_htk_hmm(FILE *fp, HTK_HMM_Data *h)
00137 {
00138 int i;
00139
00140 if (fp == NULL) return;
00141 fprintf(fp, "name: %s\n", h->name);
00142 fprintf(fp, "state num: %d\n", h->state_num);
00143 for (i=0;i<h->state_num;i++) {
00144 fprintf(fp, "**** state %d ****\n",i+1);
00145 put_htk_state(fp, h->s[i]);
00146 }
00147 put_htk_trans(fp, h->tr);
00148 }
00149
00156 void
00157 put_logical_hmm(FILE *fp, HMM_Logical *logical)
00158 {
00159 if (fp == NULL) return;
00160 fprintf(fp, "name: %s\n", logical->name);
00161 if (logical->is_pseudo) {
00162 fprintf(fp, "mapped to: %s (pseudo)\n", logical->body.pseudo->name);
00163 } else {
00164 fprintf(fp, "mapped to: %s\n", logical->body.defined->name);
00165 }
00166 }
00167
00174 void
00175 put_hmm_arc(FILE *fp, HMM *d)
00176 {
00177 A_CELL *ac;
00178 int i;
00179
00180 if (fp == NULL) return;
00181 fprintf(fp, "total len: %d\n", d->len);
00182 for (i=0;i<d->len;i++) {
00183 fprintf(fp, "node-%d\n", i);
00184 for (ac=d->state[i].ac;ac;ac=ac->next) {
00185 fprintf(fp, " arc: %d %f (%f)\n",ac->arc, ac->a, pow(10.0, ac->a));
00186 }
00187 }
00188 if (d->accept_ac_a != LOG_ZERO) {
00189 fprintf(fp, "last arc to accept state: %f\n", d->accept_ac_a);
00190 }
00191 }
00192
00199 void
00200 put_hmm_outprob(FILE *fp, HMM *d)
00201 {
00202 int i;
00203
00204 if (fp == NULL) return;
00205 fprintf(fp, "total len: %d\n", d->len);
00206 for (i=0;i<d->len;i++) {
00207 fprintf(fp, "n%d\n", i);
00208 if (d->state[i].is_pseudo_state) {
00209 fprintf(fp, "[[[pseudo state cluster with %d states]]]\n", d->state[i].out.cdset->num);
00210 } else {
00211 put_htk_state(fp, d->state[i].out.state);
00212 }
00213 }
00214 }
00215
00222 void
00223 put_hmm(FILE *fp, HMM *d)
00224 {
00225 if (fp == NULL) return;
00226 put_hmm_arc(fp, d);
00227 put_hmm_outprob(fp, d);
00228 }
00229
00236 void
00237 put_param_head(FILE *fp, HTK_Param_Header *h)
00238 {
00239 if (fp == NULL) return;
00240 fprintf(fp, "num of samples: %d\n", h->samplenum);
00241 fprintf(fp, "window shift: %d ms\n", h->wshift / 10000);
00242 fprintf(fp, "bytes per sample: %d\n", h->sampsize);
00243 fprintf(fp, "parameter type: %s\n", param_code2str(buf, h->samptype, FALSE));
00244 }
00245
00254 void
00255 put_vec(FILE *fp, VECT **p, int num, short veclen)
00256 {
00257 int t,v;
00258
00259 if (fp == NULL) return;
00260 for (t=0;t<num;t++) {
00261 fprintf(fp, "%d:\t%8.3f",t,p[t][0]);
00262 for (v=1;v<veclen;v++) {
00263 if ((v % 10) ==0) fprintf(fp, "\n\t");
00264 fprintf(fp, "%8.3f", p[t][v]);
00265 }
00266 fprintf(fp, "\n");
00267 }
00268 }
00269
00276 void
00277 put_param(FILE *fp, HTK_Param *pinfo)
00278 {
00279 if (fp == NULL) return;
00280 put_param_head(fp, &(pinfo->header));
00281 put_vec(fp, pinfo->parvec, pinfo->samplenum, pinfo->veclen);
00282 }
00283
00290 void
00291 put_param_info(FILE *fp, HTK_Param *pinfo)
00292 {
00293 HTK_Param_Header *h;
00294 float sec;
00295
00296 if (fp == NULL) return;
00297 h = &(pinfo->header);
00298 sec = (float)h->samplenum * (float)h->wshift / 10000000;
00299 fprintf(fp, "length: %d frames (%.2f sec.)\n", h->samplenum, sec);
00300 }
00301
00309 static int
00310 get_max_mixture_num(HTK_HMM_INFO *hmminfo)
00311 {
00312 HTK_HMM_State *st;
00313 int maxmixnum;
00314
00315 maxmixnum = 0;
00316 for (st = hmminfo->ststart; st; st = st->next) {
00317 if (maxmixnum < st->mix_num) maxmixnum = st->mix_num;
00318 }
00319 return(maxmixnum);
00320 }
00321
00328 void
00329 print_hmmdef_info(FILE *fp, HTK_HMM_INFO *hmminfo)
00330 {
00331 if (fp == NULL) return;
00332 fprintf(fp, " HMM Info:\n");
00333 fprintf(fp, " %d models, %d states, %d mixtures are defined\n",
00334 hmminfo->totalhmmnum, hmminfo->totalstatenum, hmminfo->totalmixnum);
00335 fprintf(fp, "\t model type = ");
00336 if (hmminfo->is_tied_mixture) fprintf(fp, "tied-mixture, ");
00337 fprintf(fp, "context dependency handling %s\n",
00338 (hmminfo->is_triphone) ? "ON" : "OFF");
00339
00340 fprintf(fp, " training parameter = %s\n",param_code2str(buf, hmminfo->opt.param_type, FALSE));
00341 fprintf(fp, "\t vector length = %d\n", hmminfo->opt.vec_size);
00342 fprintf(fp, "\tcov. matrix type = %s\n", get_cov_str(hmminfo->opt.cov_type));
00343 fprintf(fp, "\t duration type = %s\n", get_dur_str(hmminfo->opt.dur_type));
00344
00345 if (hmminfo->is_tied_mixture) {
00346 fprintf(fp, "\t codebook num = %d\n", hmminfo->codebooknum);
00347 fprintf(fp, " max codebook size = %d\n", hmminfo->maxcodebooksize);
00348 }
00349 fprintf(fp, "\t max mixture num = %d\n", get_max_mixture_num(hmminfo));
00350 fprintf(fp, "\t max state num = %d\n", hmminfo->maxstatenum);
00351
00352 fprintf(fp, " logical base phones = %d\n", hmminfo->basephone.num);
00353
00354 fprintf(fp, "\t skipping path = ");
00355 if (hmminfo->need_multipath) {
00356 fprintf(fp, "exist, multi-path handling needed\n");
00357 } else {
00358 fprintf(fp, "not exist\n");
00359 }
00360
00361 if (hmminfo->need_multipath) {
00362 fprintf(fp, " skippable models =");
00363 {
00364 HTK_HMM_Data *dtmp;
00365 int n = 0;
00366 for (dtmp = hmminfo->start; dtmp; dtmp = dtmp->next) {
00367 if (is_skippable_model(dtmp)) {
00368 fprintf(fp, " %s", dtmp->name);
00369 n++;
00370 }
00371 }
00372 if (n == 0) {
00373 fprintf(fp, " none\n");
00374 } else {
00375 fprintf(fp, " (%d model(s))\n", n);
00376 }
00377 }
00378 }
00379 }