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