00001
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #include <julius/julius.h>
00066
00067 #ifdef PASS2_STRICT_IWCD
00068
00069 #undef TCD
00070
00071
00072
00073
00074
00075
00076
00077 #undef STOCKER_DEBUG
00078
00079 #ifdef STOCKER_DEBUG
00080 static int stocked_num = 0;
00081 static int reused_num = 0;
00082 static int new_num = 0;
00083 static int request_num = 0;
00084 #endif
00085
00098 static void
00099 free_node_exec(NODE *node)
00100 {
00101 if (node == NULL) return;
00102 free(node->g);
00103 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00104 if (node->region->graphout) {
00105 free(node->wordend_frame);
00106 free(node->wordend_gscore);
00107 }
00108 #endif
00109 free(node);
00110 }
00111
00126 void
00127 free_node(NODE *node)
00128 {
00129 if (node == NULL) return;
00130
00131 if (node->region->graphout) {
00132 if (node->prevgraph != NULL && node->prevgraph->saved == FALSE) {
00133 wordgraph_free(node->prevgraph);
00134 }
00135 }
00136
00137
00138 node->next = node->region->pass2.stocker_root;
00139 node->region->pass2.stocker_root = node;
00140
00141 #ifdef STOCKER_DEBUG
00142 stocked_num++;
00143 #endif
00144 }
00145
00162 void
00163 clear_stocker(StackDecode *s)
00164 {
00165 NODE *node, *tmp;
00166 node = s->stocker_root;
00167 while(node) {
00168 tmp = node->next;
00169 free_node_exec(node);
00170 node = tmp;
00171 }
00172 s->stocker_root = NULL;
00173
00174 #ifdef STOCKER_DEBUG
00175 jlog("DEBUG: %d times requested, %d times newly allocated, %d times reused\n", request_num, new_num, reused_num);
00176 stocked_num = 0;
00177 reused_num = 0;
00178 new_num = 0;
00179 request_num = 0;
00180 #endif
00181 }
00182
00203 NODE *
00204 cpy_node(NODE *dst, NODE *src)
00205 {
00206 int peseqlen;
00207
00208 peseqlen = src->region->peseqlen;
00209
00210 dst->next = src->next;
00211 dst->prev = src->prev;
00212 memcpy(dst->g, src->g, sizeof(LOGPROB) * peseqlen);
00213 memcpy(dst->seq, src->seq, sizeof(WORD_ID) * MAXSEQNUM);
00214 #ifdef CM_SEARCH
00215 #ifdef CM_MULTIPLE_ALPHA
00216 {
00217 int w;
00218 for(w=0;w<src->seqnum;w++) {
00219 memcpy(dst->cmscore[w], src->cmscore[w], sizeof(LOGPROB) * src->region->config->annotate.cm_alpha_num);
00220 }
00221 }
00222 #else
00223 memcpy(dst->cmscore, src->cmscore, sizeof(LOGPROB) * MAXSEQNUM);
00224 #endif
00225 #endif
00226 dst->seqnum = src->seqnum;
00227 dst->score = src->score;
00228 dst->bestt = src->bestt;
00229 dst->estimated_next_t = src->estimated_next_t;
00230 dst->endflag = src->endflag;
00231 dst->state = src->state;
00232 dst->tre = src->tre;
00233 if (src->region->ccd_flag) {
00234 dst->last_ph = src->last_ph;
00235 dst->last_ph_sp_attached = src->last_ph_sp_attached;
00236 }
00237 dst->totallscore = src->totallscore;
00238 dst->final_g = src->final_g;
00239 #ifdef VISUALIZE
00240 dst->popnode = src->popnode;
00241 #endif
00242
00243 if (src->region->graphout) {
00244 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00245 memcpy(dst->wordend_frame, src->wordend_frame, sizeof(short) * peseqlen);
00246 memcpy(dst->wordend_gscore, src->wordend_gscore, sizeof(LOGPROB) * peseqlen);
00247 #endif
00248 dst->prevgraph = src->prevgraph;
00249 dst->lastcontext = src->lastcontext;
00250 #ifndef GRAPHOUT_PRECISE_BOUNDARY
00251 dst->tail_g_score = src->tail_g_score;
00252 #endif
00253 }
00254 return(dst);
00255 }
00256
00277 NODE *
00278 newnode(RecogProcess *r)
00279 {
00280 NODE *tmp;
00281 int i;
00282 int peseqlen;
00283
00284 peseqlen = r->peseqlen;
00285
00286 #ifdef STOCKER_DEBUG
00287 request_num++;
00288 #endif
00289 if ((tmp = r->pass2.stocker_root) != NULL) {
00290
00291 r->pass2.stocker_root = tmp->next;
00292 #ifdef STOCKER_DEBUG
00293 stocked_num--;
00294 reused_num++;
00295 #endif
00296 } else {
00297
00298 tmp = (NODE *)mymalloc(sizeof(NODE));
00299 tmp->g = (LOGPROB *)mymalloc(sizeof(LOGPROB) * peseqlen);
00300 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00301 if (r->graphout) {
00302 tmp->wordend_frame = (short *)mymalloc(sizeof(short) * peseqlen);
00303 tmp->wordend_gscore = (LOGPROB *)mymalloc(sizeof(LOGPROB) * peseqlen);
00304 }
00305 #endif
00306 #ifdef STOCKER_DEBUG
00307 new_num++;
00308 #endif
00309 }
00310
00311
00312
00313 tmp->next=NULL;
00314 tmp->prev=NULL;
00315 tmp->last_ph = NULL;
00316 tmp->last_ph_sp_attached = FALSE;
00317 if (r->ccd_flag) {
00318 tmp->totallscore = LOG_ZERO;
00319 }
00320 tmp->endflag = FALSE;
00321 tmp->seqnum = 0;
00322 for(i = 0; i < peseqlen; i++) {
00323 tmp->g[i] = LOG_ZERO;
00324 }
00325 tmp->final_g = LOG_ZERO;
00326 #ifdef VISUALIZE
00327 tmp->popnode = NULL;
00328 #endif
00329 if (r->graphout) {
00330 tmp->prevgraph = NULL;
00331 tmp->lastcontext = NULL;
00332 }
00333
00334 tmp->region = r;
00335
00336 return(tmp);
00337 }
00338
00339
00340
00341
00342
00343
00344
00361 void
00362 malloc_wordtrellis(RecogProcess *r)
00363 {
00364 int maxwn;
00365 StackDecode *dwrk;
00366
00367 maxwn = r->lm->winfo->maxwn + 10;
00368 dwrk = &(r->pass2);
00369
00370 dwrk->wordtrellis[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00371 dwrk->wordtrellis[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00372
00373 dwrk->g = (LOGPROB *)mymalloc(sizeof(LOGPROB) * r->peseqlen);
00374
00375 dwrk->phmmlen_max = r->lm->winfo->maxwlen + 2;
00376 dwrk->phmmseq = (HMM_Logical **)mymalloc(sizeof(HMM_Logical *) * dwrk->phmmlen_max);
00377 if (r->lm->config->enable_iwsp && r->am->hmminfo->multipath) {
00378 dwrk->has_sp = (boolean *)mymalloc(sizeof(boolean) * dwrk->phmmlen_max);
00379 } else {
00380 dwrk->has_sp = NULL;
00381 }
00382
00383 dwrk->wef = NULL;
00384 dwrk->wes = NULL;
00385 dwrk->wend_token_frame[0] = NULL;
00386 dwrk->wend_token_frame[1] = NULL;
00387 dwrk->wend_token_gscore[0] = NULL;
00388 dwrk->wend_token_gscore[1] = NULL;
00389 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00390 if (r->graphout) {
00391 dwrk->wef = (short *)mymalloc(sizeof(short) * r->peseqlen);
00392 dwrk->wes = (LOGPROB *)mymalloc(sizeof(LOGPROB) * r->peseqlen);
00393 dwrk->wend_token_frame[0] = (short *)mymalloc(sizeof(short) * maxwn);
00394 dwrk->wend_token_frame[1] = (short *)mymalloc(sizeof(short) * maxwn);
00395 dwrk->wend_token_gscore[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00396 dwrk->wend_token_gscore[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00397 }
00398 #endif
00399 }
00400
00413 void
00414 free_wordtrellis(StackDecode *dwrk)
00415 {
00416 free(dwrk->wordtrellis[0]);
00417 free(dwrk->wordtrellis[1]);
00418 free(dwrk->g);
00419 free(dwrk->phmmseq);
00420 if (dwrk->has_sp) {
00421 free(dwrk->has_sp);
00422 dwrk->has_sp = NULL;
00423 }
00424 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00425 if (dwrk->wef) {
00426 free(dwrk->wef);
00427 free(dwrk->wes);
00428 free(dwrk->wend_token_frame[0]);
00429 free(dwrk->wend_token_frame[1]);
00430 free(dwrk->wend_token_gscore[0]);
00431 free(dwrk->wend_token_gscore[1]);
00432 dwrk->wef = NULL;
00433 }
00434 #endif
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00491 static void
00492 do_viterbi(LOGPROB *g, LOGPROB *g_new, HMM_Logical **phmmseq, boolean *has_sp, int phmmlen, HTK_Param *param, int framelen, int least_frame, LOGPROB *final_g, short *wordend_frame_src, short *wordend_frame_dst, LOGPROB *wordend_gscore_src, LOGPROB *wordend_gscore_dst, RecogProcess *r)
00493 {
00494 HMM *whmm;
00495 int wordhmmnum;
00496 int startt;
00497 LOGPROB tmpmax,tmpscore;
00498 A_CELL *ac;
00499 int t,i,j;
00500 boolean node_exist_p;
00501 int tn;
00502 int tl;
00503
00504
00505 StackDecode *dwrk;
00506 WORD_INFO *winfo;
00507 HTK_HMM_INFO *hmminfo;
00508 LOGPROB *framemaxscore;
00509 #ifdef SCAN_BEAM
00510 LOGPROB scan_beam_thres;
00511 #endif
00512
00513 dwrk = &(r->pass2);
00514 winfo = r->lm->winfo;
00515 hmminfo = r->am->hmminfo;
00516 framemaxscore = r->pass2.framemaxscore;
00517 #ifdef SCAN_BEAM
00518 scan_beam_thres = r->config->pass2.scan_beam_thres;
00519 #endif
00520
00521
00522 #ifdef TCD
00523 jlog("DEBUG: scan for:");
00524 for (i=0;i<phmmlen;i++) {
00525 jlog(" %s", phmmseq[i]->name);
00526 }
00527 jlog("\n");
00528 #endif
00529
00530
00531
00532 whmm = new_make_word_hmm(hmminfo, phmmseq, phmmlen, has_sp);
00533 if (whmm == NULL) {
00534 j_internal_error("Error: failed to make word hmm\n");
00535 }
00536 wordhmmnum = whmm->len;
00537 if (wordhmmnum >= winfo->maxwn + 10) {
00538 j_internal_error("do_viterbi: word too long (>%d)\n", winfo->maxwn + 10);
00539 }
00540
00541
00542
00543 for(t = framelen-1; t >=0 ; t--) {
00544 if (
00545 #ifdef SCAN_BEAM
00546 g[t] > framemaxscore[t] - scan_beam_thres &&
00547 #endif
00548 g[t] > LOG_ZERO) {
00549 break;
00550 }
00551 }
00552 if (t < 0) {
00553
00554 for(t=0;t<framelen;t++) {
00555 g_new[t] = LOG_ZERO;
00556 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00557 if (r->graphout) {
00558 wordend_frame_dst[t] = -1;
00559 wordend_gscore_dst[t] = LOG_ZERO;
00560 }
00561 #endif
00562 }
00563 free_hmm(whmm);
00564 return;
00565 }
00566 startt = t;
00567
00568
00569
00570 for(t=framelen-1;t>startt;t--) {
00571 g_new[t] = LOG_ZERO;
00572 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00573 if (r->graphout) {
00574 wordend_frame_dst[t] = -1;
00575 wordend_gscore_dst[t] = LOG_ZERO;
00576 }
00577 #endif
00578 }
00579
00580
00581
00582
00583
00584
00585 tn = 0; tl = 1;
00586
00587 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00588 if (r->graphout) {
00589 for(i=0;i<wordhmmnum;i++) {
00590 dwrk->wend_token_frame[tn][i] = -1;
00591 dwrk->wend_token_gscore[tn][i] = LOG_ZERO;
00592 }
00593 }
00594 #endif
00595
00596 if (! hmminfo->multipath) {
00597
00598
00599 for(i=0;i<wordhmmnum-1;i++) dwrk->wordtrellis[tn][i] = LOG_ZERO;
00600 dwrk->wordtrellis[tn][wordhmmnum-1] = g[startt] + outprob(&(r->am->hmmwrk), startt, &(whmm->state[wordhmmnum-1]), param);
00601 g_new[startt] = dwrk->wordtrellis[tn][0];
00602 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00603 if (r->graphout) {
00604 dwrk->wend_token_frame[tn][wordhmmnum-1] = wordend_frame_src[startt];
00605 dwrk->wend_token_gscore[tn][wordhmmnum-1] = wordend_gscore_src[startt];
00606 wordend_frame_dst[startt] = dwrk->wend_token_frame[tn][0];
00607 wordend_gscore_dst[startt] = dwrk->wend_token_gscore[tn][0];
00608 }
00609 #endif
00610 }
00611
00612
00613
00614 for(t = hmminfo->multipath ? startt : startt - 1; t >= 0; t--) {
00615
00616
00617
00618 i = tn; tn = tl; tl = i;
00619
00620 node_exist_p = FALSE;
00621
00622 if (! hmminfo->multipath) {
00623
00624
00625
00626 tmpscore = LOG_ZERO;
00627 for (ac=whmm->state[wordhmmnum-1].ac;ac;ac=ac->next) {
00628 if (tmpscore < dwrk->wordtrellis[tl][ac->arc] + ac->a) {
00629 j = ac->arc;
00630 tmpscore = dwrk->wordtrellis[tl][ac->arc] + ac->a;
00631 }
00632 }
00633 if (g[t] > tmpscore) {
00634 tmpmax = g[t];
00635 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00636 if (r->graphout) {
00637 dwrk->wend_token_frame[tn][wordhmmnum-1] = wordend_frame_src[t];
00638 dwrk->wend_token_gscore[tn][wordhmmnum-1] = wordend_gscore_src[t];
00639 }
00640 #endif
00641 } else {
00642 tmpmax = tmpscore;
00643 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00644 if (r->graphout) {
00645 dwrk->wend_token_frame[tn][wordhmmnum-1] = dwrk->wend_token_frame[tl][j];
00646 dwrk->wend_token_gscore[tn][wordhmmnum-1] = dwrk->wend_token_gscore[tl][j];
00647 }
00648 #endif
00649 }
00650
00651
00652
00653 if (
00654 #ifdef SCAN_BEAM
00655 tmpmax <= framemaxscore[t] - scan_beam_thres ||
00656 #endif
00657 tmpmax <= LOG_ZERO
00658 ) {
00659 dwrk->wordtrellis[tn][wordhmmnum-1] = LOG_ZERO;
00660 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00661 if (r->graphout) {
00662 dwrk->wend_token_frame[tn][wordhmmnum-1] = -1;
00663 dwrk->wend_token_gscore[tn][wordhmmnum-1] = LOG_ZERO;
00664 }
00665 #endif
00666 } else {
00667 node_exist_p = TRUE;
00668 dwrk->wordtrellis[tn][wordhmmnum-1] = tmpmax + outprob(&(r->am->hmmwrk), t, &(whmm->state[wordhmmnum-1]), param);
00669 }
00670
00671 }
00672
00673
00674
00675 for(i=wordhmmnum-2;i>=0;i--) {
00676
00677
00678
00679 tmpmax = LOG_ZERO;
00680 for (ac=whmm->state[i].ac;ac;ac=ac->next) {
00681 if (hmminfo->multipath) {
00682 if (ac->arc == wordhmmnum-1) tmpscore = g[t];
00683 else if (t + 1 > startt) tmpscore = LOG_ZERO;
00684 else tmpscore = dwrk->wordtrellis[tl][ac->arc];
00685 tmpscore += ac->a;
00686 } else {
00687 tmpscore = dwrk->wordtrellis[tl][ac->arc] + ac->a;
00688 }
00689 if (tmpmax < tmpscore) {
00690 tmpmax = tmpscore;
00691 j = ac->arc;
00692 }
00693 }
00694
00695
00696
00697 if (
00698 #ifdef SCAN_BEAM
00699 tmpmax <= framemaxscore[t] - scan_beam_thres ||
00700 #endif
00701 tmpmax <= LOG_ZERO
00702 ) {
00703
00704 dwrk->wordtrellis[tn][i] = LOG_ZERO;
00705 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00706 if (r->graphout) {
00707 dwrk->wend_token_frame[tn][i] = -1;
00708 dwrk->wend_token_gscore[tn][i] = LOG_ZERO;
00709 }
00710 #endif
00711 } else {
00712
00713 node_exist_p = TRUE;
00714 dwrk->wordtrellis[tn][i] = tmpmax;
00715 if (! hmminfo->multipath || i > 0) {
00716 dwrk->wordtrellis[tn][i] += outprob(&(r->am->hmmwrk), t, &(whmm->state[i]), param);
00717 }
00718 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00719 if (r->graphout) {
00720 if (hmminfo->multipath) {
00721 if (j == wordhmmnum-1) {
00722 dwrk->wend_token_frame[tn][i] = wordend_frame_src[t];
00723 dwrk->wend_token_gscore[tn][i] = wordend_gscore_src[t];
00724 } else {
00725 dwrk->wend_token_frame[tn][i] = dwrk->wend_token_frame[tl][j];
00726 dwrk->wend_token_gscore[tn][i] = dwrk->wend_token_gscore[tl][j];
00727 }
00728 } else {
00729 dwrk->wend_token_frame[tn][i] = dwrk->wend_token_frame[tl][j];
00730 dwrk->wend_token_gscore[tn][i] = dwrk->wend_token_gscore[tl][j];
00731 }
00732 }
00733 #endif
00734 }
00735 }
00736
00737
00738
00739 g_new[t] = dwrk->wordtrellis[tn][0];
00740 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00741 if (r->graphout) {
00742
00743 wordend_frame_dst[t] = dwrk->wend_token_frame[tn][0];
00744 wordend_gscore_dst[t] = dwrk->wend_token_gscore[tn][0];
00745 }
00746 #endif
00747
00748
00749
00750
00751
00752
00753
00754 if (t < least_frame && (!node_exist_p)) {
00755
00756 for (i=t-1;i>=0;i--) {
00757 g_new[i] = LOG_ZERO;
00758 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00759 if (r->graphout) {
00760 wordend_frame_dst[i] = -1;
00761 wordend_gscore_dst[i] = LOG_ZERO;
00762 }
00763 #endif
00764 }
00765
00766 break;
00767 }
00768
00769 }
00770
00771 if (hmminfo->multipath) {
00772
00773
00774 if (t < 0) {
00775 tmpmax = LOG_ZERO;
00776 for(ac=whmm->state[0].ac;ac;ac=ac->next) {
00777 tmpscore = dwrk->wordtrellis[tn][ac->arc] + ac->a;
00778 if (tmpmax < tmpscore) tmpmax = tmpscore;
00779 }
00780 *final_g = tmpmax;
00781 } else {
00782 *final_g = LOG_ZERO;
00783 }
00784 }
00785
00786
00787 free_hmm(whmm);
00788 }
00789
00813 static void
00814 do_viterbi_next_word(NODE *now, NODE *new, HMM_Logical *lastphone, boolean sp, HTK_Param *param, RecogProcess *r)
00815 {
00816 int t, n;
00817 LOGPROB a_value;
00818 int peseqlen;
00819 boolean multipath;
00820 StackDecode *dwrk;
00821
00822 dwrk = &(r->pass2);
00823
00824 multipath = r->am->hmminfo->multipath;
00825
00826 peseqlen = r->peseqlen;
00827
00828 if (! multipath) {
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841 if (r->lm->winfo->wlen[now->seq[now->seqnum-1]] > 1) {
00842 n = hmm_logical_state_num(lastphone);
00843 a_value = (hmm_logical_trans(lastphone))->a[n-2][n-1];
00844 for(t=0; t<peseqlen-1; t++) dwrk->g[t] = now->g[t+1] + a_value;
00845 dwrk->g[peseqlen-1] = LOG_ZERO;
00846 } else {
00847 for(t=0; t<peseqlen; t++) dwrk->g[t] = now->g[t];
00848 }
00849
00850 } else {
00851
00852 for(t=0; t<peseqlen; t++) dwrk->g[t] = now->g[t];
00853 dwrk->phmmseq[0] = lastphone;
00854 if (r->lm->config->enable_iwsp) dwrk->has_sp[0] = sp;
00855
00856 }
00857
00858 do_viterbi(dwrk->g, new->g,
00859 multipath ? dwrk->phmmseq : &lastphone,
00860 (r->lm->config->enable_iwsp && multipath) ? dwrk->has_sp : NULL,
00861 1, param, peseqlen, now->estimated_next_t, &(new->final_g)
00862 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00863 , now->wordend_frame, new->wordend_frame
00864 , now->wordend_gscore, new->wordend_gscore
00865 #else
00866 , NULL, NULL
00867 , NULL, NULL
00868 #endif
00869 , r
00870 );
00871
00872 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00873 if (! multipath) {
00874 if (r->graphout) {
00875
00876
00877 new->wordend_frame[r->peseqlen-1] = new->wordend_frame[0];
00878 new->wordend_gscore[r->peseqlen-1] = new->wordend_gscore[0];
00879 for (t=0;t<r->peseqlen-1;t++) {
00880 new->wordend_frame[t] = new->wordend_frame[t+1];
00881 new->wordend_gscore[t] = new->wordend_gscore[t+1];
00882 }
00883 }
00884 }
00885 #endif
00886 }
00887
00907 void
00908 scan_word(NODE *now, HTK_Param *param, RecogProcess *r)
00909 {
00910 int i,t;
00911 WORD_ID word;
00912 int phmmlen;
00913 HMM_Logical *tailph;
00914
00915
00916 WORD_INFO *winfo;
00917 HTK_HMM_INFO *hmminfo;
00918 int peseqlen;
00919 boolean ccd_flag;
00920 boolean enable_iwsp;
00921 StackDecode *dwrk;
00922
00923 dwrk = &(r->pass2);
00924 winfo = r->lm->winfo;
00925 hmminfo = r->am->hmminfo;
00926 peseqlen = r->peseqlen;
00927 ccd_flag = r->ccd_flag;
00928 if (hmminfo->multipath) {
00929 enable_iwsp = r->lm->config->enable_iwsp;
00930 }
00931
00932 #ifndef GRAPHOUT_PRECISE_BOUNDARY
00933 if (r->graphout) {
00934 if (ccd_flag) {
00935 now->tail_g_score = now->g[now->bestt];
00936 }
00937 }
00938 #endif
00939
00940
00941
00942
00943
00944
00945
00946 word = now->seq[now->seqnum-1];
00947
00948 #ifdef TCD
00949 jlog("DEBUG: w=");
00950 for(i=0;i<winfo->wlen[word];i++) {
00951 jlog(" %s",(winfo->wseq[word][i])->name);
00952 }
00953 if (ccd_flag) {
00954 if (now->last_ph != NULL) {
00955 jlog(" | %s", (now->last_ph)->name);
00956 }
00957 }
00958 jlog("\n");
00959 #endif
00960
00961 if (ccd_flag) {
00962
00963
00964 if (now->last_ph != NULL) {
00965 tailph = get_right_context_HMM(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name, hmminfo);
00966 if (tailph == NULL) {
00967
00968
00969
00970
00971 if (winfo->wlen[word] > 1 && winfo->wseq[word][winfo->wlen[word]-1]->is_pseudo){
00972 error_missing_right_triphone(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name);
00973 }
00974
00975 tailph = winfo->wseq[word][winfo->wlen[word]-1];
00976 }
00977 } else {
00978 tailph = winfo->wseq[word][winfo->wlen[word]-1];
00979 }
00980
00981
00982
00983 if (winfo->wlen[word] == 1) {
00984 now->last_ph = tailph;
00985 if (enable_iwsp && hmminfo->multipath) now->last_ph_sp_attached = TRUE;
00986 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00987 if (r->graphout) {
00988
00989
00990 for (t=0;t<peseqlen;t++) {
00991 now->wordend_frame[t] = t;
00992 now->wordend_gscore[t] = now->g[t];
00993 }
00994 }
00995 #endif
00996 #ifdef TCD
00997 jlog("DEBUG: suspended as %s\n", (now->last_ph)->name);
00998 #endif
00999 return;
01000 }
01001
01002
01003
01004 phmmlen = winfo->wlen[word] - 1;
01005 if (phmmlen > dwrk->phmmlen_max) {
01006 j_internal_error("scan_word: num of phonemes in a word exceed phmmlenmax (%d) ?\n", dwrk->phmmlen_max);
01007 }
01008 for (i=0;i<phmmlen-1;i++) {
01009 dwrk->phmmseq[i] = winfo->wseq[word][i+1];
01010 }
01011 dwrk->phmmseq[phmmlen-1] = tailph;
01012 if (enable_iwsp && hmminfo->multipath) {
01013 for (i=0;i<phmmlen-1;i++) dwrk->has_sp[i] = FALSE;
01014 dwrk->has_sp[phmmlen-1] = TRUE;
01015 }
01016
01017 } else {
01018
01019 phmmlen = winfo->wlen[word];
01020 for (i=0;i<phmmlen;i++) dwrk->phmmseq[i] = winfo->wseq[word][i];
01021 if (enable_iwsp && hmminfo->multipath) {
01022 for (i=0;i<phmmlen;i++) dwrk->has_sp[i] = FALSE;
01023 dwrk->has_sp[phmmlen-1] = TRUE;
01024 }
01025
01026 }
01027
01028
01029
01030 for (t=0;t<peseqlen;t++) dwrk->g[t] = now->g[t];
01031
01032 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01033 if (r->graphout) {
01034
01035
01036 for (t=0;t<peseqlen;t++) {
01037 dwrk->wef[t] = t;
01038 dwrk->wes[t] = now->g[t];
01039 }
01040 }
01041 #endif
01042
01043
01044
01045 do_viterbi(dwrk->g, now->g, dwrk->phmmseq, (enable_iwsp && hmminfo->multipath) ? dwrk->has_sp : NULL,
01046 phmmlen, param, peseqlen, now->estimated_next_t, &(now->final_g)
01047 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01048
01049
01050 , dwrk->wef, now->wordend_frame
01051 , dwrk->wes, now->wordend_gscore
01052 #else
01053 , NULL, NULL
01054 , NULL, NULL
01055 #endif
01056 , r
01057 );
01058 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01059 if (! hmminfo->multipath) {
01060 if (r->graphout) {
01061
01062
01063 now->wordend_frame[peseqlen-1] = now->wordend_frame[0];
01064 now->wordend_gscore[peseqlen-1] = now->wordend_gscore[0];
01065 for (t=0;t<peseqlen-1;t++) {
01066 now->wordend_frame[t] = now->wordend_frame[t+1];
01067 now->wordend_gscore[t] = now->wordend_gscore[t+1];
01068 }
01069 }
01070 }
01071 #endif
01072
01073 if (ccd_flag) {
01074
01075
01076 now->last_ph = winfo->wseq[word][0];
01077 if (enable_iwsp && hmminfo->multipath) now->last_ph_sp_attached = FALSE;
01078 #ifdef TCD
01079 jlog("DEBUG: last_ph = %s\n", (now->last_ph)->name);
01080 #endif
01081 }
01082 }
01083
01084
01085
01086
01087
01088
01089
01115 void
01116 next_word(NODE *now, NODE *new, NEXTWORD *nword, HTK_Param *param, RecogProcess *r)
01117 {
01118 HMM_Logical *lastphone, *newphone;
01119 LOGPROB *g_src;
01120 int t;
01121 int lastword;
01122 int i;
01123 LOGPROB a_value;
01124 LOGPROB tmpp;
01125 int startt;
01126 int word;
01127 TRELLIS_ATOM *tre;
01128 LOGPROB totalscore;
01129 BACKTRELLIS *backtrellis;
01130 WORD_INFO *winfo;
01131 HTK_HMM_INFO *hmminfo;
01132 int peseqlen;
01133 boolean ccd_flag;
01134 StackDecode *dwrk;
01135
01136 dwrk = &(r->pass2);
01137 backtrellis = r->backtrellis;
01138 winfo = r->lm->winfo;
01139 hmminfo = r->am->hmminfo;
01140 peseqlen = r->peseqlen;
01141 ccd_flag = r->ccd_flag;
01142
01143 word = nword->id;
01144 lastword = now->seq[now->seqnum-1];
01145
01146
01147
01148 if (ccd_flag) {
01149
01150
01151 lastphone = get_left_context_HMM(now->last_ph, winfo->wseq[word][winfo->wlen[word]-1]->name, hmminfo);
01152 if (lastphone == NULL) {
01153
01154
01155
01156
01157 if (now->last_ph->is_pseudo){
01158 error_missing_left_triphone(now->last_ph, winfo->wseq[word][winfo->wlen[word]-1]->name);
01159 }
01160 lastphone = now->last_ph;
01161 }
01162 }
01163
01164
01165
01166 if (ccd_flag) {
01167 newphone = get_right_context_HMM(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name, hmminfo);
01168 if (newphone == NULL) {
01169
01170
01171
01172
01173 if (winfo->wlen[word] > 1 && winfo->wseq[word][winfo->wlen[word]-1]->is_pseudo){
01174 error_missing_right_triphone(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name);
01175 }
01176 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01177 }
01178 } else {
01179 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01180 }
01181
01182
01183
01184 new->score = LOG_ZERO;
01185 for (i=0;i< now->seqnum;i++){
01186 new->seq[i] = now->seq[i];
01187 #ifdef CM_SEARCH
01188 #ifdef CM_MULTIPLE_ALPHA
01189 memcpy(new->cmscore[i], now->cmscore[i], sizeof(LOGPROB) * r->config->annotate.cm_alpha_num);
01190 #else
01191 new->cmscore[i] = now->cmscore[i];
01192 #endif
01193 #endif
01194 }
01195 new->seq[i] = word;
01196 new->seqnum = now->seqnum+1;
01197 new->state = nword->next_state;
01198 new->totallscore = now->totallscore + nword->lscore;
01199 if (ccd_flag) {
01200
01201
01202 new->last_ph = lastphone;
01203 new->last_ph_sp_attached = now->last_ph_sp_attached;
01204 }
01205
01206 if (ccd_flag) {
01207
01208
01209 do_viterbi_next_word(now, new, lastphone,
01210 hmminfo->multipath ? now->last_ph_sp_attached : FALSE,
01211 param, r);
01212 g_src = new->g;
01213 } else {
01214 g_src = now->g;
01215 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01216 if (r->graphout) {
01217 memcpy(new->wordend_frame, now->wordend_frame, sizeof(short)*peseqlen);
01218 memcpy(new->wordend_gscore, now->wordend_gscore, sizeof(LOGPROB)*peseqlen);
01219 }
01220 #endif
01221 }
01222
01223
01224
01225 if (hmminfo->multipath) {
01226 startt = peseqlen-1;
01227 } else {
01228 startt = peseqlen-2;
01229 }
01230 i = hmm_logical_state_num(newphone);
01231 a_value = (hmm_logical_trans(newphone))->a[i-2][i-1];
01232 if (hmminfo->multipath) {
01233 for(t=0; t <= startt; t++) {
01234 new->g[t] = g_src[t] + nword->lscore;
01235 }
01236 } else {
01237 for(t=0; t <= startt; t++) {
01238 new->g[t] = g_src[t+1] + a_value + nword->lscore;
01239 }
01240 }
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 if (r->lmtype == LM_DFA && !r->config->pass2.looktrellis_flag) {
01253
01254
01255 for(t = startt; t >= 0; t--) {
01256 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01257 if (tre == NULL) continue;
01258 totalscore = new->g[t] + tre->backscore;
01259 if (! hmminfo->multipath) {
01260 if (newphone->is_pseudo) {
01261 tmpp = outprob_cd(&(r->am->hmmwrk), t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01262 } else {
01263 tmpp = outprob_state(&(r->am->hmmwrk), t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01264 }
01265 totalscore += tmpp;
01266 }
01267 if (new->score < totalscore) {
01268 new->score = totalscore;
01269 new->bestt = t;
01270 new->estimated_next_t = tre->begintime - 1;
01271 new->tre = tre;
01272 }
01273 }
01274
01275 return;
01276 }
01277
01278
01279
01280
01281
01282
01283
01284
01285 for(t = (nword->tre)->endtime; t >= 0; t--) {
01286 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01287 if (tre == NULL) break;
01288 totalscore = new->g[t] + tre->backscore;
01289 if (! hmminfo->multipath) {
01290 if (newphone->is_pseudo) {
01291 tmpp = outprob_cd(&(r->am->hmmwrk), t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01292 } else {
01293 tmpp = outprob_state(&(r->am->hmmwrk), t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01294 }
01295 totalscore += tmpp;
01296 }
01297 if (new->score < totalscore) {
01298 new->score = totalscore;
01299 new->bestt = t;
01300 new->estimated_next_t = tre->begintime - 1;
01301 new->tre = tre;
01302 }
01303 }
01304
01305 for(t = (nword->tre)->endtime + 1; t <= startt; t++) {
01306 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01307 if (tre == NULL) break;
01308 totalscore = new->g[t] + tre->backscore;
01309 if (! hmminfo->multipath) {
01310 if (newphone->is_pseudo) {
01311 tmpp = outprob_cd(&(r->am->hmmwrk), t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01312 } else {
01313 tmpp = outprob_state(&(r->am->hmmwrk), t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01314 }
01315 totalscore += tmpp;
01316 }
01317 if (new->score < totalscore) {
01318 new->score = totalscore;
01319 new->bestt = t;
01320 new->estimated_next_t = tre->begintime - 1;
01321 new->tre = tre;
01322 }
01323 }
01324
01325
01326 new->lscore = nword->lscore;
01327
01328 }
01329
01330
01331
01332
01333
01334
01335
01357 void
01358 start_word(NODE *new, NEXTWORD *nword, HTK_Param *param, RecogProcess *r)
01359 {
01360 HMM_Logical *newphone;
01361 WORD_ID word;
01362 TRELLIS_ATOM *tre = NULL;
01363 LOGPROB tmpp;
01364 int t;
01365
01366 BACKTRELLIS *backtrellis;
01367 WORD_INFO *winfo;
01368
01369 int peseqlen;
01370 boolean ccd_flag;
01371 boolean multipath;
01372
01373 backtrellis = r->backtrellis;
01374 winfo = r->lm->winfo;
01375 peseqlen = r->peseqlen;
01376 ccd_flag = r->ccd_flag;
01377 multipath = r->am->hmminfo->multipath;
01378
01379
01380 word = nword->id;
01381 new->score = LOG_ZERO;
01382 new->seqnum = 1;
01383 new->seq[0] = word;
01384
01385 new->state = nword->next_state;
01386 new->totallscore = nword->lscore;
01387
01388
01389 new->lscore = nword->lscore;
01390
01391
01392 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01393 if (ccd_flag) {
01394 new->last_ph = NULL;
01395 }
01396
01397 if (r->lmtype == LM_PROB) {
01398 new->g[peseqlen-1] = nword->lscore;
01399 } else {
01400 new->g[peseqlen-1] = 0;
01401 }
01402
01403 for (t=peseqlen-1; t>=0; t--) {
01404 tre = bt_binsearch_atom(backtrellis, t, word);
01405 if (tre != NULL) {
01406 if (r->graphout) {
01407 new->bestt = peseqlen-1;
01408 } else {
01409 new->bestt = t;
01410 }
01411 new->score = new->g[peseqlen-1] + tre->backscore;
01412 if (! multipath) {
01413 if (newphone->is_pseudo) {
01414 tmpp = outprob_cd(&(r->am->hmmwrk), peseqlen-1, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01415 } else {
01416 tmpp = outprob_state(&(r->am->hmmwrk), peseqlen-1, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01417 }
01418 new->score += tmpp;
01419 }
01420 new->estimated_next_t = tre->begintime - 1;
01421 new->tre = tre;
01422 break;
01423 }
01424 }
01425 if (tre == NULL) {
01426 new->score = LOG_ZERO;
01427 }
01428 }
01429
01451 void
01452 last_next_word(NODE *now, NODE *new, HTK_Param *param, RecogProcess *r)
01453 {
01454 cpy_node(new, now);
01455 if (r->ccd_flag) {
01456
01457
01458 if (r->am->hmminfo->multipath) {
01459 do_viterbi_next_word(now, new, now->last_ph, now->last_ph_sp_attached, param, r);
01460 new->score = new->final_g;
01461 } else {
01462 do_viterbi_next_word(now, new, now->last_ph, FALSE, param, r);
01463 new->score = new->g[0];
01464 }
01465 } else {
01466 if (r->am->hmminfo->multipath) {
01467 new->score = now->final_g;
01468 } else {
01469 new->score = now->g[0];
01470 }
01471 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01472 if (r->graphout) {
01473
01474 memcpy(new->wordend_frame, now->wordend_frame, sizeof(short)*r->peseqlen);
01475 memcpy(new->wordend_gscore, now->wordend_gscore, sizeof(LOGPROB)*r->peseqlen);
01476 }
01477 #endif
01478 }
01479 }
01480
01481 #endif
01482
01483