00001
00018
00019
00020
00021
00022
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
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
00072
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
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;
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;
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;
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
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;
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
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
00466 #else
00467 if (out2_cm) {
00468 module_send(module_sd, " CM=\"%5.3f\"", s->confidence[i]);
00469 }
00470 #endif
00471 #endif
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
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;
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
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
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
00696
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);
00708 callback_add(recog, CALLBACK_RESULT_GMM, result_gmm, data);
00709
00710 callback_add(recog, CALLBACK_RESULT_GRAPH, result_graph, data);
00711
00712
00713
00714
00715 }