00001
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #include <julius.h>
00066
00067 #ifdef PASS2_STRICT_IWCD
00068
00069 #undef TCD
00070
00071
00072
00073
00074
00075
00076
00089 void
00090 free_node(NODE *node)
00091 {
00092 if (node == NULL) return;
00093 free(node->g);
00094 #ifdef GRAPHOUT
00095 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00096 free(node->wordend_frame);
00097 free(node->wordend_gscore);
00098 #endif
00099 if (node->prevgraph != NULL && node->prevgraph->saved == FALSE) {
00100 wordgraph_free(node->prevgraph);
00101 }
00102 #endif
00103 free(node);
00104 }
00105
00124 NODE *
00125 cpy_node(NODE *dst, NODE *src)
00126 {
00127
00128 dst->next = src->next;
00129 dst->prev = src->prev;
00130 memcpy(dst->g, src->g, sizeof(LOGPROB) * peseqlen);
00131 memcpy(dst->seq, src->seq, sizeof(WORD_ID) * MAXSEQNUM);
00132 #ifdef CM_SEARCH
00133 #ifdef CM_MULTIPLE_ALPHA
00134 {
00135 int w;
00136 for(w=0;w<src->seqnum;w++) {
00137 memcpy(dst->cmscore[w], src->cmscore[w], sizeof(LOGPROB) * cm_alpha_num);
00138 }
00139 }
00140 #else
00141 memcpy(dst->cmscore, src->cmscore, sizeof(LOGPROB) * MAXSEQNUM);
00142 #endif
00143 #endif
00144 dst->seqnum = src->seqnum;
00145 dst->score = src->score;
00146 dst->bestt = src->bestt;
00147 dst->estimated_next_t = src->estimated_next_t;
00148 dst->endflag = src->endflag;
00149 #ifdef USE_DFA
00150 dst->state = src->state;
00151 #endif
00152 dst->tre = src->tre;
00153 if (ccd_flag) {
00154 dst->last_ph = src->last_ph;
00155 #ifdef MULTIPATH_VERSION
00156 dst->last_ph_sp_attached = src->last_ph_sp_attached;
00157 #endif
00158 }
00159 #ifdef USE_NGRAM
00160 dst->totallscore = src->totallscore;
00161 #endif
00162 #ifdef MULTIPATH_VERSION
00163 dst->final_g = src->final_g;
00164 #endif
00165 #ifdef VISUALIZE
00166 dst->popnode = src->popnode;
00167 #endif
00168 #ifdef GRAPHOUT
00169 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00170 memcpy(dst->wordend_frame, src->wordend_frame, sizeof(short)*peseqlen);
00171 memcpy(dst->wordend_gscore, src->wordend_gscore, sizeof(LOGPROB)*peseqlen);
00172 #endif
00173 dst->prevgraph = src->prevgraph;
00174 dst->lastcontext = src->lastcontext;
00175 #ifndef GRAPHOUT_PRECISE_BOUNDARY
00176 dst->tail_g_score = src->tail_g_score;
00177 #endif
00178 #endif
00179 return(dst);
00180 }
00181
00194 NODE *
00195 newnode()
00196 {
00197 NODE *tmp;
00198 int i;
00199
00200 if ((tmp=(NODE *)mymalloc(sizeof(NODE)))==NULL) {
00201 j_error("can't malloc\n");
00202 }
00203
00204 tmp->next=NULL;
00205 tmp->prev=NULL;
00206 tmp->g = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
00207 tmp->last_ph = NULL;
00208 #ifdef MULTIPATH_VERSION
00209 tmp->last_ph_sp_attached = FALSE;
00210 #endif
00211 if (ccd_flag) {
00212 #ifdef USE_NGRAM
00213 tmp->totallscore = LOG_ZERO;
00214 #endif
00215 }
00216 tmp->endflag = FALSE;
00217 tmp->seqnum = 0;
00218 for(i=0;i<peseqlen;i++) {
00219 tmp->g[i] = LOG_ZERO;
00220 }
00221 #ifdef MULTIPATH_VERSION
00222 tmp->final_g = LOG_ZERO;
00223 #endif
00224 #ifdef VISUALIZE
00225 tmp->popnode = NULL;
00226 #endif
00227 #ifdef GRAPHOUT
00228 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00229 tmp->wordend_frame = (short *)mymalloc(sizeof(short)*peseqlen);
00230 tmp->wordend_gscore = (LOGPROB *)mymalloc(sizeof(LOGPROB)*peseqlen);
00231 #endif
00232 tmp->prevgraph = NULL;
00233 tmp->lastcontext = NULL;
00234 #endif
00235
00236 return(tmp);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 static LOGPROB *wordtrellis[2];
00246 static int tn;
00247 static int tl;
00248 static LOGPROB *g;
00249 static HMM_Logical **phmmseq;
00250 static int phmmlen_max;
00251 static HMM_Logical *tailph;
00252 #ifdef MULTIPATH_VERSION
00253 static boolean *has_sp;
00254 #endif
00255
00256 #ifdef GRAPHOUT
00257 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00258 static short *wend_token_frame[2];
00259 static LOGPROB *wend_token_gscore[2];
00260 static short *wef;
00261 static LOGPROB *wes;
00262 #endif
00263 #endif
00264
00275 void
00276 malloc_wordtrellis()
00277 {
00278 int maxwn;
00279
00280 maxwn = winfo->maxwn + 10;
00281 wordtrellis[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00282 wordtrellis[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00283
00284 g = (LOGPROB *)mymalloc(sizeof(LOGPROB) * peseqlen);
00285
00286 phmmlen_max = winfo->maxwlen + 2;
00287 phmmseq = (HMM_Logical **)mymalloc(sizeof(HMM_Logical *) * phmmlen_max);
00288 #ifdef MULTIPATH_VERSION
00289 has_sp = (boolean *)mymalloc(sizeof(boolean) * phmmlen_max);
00290 #endif
00291
00292 #ifdef GRAPHOUT
00293 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00294 wef = (short *)mymalloc(sizeof(short) * peseqlen);
00295 wes = (LOGPROB *)mymalloc(sizeof(LOGPROB) * peseqlen);
00296 wend_token_frame[0] = (short *)mymalloc(sizeof(short) * maxwn);
00297 wend_token_frame[1] = (short *)mymalloc(sizeof(short) * maxwn);
00298 wend_token_gscore[0] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00299 wend_token_gscore[1] = (LOGPROB *)mymalloc(sizeof(LOGPROB) * maxwn);
00300 #endif
00301 #endif
00302 }
00303
00314 void
00315 free_wordtrellis()
00316 {
00317 free(wordtrellis[0]);
00318 free(wordtrellis[1]);
00319 free(g);
00320 free(phmmseq);
00321 #ifdef MULTIPATH_VERSION
00322 free(has_sp);
00323 #endif
00324 #ifdef GRAPHOUT
00325 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00326 free(wef);
00327 free(wes);
00328 free(wend_token_frame[0]);
00329 free(wend_token_frame[1]);
00330 free(wend_token_gscore[0]);
00331 free(wend_token_gscore[1]);
00332 #endif
00333 #endif
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00383 static void
00384 do_viterbi(LOGPROB *g, LOGPROB *g_new, HMM_Logical **phmmseq
00385 #ifdef MULTIPATH_VERSION
00386 , boolean *has_sp
00387 #endif
00388 , int phmmlen, HTK_Param *param, int framelen, int least_frame
00389 #ifdef MULTIPATH_VERSION
00390 , LOGPROB *final_g
00391 #endif
00392 #ifdef GRAPHOUT
00393 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00394 , short *wordend_frame_src, short *wordend_frame_dst
00395 , LOGPROB *wordend_gscore_src, LOGPROB *wordend_gscore_dst
00396 #endif
00397 #endif
00398 )
00399 {
00400 HMM *whmm;
00401 int wordhmmnum;
00402 int startt;
00403 LOGPROB tmpmax,tmpscore;
00404 A_CELL *ac;
00405 int t,i,j;
00406 boolean node_exist_p;
00407
00408 #ifdef TCD
00409 j_printf("scan for:");
00410 for (i=0;i<phmmlen;i++) {
00411 j_printf(" %s", phmmseq[i]->name);
00412 }
00413 j_printf("\n");
00414 #endif
00415
00416
00417
00418 whmm = new_make_word_hmm(hmminfo, phmmseq, phmmlen
00419 #ifdef MULTIPATH_VERSION
00420 , has_sp
00421 #endif
00422 );
00423 wordhmmnum = whmm->len;
00424 if (wordhmmnum >= winfo->maxwn + 10) {
00425 j_error("scan_word: word too long\n");
00426 }
00427
00428
00429
00430 for(t = framelen-1; t >=0 ; t--) {
00431 if (
00432 #ifdef SCAN_BEAM
00433 g[t] > framemaxscore[t] - scan_beam_thres &&
00434 #endif
00435 g[t] > LOG_ZERO) {
00436 break;
00437 }
00438 }
00439 if (t < 0) { /* no node has score > LOG_ZERO */
00440
00441 for(t=0;t<framelen;t++) {
00442 g_new[t] = LOG_ZERO;
00443 #ifdef GRAPHOUT
00444 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00445 wordend_frame_dst[t] = -1;
00446 wordend_gscore_dst[t] = LOG_ZERO;
00447 #endif
00448 #endif
00449 }
00450 free_hmm(whmm);
00451 return;
00452 }
00453 startt = t;
00454
00455
00456
00457 for(t=framelen-1;t>startt;t--) {
00458 g_new[t] = LOG_ZERO;
00459 #ifdef GRAPHOUT
00460 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00461 wordend_frame_dst[t] = -1;
00462 wordend_gscore_dst[t] = LOG_ZERO;
00463 #endif
00464 #endif
00465 }
00466
00467
00468
00469
00470
00471
00472 tn = 0; tl = 1;
00473
00474 #ifdef GRAPHOUT
00475 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00476 for(i=0;i<wordhmmnum;i++) {
00477 wend_token_frame[tn][i] = -1;
00478 wend_token_gscore[tn][i] = LOG_ZERO;
00479 }
00480 #endif
00481 #endif
00482
00483 #ifndef MULTIPATH_VERSION
00484
00485
00486 for(i=0;i<wordhmmnum-1;i++) wordtrellis[tn][i] = LOG_ZERO;
00487 wordtrellis[tn][wordhmmnum-1] = g[startt] + outprob(startt, &(whmm->state[wordhmmnum-1]), param);
00488 g_new[startt] = wordtrellis[tn][0];
00489 #ifdef GRAPHOUT
00490 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00491 wend_token_frame[tn][wordhmmnum-1] = wordend_frame_src[startt];
00492 wend_token_gscore[tn][wordhmmnum-1] = wordend_gscore_src[startt];
00493 wordend_frame_dst[startt] = wend_token_frame[tn][0];
00494 wordend_gscore_dst[startt] = wend_token_gscore[tn][0];
00495 #endif
00496 #endif
00497 #endif
00498
00499
00500
00501 for(t=
00502 #ifdef MULTIPATH_VERSION
00503 startt
00504 #else
00505 startt-1
00506 #endif
00507 ; t>=0; t--) {
00508
00509
00510
00511 i = tn; tn = tl; tl = i;
00512
00513 node_exist_p = FALSE;
00514
00515 #ifndef MULTIPATH_VERSION
00516
00517
00518
00519 tmpscore = LOG_ZERO;
00520 for (ac=whmm->state[wordhmmnum-1].ac;ac;ac=ac->next) {
00521 if (tmpscore < wordtrellis[tl][ac->arc] + ac->a)
00522 j = ac->arc;
00523 tmpscore = wordtrellis[tl][ac->arc] + ac->a;
00524 }
00525 if (g[t] > tmpscore) {
00526 tmpmax = g[t];
00527 #ifdef GRAPHOUT
00528 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00529 wend_token_frame[tn][wordhmmnum-1] = wordend_frame_src[t];
00530 wend_token_gscore[tn][wordhmmnum-1] = wordend_gscore_src[t];
00531 #endif
00532 #endif
00533 } else {
00534 tmpmax = tmpscore;
00535 #ifdef GRAPHOUT
00536 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00537 wend_token_frame[tn][wordhmmnum-1] = wend_token_frame[tl][j];
00538 wend_token_gscore[tn][wordhmmnum-1] = wend_token_gscore[tl][j];
00539 #endif
00540 #endif
00541 }
00542
00543
00544
00545 if (
00546 #ifdef SCAN_BEAM
00547 tmpmax <= framemaxscore[t] - scan_beam_thres ||
00548 #endif
00549 tmpmax <= LOG_ZERO
00550 ) {
00551 wordtrellis[tn][wordhmmnum-1] = LOG_ZERO;
00552 #ifdef GRAPHOUT
00553 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00554 wend_token_frame[tn][wordhmmnum-1] = -1;
00555 wend_token_gscore[tn][wordhmmnum-1] = LOG_ZERO;
00556 #endif
00557 #endif
00558 } else {
00559 node_exist_p = TRUE;
00560 wordtrellis[tn][wordhmmnum-1] = tmpmax + outprob(t, &(whmm->state[wordhmmnum-1]), param);
00561 }
00562
00563 #endif
00564
00565
00566
00567 for(i=wordhmmnum-2;i>=0;i--) {
00568
00569
00570
00571 tmpmax = LOG_ZERO;
00572 for (ac=whmm->state[i].ac;ac;ac=ac->next) {
00573 #ifdef MULTIPATH_VERSION
00574 if (ac->arc == wordhmmnum-1) tmpscore = g[t];
00575 else if (t + 1 > startt) tmpscore = LOG_ZERO;
00576 else tmpscore = wordtrellis[tl][ac->arc];
00577 tmpscore += ac->a;
00578 #else
00579 tmpscore = wordtrellis[tl][ac->arc] + ac->a;
00580 #endif
00581 if (tmpmax < tmpscore) {
00582 tmpmax = tmpscore;
00583 j = ac->arc;
00584 }
00585 }
00586
00587
00588
00589 if (
00590 #ifdef SCAN_BEAM
00591 tmpmax <= framemaxscore[t] - scan_beam_thres ||
00592 #endif
00593 tmpmax <= LOG_ZERO
00594 ) {
00595
00596 wordtrellis[tn][i] = LOG_ZERO;
00597 #ifdef GRAPHOUT
00598 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00599 wend_token_frame[tn][i] = -1;
00600 wend_token_gscore[tn][i] = LOG_ZERO;
00601 #endif
00602 #endif
00603 } else {
00604
00605 node_exist_p = TRUE;
00606 #ifdef MULTIPATH_VERSION
00607 wordtrellis[tn][i] = tmpmax;
00608 if (i > 0) wordtrellis[tn][i] += outprob(t, &(whmm->state[i]), param);
00609 #else
00610 wordtrellis[tn][i] = tmpmax + outprob(t, &(whmm->state[i]), param);
00611 #endif
00612 #ifdef GRAPHOUT
00613 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00614 #ifdef MULTIPATH_VERSION
00615 if (j == wordhmmnum-1) {
00616 wend_token_frame[tn][i] = wordend_frame_src[t];
00617 wend_token_gscore[tn][i] = wordend_gscore_src[t];
00618 } else {
00619 wend_token_frame[tn][i] = wend_token_frame[tl][j];
00620 wend_token_gscore[tn][i] = wend_token_gscore[tl][j];
00621 }
00622 #else
00623 wend_token_frame[tn][i] = wend_token_frame[tl][j];
00624 wend_token_gscore[tn][i] = wend_token_gscore[tl][j];
00625 #endif
00626 #endif
00627 #endif
00628 }
00629 }
00630
00631
00632
00633 g_new[t] = wordtrellis[tn][0];
00634 #ifdef GRAPHOUT
00635 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00636
00637 wordend_frame_dst[t] = wend_token_frame[tn][0];
00638 wordend_gscore_dst[t] = wend_token_gscore[tn][0];
00639 #endif
00640 #endif
00641
00642
00643
00644
00645
00646
00647
00648 if (t < least_frame && (!node_exist_p)) {
00649
00650 for (i=t-1;i>=0;i--) {
00651 g_new[i] = LOG_ZERO;
00652 #ifdef GRAPHOUT
00653 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00654 wordend_frame_dst[i] = -1;
00655 wordend_gscore_dst[i] = LOG_ZERO;
00656 #endif
00657 #endif
00658 }
00659
00660 break;
00661 }
00662
00663 }
00664
00665 #ifdef MULTIPATH_VERSION
00666
00667
00668 if (t < 0) {
00669 tmpmax = LOG_ZERO;
00670 for(ac=whmm->state[0].ac;ac;ac=ac->next) {
00671 tmpscore = wordtrellis[tn][ac->arc] + ac->a;
00672 if (tmpmax < tmpscore) tmpmax = tmpscore;
00673 }
00674 *final_g = tmpmax;
00675 } else {
00676 *final_g = LOG_ZERO;
00677 }
00678 #endif
00679
00680
00681 free_hmm(whmm);
00682 }
00683
00703 static void
00704 do_viterbi_next_word(NODE *now, NODE *new, HMM_Logical *lastphone
00705 #ifdef MULTIPATH_VERSION
00706 , boolean sp
00707 #endif
00708 , HTK_Param *param)
00709 {
00710 int t, n;
00711 #ifndef MULTIPATH_VERSION
00712 LOGPROB a_value;
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 if (winfo->wlen[now->seq[now->seqnum-1]] > 1) {
00726 n = hmm_logical_state_num(lastphone);
00727 a_value = (hmm_logical_trans(lastphone))->a[n-2][n-1];
00728 for(t=0; t<peseqlen-1; t++) g[t] = now->g[t+1] + a_value;
00729 g[peseqlen-1] = LOG_ZERO;
00730 } else {
00731 for(t=0; t<peseqlen; t++) g[t] = now->g[t];
00732 }
00733
00734 # else
00735
00736 for(t=0; t<peseqlen; t++) g[t] = now->g[t];
00737 phmmseq[0] = lastphone;
00738 has_sp[0] = sp;
00739
00740 #endif
00741
00742 do_viterbi(g, new->g
00743 #ifdef MULTIPATH_VERSION
00744 , phmmseq, has_sp, 1, param
00745 #else
00746 , &lastphone, 1, param
00747 #endif
00748 , peseqlen, now->estimated_next_t
00749 #ifdef MULTIPATH_VERSION
00750 , &(new->final_g)
00751 #endif
00752 #ifdef GRAPHOUT
00753 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00754 , now->wordend_frame, new->wordend_frame
00755 , now->wordend_gscore, new->wordend_gscore
00756 #endif
00757 #endif
00758 );
00759
00760 #ifndef MULTIPATH_VERSION
00761 #ifdef GRAPHOUT
00762 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00763
00764
00765 new->wordend_frame[peseqlen-1] = new->wordend_frame[0];
00766 new->wordend_gscore[peseqlen-1] = new->wordend_gscore[0];
00767 for (t=0;t<peseqlen-1;t++) {
00768 new->wordend_frame[t] = new->wordend_frame[t+1];
00769 new->wordend_gscore[t] = new->wordend_gscore[t+1];
00770 }
00771 #endif
00772 #endif
00773 #endif
00774 }
00775
00791 void
00792 scan_word(NODE *now, HTK_Param *param)
00793 {
00794 int i,t;
00795 WORD_ID word;
00796 int phmmlen;
00797 #ifdef MULTIPATH_VERSION
00798 boolean tail_ph_sp_attached;
00799 #endif
00800
00801 #ifdef GRAPHOUT
00802 #ifndef GRAPHOUT_PRECISE_BOUNDARY
00803 if (ccd_flag) {
00804 now->tail_g_score = now->g[now->bestt];
00805 }
00806 #endif
00807 #endif
00808
00809
00810
00811
00812
00813
00814
00815 word = now->seq[now->seqnum-1];
00816
00817 #ifdef TCD
00818 j_printf("w=");
00819 for(i=0;i<winfo->wlen[word];i++) {
00820 j_printf(" %s",(winfo->wseq[word][i])->name);
00821 }
00822 if (ccd_flag) {
00823 if (now->last_ph != NULL) {
00824 j_printf(" | %s", (now->last_ph)->name);
00825 }
00826 }
00827 j_printf("\n");
00828 #endif
00829
00830 if (ccd_flag) {
00831
00832
00833 if (now->last_ph != NULL) {
00834 tailph = get_right_context_HMM(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name, hmminfo);
00835 if (tailph == NULL) {
00836
00837
00838
00839
00840 if (winfo->wlen[word] > 1 && winfo->wseq[word][winfo->wlen[word]-1]->is_pseudo){
00841 error_missing_right_triphone(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name);
00842 }
00843
00844 tailph = winfo->wseq[word][winfo->wlen[word]-1];
00845 }
00846 } else {
00847 tailph = winfo->wseq[word][winfo->wlen[word]-1];
00848 }
00849
00850
00851
00852 if (winfo->wlen[word] == 1) {
00853 now->last_ph = tailph;
00854 #ifdef MULTIPATH_VERSION
00855 now->last_ph_sp_attached = TRUE;
00856 #endif
00857 #ifdef GRAPHOUT
00858 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00859
00860
00861 for (t=0;t<peseqlen;t++) {
00862 now->wordend_frame[t] = t;
00863 now->wordend_gscore[t] = now->g[t];
00864 }
00865 #endif
00866 #endif
00867 #ifdef TCD
00868 j_printf("suspended as %s\n", (now->last_ph)->name);
00869 #endif
00870 return;
00871 }
00872
00873
00874
00875 phmmlen = winfo->wlen[word] - 1;
00876 if (phmmlen > phmmlen_max) {
00877 j_error("short of phmmlen\n");
00878 }
00879 for (i=0;i<phmmlen-1;i++) {
00880 phmmseq[i] = winfo->wseq[word][i+1];
00881 #ifdef MULTIPATH_VERSION
00882 has_sp[i] = FALSE;
00883 #endif
00884 }
00885 phmmseq[phmmlen-1] = tailph;
00886 #ifdef MULTIPATH_VERSION
00887 has_sp[phmmlen-1] = (enable_iwsp) ? TRUE : FALSE;
00888 #endif
00889 } else {
00890 phmmlen = winfo->wlen[word];
00891 #ifdef MULTIPATH_VERSION
00892 for (i=0;i<phmmlen;i++) {
00893 phmmseq[i] = winfo->wseq[word][i];
00894 has_sp[i] = FALSE;
00895 }
00896 if (enable_iwsp) has_sp[phmmlen-1] = TRUE;
00897 #else
00898 for (i=0;i<phmmlen;i++) phmmseq[i] = winfo->wseq[word][i];
00899 #endif
00900 }
00901
00902
00903
00904 for (t=0;t<peseqlen;t++) g[t] = now->g[t];
00905
00906 #ifdef GRAPHOUT
00907 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00908
00909
00910 for (t=0;t<peseqlen;t++) {
00911 wef[t] = t;
00912 wes[t] = now->g[t];
00913 }
00914 #endif
00915 #endif
00916
00917
00918
00919 do_viterbi(g, now->g, phmmseq
00920 #ifdef MULTIPATH_VERSION
00921 , has_sp
00922 #endif
00923 , phmmlen, param, peseqlen, now->estimated_next_t
00924 #ifdef MULTIPATH_VERSION
00925 , &(now->final_g)
00926 #endif
00927 #ifdef GRAPHOUT
00928 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00929
00930
00931 , wef, now->wordend_frame
00932 , wes, now->wordend_gscore
00933 #endif
00934 #endif
00935 );
00936 #ifndef MULTIPATH_VERSION
00937 #ifdef GRAPHOUT
00938 #ifdef GRAPHOUT_PRECISE_BOUNDARY
00939
00940
00941 now->wordend_frame[peseqlen-1] = now->wordend_frame[0];
00942 now->wordend_gscore[peseqlen-1] = now->wordend_gscore[0];
00943 for (t=0;t<peseqlen-1;t++) {
00944 now->wordend_frame[t] = now->wordend_frame[t+1];
00945 now->wordend_gscore[t] = now->wordend_gscore[t+1];
00946 }
00947 #endif
00948 #endif
00949 #endif
00950
00951 if (ccd_flag) {
00952
00953
00954 now->last_ph = winfo->wseq[word][0];
00955 #ifdef MULTIPATH_VERSION
00956 now->last_ph_sp_attached = FALSE;
00957 #endif
00958 #ifdef TCD
00959 j_printf("last_ph = %s\n", (now->last_ph)->name);
00960 #endif
00961 }
00962 }
00963
00964
00965
00966
00967
00968
00969
00970 static HMM_Logical *lastphone, *newphone;
00971 static LOGPROB *g_src;
00972
00996 void
00997 next_word(NODE *now, NODE *new, NEXTWORD *nword, HTK_Param *param, BACKTRELLIS *backtrellis)
00998 {
00999 int t;
01000 int lastword;
01001 int i;
01002 LOGPROB a_value;
01003 LOGPROB tmpp;
01004 int startt;
01005 int word;
01006 TRELLIS_ATOM *tre;
01007 LOGPROB totalscore;
01008 #ifdef GRAPHOUT
01009 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01010 short *wendf;
01011 LOGPROB *wends;
01012 #endif
01013 #endif
01014
01015
01016 word = nword->id;
01017 lastword = now->seq[now->seqnum-1];
01018
01019
01020
01021 if (ccd_flag) {
01022
01023
01024 lastphone = get_left_context_HMM(now->last_ph, winfo->wseq[word][winfo->wlen[word]-1]->name, hmminfo);
01025 if (lastphone == NULL) {
01026
01027
01028
01029
01030 if (now->last_ph->is_pseudo){
01031 error_missing_left_triphone(now->last_ph, winfo->wseq[word][winfo->wlen[word]-1]->name);
01032 }
01033 lastphone = now->last_ph;
01034 }
01035 }
01036
01037
01038
01039 if (ccd_flag) {
01040 newphone = get_right_context_HMM(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name, hmminfo);
01041 if (newphone == NULL) {
01042
01043
01044
01045
01046 if (winfo->wlen[word] > 1 && winfo->wseq[word][winfo->wlen[word]-1]->is_pseudo){
01047 error_missing_right_triphone(winfo->wseq[word][winfo->wlen[word]-1], now->last_ph->name);
01048 }
01049 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01050 }
01051 } else {
01052 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01053 }
01054
01055
01056
01057 new->score = LOG_ZERO;
01058 for (i=0;i< now->seqnum;i++){
01059 new->seq[i] = now->seq[i];
01060 #ifdef CM_SEARCH
01061 #ifdef CM_MULTIPLE_ALPHA
01062 memcpy(new->cmscore[i], now->cmscore[i], sizeof(LOGPROB) * cm_alpha_num);
01063 #else
01064 new->cmscore[i] = now->cmscore[i];
01065 #endif
01066 #endif
01067 }
01068 new->seq[i] = word;
01069 new->seqnum = now->seqnum+1;
01070 #ifdef USE_DFA
01071 new->state = nword->next_state;
01072 #endif
01073 #ifdef USE_NGRAM
01074 new->totallscore = now->totallscore + nword->lscore;
01075 #endif
01076 if (ccd_flag) {
01077
01078
01079 new->last_ph = lastphone;
01080 #ifdef MULTIPATH_VERSION
01081 new->last_ph_sp_attached = now->last_ph_sp_attached;
01082 #endif
01083 }
01084
01085 if (ccd_flag) {
01086
01087
01088 do_viterbi_next_word(now, new, lastphone
01089 #ifdef MULTIPATH_VERSION
01090 , now->last_ph_sp_attached
01091 #endif
01092 , param);
01093 g_src = new->g;
01094 } else {
01095 g_src = now->g;
01096 #ifdef GRAPHOUT
01097 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01098 memcpy(new->wordend_frame, now->wordend_frame, sizeof(short)*peseqlen);
01099 memcpy(new->wordend_gscore, now->wordend_gscore, sizeof(LOGPROB)*peseqlen);
01100 #endif
01101 #endif
01102 }
01103
01104
01105
01106 #ifdef MULTIPATH_VERSION
01107 startt = peseqlen-1;
01108 #else
01109 startt = peseqlen-2;
01110 #endif
01111 i = hmm_logical_state_num(newphone);
01112 a_value = (hmm_logical_trans(newphone))->a[i-2][i-1];
01113 for(t=0; t <= startt; t++) {
01114 new->g[t] =
01115 #ifdef MULTIPATH_VERSION
01116 g_src[t]
01117 #else
01118 g_src[t+1] + a_value
01119 #endif
01120 #ifdef USE_NGRAM
01121 + nword->lscore
01122 #else
01123 + penalty2
01124 #endif
01125 ;
01126 }
01127
01128
01129
01130
01131
01132 #ifdef WORD_GRAPH
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142 new->bestt = (nword->tre)->endtime;
01143
01144
01145
01146 new->estimated_next_t = (nword->tre)->begintime - 1;
01147
01148
01149 #ifdef MULTIPATH_VERSION
01150 new->score = new->g[new->bestt] + (nword->tre)->backscore;
01151 #else
01152
01153
01154 if (newphone->is_pseudo) {
01155 tmpp = outprob_cd(new->bestt, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01156 } else {
01157 tmpp = outprob_state(new->bestt, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01158 }
01159 new->score = new->g[new->bestt] + (nword->tre)->backscore + tmpp;
01160 #endif
01161
01162
01163 new->tre = nword->tre;
01164
01165 #else
01166
01167
01168
01169
01170
01171
01172
01173 #ifdef USE_DFA
01174 if (!looktrellis_flag) {
01175
01176
01177 for(t = startt; t >= 0; t--) {
01178 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01179 if (tre == NULL) continue;
01180 #ifdef MULTIPATH_VERSION
01181 totalscore = new->g[t] + tre->backscore;
01182 #else
01183 if (newphone->is_pseudo) {
01184 tmpp = outprob_cd(t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01185 } else {
01186 tmpp = outprob_state(t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01187 }
01188 totalscore = new->g[t] + tre->backscore + tmpp;
01189 #endif
01190 if (new->score < totalscore) {
01191 new->score = totalscore;
01192 new->bestt = t;
01193 new->estimated_next_t = tre->begintime - 1;
01194 new->tre = tre;
01195 }
01196 }
01197 } else {
01198 #endif
01199
01200
01201
01202
01203
01204
01205
01206
01207 for(t = (nword->tre)->endtime; t >= 0; t--) {
01208 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01209 if (tre == NULL) break;
01210 #ifdef MULTIPATH_VERSION
01211 totalscore = new->g[t] + tre->backscore;
01212 #else
01213 if (newphone->is_pseudo) {
01214 tmpp = outprob_cd(t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01215 } else {
01216 tmpp = outprob_state(t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01217 }
01218 totalscore = new->g[t] + tre->backscore + tmpp;
01219 #endif
01220 if (new->score < totalscore) {
01221 new->score = totalscore;
01222 new->bestt = t;
01223 new->estimated_next_t = tre->begintime - 1;
01224 new->tre = tre;
01225 }
01226 }
01227
01228 for(t = (nword->tre)->endtime + 1; t <= startt; t++) {
01229 tre = bt_binsearch_atom(backtrellis, t, (WORD_ID) word);
01230 if (tre == NULL) break;
01231 #ifdef MULTIPATH_VERSION
01232 totalscore = new->g[t] + tre->backscore;
01233 #else
01234 if (newphone->is_pseudo) {
01235 tmpp = outprob_cd(t, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01236 } else {
01237 tmpp = outprob_state(t, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01238 }
01239 totalscore = new->g[t] + tre->backscore + tmpp;
01240 #endif
01241 if (new->score < totalscore) {
01242 new->score = totalscore;
01243 new->bestt = t;
01244 new->estimated_next_t = tre->begintime - 1;
01245 new->tre = tre;
01246 }
01247 }
01248
01249 #ifdef USE_DFA
01250 }
01251 #endif
01252
01253 #endif
01254
01255 #ifdef USE_NGRAM
01256
01257 new->lscore = nword->lscore;
01258 #endif
01259
01260 }
01261
01262
01263
01264
01265
01266
01267
01287 void
01288 start_word(NODE *new, NEXTWORD *nword, HTK_Param *param, BACKTRELLIS *backtrellis)
01289 {
01290 HMM_Logical *newphone;
01291 WORD_ID word;
01292 TRELLIS_ATOM *tre = NULL;
01293 LOGPROB tmpp;
01294 int t;
01295
01296
01297 word = nword->id;
01298 new->score = LOG_ZERO;
01299 new->seqnum = 1;
01300 new->seq[0] = word;
01301
01302 #ifdef USE_DFA
01303 new->state = nword->next_state;
01304 #endif
01305 #ifdef USE_NGRAM
01306 new->totallscore = nword->lscore;
01307 #endif
01308
01309 #ifdef USE_NGRAM
01310
01311 new->lscore = nword->lscore;
01312 #endif
01313
01314
01315 newphone = winfo->wseq[word][winfo->wlen[word]-1];
01316 if (ccd_flag) {
01317 new->last_ph = NULL;
01318 }
01319
01320 #ifdef USE_NGRAM
01321 new->g[peseqlen-1] = nword->lscore;
01322 #else
01323 new->g[peseqlen-1] = 0;
01324 #endif
01325
01326 #ifdef WORD_GRAPH
01327 new->score = new->g[peseqlen-1] + (nword->tre)->backscore;
01328 new->tre = nword->tre;
01329 new->bestt = peseqlen-1;
01330 new->estimated_next_t = (nword->tre)->begintime - 1;
01331
01332 #else
01333
01334 for (t=peseqlen-1; t>=0; t--) {
01335 tre = bt_binsearch_atom(backtrellis, t, word);
01336 if (tre != NULL) {
01337 #ifdef GRAPHOUT
01338 new->bestt = peseqlen-1;
01339 #else
01340 new->bestt = t;
01341 #endif
01342 #ifdef MULTIPATH_VERSION
01343 new->score = new->g[peseqlen-1] + tre->backscore;
01344 #else
01345 if (newphone->is_pseudo) {
01346 tmpp = outprob_cd(peseqlen-1, &(newphone->body.pseudo->stateset[newphone->body.pseudo->state_num-2]), param);
01347 } else {
01348 tmpp = outprob_state(peseqlen-1, newphone->body.defined->s[newphone->body.defined->state_num-2], param);
01349 }
01350 new->score = new->g[peseqlen-1] + tre->backscore + tmpp;
01351 #endif
01352 new->estimated_next_t = tre->begintime - 1;
01353 new->tre = tre;
01354 break;
01355 }
01356 }
01357 if (tre == NULL) {
01358 new->score = LOG_ZERO;
01359 }
01360 #endif
01361 }
01362
01380 void
01381 last_next_word(NODE *now, NODE *new, HTK_Param *param)
01382 {
01383 cpy_node(new, now);
01384 if (ccd_flag) {
01385
01386
01387 do_viterbi_next_word(now, new, now->last_ph
01388 #ifdef MULTIPATH_VERSION
01389 , now->last_ph_sp_attached
01390 #endif
01391 , param);
01392 #ifdef MULTIPATH_VERSION
01393 new->score = new->final_g;
01394 #else
01395 new->score = new->g[0];
01396 #endif
01397 } else {
01398 #ifdef MULTIPATH_VERSION
01399 new->score = now->final_g;
01400 #else
01401 new->score = now->g[0];
01402 #endif
01403 #ifdef GRAPHOUT
01404 #ifdef GRAPHOUT_PRECISE_BOUNDARY
01405
01406 memcpy(new->wordend_frame, now->wordend_frame, sizeof(short)*peseqlen);
01407 memcpy(new->wordend_gscore, now->wordend_gscore, sizeof(LOGPROB)*peseqlen);
01408 #endif
01409 #endif
01410 }
01411 }
01412
01413 #endif