00001
00018
00019
00020
00021
00022
00023
00024
00025 #include "app.h"
00026
00031 #define TEXTWIDTH 70
00032 #define MAXBUFLEN 4096
00033
00034 static char fname[MAXBUFLEN];
00035 static FILE *fp = NULL;
00036
00037 void
00038 outfile_set_fname(char *input_filename)
00039 {
00040 char *p;
00041
00042 strncpy(fname, input_filename, MAXBUFLEN);
00043 if ((p = strrchr(fname, '.')) != NULL) {
00044 *p = '\0';
00045 }
00046 strcat(fname, OUTPUT_FILE_SUFFIX);
00047 }
00048
00049 static void
00050 outfile_open(Recog *recog, void *dummy)
00051 {
00052 if ((fp = fopen(fname, "w")) == NULL) {
00053 fprintf(stderr, "output_rec: failed to open \"%s\", result not saved\n", fname);
00054 return;
00055 }
00056 }
00057
00058 static void
00059 outfile_close(Recog *recog, void *dummy)
00060 {
00061 if (fp != NULL) {
00062 fclose(fp);
00063 fprintf(stderr, "result written to \"%s\"\n", fname);
00064 }
00065 fp = NULL;
00066 }
00067
00068 static void
00069 outfile_sentence(Recog *recog, void *dummy)
00070 {
00071 RecogProcess *r;
00072 Sentence *s;
00073 WORD_INFO *winfo;
00074 WORD_ID *seq;
00075 int seqnum;
00076 int n, num;
00077 int i, j;
00078 boolean multi;
00079 static char phbuf[MAX_HMMNAME_LEN];
00080 SentenceAlign *align;
00081 HMM_Logical *p;
00082
00083 if (recog->process_list->next != NULL) multi = TRUE;
00084 else multi = FALSE;
00085
00086 for(r=recog->process_list;r;r=r->next) {
00087 if (! r->live) continue;
00088 if (multi) fprintf(fp, "[#%d %s]\n", r->config->id, r->config->name);
00089
00090 if (r->result.status < 0) {
00091 switch(r->result.status) {
00092 case J_RESULT_STATUS_REJECT_POWER:
00093 fprintf(fp, "<input rejected by power>\n");
00094 break;
00095 case J_RESULT_STATUS_TERMINATE:
00096 fprintf(fp, "<input teminated by request>\n");
00097 break;
00098 case J_RESULT_STATUS_ONLY_SILENCE:
00099 fprintf(fp, "<input rejected by decoder (silence input result)>\n");
00100 break;
00101 case J_RESULT_STATUS_REJECT_GMM:
00102 fprintf(fp, "<input rejected by GMM>\n");
00103 break;
00104 case J_RESULT_STATUS_REJECT_SHORT:
00105 fprintf(fp, "<input rejected by short input>\n");
00106 break;
00107 case J_RESULT_STATUS_FAIL:
00108 fprintf(fp, "<search failed>\n");
00109 break;
00110 }
00111 continue;
00112 }
00113
00114 winfo = r->lm->winfo;
00115 num = r->result.sentnum;
00116
00117 for(n=0;n<num;n++) {
00118 s = &(r->result.sent[n]);
00119 seq = s->word;
00120 seqnum = s->word_num;
00121
00122 fprintf(fp, "sentence%d:", n+1);
00123 for (i=0;i<seqnum;i++) {
00124 fprintf(fp, " %s", winfo->woutput[seq[i]]);
00125 }
00126 fprintf(fp, "\n");
00127
00128 fprintf(fp, "wseq%d:", n+1);
00129 for (i=0;i<seqnum;i++) {
00130 fprintf(fp, " %s", winfo->wname[seq[i]]);
00131 }
00132 fprintf(fp, "\n");
00133
00134 fprintf(fp, "phseq%d:", n+1);
00135 for (i=0;i<seqnum;i++) {
00136 if (i > 0) fprintf(fp, " |");
00137 for (j=0;j<winfo->wlen[seq[i]];j++) {
00138 center_name(winfo->wseq[seq[i]][j]->name, phbuf);
00139 fprintf(fp, " %s", phbuf);
00140 }
00141 }
00142 fprintf(fp, "\n");
00143
00144 #ifdef CONFIDENCE_MEASURE
00145 fprintf(fp, "cmscore%d:", n+1);
00146 for (i=0;i<seqnum;i++) {
00147 fprintf(fp, " %5.3f", s->confidence[i]);
00148 }
00149 fprintf(fp, "\n");
00150 #endif
00151 fprintf(fp, "score%d: %f", n+1, s->score);
00152 if (r->lmtype == LM_PROB) {
00153 fprintf(fp, " (AM: %f LM: %f)", s->score_am, s->score_lm);
00154 }
00155 fprintf(fp, "\n");
00156 if (r->lmtype == LM_DFA) {
00157 if (multigram_get_all_num(r->lm) > 1) {
00158 fprintf(fp, "grammar%d: %d\n", n+1, s->gram_id);
00159 }
00160 }
00161
00162 for (align = s->align; align; align = align->next) {
00163 fprintf(fp, "=== begin forced alignment ===\n");
00164 switch(align->unittype) {
00165 case PER_WORD:
00166 fprintf(fp, "-- word alignment --\n"); break;
00167 case PER_PHONEME:
00168 fprintf(fp, "-- phoneme alignment --\n"); break;
00169 case PER_STATE:
00170 fprintf(fp, "-- state alignment --\n"); break;
00171 }
00172 fprintf(fp, " id: from to n_score unit\n");
00173 fprintf(fp, " ----------------------------------------\n");
00174 for(i=0;i<align->num;i++) {
00175 fprintf(fp, "[%4d %4d] %f ", align->begin_frame[i], align->end_frame[i], align->avgscore[i]);
00176 switch(align->unittype) {
00177 case PER_WORD:
00178 fprintf(fp, "%s\t[%s]\n", winfo->wname[align->w[i]], winfo->woutput[align->w[i]]);
00179 break;
00180 case PER_PHONEME:
00181 p = align->ph[i];
00182 if (p->is_pseudo) {
00183 fprintf(fp, "{%s}\n", p->name);
00184 } else if (strmatch(p->name, p->body.defined->name)) {
00185 fprintf(fp, "%s\n", p->name);
00186 } else {
00187 fprintf(fp, "%s[%s]\n", p->name, p->body.defined->name);
00188 }
00189 break;
00190 case PER_STATE:
00191 p = align->ph[i];
00192 if (p->is_pseudo) {
00193 fprintf(fp, "{%s}", p->name);
00194 } else if (strmatch(p->name, p->body.defined->name)) {
00195 fprintf(fp, "%s", p->name);
00196 } else {
00197 fprintf(fp, "%s[%s]", p->name, p->body.defined->name);
00198 }
00199 if (r->am->hmminfo->multipath) {
00200 if (align->is_iwsp[i]) {
00201 fprintf(fp, " #%d (sp)\n", align->loc[i]);
00202 } else {
00203 fprintf(fp, " #%d\n", align->loc[i]);
00204 }
00205 } else {
00206 fprintf(fp, " #%d\n", align->loc[i]);
00207 }
00208 break;
00209 }
00210 }
00211
00212 fprintf(fp, "re-computed AM score: %f\n", align->allscore);
00213
00214 fprintf(fp, "=== end forced alignment ===\n");
00215 }
00216 }
00217 }
00218
00219 }
00220
00221 static void
00222 outfile_gmm(Recog *recog, void *dummy)
00223 {
00224 HTK_HMM_Data *d;
00225 GMMCalc *gc;
00226 int i;
00227
00228 gc = recog->gc;
00229
00230 fprintf(fp, "--- GMM result begin ---\n");
00231 i = 0;
00232 for(d=recog->gmm->start;d;d=d->next) {
00233 fprintf(fp, " [%8s: total=%f avg=%f]\n", d->name, gc->gmm_score[i], gc->gmm_score[i] / (float)gc->framecount);
00234 i++;
00235 }
00236 fprintf(fp, " max = \"%s\"", gc->max_d->name);
00237 #ifdef CONFIDENCE_MEASURE
00238 fprintf(fp, " (CM: %f)", gc->gmm_max_cm);
00239 #endif
00240 fprintf(fp, "\n");
00241 fprintf(fp, "--- GMM result end ---\n");
00242 }
00243
00244 static void
00245 outfile_graph(Recog *recog, void *dummy)
00246 {
00247 WordGraph *wg;
00248 int tw1, tw2, i;
00249 WORD_INFO *winfo;
00250 RecogProcess *r;
00251 boolean multi;
00252
00253 if (recog->process_list->next != NULL) multi = TRUE;
00254 else multi = FALSE;
00255
00256 for(r=recog->process_list;r;r=r->next) {
00257 if (! r->live) continue;
00258 if (r->result.wg == NULL) continue;
00259 if (multi) fprintf(fp, "[#%d %s]\n", r->config->id, r->config->name);
00260
00261 winfo = r->lm->winfo;
00262
00263
00264 wordgraph_dump(fp, r->result.wg, winfo);
00265
00266 fprintf(fp, "-------------------------- begin wordgraph show -------------------------\n");
00267 for(wg=r->result.wg;wg;wg=wg->next) {
00268 tw1 = (TEXTWIDTH * wg->lefttime) / r->peseqlen;
00269 tw2 = (TEXTWIDTH * wg->righttime) / r->peseqlen;
00270 fprintf(fp, "%4d:", wg->id);
00271 for(i=0;i<tw1;i++) fprintf(fp, " ");
00272 fprintf(fp, " %s\n", winfo->woutput[wg->wid]);
00273 fprintf(fp, "%4d:", wg->lefttime);
00274 for(i=0;i<tw1;i++) fprintf(fp, " ");
00275 fprintf(fp, "|");
00276 for(i=tw1+1;i<tw2;i++) fprintf(fp, "-");
00277 fprintf(fp, "|\n");
00278 }
00279 fprintf(fp, "-------------------------- end wordgraph show ---------------------------\n");
00280 }
00281 }
00282
00283 static void
00284 outfile_confnet(Recog *recog, void *dummy)
00285 {
00286 CN_CLUSTER *c;
00287 int i;
00288 RecogProcess *r;
00289 boolean multi;
00290
00291 if (recog->process_list->next != NULL) multi = TRUE;
00292 else multi = FALSE;
00293
00294 for(r=recog->process_list;r;r=r->next) {
00295 if (! r->live) continue;
00296 if (r->result.confnet == NULL) continue;
00297 if (multi) fprintf(fp, "[#%d %s]\n", r->config->id, r->config->name);
00298
00299 fprintf(fp, "---- begin confusion network ---\n");
00300 for(c=r->result.confnet;c;c=c->next) {
00301 for(i=0;i<c->wordsnum;i++) {
00302 fprintf(fp, "(%s:%.3f)", (c->words[i] == WORD_INVALID) ? "-" : r->lm->winfo->woutput[c->words[i]], c->pp[i]);
00303 if (i == 0) fprintf(fp, " ");
00304 }
00305 fprintf(fp, "\n");
00306 }
00307 fprintf(fp, "---- end confusion network ---\n");
00308 }
00309 }
00310
00311
00312 void
00313 setup_output_file(Recog *recog, void *data)
00314 {
00315 callback_add(recog, CALLBACK_EVENT_RECOGNITION_BEGIN, outfile_open, data);
00316 callback_add(recog, CALLBACK_EVENT_RECOGNITION_END, outfile_close, data);
00317 callback_add(recog, CALLBACK_RESULT, outfile_sentence, data);
00318 callback_add(recog, CALLBACK_RESULT_GMM, outfile_gmm, data);
00319 callback_add(recog, CALLBACK_RESULT_GRAPH, outfile_graph, data);
00320 callback_add(recog, CALLBACK_RESULT_CONFNET, outfile_confnet, data);
00321 }
00322