Julius 4.2
julius/output_file.c
説明を見る。
00001 
00018 /*
00019  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00020  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00021  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00022  * All rights reserved
00023  */
00024 
00025 #include "app.h"
00026 
00031 #define TEXTWIDTH 70
00032 #define MAXBUFLEN 4096 ///< Maximum line length of a message sent from a client
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       /* output alignment result if exist */
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; /* no graphout specified */
00259     if (multi) fprintf(fp, "[#%d %s]\n", r->config->id, r->config->name);
00260 
00261     winfo = r->lm->winfo;
00262 
00263     /* debug: output all graph word info */
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;    /* no confnet obtained */
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