1 /**
2  * @file   put_htkdata_info.c
3  *
4  * <JA>
5  * @brief  %HMM �������ħ�ѥ�᡼���ξ����ƥ����Ƚ��Ϥ���
6  * </JA>
7  *
8  * <EN>
9  * @brief  Output %HMM and parameter information to standard out
10  * </EN>
11  *
12  * @author Akinobu LEE
13  * @date   Tue Feb 15 23:36:00 2005
14  *
15  * $Revision: 1.5 $
16  *
17  */
18 /*
19  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
20  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
21  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
22  * All rights reserved
23  */
24 
25 #include <sent/stddefs.h>
26 #include <sent/htk_hmm.h>
27 #include <sent/htk_param.h>
28 #include <sent/hmm.h>
29 #include <sent/hmm_calc.h>
30 
31 
32 /**
33  * Output transition matrix.
34  *
35  * @param fp [in] file descriptor
36  * @param t [in] pointer to a transion matrix
37  */
38 void
put_htk_trans(FILE * fp,HTK_HMM_Trans * t)39 put_htk_trans(FILE *fp, HTK_HMM_Trans *t)
40 {
41   int i,j;
42 
43   if (fp == NULL) return;
44   if (t == NULL) {
45     fprintf(fp, "no transition\n");
46   } else {
47     for (i=0;i<t->statenum;i++) {
48       for (j=0;j<t->statenum;j++) {
49 	fprintf(fp, " %e", t->a[i][j]);
50       }
51       fprintf(fp, "\n");
52     }
53   }
54 }
55 
56 /**
57  * Output variance vector (diagonal).
58  *
59  * @param fp [in] file descriptor
60  * @param v [in] pointer to a variance data
61  */
62 void
put_htk_var(FILE * fp,HTK_HMM_Var * v)63 put_htk_var(FILE *fp, HTK_HMM_Var *v)
64 {
65   int i;
66 
67   if (fp == NULL) return;
68   if (v == NULL) {
69     fprintf(fp, "no covariance\n");
70   } else {
71     fprintf(fp, "variance(%d): (may be inversed)", v->len);
72     for (i=0;i<v->len;i++) {
73       fprintf(fp, " %e", v->vec[i]);
74     }
75     fprintf(fp, "\n");
76   }
77 }
78 
79 /**
80  * Output a density information, mean and variance.
81  *
82  * @param fp [in] file descriptor
83  * @param d [in] pointer to a density data
84  */
85 void
put_htk_dens(FILE * fp,HTK_HMM_Dens * d)86 put_htk_dens(FILE *fp, HTK_HMM_Dens *d)
87 {
88   int i;
89 
90   if (fp == NULL) return;
91   if (d == NULL) {
92     fprintf(fp, "no dens\n");
93   } else {
94     fprintf(fp, "mean(%d):", d->meanlen);
95     for (i=0;i<d->meanlen;i++) {
96       fprintf(fp, " %e", d->mean[i]);
97     }
98     fprintf(fp, "\n");
99     put_htk_var(fp, d->var);
100     fprintf(fp, "gconst: %e\n", d->gconst);
101   }
102 }
103 
104 /**
105  * Output a mixture component.
106  *
107  * @param fp [in] file descriptor
108  * @param m [in] pointer to %HMM mixture PDF
109  */
110 void
put_htk_mpdf(FILE * fp,HTK_HMM_PDF * m)111 put_htk_mpdf(FILE *fp, HTK_HMM_PDF *m)
112 {
113   int i;
114   GCODEBOOK *book;
115 
116   if (m == NULL) {
117     fprintf(fp, "no mixture pdf\n");
118     return;
119   }
120   if (m->name != NULL) fprintf(fp, "  [~p \"%s\"] (stream %d)\n", m->name, m->stream_id + 1);
121   if (m->tmix) {
122     book = (GCODEBOOK *)m->b;
123     fprintf(fp, "  tmix codebook = \"%s\" (size=%d)\n", book->name, book->num);
124     for (i=0;i<m->mix_num;i++) {
125       fprintf(fp, "    weight%d = %f\n", i, exp(m->bweight[i]));
126     }
127   } else {
128     for (i=0;i<m->mix_num;i++) {
129       fprintf(fp, "-- d%d (weight=%f)--\n",i+1,exp(m->bweight[i]));
130       put_htk_dens(fp, m->b[i]);
131     }
132   }
133 }
134 
135 /**
136  * Output a state.
137  *
138  * @param fp [in] file descriptor
139  * @param s [in] pointer to %HMM state
140  */
141 void
put_htk_state(FILE * fp,HTK_HMM_State * s)142 put_htk_state(FILE *fp, HTK_HMM_State *s)
143 {
144   int st;
145 
146   if (fp == NULL) return;
147   if (s == NULL) {
148     fprintf(fp, "no output state\n");
149   } else {
150     if (s->name != NULL) fprintf(fp, "[~s \"%s\"]\n", s->name);
151     for (st=0;st<s->nstream;st++) {
152       fprintf(fp, "stream %d:", st + 1);
153       if (s->w != NULL) {
154 	fprintf(fp, " (weight=%f", s->w->weight[st]);
155 	if (s->w->name != NULL) {
156 	  fprintf(fp, " <- ~w \"%s\"", s->w->name);
157 	}
158 	fprintf(fp, ")");
159       }
160       fprintf(fp, "\n");
161       put_htk_mpdf(fp, s->pdf[st]);
162     }
163   }
164 }
165 
166 /**
167  * Output %HMM model, number of states and information for each state.
168  *
169  * @param fp [in] file descriptor
170  * @param h [in] pointer to %HMM model
171  */
172 void
put_htk_hmm(FILE * fp,HTK_HMM_Data * h)173 put_htk_hmm(FILE *fp, HTK_HMM_Data *h)
174 {
175   int i;
176 
177   if (fp == NULL) return;
178   fprintf(fp, "name: %s\n", h->name);
179   fprintf(fp, "state num: %d\n", h->state_num);
180   for (i=0;i<h->state_num;i++) {
181     fprintf(fp, "**** state %d ****\n",i+1);
182     put_htk_state(fp, h->s[i]);
183   }
184   put_htk_trans(fp, h->tr);
185 }
186 
187 /**
188  * Output logical %HMM data and its mapping status.
189  *
190  * @param fp [in] file descriptor
191  * @param logical [in] pointer to a logical %HMM
192  */
193 void
put_logical_hmm(FILE * fp,HMM_Logical * logical)194 put_logical_hmm(FILE *fp, HMM_Logical *logical)
195 {
196   if (fp == NULL) return;
197   fprintf(fp, "name: %s\n", logical->name);
198   if (logical->is_pseudo) {
199     fprintf(fp, "mapped to: %s (pseudo)\n", logical->body.pseudo->name);
200   } else {
201     fprintf(fp, "mapped to: %s\n", logical->body.defined->name);
202   }
203 }
204 
205 /**
206  * Output transition arcs of an HMM instance.
207  *
208  * @param fp [in] file descriptor
209  * @param d [in] pointer to a HMM instance.
210  */
211 void
put_hmm_arc(FILE * fp,HMM * d)212 put_hmm_arc(FILE *fp, HMM *d)
213 {
214   A_CELL *ac;
215   int i;
216 
217   if (fp == NULL) return;
218   fprintf(fp, "total len: %d\n", d->len);
219   for (i=0;i<d->len;i++) {
220     fprintf(fp, "node-%d\n", i);
221     for (ac=d->state[i].ac;ac;ac=ac->next) {
222       fprintf(fp, " arc: %d %f (%f)\n",ac->arc, ac->a, pow(10.0, ac->a));
223     }
224   }
225   if (d->accept_ac_a != LOG_ZERO) {
226     fprintf(fp, "last arc to accept state: %f\n", d->accept_ac_a);
227   }
228 }
229 
230 /**
231  * Output output probability information of an HMM instance.
232  *
233  * @param fp [in] file descriptor
234  * @param d [in] pointer to a HMM instance.
235  */
236 void
put_hmm_outprob(FILE * fp,HMM * d)237 put_hmm_outprob(FILE *fp, HMM *d)
238 {
239   int i;
240 
241   if (fp == NULL) return;
242   fprintf(fp, "total len: %d\n", d->len);
243   for (i=0;i<d->len;i++) {
244     fprintf(fp, "n%d\n", i);
245     if (d->state[i].is_pseudo_state) {
246       fprintf(fp, "[[[pseudo state cluster with %d states]]]\n", d->state[i].out.cdset->num);
247     } else {
248       put_htk_state(fp, d->state[i].out.state);
249     }
250   }
251 }
252 
253 /**
254  * Output an HMM instance.
255  *
256  * @param fp [in] file descriptor
257  * @param d [in] pointer to a HMM instance.
258  */
259 void
put_hmm(FILE * fp,HMM * d)260 put_hmm(FILE *fp, HMM *d)
261 {
262   if (fp == NULL) return;
263   put_hmm_arc(fp, d);
264   put_hmm_outprob(fp, d);
265 }
266 
267 /**
268  * Output parameter header.
269  *
270  * @param fp [in] file descriptor
271  * @param h [in] pointer to a parameter header information
272  */
273 void
put_param_head(FILE * fp,HTK_Param_Header * h)274 put_param_head(FILE *fp, HTK_Param_Header *h)
275 {
276   char buf[128];
277 
278   if (fp == NULL) return;
279   fprintf(fp, "num of samples: %d\n", h->samplenum);
280   fprintf(fp, "window shift: %d ms\n", h->wshift / 10000);
281   fprintf(fp, "bytes per sample: %d\n", h->sampsize);
282   fprintf(fp, "parameter type: %s\n", param_code2str(buf, h->samptype, FALSE));
283 }
284 
285 /**
286  * Output array of vectors.
287  *
288  * @param fp [in] file descriptor
289  * @param p [in] pointer to vector array represented as [0..num-1][0...veclen-1]
290  * @param num [in] number of vectors in @a p
291  * @param veclen [in] length of each vector
292  */
293 void
put_vec(FILE * fp,VECT ** p,int num,short veclen)294 put_vec(FILE *fp, VECT **p, int num, short veclen)
295 {
296   int t,v;
297 
298   if (fp == NULL) return;
299   for (t=0;t<num;t++) {
300     fprintf(fp, "%d:\t%8.3f",t,p[t][0]);
301     for (v=1;v<veclen;v++) {
302       if ((v % 10) ==0) fprintf(fp, "\n\t");
303       fprintf(fp, "%8.3f", p[t][v]);
304     }
305     fprintf(fp, "\n");
306   }
307 }
308 
309 /**
310  * Output the whole parameter information, including header and all vectors.
311  *
312  * @param fp [in] file descriptor
313  * @param pinfo [in] pointer to parameter structure.
314  */
315 void
put_param(FILE * fp,HTK_Param * pinfo)316 put_param(FILE *fp, HTK_Param *pinfo)
317 {
318   if (fp == NULL) return;
319   put_param_head(fp, &(pinfo->header));
320   put_vec(fp, pinfo->parvec, pinfo->samplenum, pinfo->veclen);
321 }
322 
323 /**
324  * Output the length of an input parameter by number of frames and seconds.
325  *
326  * @param fp [in] file descriptor
327  * @param pinfo [in] pointer to parameter structure.
328  */
329 void
put_param_info(FILE * fp,HTK_Param * pinfo)330 put_param_info(FILE *fp, HTK_Param *pinfo)
331 {
332   HTK_Param_Header *h;
333   float sec;
334 
335   if (fp == NULL) return;
336   h = &(pinfo->header);
337   sec = (float)h->samplenum * (float)h->wshift / 10000000;
338   fprintf(fp, "length: %d frames (%.2f sec.)\n", h->samplenum, sec);
339 }
340 
341 /**
342  * Output total statistic informations of the %HMM definition data.
343  *
344  * @param fp [in] file descriptor
345  * @param hmminfo [in] %HMM definition data.
346  */
347 void
print_hmmdef_info(FILE * fp,HTK_HMM_INFO * hmminfo)348 print_hmmdef_info(FILE *fp, HTK_HMM_INFO *hmminfo)
349 {
350   char buf[128];
351   int i, d;
352 
353   if (fp == NULL) return;
354   fprintf(fp, " HMM Info:\n");
355   fprintf(fp, "    %d models, %d states, %d mpdfs, %d Gaussians are defined\n", hmminfo->totalhmmnum, hmminfo->totalstatenum, hmminfo->totalpdfnum, hmminfo->totalmixnum);
356   fprintf(fp, "\t      model type = ");
357   if (hmminfo->is_tied_mixture) fprintf(fp, "has tied-mixture, ");
358   if (hmminfo->opt.stream_info.num > 1) fprintf(fp, "multi-stream, ");
359 #ifdef ENABLE_MSD
360   if (hmminfo->has_msd) fprintf(fp, "MSD-HMM, ");
361 #endif
362   fprintf(fp, "context dependency handling %s\n",
363 	     (hmminfo->is_triphone) ? "ON" : "OFF");
364 
365   fprintf(fp, "      training parameter = %s\n",param_code2str(buf, hmminfo->opt.param_type, FALSE));
366   fprintf(fp, "\t   vector length = %d\n", hmminfo->opt.vec_size);
367   fprintf(fp, "\tnumber of stream = %d\n", hmminfo->opt.stream_info.num);
368   fprintf(fp, "\t     stream info =");
369   for(d=0,i=0;i<hmminfo->opt.stream_info.num;i++) {
370     if (hmminfo->opt.stream_info.vsize[i] == 1) {
371       fprintf(fp, " [%d]", d);
372     } else {
373       fprintf(fp, " [%d-%d]", d, d + hmminfo->opt.stream_info.vsize[i] - 1);
374     }
375     d += hmminfo->opt.stream_info.vsize[i];
376   }
377   fprintf(fp, "\n");
378   fprintf(fp, "\tcov. matrix type = %s\n", get_cov_str(hmminfo->opt.cov_type));
379   fprintf(fp, "\t   duration type = %s\n", get_dur_str(hmminfo->opt.dur_type));
380 
381   if (hmminfo->is_tied_mixture) {
382     fprintf(fp, "\t    codebook num = %d\n", hmminfo->codebooknum);
383     fprintf(fp, "       max codebook size = %d\n", hmminfo->maxcodebooksize);
384   }
385   fprintf(fp, "\tmax mixture size = %d Gaussians\n", hmminfo->maxmixturenum);
386   fprintf(fp, "     max length of model = %d states\n", hmminfo->maxstatenum);
387 
388   fprintf(fp, "     logical base phones = %d\n", hmminfo->basephone.num);
389 
390   fprintf(fp, "       model skip trans. = ");
391   if (hmminfo->need_multipath) {
392     fprintf(fp, "exist, require multi-path handling\n");
393   } else {
394     fprintf(fp, "not exist, no multi-path handling\n");
395   }
396 
397   if (hmminfo->need_multipath) {
398     fprintf(fp, "      skippable models =");
399     {
400       HTK_HMM_Data *dtmp;
401       int n = 0;
402       for (dtmp = hmminfo->start; dtmp; dtmp = dtmp->next) {
403 	if (is_skippable_model(dtmp)) {
404 	  fprintf(fp, " %s", dtmp->name);
405 	  n++;
406 	}
407       }
408       if (n == 0) {
409 	fprintf(fp, " none\n");
410       } else {
411 	fprintf(fp, " (%d model(s))\n", n);
412       }
413     }
414   }
415 }
416