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