julius/output_module.c

Go to the documentation of this file.
00001 
00018 /*
00019  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00020  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00021  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00022  * All rights reserved
00023  */
00024 
00025 #include "app.h"
00026 
00027 #include <time.h>
00028 
00029 extern int module_sd;
00030 extern boolean separate_score_flag;
00031 
00032 
00034 static char *hookstr[] = {"", "delete", "activate", "deactivate"};
00035 
00036 /**********************************************************************/
00037 /* process online/offline status  */
00038 
00049 static void
00050 status_process_online(Recog *recog, void *dummy)
00051 {
00052   module_send(module_sd, "<STARTPROC/>\n.\n");
00053 }
00064 static void
00065 status_process_offline(Recog *recog, void *dummy)
00066 {
00067   module_send(module_sd, "<STOPPROC/>\n.\n");
00068 }
00069 
00070 /**********************************************************************/
00071 /* decode outcode "WLPSwlps" to each boolean value */
00072 /* default: "WLPS" */
00073 static boolean out1_word = FALSE, out1_lm = FALSE, out1_phone = FALSE, out1_score = FALSE;
00074 static boolean out2_word = TRUE, out2_lm = TRUE, out2_phone = TRUE, out2_score = TRUE;
00075 static boolean out1_never = TRUE, out2_never = FALSE;
00076 #ifdef CONFIDENCE_MEASURE
00077 static boolean out2_cm = TRUE;
00078 #endif
00079 
00092 void
00093 decode_output_selection(char *str)
00094 {
00095   int i;
00096   out1_word = out1_lm = out1_phone = out1_score = FALSE;
00097   out2_word = out2_lm = out2_phone = out2_score = FALSE;
00098 #ifdef CONFIDENCE_MEASURE
00099   out2_cm = FALSE;
00100 #endif
00101   for(i = strlen(str) - 1; i >= 0; i--) {
00102     switch(str[i]) {
00103     case 'W': out2_word  = TRUE; break;
00104     case 'L': out2_lm    = TRUE; break;
00105     case 'P': out2_phone = TRUE; break;
00106     case 'S': out2_score = TRUE; break;
00107     case 'w': out1_word  = TRUE; break;
00108     case 'l': out1_lm    = TRUE; break;
00109     case 'p': out1_phone = TRUE; break;
00110     case 's': out1_score = TRUE; break;
00111 #ifdef CONFIDENCE_MEASURE
00112     case 'C': out2_cm    = TRUE; break;
00113 #endif
00114     default:
00115       fprintf(stderr, "Error: unknown outcode `%c', ignored\n", str[i]);
00116       break;
00117     }
00118   }
00119   out1_never = ! (out1_word | out1_lm | out1_phone | out1_score);
00120   out2_never = ! (out2_word | out2_lm | out2_phone | out2_score
00121 #ifdef CONFIDENCE_MEASURE
00122                   | out2_cm
00123 #endif
00124                   );
00125 
00126 }
00127 
00142 static void
00143 msock_word_out1(WORD_ID w, RecogProcess *r)
00144 {
00145   int j;
00146   static char buf[MAX_HMMNAME_LEN];
00147   WORD_INFO *winfo;
00148 
00149   winfo = r->lm->winfo;
00150 
00151   if (out1_word) {
00152     module_send(module_sd, " WORD=\"%s\"", winfo->woutput[w]);
00153   }
00154   if (out1_lm) {
00155     module_send(module_sd, " CLASSID=\"%s\"", winfo->wname[w]);
00156   }
00157   if (out1_phone) {
00158     module_send(module_sd, " PHONE=\"");
00159     for(j=0;j<winfo->wlen[w];j++) {
00160       center_name(winfo->wseq[w][j]->name, buf);
00161       if (j == 0) module_send(module_sd, "%s", buf);
00162       else module_send(module_sd, " %s", buf);
00163     }
00164     module_send(module_sd, "\"");
00165   }
00166 }
00167 
00182 static void
00183 msock_word_out2(WORD_ID w, RecogProcess *r)
00184 {
00185   int j;
00186   static char buf[MAX_HMMNAME_LEN];
00187   WORD_INFO *winfo;
00188 
00189   winfo = r->lm->winfo;
00190 
00191   if (out2_word) {
00192     module_send(module_sd, " WORD=\"%s\"", winfo->woutput[w]);
00193   }
00194   if (out2_lm) {
00195     module_send(module_sd, " CLASSID=\"%s\"", winfo->wname[w]);
00196   }
00197   if (out2_phone) {
00198     module_send(module_sd, " PHONE=\"");
00199     for(j=0;j<winfo->wlen[w];j++) {
00200       center_name(winfo->wseq[w][j]->name, buf);
00201       if (j == 0) module_send(module_sd, "%s", buf);
00202       else module_send(module_sd, " %s", buf);
00203     }
00204     module_send(module_sd, "\"");
00205   }
00206 }
00207 
00208 
00209 /**********************************************************************/
00210 /* 1st pass output */
00211 
00222 static void
00223 status_pass1_begin(Recog *recog, void *dummy)
00224 {
00225   module_send(module_sd, "<STARTRECOG/>\n.\n");
00226 }
00227 
00250 static void
00251 result_pass1_current(Recog *recog, void *dummy)
00252 {
00253   int i;
00254   WORD_INFO *winfo;
00255   WORD_ID *seq;
00256   int num;
00257   RecogProcess *r;
00258   boolean multi;
00259 
00260   if (out1_never) return;       /* no output specified */
00261 
00262   if (recog->process_list->next != NULL) multi = TRUE;
00263   else multi = FALSE;
00264 
00265   for(r=recog->process_list;r;r=r->next) {
00266     if (! r->live) continue;
00267     if (! r->have_interim) continue;
00268 
00269     winfo = r->lm->winfo;
00270     seq = r->result.pass1.word;
00271     num = r->result.pass1.word_num;
00272 
00273     if (multi) {
00274       module_send(module_sd, "<RECOGOUT ID=\"SR%02d\" NAME=\"%s\">\n", r->config->id, r->config->name);
00275     } else {
00276       module_send(module_sd, "<RECOGOUT>\n");
00277     }
00278     if (out1_score) {
00279       module_send(module_sd, "  <PHYPO PASS=\"1\" SCORE=\"%f\" FRAME=\"%d\" TIME=\"%ld\"/>\n", r->result.pass1.score, r->result.num_frame, time(NULL));
00280     } else {
00281       module_send(module_sd, "  <PHYPO PASS=\"1\" FRAME=\"%d\" TIME=\"%ld\"/>\n", r->result.num_frame, time(NULL));
00282     }
00283     for (i=0;i<num;i++) {
00284       module_send(module_sd, "    <WHYPO");
00285       msock_word_out1(seq[i], r);
00286       module_send(module_sd, "/>\n");
00287     }
00288     module_send(module_sd, "  </PHYPO>\n</RECOGOUT>\n.\n");
00289   }
00290 }
00291 
00315 static void
00316 result_pass1_final(Recog *recog, void *dummy)
00317 {
00318   int i;
00319   RecogProcess *r;
00320   boolean multi;
00321 
00322   if (out1_never) return;       /* no output specified */
00323 
00324   if (recog->process_list->next != NULL) multi = TRUE;
00325   else multi = FALSE;
00326 
00327   for(r=recog->process_list;r;r=r->next) {
00328     if (! r->live) continue;
00329     if (r->result.status < 0) continue; /* search already failed  */
00330 
00331     if (multi) {
00332       module_send(module_sd, "<RECOGOUT ID=\"SR%02d\" NAME=\"%s\">\n", r->config->id, r->config->name);
00333     } else {
00334       module_send(module_sd, "<RECOGOUT>\n");
00335     }
00336     if (out1_score) {
00337       module_send(module_sd, "  <SHYPO PASS=\"1\" SCORE=\"%f\">\n", r->result.pass1.score);
00338     } else {
00339       module_send(module_sd, "  <SHYPO PASS=\"1\">\n", r->result.pass1.score);
00340     }
00341     for (i=0;i<r->result.pass1.word_num;i++) {
00342       module_send(module_sd, "    <WHYPO");
00343       msock_word_out1(r->result.pass1.word[i], r);
00344       module_send(module_sd, "/>\n");
00345     }
00346     module_send(module_sd, "  </SHYPO>\n</RECOGOUT>\n.\n");
00347   }
00348 }
00349 
00360 static void
00361 status_pass1_end(Recog *recog, void *dummy)
00362 {
00363   module_send(module_sd, "<ENDRECOG/>\n.\n");
00364 }
00365 
00366 /**********************************************************************/
00367 /* 2nd pass output */
00368 
00385 static void
00386 result_pass2(Recog *recog, void *dummy)
00387 {
00388   int i, n, num;
00389   WORD_INFO *winfo;
00390   WORD_ID *seq;
00391   int seqnum;
00392   Sentence *s;
00393   RecogProcess *r;
00394   boolean multi;
00395 
00396   if (recog->process_list->next != NULL) multi = TRUE;
00397   else multi = FALSE;
00398 
00399   for(r=recog->process_list;r;r=r->next) {
00400     if (! r->live) continue;
00401 
00402     if (r->result.status < 0) {
00403       switch(r->result.status) {
00404       case J_RESULT_STATUS_REJECT_POWER:
00405         module_send(module_sd, "<REJECTED REASON=\"by power\"");
00406         break;
00407       case J_RESULT_STATUS_TERMINATE:
00408         module_send(module_sd, "<REJECTED REASON=\"input terminated by request\"");
00409         break;
00410       case J_RESULT_STATUS_ONLY_SILENCE:
00411         module_send(module_sd, "<REJECTED REASON=\"result has pause words only\"");
00412         break;
00413       case J_RESULT_STATUS_REJECT_GMM:
00414         module_send(module_sd, "<REJECTED REASON=\"by GMM\"");
00415         break;
00416       case J_RESULT_STATUS_REJECT_SHORT:
00417         module_send(module_sd, "<REJECTED REASON=\"too short input\"");
00418         break;
00419       case J_RESULT_STATUS_FAIL:
00420         module_send(module_sd, "<RECOGFAIL");
00421         break;
00422       }
00423       if (multi) {
00424         module_send(module_sd, " ID=\"SR%02d\" NAME=\"%s\"", r->config->id, r->config->name);
00425       }
00426       module_send(module_sd, "/>\n.\n");
00427       continue;
00428     }
00429 
00430     if (out2_never) continue;   /* no output specified */
00431 
00432     winfo = r->lm->winfo;
00433     num = r->result.sentnum;
00434 
00435     if (multi) {
00436       module_send(module_sd, "<RECOGOUT ID=\"SR%02d\" NAME=\"%s\">\n", r->config->id, r->config->name);
00437     } else {
00438       module_send(module_sd, "<RECOGOUT>\n");
00439     }
00440     for(n=0;n<num;n++) {
00441       s = &(r->result.sent[n]);
00442       seq = s->word;
00443       seqnum = s->word_num;
00444       
00445       module_send(module_sd, "  <SHYPO RANK=\"%d\"", n+1);
00446       if (out2_score) {
00447         module_send(module_sd, " SCORE=\"%f\"", s->score);
00448         if (r->lmtype == LM_PROB) {
00449           if (separate_score_flag) {
00450             module_send(module_sd, " AMSCORE=\"%f\" LMSCORE=\"%f\"", s->score_am, s->score_lm);
00451           }
00452         }
00453       }
00454       if (r->lmtype == LM_DFA) {
00455         /* output which grammar the best hypothesis belongs to */
00456         module_send(module_sd, " GRAM=\"%d\"", s->gram_id);
00457       }
00458       
00459       module_send(module_sd, ">\n");
00460       for (i=0;i<seqnum;i++) {
00461         module_send(module_sd, "    <WHYPO");
00462         msock_word_out2(seq[i], r);
00463 #ifdef CONFIDENCE_MEASURE
00464 #ifdef CM_MULTIPLE_ALPHA
00465         /* currently not handle multiple alpha output */
00466 #else
00467         if (out2_cm) {
00468           module_send(module_sd, " CM=\"%5.3f\"", s->confidence[i]);
00469         }
00470 #endif
00471 #endif /* CONFIDENCE_MEASURE */
00472         module_send(module_sd, "/>\n");
00473       }
00474       module_send(module_sd, "  </SHYPO>\n");
00475     }
00476     module_send(module_sd, "</RECOGOUT>\n.\n");
00477 
00478   }
00479 
00480 }
00481 
00482 
00483 /**********************************************************************/
00484 /* word graph output */
00485 
00500 static void
00501 result_graph(Recog *recog, void *dummy)
00502 {
00503   WordGraph *wg;
00504   int i;
00505   int nodenum, arcnum;
00506   WORD_INFO *winfo;
00507   WordGraph *root;
00508   RecogProcess *r;
00509   boolean multi;
00510 
00511   if (recog->process_list->next != NULL) multi = TRUE;
00512   else multi = FALSE;
00513 
00514   for(r=recog->process_list;r;r=r->next) {
00515     if (! r->live) continue;
00516     if (r->result.wg == NULL) continue; /* no graph obtained */
00517 
00518     winfo = r->lm->winfo;
00519     root = r->result.wg;
00520     nodenum = r->graph_totalwordnum;
00521     arcnum = 0;
00522     for(wg=root;wg;wg=wg->next) {
00523       arcnum += wg->rightwordnum;
00524     }
00525 
00526     module_send(module_sd, "<GRAPHOUT");
00527     if (multi) module_send(module_sd, " ID=\"SR%02d\" NAME=\"%s\"", r->config->id, r->config->name);
00528     module_send(module_sd, " NODENUM=\"%d\" ARCNUM=\"%d\">\n", nodenum, arcnum);
00529     for(wg=root;wg;wg=wg->next) {
00530       module_send(module_sd, "    <NODE GID=\"%d\"", wg->id);
00531       msock_word_out2(wg->wid, r);
00532       module_send(module_sd, " BEGIN=\"%d\"", wg->lefttime);
00533       module_send(module_sd, " END=\"%d\"", wg->righttime);
00534       module_send(module_sd, "/>\n");
00535     }
00536     for(wg=root;wg;wg=wg->next) {
00537       for(i=0;i<wg->rightwordnum;i++) {
00538         module_send(module_sd, "    <ARC FROM=\"%d\" TO=\"%d\"/>\n", wg->id, wg->rightword[i]->id);
00539       }
00540     }
00541     module_send(module_sd, "</GRAPHOUT>\n.\n");
00542   }
00543 }
00544 
00555 static void
00556 status_recready(Recog *recog, void *dummy)
00557 {
00558   module_send(module_sd, "<INPUT STATUS=\"LISTEN\" TIME=\"%ld\"/>\n.\n", time(NULL));
00559 }
00560 
00571 static void
00572 status_recstart(Recog *recog, void *dummy)
00573 {
00574   module_send(module_sd, "<INPUT STATUS=\"STARTREC\" TIME=\"%ld\"/>\n.\n", time(NULL));
00575 }
00586 static void
00587 status_recend(Recog *recog, void *dummy)
00588 {
00589   module_send(module_sd, "<INPUT STATUS=\"ENDREC\" TIME=\"%ld\"/>\n.\n", time(NULL));
00590 }
00603 static void
00604 status_param(Recog *recog, void *dummy)
00605 {
00606   MFCCCalc *mfcc;
00607   boolean multi;
00608   int frames;
00609   int msec;
00610 
00611   if (recog->mfcclist->next != NULL) multi = TRUE;
00612   else multi = FALSE;
00613 
00614   for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00615     frames = mfcc->param->samplenum;
00616     msec = (float)mfcc->param->samplenum * (float)recog->jconf->input.period * (float)recog->jconf->input.frameshift / 10000.0;
00617     if (multi) {
00618       module_send(module_sd, "<INPUTPARAM MFCCID=\"%02d\" FRAMES=\"%d\" MSEC=\"%d\"/>\n.\n", mfcc->id, frames, msec);
00619     } else {
00620       module_send(module_sd, "<INPUTPARAM FRAMES=\"%d\" MSEC=\"%d\"/>\n.\n", frames, msec);
00621     }
00622   }
00623 }
00624 
00625 /********************* RESULT OUTPUT FOR GMM *************************/
00635 static void
00636 result_gmm(Recog *recog, void *dummy)
00637 {
00638   module_send(module_sd, "<GMM RESULT=\"%s\"", recog->gc->max_d->name);
00639 #ifdef CONFIDENCE_MEASURE
00640   module_send(module_sd, " CMSCORE=\"%f\"", recog->gc->gmm_max_cm);
00641 #endif
00642   module_send(module_sd, "/>\n.\n");
00643 }
00644 
00655 void
00656 send_gram_info(RecogProcess *r)
00657 {
00658   MULTIGRAM *m;
00659 
00660   module_send(module_sd, "<GRAMINFO>\n");
00661   for(m=r->lm->grammars;m;m=m->next) {
00662     module_send(module_sd, "  #%2d: [%-11s] %4d words, %3d categories, %4d nodes",
00663                 m->id,
00664                 m->active ? "active" : "inactive",
00665                 m->winfo->num, m->dfa->term_num, m->dfa->state_num);
00666     if (m->newbie) module_send(module_sd, " (new)");
00667     if (m->hook != MULTIGRAM_DEFAULT) {
00668       module_send(module_sd, " (next: %s)", hookstr[m->hook]);
00669     }
00670     module_send(module_sd, " \"%s\"\n", m->name);
00671   }
00672   if (r->lm->dfa != NULL) {
00673     module_send(module_sd, "  Global:            %4d words, %3d categories, %4d nodes\n", r->lm->winfo->num, r->lm->dfa->term_num, r->lm->dfa->state_num);
00674   }
00675   module_send(module_sd, "</GRAMINFO>\n.\n");
00676 }
00677 
00678 /**********************************************************************/
00679 /* register functions for module output */
00690 void
00691 setup_output_msock(Recog *recog, void *data)
00692 {
00693   callback_add(recog, CALLBACK_EVENT_PROCESS_ONLINE, status_process_online, data);
00694   callback_add(recog, CALLBACK_EVENT_PROCESS_OFFLINE, status_process_offline, data);
00695   //callback_add(recog, CALLBACK_EVENT_STREAM_BEGIN,     , data);
00696   //callback_add(recog, CALLBACK_EVENT_STREAM_END,        , data);
00697   callback_add(recog, CALLBACK_EVENT_SPEECH_READY, status_recready, data);
00698   callback_add(recog, CALLBACK_EVENT_SPEECH_START, status_recstart, data);
00699   callback_add(recog, CALLBACK_EVENT_SPEECH_STOP, status_recend, data);
00700   callback_add(recog, CALLBACK_EVENT_PASS1_BEGIN, status_pass1_begin, data);
00701   callback_add(recog, CALLBACK_EVENT_PASS1_END, status_pass1_end, data);
00702   callback_add(recog, CALLBACK_RESULT_PASS1_INTERIM, result_pass1_current, data);
00703   callback_add(recog, CALLBACK_RESULT_PASS1, result_pass1_final, data);
00704 
00705   callback_add(recog, CALLBACK_STATUS_PARAM, status_param, data);
00706 
00707   callback_add(recog, CALLBACK_RESULT, result_pass2, data); // rejected, failed
00708   callback_add(recog, CALLBACK_RESULT_GMM, result_gmm, data);
00709   /* below will not be called if "-graphout" not specified */
00710   callback_add(recog, CALLBACK_RESULT_GRAPH, result_graph, data);
00711 
00712   //callback_add(recog, CALLBACK_EVENT_PAUSE, status_pause, data);
00713   //callback_add(recog, CALLBACK_EVENT_RESUME, status_resume, data);
00714 
00715 }

Generated on Tue Dec 18 15:59:50 2007 for Julius by  doxygen 1.5.4