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