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