00001
00098
00099
00100
00101
00102
00103
00104
00105 #include <julius.h>
00106
00107 #ifndef PASS2_STRICT_IWCD
00108
00109 #undef TCD
00110
00111
00112
00113
00114
00115
00128 void
00129 free_node(NODE *node)
00130 {
00131 if (node == NULL) return;
00132 free(node->g);
00133 if (ccd_flag) free(node->g_prev);
00134 #ifdef GRAPHOUT
00135 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00136 free(node->wordend_frame);
00137 free(node->wordend_gscore);
00138 #endif
00139 if (node->prevgraph != NULL && node->prevgraph->saved == FALSE) {
00140 wordgraph_free(node->prevgraph);
00141 }
00142 #endif
00143
00144 free(node);
00145 }
00146
00165 NODE *
00166 cpy_node(NODE *dst, NODE *src)
00167 {
00168
00169 dst->next = src->next;
00170 dst->prev = src->prev;
00171 memcpy(dst->g, src->g, sizeof(LOGPROB) * peseqlen);
00172 memcpy(dst->seq, src->seq, sizeof(WORD_ID) * MAXSEQNUM);
00173 #ifdef CM_SEARCH
00174 #ifdef CM_MULTIPLE_ALPHA
00175 {
00176 int w;
00177 for(w=0;w<src->seqnum;w++) {
00178 memcpy(dst->cmscore[w], src->cmscore[w], sizeof(LOGPROB) * cm_alpha_num);
00179 }
00180 }
00181 #else
00182 memcpy(dst->cmscore, src->cmscore, sizeof(LOGPROB) * MAXSEQNUM);
00183 #endif
00184 #endif
00185 dst->seqnum = src->seqnum;
00186 dst->score = src->score;
00187 dst->bestt = src->bestt;
00188 dst->estimated_next_t = src->estimated_next_t;
00189 dst->endflag = src->endflag;
00190 #ifdef USE_DFA
00191 dst->state = src->state;
00192 #endif
00193 dst->tre = src->tre;
00194 if (ccd_flag) {
00195 memcpy(dst->g_prev, src->g_prev, sizeof(LOGPROB)*peseqlen);
00196 dst->last_ph = src->last_ph;
00197 #ifdef MULTIPATH_VERSION
00198 dst->last_ph_sp_attached = src->last_ph_sp_attached;
00199 #endif
00200 #ifdef USE_NGRAM
00201 dst->lscore = src->lscore;
00202 #endif
00203 }
00204 #ifdef USE_NGRAM
00205 dst->totallscore = src->totallscore;
00206 #endif
00207 #ifdef MULTIPATH_VERSION
00208 dst->final_g = src->final_g;
00209 #endif
00210 #ifdef VISUALIZE
00211 dst->popnode = src->popnode;
00212 #endif
00213 #ifdef GRAPHOUT
00214 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00215 memcpy(dst->wordend_frame, src->wordend_frame, sizeof(short)*peseqlen);
00216 memcpy(dst->wordend_gscore, src->wordend_gscore, sizeof(LOGPROB)*peseqlen);
00217 #endif
00218 dst->prevgraph = src->prevgraph;
00219 dst->lastcontext = src->lastcontext;
00220 #ifndef GRAPHOUT_PRECISE_BOUNDARY
00221 dst->tail_g_score = src->tail_g_score;
00222 #endif
00223 #endif
00224 return(dst);
00225 }
00226
00239 NODE *
00240 newnode()
00241 {
00242 NODE *tmp;
00243 int i;
00244
00245 if ((tmp=(NODE *)mymalloc(sizeof(NODE)))==NULL) {
00246 j_error("can't malloc\n");
00247 }
00248
00249 tmp->next=NULL;
00250 tmp->prev=NULL;
00251 tmp->g = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
00252 tmp->last_ph = NULL;
00253 #ifdef MULTIPATH_VERSION
00254 tmp->last_ph_sp_attached = FALSE;
00255 #endif
00256 if (ccd_flag) {
00257 tmp->g_prev = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
00258 #ifdef USE_NGRAM
00259 tmp->lscore = LOG_ZERO;
00260 tmp->totallscore = LOG_ZERO;
00261 #endif
00262 }
00263 tmp->endflag = FALSE;
00264 tmp->seqnum = 0;
00265 for(i=0;i<peseqlen;i++) {
00266 tmp->g[i] = LOG_ZERO;
00267 if (ccd_flag) tmp->g_prev[i] = LOG_ZERO;
00268 }
00269 #ifdef MULTIPATH_VERSION
00270 tmp->final_g = LOG_ZERO;
00271 #endif
00272 #ifdef VISUALIZE
00273 tmp->popnode = NULL;
00274 #endif
00275 tmp->tre = NULL;
00276 #ifdef GRAPHOUT
00277 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00278 tmp->wordend_frame = (short *)mymalloc(sizeof(short)*peseqlen);
00279 tmp->wordend_gscore = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
00280 #endif
00281 tmp->prevgraph = NULL;
00282 tmp->lastcontext = NULL;
00283 #endif
00284 return(tmp);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 static LOGPROB *wordtrellis[2];
00294 static int tn;
00295 static int tl;
00296 static LOGPROB *g;
00297 static HMM_Logical **phmmseq;
00298 static int phmmlen_max;
00299 #ifdef MULTIPATH_VERSION
00300 static boolean *has_sp;
00301 #endif
00302
00303 #ifdef GRAPHOUT
00304 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00305 static short *wend_token_frame[2];
00306 static LOGPROB *wend_token_gscore[2];
00307 #endif
00308 #endif
00309
00320 void
00321 malloc_wordtrellis()
00322 {
00323 int maxwn;
00324
00325 maxwn = winfo->maxwn + 10;
00326 wordtrellis[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00327 wordtrellis[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00328
00329 g = (LOGPROB *)mymalloc(sizeof(LOGPROB) * peseqlen);
00330
00331 phmmlen_max = winfo->maxwlen + 2;
00332 phmmseq = (HMM_Logical **)mymalloc(sizeof(HMM_Logical *) * phmmlen_max);
00333 #ifdef MULTIPATH_VERSION
00334 has_sp = (boolean *)mymalloc(sizeof(boolean) * phmmlen_max);
00335 #endif
00336
00337 #ifdef GRAPHOUT
00338 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00339 wend_token_frame[0] = (short *)mymalloc(sizeof(short) * maxwn);
00340 wend_token_frame[1] = (short *)mymalloc(sizeof(short) * maxwn);
00341 wend_token_gscore[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00342 wend_token_gscore[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00343 #endif
00344 #endif
00345
00346 }
00347
00358 void
00359 free_wordtrellis()
00360 {
00361 free(wordtrellis[0]);
00362 free(wordtrellis[1]);
00363 free(g);
00364 free(phmmseq);
00365 #ifdef MULTIPATH_VERSION
00366 free(has_sp);
00367 #endif
00368 #ifdef GRAPHOUT
00369 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00370 free(wend_token_frame[0]);
00371 free(wend_token_frame[1]);
00372 free(wend_token_gscore[0]);
00373 free(wend_token_gscore[1]);
00374 #endif
00375 #endif
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 #ifdef MULTIPATH_VERSION
00385
00403 static LOGPROB
00404 get_max_out_arc(HTK_HMM_Trans *tr, int state_num)
00405 {
00406 LOGPROB max_a;
00407 int afrom;
00408 LOGPROB a;
00409
00410 max_a = LOG_ZERO;
00411 for (afrom = 0; afrom < state_num - 1; afrom++) {
00412 a = tr->a[afrom][state_num-1];
00413 if (max_a < a) max_a = a;
00414 }
00415 return(max_a);
00416 }
00417
00434 static LOGPROB
00435 max_out_arc(HMM_Logical *l)
00436 {
00437 return(get_max_out_arc(hmm_logical_trans(l), hmm_logical_state_num(l)));
00438 }
00439
00440 #endif
00441
00457 void
00458 scan_word(NODE *now, HTK_Param *param)
00459 {
00460 int i,t, j;
00461 HMM *whmm;
00462 A_CELL *ac;
00463 WORD_ID word;
00464 LOGPROB tmpmax, tmptmp, score1;
00465 int startt = 0, endt;
00466 int wordhmmnum;
00467 #ifdef MULTIPATH_VERSION
00468 LOGPROB tmpmax_store, store_point_maxarc;
00469 #else
00470 LOGPROB tmpmax2 = LOG_ZERO;
00471 #endif
00472 int phmmlen;
00473 HMM_Logical *ret, *wend;
00474 #ifdef MULTIPATH_VERSION
00475 int store_point = -1;
00476 #else
00477 int store_point = 0;
00478 #endif
00479 int crossword_point = 0;
00480 boolean back_rescan = FALSE;
00481 boolean node_exist_p;
00482
00483
00484
00485 if (ccd_flag) {
00486
00487
00488 if (now->last_ph == NULL) {
00489
00490
00491 back_rescan = FALSE;
00492 } else {
00493
00494
00495 back_rescan = TRUE;
00496 }
00497 }
00498 #ifdef TCD
00499 if (now->last_ph != NULL) {
00500 j_printf("inherited last_ph: %s\n", (now->last_ph)->name);
00501 #ifdef MULTIPATH_VERSION
00502 if (now->last_ph_sp_attached) j_printf(" (sp attached)\n");
00503 #endif
00504 } else {
00505 j_printf("no last_ph inherited\n");
00506 }
00507 #endif
00508
00509
00510
00511 word = now->seq[now->seqnum-1];
00512
00513 if (ccd_flag) {
00514
00515 if (back_rescan) {
00516
00517
00518
00519 phmmlen = winfo->wlen[word] + 1;
00520 if (phmmlen > phmmlen_max) {
00521 j_error("short of phmmlen\n");
00522 }
00523 for (i=0;i<phmmlen - 2;i++) {
00524 phmmseq[i] = winfo->wseq[word][i];
00525 #ifdef MULTIPATH_VERSION
00526 has_sp[i] = FALSE;
00527 #endif
00528 }
00529
00530
00531 wend = winfo->wseq[word][winfo->wlen[word]-1];
00532 ret = get_right_context_HMM(wend, now->last_ph->name, hmminfo);
00533 if (ret == NULL) {
00534
00535
00536
00537
00538 if (winfo->wlen[word] > 1 && wend->is_pseudo) {
00539 error_missing_right_triphone(wend, now->last_ph->name);
00540 }
00541 phmmseq[phmmlen-2] = wend;
00542 } else {
00543 phmmseq[phmmlen-2] = ret;
00544 }
00545 ret = get_left_context_HMM(now->last_ph, wend->name, hmminfo);
00546 if (ret == NULL) {
00547
00548
00549
00550 if (now->last_ph->is_pseudo) {
00551 error_missing_left_triphone(now->last_ph, wend->name);
00552 }
00553 phmmseq[phmmlen-1] = now->last_ph;
00554 } else {
00555 phmmseq[phmmlen-1] = ret;
00556 }
00557
00558 #ifdef MULTIPATH_VERSION
00559 has_sp[phmmlen-2] = has_sp[phmmlen-1] = FALSE;
00560 if (enable_iwsp) {
00561 has_sp[phmmlen-2] = TRUE;
00562 if (now->last_ph_sp_attached) {
00563 has_sp[phmmlen-1] = TRUE;
00564 }
00565 }
00566 #endif
00567
00568 #ifdef TCD
00569 j_printf("w=");
00570 for(i=0;i<winfo->wlen[word];i++) {
00571 j_printf(" %s",(winfo->wseq[word][i])->name);
00572 #ifdef MULTIPATH_VERSION
00573 if (has_sp[i]) j_printf("(sp)");
00574 #endif
00575 }
00576 j_printf(" | %s\n", (now->last_ph)->name);
00577 #ifdef MULTIPATH_VERSION
00578 if (now->last_ph_sp_attached) j_printf(" (sp)\n");
00579 #endif
00580 j_printf("scan for:");
00581
00582 for (i=0;i<phmmlen;i++) {
00583 j_printf(" %s", phmmseq[i]->name);
00584 #ifdef MULTIPATH_VERSION
00585 if (has_sp[i]) j_printf("(sp)");
00586 #endif
00587 }
00588 j_printf("\n");
00589 #endif
00590
00591
00592
00593 whmm = new_make_word_hmm(hmminfo, phmmseq, phmmlen
00594 #ifdef MULTIPATH_VERSION
00595 ,has_sp
00596 #endif
00597 );
00598
00599
00600
00601
00602 for (t=0;t<peseqlen;t++) {
00603 g[t]=now->g_prev[t];
00604
00605 }
00606
00607
00608
00609
00610 #ifdef MULTIPATH_VERSION
00611 store_point = hmm_logical_state_num(phmmseq[0]) - 2;
00612 store_point_maxarc = max_out_arc(phmmseq[0]);
00613 if (enable_iwsp && has_sp[0]) {
00614 store_point += hmm_logical_state_num(hmminfo->sp) - 2;
00615 if (store_point_maxarc < max_out_arc(hmminfo->sp)) {
00616 store_point_maxarc = max_out_arc(hmminfo->sp);
00617 }
00618 }
00619 #else
00620 store_point = hmm_logical_state_num(phmmseq[0]) - 2 - 1;
00621 #endif
00622
00623
00624 #ifdef MULTIPATH_VERSION
00625 crossword_point = whmm->len - hmm_logical_state_num(phmmseq[phmmlen-1]);
00626 if (enable_iwsp && has_sp[phmmlen-1]) {
00627 crossword_point -= hmm_logical_state_num(hmminfo->sp) - 2;
00628 }
00629 #else
00630 crossword_point = whmm->len - (hmm_logical_state_num(phmmseq[phmmlen-1]) - 2) - 1;
00631 #endif
00632
00633 } else {
00634
00635
00636
00637 #ifdef TCD
00638 j_printf("scan(org):");
00639 for (i=0;i<winfo->wlen[word];i++) {
00640 j_printf(" %s", (winfo->wseq[word][i])->name);
00641 }
00642 j_printf("\n");
00643 #endif
00644
00645 #ifdef MULTIPATH_VERSION
00646
00647 for(i=0;i<winfo->wlen[word];i++) {
00648 has_sp[i] = FALSE;
00649 }
00650 if (enable_iwsp) {
00651 has_sp[winfo->wlen[word]-1] = TRUE;
00652 }
00653 #endif
00654
00655
00656
00657 whmm = new_make_word_hmm(hmminfo, winfo->wseq[word], winfo->wlen[word]
00658 #ifdef MULTIPATH_VERSION
00659 , has_sp
00660 #endif
00661 );
00662
00663
00664
00665 for (t=0;t<peseqlen;t++) {
00666 g[t]=now->g[t];
00667 }
00668
00669
00670
00671
00672 #ifdef MULTIPATH_VERSION
00673 store_point = hmm_logical_state_num(winfo->wseq[word][0]) - 2;
00674 store_point_maxarc = max_out_arc(winfo->wseq[word][0]);
00675 if (enable_iwsp && has_sp[0]) {
00676 store_point += hmm_logical_state_num(hmminfo->sp) - 2;
00677 if (store_point_maxarc < max_out_arc(hmminfo->sp)) {
00678 store_point_maxarc = max_out_arc(hmminfo->sp);
00679 }
00680 }
00681 #else
00682 store_point = hmm_logical_state_num(winfo->wseq[word][0]) - 2 - 1;
00683 #endif
00684
00685
00686
00687 crossword_point = -1;
00688 }
00689
00690 } else {
00691
00692 #ifdef MULTIPATH_VERSION
00693
00694 for(i=0;i<winfo->wlen[word];i++) {
00695 has_sp[i] = FALSE;
00696 }
00697 if (enable_iwsp) {
00698 has_sp[winfo->wlen[word]-1] = TRUE;
00699 }
00700 #endif
00701
00702
00703
00704 whmm = new_make_word_hmm(hmminfo, winfo->wseq[word], winfo->wlen[word]
00705 #ifdef MULTIPATH_VERSION
00706 , has_sp
00707 #endif
00708 );
00709
00710
00711
00712 for (t=0;t<peseqlen;t++) {
00713 g[t]=now->g[t];
00714 }
00715
00716 }
00717
00718 #ifdef TCD
00719 j_printf("whmm len = %d\n",whmm->len);
00720 j_printf("crossword_point = %d\n", crossword_point);
00721 j_printf("g[] store point = %d\n", store_point);
00722 #endif
00723
00724 wordhmmnum = whmm->len;
00725 if (wordhmmnum >= winfo->maxwn + 10) {
00726 j_error("scan_word: word too long\n");
00727 }
00728
00729 #ifdef GRAPHOUT
00730 #ifndef GRAPHOUT_PRECISE_BOUNDARY
00731 if (ccd_flag) {
00732 now->tail_g_score = now->g[now->bestt];
00733 }
00734 #endif
00735 #endif
00736
00737
00738
00739
00740
00741 for(t = peseqlen-1; t >=0 ; t--) {
00742 if (
00743 #ifdef SCAN_BEAM
00744 g[t] > framemaxscore[t] - scan_beam_thres &&
00745 #endif
00746 g[t] > LOG_ZERO) {
00747 break;
00748 }
00749 }
00750 if (t < 0) { /* no node has score > LOG_ZERO */
00751 for(t=0;t<peseqlen;t++) {
00752 if (ccd_flag) now->g_prev[t] = LOG_ZERO;
00753 now->g[t] = LOG_ZERO;
00754 #ifdef GRAPHOUT
00755 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00756 now->wordend_frame[t] = -1;
00757 now->wordend_gscore[t] = LOG_ZERO;
00758 #endif
00759 #endif
00760 }
00761 goto end_of_scan;
00762 }
00763 startt = t;
00764
00765
00766 for(t=peseqlen-1;t>startt;t--) {
00767 if (ccd_flag) now->g_prev[t] = LOG_ZERO;
00768 now->g[t] = LOG_ZERO;
00769 #ifdef GRAPHOUT
00770 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00771 now->wordend_frame[t] = -1;
00772 now->wordend_gscore[t] = LOG_ZERO;
00773 #endif
00774 #endif
00775 }
00776
00777
00778 tn = 0; tl = 1;
00779
00780 #ifdef GRAPHOUT
00781 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00782 for(i=0;i<wordhmmnum;i++) {
00783 wend_token_frame[tn][i] = -1;
00784 wend_token_gscore[tn][i] = LOG_ZERO;
00785 }
00786 #endif
00787 #endif
00788
00789 #ifndef MULTIPATH_VERSION
00790
00791
00792
00793
00794
00795 for(i=0;i<wordhmmnum-1;i++) wordtrellis[tn][i] = LOG_ZERO;
00796 wordtrellis[tn][wordhmmnum-1] = g[startt] + outprob(startt, &(whmm->state[wordhmmnum-1]), param);
00797 if (ccd_flag) {
00798 now->g_prev[startt] = wordtrellis[tn][store_point];
00799 }
00800 now->g[startt] = wordtrellis[tn][0];
00801
00802 #ifdef GRAPHOUT
00803 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00804 if (ccd_flag) {
00805 if (back_rescan) {
00806 if (wordhmmnum-1 == crossword_point) {
00807 wend_token_frame[tn][wordhmmnum-1] = startt;
00808 wend_token_gscore[tn][wordhmmnum-1] = g[startt];
00809 } else {
00810 wend_token_frame[tn][wordhmmnum-1] = -1;
00811 wend_token_gscore[tn][wordhmmnum-1] = LOG_ZERO;
00812 }
00813 } else {
00814 wend_token_frame[tn][wordhmmnum-1] = startt;
00815 wend_token_gscore[tn][wordhmmnum-1] = g[startt];
00816 }
00817 } else {
00818 wend_token_frame[tn][wordhmmnum-1] = startt;
00819 wend_token_gscore[tn][wordhmmnum-1] = g[startt];
00820 }
00821 now->wordend_frame[startt] = wend_token_frame[tn][0];
00822 now->wordend_gscore[startt] = wend_token_gscore[tn][0];
00823 #endif
00824 #endif
00825
00826 #endif
00827
00828 endt = startt;
00829
00830
00831
00832 for(t=
00833 #ifdef MULTIPATH_VERSION
00834 startt
00835 #else
00836 startt-1
00837 #endif
00838 ;t>=0;t--) {
00839
00840
00841 i = tn; tn = tl; tl = i;
00842
00843 node_exist_p = FALSE;
00844
00845 #ifdef MULTIPATH_VERSION
00846
00847
00848
00849
00850
00851
00852 tmpmax_store = LOG_ZERO;
00853
00854 #else
00855
00856
00857
00858 tmptmp = LOG_ZERO;
00859 for (ac=whmm->state[wordhmmnum-1].ac;ac;ac=ac->next) {
00860 score1 = wordtrellis[tl][ac->arc] + ac->a;
00861 if (tmptmp < score1) {
00862 j = ac->arc;
00863 tmptmp = score1;
00864 }
00865 }
00866 if (g[t] > tmptmp) {
00867 tmpmax = g[t];
00868 #ifdef GRAPHOUT
00869 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00870 if (!back_rescan || wordhmmnum-1 == crossword_point) {
00871 wend_token_frame[tn][wordhmmnum-1] = t;
00872 wend_token_gscore[tn][wordhmmnum-1] = g[t];
00873 } else {
00874 wend_token_frame[tn][wordhmmnum-1] = wend_token_frame[tl][j];
00875 wend_token_gscore[tn][wordhmmnum-1] = wend_token_gscore[tl][j];
00876 }
00877 #endif
00878 #endif
00879 } else {
00880 tmpmax = tmptmp;
00881 #ifdef GRAPHOUT
00882 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00883 wend_token_frame[tn][wordhmmnum-1] = wend_token_frame[tl][j];
00884 wend_token_gscore[tn][wordhmmnum-1] = wend_token_gscore[tl][j];
00885 #endif
00886 #endif
00887 }
00888
00889
00890
00891 if (
00892 #ifdef SCAN_BEAM
00893 tmpmax <= framemaxscore[t] - scan_beam_thres ||
00894 #endif
00895 tmpmax <= LOG_ZERO
00896 ) {
00897 wordtrellis[tn][wordhmmnum-1] = LOG_ZERO;
00898 #ifdef GRAPHOUT
00899 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00900 wend_token_frame[tn][wordhmmnum-1] = -1;
00901 wend_token_gscore[tn][wordhmmnum-1] = LOG_ZERO;
00902 #endif
00903 #endif
00904 } else {
00905 node_exist_p = TRUE;
00906 wordtrellis[tn][wordhmmnum-1] = tmpmax + outprob(t, &(whmm->state[wordhmmnum-1]), param);
00907 }
00908
00909 #endif
00910
00911
00912
00913 for(i=wordhmmnum-2;i>=0;i--) {
00914
00915 if (ccd_flag) {
00916
00917
00918
00919
00920
00921 #ifndef MULTIPATH_VERSION
00922 if (i == store_point) {
00923 tmpmax2 = LOG_ZERO;
00924 }
00925 #endif
00926 tmpmax = LOG_ZERO;
00927 for (ac=whmm->state[i].ac;ac;ac=ac->next) {
00928 #ifdef MULTIPATH_VERSION
00929 if (ac->arc == wordhmmnum-1) score1 = g[t];
00930 else if (t + 1 > startt) score1 = LOG_ZERO;
00931 else score1 = wordtrellis[tl][ac->arc];
00932 score1 += ac->a;
00933 #else
00934 score1 = wordtrellis[tl][ac->arc] + ac->a;
00935 #endif
00936 if (i <= crossword_point && ac->arc > crossword_point) {
00937
00938
00939 #ifdef USE_NGRAM
00940 score1 += now->lscore;
00941 #else
00942 score1 += penalty2;
00943 #endif
00944 }
00945 #ifdef MULTIPATH_VERSION
00946 if (i <= store_point && ac->arc > store_point) {
00947 if (tmpmax_store < score1) tmpmax_store = score1;
00948 }
00949 #else
00950 if (i == store_point && i != ac->arc) {
00951 if (tmpmax2 < score1) tmpmax2 = score1;
00952 }
00953 #endif
00954 if (tmpmax < score1) {
00955 tmpmax = score1;
00956 j = ac->arc;
00957 }
00958 }
00959
00960
00961
00962 if (
00963 #ifdef SCAN_BEAM
00964 tmpmax <= framemaxscore[t] - scan_beam_thres ||
00965 #endif
00966 tmpmax <= LOG_ZERO
00967 ) {
00968 wordtrellis[tn][i] = LOG_ZERO;
00969 #ifdef GRAPHOUT
00970 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00971 wend_token_frame[tn][i] = -1;
00972 wend_token_gscore[tn][i] = LOG_ZERO;
00973 #endif
00974 #endif
00975 #ifndef MULTIPATH_VERSION
00976 if (i == store_point) now->g_prev[t] = LOG_ZERO;
00977 #endif
00978 } else {
00979 #ifndef MULTIPATH_VERSION
00980 if (i == store_point) now->g_prev[t] = tmpmax2;
00981 #endif
00982 #ifdef GRAPHOUT
00983 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00984 if (
00985 #ifdef MULTIPATH_VERSION
00986 (back_rescan && i <= crossword_point && j > crossword_point)
00987 || j == wordhmmnum-1
00988 #else
00989 i <= crossword_point && j > crossword_point
00990 #endif
00991 ) {
00992 wend_token_frame[tn][i] = t;
00993 wend_token_gscore[tn][i] = tmpmax;
00994 } else {
00995 wend_token_frame[tn][i] = wend_token_frame[tl][j];
00996 wend_token_gscore[tn][i] = wend_token_gscore[tl][j];
00997 }
00998 #endif
00999 #endif
01000 node_exist_p = TRUE;
01001 #ifdef MULTIPATH_VERSION
01002 wordtrellis[tn][i] = tmpmax;
01003 if (i > 0) {
01004
01005 wordtrellis[tn][i] += outprob(t, &(whmm->state[i]), param);
01006 }
01007 #else
01008
01009 tmptmp = outprob(t, &(whmm->state[i]), param);
01010
01011 wordtrellis[tn][i] = tmpmax + tmptmp;
01012 #endif
01013 }
01014
01015 } else {
01016
01017
01018
01019 tmpmax = LOG_ZERO;
01020 for (ac=whmm->state[i].ac;ac;ac=ac->next) {
01021 #ifdef MULTIPATH_VERSION
01022 if (ac->arc == wordhmmnum-1) score1 = g[t];
01023 else if (t + 1 > startt) score1 = LOG_ZERO;
01024 else score1 = wordtrellis[tl][ac->arc];
01025 score1 += ac->a;
01026 #else
01027 score1 = wordtrellis[tl][ac->arc] + ac->a;
01028 #endif
01029 if (tmpmax < score1) {
01030 tmpmax = score1;
01031 j = ac->arc;
01032 }
01033 }
01034
01035
01036
01037 if (
01038 #ifdef SCAN_BEAM
01039 tmpmax <= framemaxscore[t] - scan_beam_thres ||
01040 #endif
01041 tmpmax <= LOG_ZERO
01042 ) {
01043
01044 wordtrellis[tn][i] = LOG_ZERO;
01045 #ifdef GRAPHOUT
01046 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01047 wend_token_frame[tn][i] = -1;
01048 wend_token_gscore[tn][i] = LOG_ZERO;
01049 #endif
01050 #endif
01051 } else {
01052
01053 node_exist_p = TRUE;
01054 #ifdef GRAPHOUT
01055 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01056 #ifdef MULTIPATH_VERSION
01057 if (j == wordhmmnum-1) {
01058 wend_token_frame[tn][i] = t;
01059 wend_token_gscore[tn][i] = tmpmax;
01060 } else {
01061 wend_token_frame[tn][i] = wend_token_frame[tl][j];
01062 wend_token_gscore[tn][i] = wend_token_gscore[tl][j];
01063 }
01064 #else
01065 wend_token_frame[tn][i] = wend_token_frame[tl][j];
01066 wend_token_gscore[tn][i] = wend_token_gscore[tl][j];
01067 #endif
01068 #endif
01069 #endif
01070
01071 #ifdef MULTIPATH_VERSION
01072 wordtrellis[tn][i] = tmpmax;
01073 if (i > 0) {
01074 wordtrellis[tn][i] += outprob(t, &(whmm->state[i]), param);
01075 }
01076 #else
01077 wordtrellis[tn][i] = tmpmax + outprob(t, &(whmm->state[i]), param);
01078 #endif
01079 }
01080
01081 }
01082 }
01083
01084
01085
01086
01087 now->g[t] = wordtrellis[tn][0];
01088 #ifdef GRAPHOUT
01089 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01090 now->wordend_frame[t] = wend_token_frame[tn][0];
01091 now->wordend_gscore[t] = wend_token_gscore[tn][0];
01092 #endif
01093 #endif
01094
01095 #ifdef MULTIPATH_VERSION
01096
01097
01098 if (ccd_flag) {
01099
01100 tmpmax_store -= store_point_maxarc;
01101 if (tmpmax_store < LOG_ZERO) tmpmax_store = LOG_ZERO;
01102 now->g_prev[t] = tmpmax_store;
01103 }
01104 #endif
01105
01106
01107 if (node_exist_p) endt = t;
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 if (t < now->estimated_next_t && (!node_exist_p)) {
01118
01119 for (i=t-1;i>=0;i--) {
01120 now->g[i] = LOG_ZERO;
01121 #ifdef GRAPHOUT
01122 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01123 now->wordend_frame[i] = -1;
01124 now->wordend_gscore[i] = LOG_ZERO;
01125 #endif
01126 #endif
01127 if (ccd_flag) now->g_prev[i] = LOG_ZERO;
01128 }
01129
01130 break;
01131 }
01132
01133 }
01134
01135 if (debug2_flag) j_printf("scanned: [%3d-%3d]\n", endt, startt);
01136
01137 end_of_scan:
01138
01139 #ifdef MULTIPATH_VERSION
01140
01141
01142 if (endt == 0) {
01143 tmpmax = LOG_ZERO;
01144 for(ac=whmm->state[0].ac;ac;ac=ac->next) {
01145 score1 = wordtrellis[tn][ac->arc] + ac->a;
01146 if (tmpmax < score1) tmpmax = score1;
01147 }
01148 now->final_g = score1;
01149 } else {
01150 now->final_g = LOG_ZERO;
01151 }
01152 #endif
01153
01154
01155
01156 if (ccd_flag) {
01157 if (store_point ==
01158 #ifdef MULTIPATH_VERSION
01159 wordhmmnum - 2
01160 #else
01161 wordhmmnum - 1
01162 #endif
01163 ) {
01164
01165
01166
01167
01168
01169
01170
01171 for (t = startt; t>=0; t--) {
01172 now->g_prev[t] = g[t];
01173 }
01174 }
01175 #ifdef GRAPHOUT
01176 #ifndef GRAPHOUT_PRECISE_BOUNDARY
01177 if (now->tail_g_score != LOG_ZERO) {
01178 if (now->prevgraph != NULL) {
01179 (now->prevgraph)->leftscore = now->tail_g_score;
01180 }
01181 }
01182 #endif
01183 #endif
01184
01185
01186 if (back_rescan) {
01187 now->last_ph = phmmseq[0];
01188 } else {
01189 now->last_ph = winfo->wseq[word][0];
01190 }
01191 #ifdef MULTIPATH_VERSION
01192 now->last_ph_sp_attached = has_sp[0];
01193 #endif
01194 }
01195
01196 #ifndef MULTIPATH_VERSION
01197 #ifdef GRAPHOUT
01198 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01199
01200
01201 now->wordend_frame[peseqlen-1] = now->wordend_frame[0];
01202 now->wordend_gscore[peseqlen-1] = now->wordend_gscore[0];
01203 for (t=0;t<peseqlen-1;t++) {
01204 now->wordend_frame[t] = now->wordend_frame[t+1];
01205 now->wordend_gscore[t] = now->wordend_gscore[t+1];
01206 }
01207 #endif
01208 #endif
01209 #endif
01210
01211
01212 free_hmm(whmm);
01213 #ifdef TCD
01214 #ifdef MULTIPATH_VERSION
01215 if (ccd_flag) {
01216 j_printf("last_ph = %s", (now->last_ph)->name);
01217 if (now->last_ph_sp_attached) j_printf(" (sp attached)");
01218 j_printf("\n");
01219 }
01220 #else
01221 j_printf("last_ph = %s\n", (now->last_ph)->name);
01222 #endif
01223 #endif
01224 }
01225
01226
01227
01228
01229
01230
01231
01255 void
01256 next_word(NODE *now, NODE *new, NEXTWORD *nword, HTK_Param *param, BACKTRELLIS *backtrellis)
01257 {
01258 int t;
01259 HMM_Logical *newphone;
01260 int lastword;
01261 int i;
01262 LOGPROB tmpp;
01263 #ifndef MULTIPATH_VERSION
01264 LOGPROB a_value;
01265 #endif
01266 int startt;
01267 int word;
01268 #ifndef WORD_GRAPH
01269 LOGPROB totalscore;
01270 TRELLIS_ATOM *tre;
01271 #endif
01272
01273 new->score = LOG_ZERO;
01274
01275 word = nword->id;
01276 lastword=now->seq[now->seqnum-1];
01277
01278
01279
01280 for (i=0;i< now->seqnum;i++){
01281 new->seq[i] = now->seq[i];
01282 #ifdef CM_SEARCH
01283 #ifdef CM_MULTIPLE_ALPHA
01284 memcpy(new->cmscore[i], now->cmscore[i], sizeof(LOGPROB) * cm_alpha_num);
01285 #else
01286 new->cmscore[i] = now->cmscore[i];
01287 #endif
01288 #endif
01289 }
01290 new->seq[i] = word;
01291 new->seqnum = now->seqnum+1;
01292 #ifdef USE_DFA
01293 new->state = nword->next_state;
01294 #endif
01295 #ifdef USE_NGRAM
01296 new->totallscore = now->totallscore + nword->lscore;
01297 #endif
01298 #ifdef MULTIPATH_VERSION
01299 new->final_g = now->final_g;
01300 #endif
01301
01302 if (ccd_flag) {
01303
01304
01305
01306
01307
01308 newphone = get_right_context_HMM(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name, hmminfo);
01309 if (newphone == NULL) {
01310
01311
01312
01313
01314 if (winfo->wlen[word] > 1 && winfo->wseq[word][winfo->wlen[word]-1]->is_pseudo){
01315 error_missing_right_triphone(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name);
01316 }
01317 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01318 }
01319
01320
01321
01322 new->last_ph = now->last_ph;
01323 #ifdef MULTIPATH_VERSION
01324 new->last_ph_sp_attached = now->last_ph_sp_attached;
01325 #endif
01326
01327
01328
01329 for (t=0;t<peseqlen;t++) {
01330 new->g_prev[t] = now->g_prev[t];
01331 }
01332
01333 } else {
01334
01335
01336
01337 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01338 }
01339
01340 #ifdef USE_NGRAM
01341
01342 new->lscore = nword->lscore;
01343 #endif
01344
01345 #ifndef MULTIPATH_VERSION
01346
01347
01348 i = hmm_logical_state_num(newphone);
01349 a_value = (hmm_logical_trans(newphone))->a[i-2][i-1];
01350 #endif
01351
01352
01353
01354
01355
01356
01357 #ifdef MULTIPATH_VERSION
01358 startt = peseqlen-1;
01359 #else
01360 startt = peseqlen-2;
01361 new->g[startt+1] = LOG_ZERO;
01362 #endif
01363
01364 #ifdef WORD_GRAPH
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374 for(t=startt;t>=0;t--) {
01375 new->g[t] =
01376 #ifdef MULTIPATH_VERSION
01377 now->g[t]
01378 #else
01379 now->g[t+1] + a_value
01380 #endif
01381 #ifdef USE_NGRAM
01382 + nword->lscore
01383 #else
01384 + penalty2
01385 #endif
01386 ;
01387 }
01388
01389
01390
01391 new->bestt = (nword->tre)->endtime;
01392
01393
01394
01395 new->estimated_next_t = (nword->tre)->begintime - 1;
01396
01397
01398 #ifdef MULTIPATH_VERSION
01399 new->score = new->g[new->bestt] + (nword->tre)->backscore;
01400 #else
01401
01402
01403 if (newphone->is_pseudo) {
01404 tmpp = outprob_cd(new->bestt, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01405 } else {
01406 tmpp = outprob_state(new->bestt, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01407 }
01408 new->score = new->g[new->bestt] + (nword->tre)->backscore + tmpp;
01409 #endif
01410
01411
01412 new->tre = nword->tre;
01413
01414 #else
01415
01416
01417
01418
01419
01420
01421
01422
01423 for(t=startt;t>=0;t--) {
01424 new->g[t] =
01425 #ifdef MULTIPATH_VERSION
01426 now->g[t]
01427 #else
01428 now->g[t+1] + a_value
01429 #endif
01430 #ifdef USE_NGRAM
01431 + nword->lscore
01432 #else
01433 + penalty2
01434 #endif
01435 ;
01436 }
01437
01438 #ifdef USE_DFA
01439 if (!looktrellis_flag) {
01440
01441
01442 for(t = startt; t >= 0; t--) {
01443 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01444 if (tre == NULL) continue;
01445 #ifdef MULTIPATH_VERSION
01446 totalscore = new->g[t] + tre->backscore;
01447 #else
01448 if (newphone->is_pseudo) {
01449 tmpp = outprob_cd(t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01450 } else {
01451 tmpp = outprob_state(t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01452 }
01453 totalscore = new->g[t] + tre->backscore + tmpp;
01454 #endif
01455 if (new->score < totalscore) {
01456 new->score = totalscore;
01457 new->bestt = t;
01458 new->estimated_next_t = tre->begintime - 1;
01459 new->tre = tre;
01460 }
01461 }
01462 } else {
01463 #endif
01464
01465
01466
01467
01468
01469 for(t = (nword->tre)->endtime; t >= 0; t--) {
01470 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01471 if (tre == NULL) break;
01472 #ifdef MULTIPATH_VERSION
01473 totalscore = new->g[t] + tre->backscore;
01474 #else
01475 if (newphone->is_pseudo) {
01476 tmpp = outprob_cd(t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01477 } else {
01478 tmpp = outprob_state(t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01479 }
01480 totalscore = new->g[t] + tre->backscore + tmpp;
01481 #endif
01482 if (new->score < totalscore) {
01483 new->score = totalscore;
01484 new->bestt = t;
01485 new->estimated_next_t = tre->begintime - 1;
01486 new->tre = tre;
01487 }
01488 }
01489
01490 for(t = (nword->tre)->endtime + 1; t <= startt; t++) {
01491 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01492 if (tre == NULL) break;
01493 #ifdef MULTIPATH_VERSION
01494 totalscore = new->g[t] + tre->backscore;
01495 #else
01496 if (newphone->is_pseudo) {
01497 tmpp = outprob_cd(t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01498 } else {
01499 tmpp = outprob_state(t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01500 }
01501 totalscore = new->g[t] + tre->backscore + tmpp;
01502 #endif
01503 if (new->score < totalscore) {
01504 new->score = totalscore;
01505 new->bestt = t;
01506 new->estimated_next_t = tre->begintime - 1;
01507 new->tre = tre;
01508 }
01509 }
01510
01511 #ifdef USE_DFA
01512 }
01513 #endif
01514
01515 #endif
01516
01517 }
01518
01519
01520
01521
01522
01523
01543 void
01544 start_word(NODE *new, NEXTWORD *nword, HTK_Param *param, BACKTRELLIS *backtrellis)
01545 {
01546 HMM_Logical *newphone;
01547 WORD_ID word;
01548 LOGPROB tmpp;
01549 #ifndef WORD_GRAPH
01550 int t;
01551 TRELLIS_ATOM *tre = NULL;
01552 #endif
01553
01554
01555 word = nword->id;
01556 new->score = LOG_ZERO;
01557 new->seqnum = 1;
01558 new->seq[0] = word;
01559
01560 #ifdef USE_DFA
01561 new->state = nword->next_state;
01562 #endif
01563 #ifdef USE_NGRAM
01564 new->totallscore = nword->lscore;
01565 #endif
01566
01567
01568 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01569 if (ccd_flag) {
01570 new->last_ph = NULL;
01571 #ifdef MULTIPATH_VERSION
01572 new->last_ph_sp_attached = FALSE;
01573 #endif
01574 }
01575 #ifdef USE_NGRAM
01576 new->lscore = nword->lscore;
01577 #endif
01578
01579 #ifdef USE_NGRAM
01580 new->g[peseqlen-1] = nword->lscore;
01581 #else
01582 new->g[peseqlen-1] = 0;
01583 #endif
01584
01585 #ifdef WORD_GRAPH
01586 #ifdef MULTIPATH_VERSION
01587 new->score = new->g[peseqlen-1] + (nword->tre)->backscore;
01588 #else
01589 if (newphone->is_pseudo) {
01590 tmpp = outprob_cd(peseqlen-1, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01591 } else {
01592 tmpp = outprob_state(peseqlen-1, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01593 }
01594 new->score = new->g[peseqlen-1] + (nword->tre)->backscore + tmpp;
01595 #endif
01596 new->tre = nword->tre;
01597 new->bestt = peseqlen-1;
01598 new->estimated_next_t = (nword->tre)->begintime - 1;
01599
01600 #else
01601
01602 for (t=peseqlen-1; t>=0; t--) {
01603 tre = bt_binsearch_atom(backtrellis, t, word);
01604 if (tre != NULL) {
01605 #ifdef GRAPHOUT
01606 new->bestt = peseqlen-1;
01607 #else
01608 new->bestt = t;
01609 #endif
01610 #ifdef MULTIPATH_VERSION
01611 new->score = new->g[peseqlen-1] + tre->backscore;
01612 #else
01613 if (newphone->is_pseudo) {
01614 tmpp = outprob_cd(peseqlen-1, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01615 } else {
01616 tmpp = outprob_state(peseqlen-1, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01617 }
01618 new->score = new->g[peseqlen-1] + tre->backscore + tmpp;
01619 #endif
01620 new->estimated_next_t = tre->begintime - 1;
01621 new->tre = tre;
01622 break;
01623 }
01624 }
01625 if (tre == NULL) {
01626 new->score = LOG_ZERO;
01627 }
01628 #endif
01629 }
01630
01631
01649 void
01650 last_next_word(NODE *now, NODE *new, HTK_Param *param)
01651 {
01652 cpy_node(new, now);
01653
01654
01655 #ifdef MULTIPATH_VERSION
01656 new->score = now->final_g;
01657 #else
01658 new->score = now->g[0];
01659 #endif
01660 }
01661
01662
01663 #endif