julius/output_module.c

説明を見る。
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 /**********************************************************************/
00033 /* process online/offline status  */
00034 
00045 static void
00046 status_process_online(Recog *recog, void *dummy)
00047 {
00048   module_send(module_sd, "<STARTPROC/>\n.\n");
00049 }
00060 static void
00061 status_process_offline(Recog *recog, void *dummy)
00062 {
00063   module_send(module_sd, "<STOPPROC/>\n.\n");
00064 }
00065 
00066 /**********************************************************************/
00067 /* decode outcode "WLPSwlps" to each boolean value */
00068 /* default: "WLPS" */
00069 static boolean out1_word = FALSE, out1_lm = FALSE, out1_phone = FALSE, out1_score = FALSE;
00070 static boolean out2_word = TRUE, out2_lm = TRUE, out2_phone = TRUE, out2_score = TRUE;
00071 static boolean out1_never = TRUE, out2_never = FALSE;
00072 #ifdef CONFIDENCE_MEASURE
00073 static boolean out2_cm = TRUE;
00074 #endif
00075 
00088 void
00089 decode_output_selection(char *str)
00090 {
00091   int i;
00092   out1_word = out1_lm = out1_phone = out1_score = FALSE;
00093   out2_word = out2_lm = out2_phone = out2_score = FALSE;
00094 #ifdef CONFIDENCE_MEASURE
00095   out2_cm = FALSE;
00096 #endif
00097   for(i = strlen(str) - 1; i >= 0; i--) {
00098     switch(str[i]) {
00099     case 'W': out2_word  = TRUE; break;
00100     case 'L': out2_lm    = TRUE; break;
00101     case 'P': out2_phone = TRUE; break;
00102     case 'S': out2_score = TRUE; break;
00103     case 'w': out1_word  = TRUE; break;
00104     case 'l': out1_lm    = TRUE; break;
00105     case 'p': out1_phone = TRUE; break;
00106     case 's': out1_score = TRUE; break;
00107 #ifdef CONFIDENCE_MEASURE
00108     case 'C': out2_cm    = TRUE; break;
00109 #endif
00110     default:
00111       fprintf(stderr, "Error: unknown outcode `%c', ignored\n", str[i]);
00112       break;
00113     }
00114   }
00115   out1_never = ! (out1_word | out1_lm | out1_phone | out1_score);
00116   out2_never = ! (out2_word | out2_lm | out2_phone | out2_score
00117 #ifdef CONFIDENCE_MEASURE
00118                   | out2_cm
00119 #endif
00120                   );
00121 
00122 }
00123 
00138 static void
00139 msock_word_out1(WORD_ID w, RecogProcess *r)
00140 {
00141   int j;
00142   static char buf[MAX_HMMNAME_LEN];
00143   WORD_INFO *winfo;
00144 
00145   winfo = r->lm->winfo;
00146 
00147   if (out1_word) {
00148     module_send(module_sd, " WORD=\"%s\"", winfo->woutput[w]);
00149   }
00150   if (out1_lm) {
00151     module_send(module_sd, " CLASSID=\"%s\"", winfo->wname[w]);
00152   }
00153   if (out1_phone) {
00154     module_send(module_sd, " PHONE=\"");
00155     for(j=0;j<winfo->wlen[w];j++) {
00156       center_name(winfo->wseq[w][j]->name, buf);
00157       if (j == 0) module_send(module_sd, "%s", buf);
00158       else module_send(module_sd, " %s", buf);
00159     }
00160     module_send(module_sd, "\"");
00161   }
00162 }
00163 
00178 static void
00179 msock_word_out2(WORD_ID w, RecogProcess *r)
00180 {
00181   int j;
00182   static char buf[MAX_HMMNAME_LEN];
00183   WORD_INFO *winfo;
00184 
00185   winfo = r->lm->winfo;
00186 
00187   if (out2_word) {
00188     module_send(module_sd, " WORD=\"%s\"", winfo->woutput[w]);
00189   }
00190   if (out2_lm) {
00191     module_send(module_sd, " CLASSID=\"%s\"", winfo->wname[w]);
00192   }
00193   if (out2_phone) {
00194     module_send(module_sd, " PHONE=\"");
00195     for(j=0;j<winfo->wlen[w];j++) {
00196       center_name(winfo->wseq[w][j]->name, buf);
00197       if (j == 0) module_send(module_sd, "%s", buf);
00198       else module_send(module_sd, " %s", buf);
00199     }
00200     module_send(module_sd, "\"");
00201   }
00202 }
00203 
00204 
00205 /**********************************************************************/
00206 /* 1st pass output */
00207 
00218 static void
00219 status_pass1_begin(Recog *recog, void *dummy)
00220 {
00221   module_send(module_sd, "<STARTRECOG/>\n.\n");
00222 }
00223 
00246 static void
00247 result_pass1_current(Recog *recog, void *dummy)
00248 {
00249   int i;
00250   WORD_INFO *winfo;
00251   WORD_ID *seq;
00252   int num;
00253   RecogProcess *r;
00254   boolean multi;
00255 
00256   if (out1_never) return;       /* no output specified */
00257 
00258   if (recog->process_list->next != NULL) multi = TRUE;
00259   else multi = FALSE;
00260 
00261   for(r=recog->process_list;r;r=r->next) {
00262     if (! r->live) continue;
00263     if (! r->have_interim) continue;
00264 
00265     winfo = r->lm->winfo;
00266     seq = r->result.pass1.word;
00267     num = r->result.pass1.word_num;
00268 
00269     if (multi) {
00270       module_send(module_sd, "<RECOGOUT ID=\"SR%02d\" NAME=\"%s\">\n", r->config->id, r->config->name);
00271     } else {
00272       module_send(module_sd, "<RECOGOUT>\n");
00273     }
00274     if (out1_score) {
00275       module_send(module_sd, "  <PHYPO PASS=\"1\" SCORE=\"%f\" FRAME=\"%d\" TIME=\"%ld\"/>\n", r->result.pass1.score, r->result.num_frame, time(NULL));
00276     } else {
00277       module_send(module_sd, "  <PHYPO PASS=\"1\" FRAME=\"%d\" TIME=\"%ld\"/>\n", r->result.num_frame, time(NULL));
00278     }
00279     for (i=0;i<num;i++) {
00280       module_send(module_sd, "    <WHYPO");
00281       msock_word_out1(seq[i], r);
00282       module_send(module_sd, "/>\n");
00283     }
00284     module_send(module_sd, "  </PHYPO>\n</RECOGOUT>\n.\n");
00285   }
00286 }
00287 
00311 static void
00312 result_pass1_final(Recog *recog, void *dummy)
00313 {
00314   int i;
00315   RecogProcess *r;
00316   boolean multi;
00317 
00318   if (out1_never) return;       /* no output specified */
00319 
00320   if (recog->process_list->next != NULL) multi = TRUE;
00321   else multi = FALSE;
00322 
00323   for(r=recog->process_list;r;r=r->next) {
00324     if (! r->live) continue;
00325     if (r->result.status < 0) continue; /* search already failed  */
00326 
00327     if (multi) {
00328       module_send(module_sd, "<RECOGOUT ID=\"SR%02d\" NAME=\"%s\">\n", r->config->id, r->config->name);
00329     } else {
00330       module_send(module_sd, "<RECOGOUT>\n");
00331     }
00332     if (out1_score) {
00333       module_send(module_sd, "  <SHYPO PASS=\"1\" SCORE=\"%f\">\n", r->result.pass1.score);
00334     } else {
00335       module_send(module_sd, "  <SHYPO PASS=\"1\">\n", r->result.pass1.score);
00336     }
00337     for (i=0;i<r->result.pass1.word_num;i++) {
00338       module_send(module_sd, "    <WHYPO");
00339       msock_word_out1(r->result.pass1.word[i], r);
00340       module_send(module_sd, "/>\n");
00341     }
00342     module_send(module_sd, "  </SHYPO>\n</RECOGOUT>\n.\n");
00343   }
00344 }
00345 
00356 static void
00357 status_pass1_end(Recog *recog, void *dummy)
00358 {
00359   module_send(module_sd, "<ENDRECOG/>\n.\n");
00360 }
00361 
00362 /**********************************************************************/
00363 /* 2nd pass output */
00364 
00381 static void
00382 result_pass2(Recog *recog, void *dummy)
00383 {
00384   int i, n, num;
00385   WORD_INFO *winfo;
00386   WORD_ID *seq;
00387   int seqnum;
00388   Sentence *s;
00389   RecogProcess *r;
00390   boolean multi;
00391 
00392   if (recog->process_list->next != NULL) multi = TRUE;
00393   else multi = FALSE;
00394 
00395   for(r=recog->process_list;r;r=r->next) {
00396     if (! r->live) continue;
00397 
00398     if (r->result.status < 0) {
00399       switch(r->result.status) {
00400       case J_RESULT_STATUS_REJECT_POWER:
00401         module_send(module_sd, "<REJECTED REASON=\"by power\"");
00402         break;
00403       case J_RESULT_STATUS_TERMINATE:
00404         module_send(module_sd, "<REJECTED REASON=\"input terminated by request\"");
00405         break;
00406       case J_RESULT_STATUS_ONLY_SILENCE:
00407         module_send(module_sd, "<REJECTED REASON=\"result has pause words only\"");
00408         break;
00409       case J_RESULT_STATUS_REJECT_GMM:
00410         module_send(module_sd, "<REJECTED REASON=\"by GMM\"");
00411         break;
00412       case J_RESULT_STATUS_REJECT_SHORT:
00413         module_send(module_sd, "<REJECTED REASON=\"too short input\"");
00414         break;
00415       case J_RESULT_STATUS_FAIL:
00416         module_send(module_sd, "<RECOGFAIL");
00417         break;
00418       }
00419       if (multi) {
00420         module_send(module_sd, " ID=\"SR%02d\" NAME=\"%s\"", r->config->id, r->config->name);
00421       }
00422       module_send(module_sd, "/>\n.\n");
00423       continue;
00424     }
00425 
00426     if (out2_never) continue;   /* no output specified */
00427 
00428     winfo = r->lm->winfo;
00429     num = r->result.sentnum;
00430 
00431     if (multi) {
00432       module_send(module_sd, "<RECOGOUT ID=\"SR%02d\" NAME=\"%s\">\n", r->config->id, r->config->name);
00433     } else {
00434       module_send(module_sd, "<RECOGOUT>\n");
00435     }
00436     for(n=0;n<num;n++) {
00437       s = &(r->result.sent[n]);
00438       seq = s->word;
00439       seqnum = s->word_num;
00440       
00441       module_send(module_sd, "  <SHYPO RANK=\"%d\"", n+1);
00442       if (out2_score) {
00443         module_send(module_sd, " SCORE=\"%f\"", s->score);
00444         if (r->lmtype == LM_PROB) {
00445           if (separate_score_flag) {
00446             module_send(module_sd, " AMSCORE=\"%f\" LMSCORE=\"%f\"", s->score_am, s->score_lm);
00447           }
00448         }
00449       }
00450       if (r->lmtype == LM_DFA) {
00451         /* output which grammar the best hypothesis belongs to */
00452         module_send(module_sd, " GRAM=\"%d\"", s->gram_id);
00453       }
00454       
00455       module_send(module_sd, ">\n");
00456       for (i=0;i<seqnum;i++) {
00457         module_send(module_sd, "    <WHYPO");
00458         msock_word_out2(seq[i], r);
00459 #ifdef CONFIDENCE_MEASURE
00460 #ifdef CM_MULTIPLE_ALPHA
00461         /* currently not handle multiple alpha output */
00462 #else
00463         if (out2_cm) {
00464           module_send(module_sd, " CM=\"%5.3f\"", s->confidence[i]);
00465         }
00466 #endif
00467 #endif /* CONFIDENCE_MEASURE */
00468         module_send(module_sd, "/>\n");
00469       }
00470       module_send(module_sd, "  </SHYPO>\n");
00471     }
00472     module_send(module_sd, "</RECOGOUT>\n.\n");
00473 
00474   }
00475 
00476 }
00477 
00478 
00479 /**********************************************************************/
00480 /* word graph output */
00481 
00496 static void
00497 result_graph(Recog *recog, void *dummy)
00498 {
00499   WordGraph *wg;
00500   int i;
00501   int nodenum, arcnum;
00502   WORD_INFO *winfo;
00503   WordGraph *root;
00504   RecogProcess *r;
00505   boolean multi;
00506 
00507   if (recog->process_list->next != NULL) multi = TRUE;
00508   else multi = FALSE;
00509 
00510   for(r=recog->process_list;r;r=r->next) {
00511     if (! r->live) continue;
00512     if (r->result.wg == NULL) continue; /* no graph obtained */
00513 
00514     winfo = r->lm->winfo;
00515     root = r->result.wg;
00516     nodenum = r->graph_totalwordnum;
00517     arcnum = 0;
00518     for(wg=root;wg;wg=wg->next) {
00519       arcnum += wg->rightwordnum;
00520     }
00521 
00522     module_send(module_sd, "<GRAPHOUT");
00523     if (multi) module_send(module_sd, " ID=\"SR%02d\" NAME=\"%s\"", r->config->id, r->config->name);
00524     module_send(module_sd, " NODENUM=\"%d\" ARCNUM=\"%d\">\n", nodenum, arcnum);
00525     for(wg=root;wg;wg=wg->next) {
00526       module_send(module_sd, "    <NODE GID=\"%d\"", wg->id);
00527       msock_word_out2(wg->wid, r);
00528       module_send(module_sd, " BEGIN=\"%d\"", wg->lefttime);
00529       module_send(module_sd, " END=\"%d\"", wg->righttime);
00530       module_send(module_sd, "/>\n");
00531     }
00532     for(wg=root;wg;wg=wg->next) {
00533       for(i=0;i<wg->rightwordnum;i++) {
00534         module_send(module_sd, "    <ARC FROM=\"%d\" TO=\"%d\"/>\n", wg->id, wg->rightword[i]->id);
00535       }
00536     }
00537     module_send(module_sd, "</GRAPHOUT>\n.\n");
00538   }
00539 }
00540 
00551 static void
00552 status_recready(Recog *recog, void *dummy)
00553 {
00554   module_send(module_sd, "<INPUT STATUS=\"LISTEN\" TIME=\"%ld\"/>\n.\n", time(NULL));
00555 }
00556 
00567 static void
00568 status_recstart(Recog *recog, void *dummy)
00569 {
00570   module_send(module_sd, "<INPUT STATUS=\"STARTREC\" TIME=\"%ld\"/>\n.\n", time(NULL));
00571 }
00582 static void
00583 status_recend(Recog *recog, void *dummy)
00584 {
00585   module_send(module_sd, "<INPUT STATUS=\"ENDREC\" TIME=\"%ld\"/>\n.\n", time(NULL));
00586 }
00599 static void
00600 status_param(Recog *recog, void *dummy)
00601 {
00602   MFCCCalc *mfcc;
00603   boolean multi;
00604   int frames;
00605   int msec;
00606 
00607   if (recog->mfcclist->next != NULL) multi = TRUE;
00608   else multi = FALSE;
00609 
00610   for(mfcc=recog->mfcclist;mfcc;mfcc=mfcc->next) {
00611     frames = mfcc->param->samplenum;
00612     msec = (float)mfcc->param->samplenum * (float)recog->jconf->input.period * (float)recog->jconf->input.frameshift / 10000.0;
00613     if (multi) {
00614       module_send(module_sd, "<INPUTPARAM MFCCID=\"%02d\" FRAMES=\"%d\" MSEC=\"%d\"/>\n.\n", mfcc->id, frames, msec);
00615     } else {
00616       module_send(module_sd, "<INPUTPARAM FRAMES=\"%d\" MSEC=\"%d\"/>\n.\n", frames, msec);
00617     }
00618   }
00619 }
00620 
00621 /********************* RESULT OUTPUT FOR GMM *************************/
00631 static void
00632 result_gmm(Recog *recog, void *dummy)
00633 {
00634   module_send(module_sd, "<GMM RESULT=\"%s\"", recog->gc->max_d->name);
00635 #ifdef CONFIDENCE_MEASURE
00636   module_send(module_sd, " CMSCORE=\"%f\"", recog->gc->gmm_max_cm);
00637 #endif
00638   module_send(module_sd, "/>\n.\n");
00639 }
00640 
00651 void
00652 send_gram_info(RecogProcess *r)
00653 {
00654   MULTIGRAM *m;
00655   char buf[1024];
00656 
00657   if (r->lmtype == LM_PROB) {
00658     module_send(module_sd, "<GRAMMAR STATUS=\"ERROR\" REASON=\"NOT A GRAMMAR-BASED LM\"/>\n.\n");
00659     return;
00660   }
00661   module_send(module_sd, "<GRAMINFO>\n");
00662   for(m=r->lm->grammars;m;m=m->next) {
00663     buf[0] = '\0';
00664     if (m->dfa) {
00665       snprintf(buf, 1024, ", %3d categories, %4d nodes",
00666                m->dfa->term_num, m->dfa->state_num);
00667     }
00668     if (m->newbie) strcat(buf, " (new)");
00669     if (m->hook != 0) {
00670       strcat(buf, " (next:");
00671       if (m->hook & MULTIGRAM_DELETE) {
00672         strcat(buf, " delete");
00673       }
00674       if (m->hook & MULTIGRAM_ACTIVATE) {
00675         strcat(buf, " activate");
00676       }
00677       if (m->hook & MULTIGRAM_DEACTIVATE) {
00678         strcat(buf, " deactivate");
00679       }
00680       if (m->hook & MULTIGRAM_MODIFIED) {
00681         strcat(buf, " modified");
00682       }
00683       strcat(buf, ")");
00684     }
00685     module_send(module_sd, "  #%2d: [%-11s] %4d words%s \"%s\"\n",
00686                 m->id,
00687                 m->active ? "active" : "inactive",
00688                 m->winfo->num,
00689                 buf,
00690                 m->name);
00691   }
00692   if (r->lm->dfa != NULL) {
00693     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);
00694   }
00695   module_send(module_sd, "</GRAMINFO>\n.\n");
00696 }
00697 
00698 /**********************************************************************/
00699 /* register functions for module output */
00710 void
00711 setup_output_msock(Recog *recog, void *data)
00712 {
00713   callback_add(recog, CALLBACK_EVENT_PROCESS_ONLINE, status_process_online, data);
00714   callback_add(recog, CALLBACK_EVENT_PROCESS_OFFLINE, status_process_offline, data);
00715   //callback_add(recog, CALLBACK_EVENT_STREAM_BEGIN,     , data);
00716   //callback_add(recog, CALLBACK_EVENT_STREAM_END,        , data);
00717   callback_add(recog, CALLBACK_EVENT_SPEECH_READY, status_recready, data);
00718   callback_add(recog, CALLBACK_EVENT_SPEECH_START, status_recstart, data);
00719   callback_add(recog, CALLBACK_EVENT_SPEECH_STOP, status_recend, data);
00720   callback_add(recog, CALLBACK_EVENT_PASS1_BEGIN, status_pass1_begin, data);
00721   callback_add(recog, CALLBACK_EVENT_PASS1_END, status_pass1_end, data);
00722   callback_add(recog, CALLBACK_RESULT_PASS1_INTERIM, result_pass1_current, data);
00723   callback_add(recog, CALLBACK_RESULT_PASS1, result_pass1_final, data);
00724 
00725   callback_add(recog, CALLBACK_STATUS_PARAM, status_param, data);
00726 
00727   callback_add(recog, CALLBACK_RESULT, result_pass2, data); // rejected, failed
00728   callback_add(recog, CALLBACK_RESULT_GMM, result_gmm, data);
00729   /* below will not be called if "-graphout" not specified */
00730   callback_add(recog, CALLBACK_RESULT_GRAPH, result_graph, data);
00731 
00732   //callback_add(recog, CALLBACK_EVENT_PAUSE, status_pause, data);
00733   //callback_add(recog, CALLBACK_EVENT_RESUME, status_resume, data);
00734 
00735 }

Juliusに対してThu Jul 23 12:16:22 2009に生成されました。  doxygen 1.5.1