00001 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 #include <julius.h>
00060 
00061 #undef DEBUG
00062 
00063 static boolean idc_on;          
00064 static int progout_interval_frame; 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 #ifdef WORD_GRAPH
00073 
00074 
00075 static int glevel;              
00076 static int gnodes;              
00077 static int garcs;               
00078 
00107 static void
00108 generate_lattice(int frame, BACKTRELLIS *bt, WORD_INFO *winfo)
00109 {
00110   TRELLIS_ATOM *ta;
00111   int i, j;
00112   boolean new_node = FALSE;
00113   LOGPROB l;
00114 
00115   glevel++;
00116 
00117   if (frame >= 0) {
00118     for (i=0;i<bt->num[frame];i++) {
00119       ta = bt->rw[frame][i];
00120       
00121 
00122       if (! ta->within_context) continue; 
00123       if (ta->within_wordgraph) continue; 
00124       
00125       ta->within_wordgraph = TRUE;
00126       new_node = TRUE;
00127       if (debug2_flag) {
00128         for(j=0;j<glevel;j++) j_printf(" ");
00129         j_printf("%s: [%d..%d]\n", winfo->wname[ta->wid], ta->begintime, ta->endtime);
00130       }
00131       if (verbose_flag) {
00132         j_printf("%d: [%d..%d] wid=%d name=\"%s\" lname=\"%s\" score=%f", garcs, ta->begintime, ta->endtime, ta->wid, winfo->woutput[ta->wid], winfo->wname[ta->wid], ta->backscore);
00133       }
00134 #ifdef USE_NGRAM
00135       j_printf(" lscore=%f", ta->lscore);
00136 #endif
00137       l = ta->backscore;
00138       if (ta->last_tre->wid != WORD_INVALID) {
00139         l -= ta->last_tre->backscore;
00140       }
00141 #ifdef USE_NGRAM
00142       l -= ta->lscore;
00143 #endif
00144       j_printf(" AMavg=%f\n", l / (ta->endtime - ta->begintime + 1));
00145 
00146       garcs++;
00147       
00148       generate_lattice(ta->last_tre->endtime, bt, winfo);
00149     }
00150   }
00151   if (new_node) {
00152     gnodes++;
00153   }
00154   glevel--;
00155 }
00156 #endif
00157 
00172 static void
00173 put_atom(TRELLIS_ATOM *atom, WORD_INFO *winfo)
00174 {
00175   int i;
00176   j_printf("%3d,%3d %f %16s (id=%5d)", atom->begintime, atom->endtime,
00177          atom->backscore, winfo->wname[atom->wid], atom->wid);
00178   for (i=0;i<winfo->wlen[atom->wid]; i++) {
00179     j_printf(" %s",winfo->wseq[atom->wid][i]->name);
00180   }
00181   j_printf("\n");
00182 }
00183 
00216 static LOGPROB
00217 trace_backptr(WORD_ID wordseq_rt[MAXSEQNUM], int *rt_wordlen, TRELLIS_ATOM *atom, BACKTRELLIS *backtrellis, WORD_INFO *winfo)
00218 {
00219   int wordlen = 0;              
00220   TRELLIS_ATOM *tretmp;
00221   LOGPROB langscore = 0.0;
00222   static WORD_ID wordseq[MAXSEQNUM];    
00223   int i;
00224   
00225   
00226   wordseq[0] = atom->wid;       
00227   wordlen = 1;
00228   tretmp = atom;
00229 #ifdef USE_NGRAM
00230   langscore += tretmp->lscore;
00231 #endif
00232   if (debug2_flag) {
00233     put_atom(tretmp, winfo);
00234   }
00235   
00236   
00237   while (tretmp->begintime > 0) {
00238     tretmp = tretmp->last_tre;
00239 
00240 
00241     if (tretmp == NULL) {       
00242       j_error("ERROR: BackTrellis Pass missing??\n");
00243     }
00244 #ifdef USE_NGRAM
00245     langscore += tretmp->lscore;
00246 #endif
00247     wordseq[wordlen] = tretmp->wid;
00248     wordlen++;
00249     if (debug2_flag) {
00250       put_atom(tretmp, winfo);
00251     }
00252     if (wordlen >= MAXSEQNUM) {
00253       j_error("sentence length exceeded ( > %d)\n",MAXSEQNUM);
00254     }
00255   }
00256   *rt_wordlen = wordlen;
00257   
00258   for(i=0;i<wordlen;i++) wordseq_rt[i] = wordseq[wordlen-i-1];
00259   return(langscore);
00260 }
00261 
00311 static LOGPROB
00312 print_1pass_result(BACKTRELLIS *backtrellis, int framelen, WORD_INFO *winfo)
00313 {
00314   WORD_ID wordseq[MAXSEQNUM];
00315   int wordlen;
00316   int i;
00317   TRELLIS_ATOM *best;
00318   int last_time;
00319   LOGPROB total_lscore;
00320   LOGPROB maxscore;
00321   TRELLIS_ATOM *tmp;
00322 
00323   
00324   for (last_time = framelen - 1; last_time >= 0; last_time--) {
00325 #ifdef USE_NGRAM
00326 #ifdef SP_BREAK_CURRENT_FRAME   
00327     
00328     
00329     maxscore = LOG_ZERO;
00330     for (i=0;i<backtrellis->num[last_time];i++) {
00331       tmp = backtrellis->rw[last_time][i];
00332 #ifdef WORD_GRAPH
00333       
00334       if (!tmp->within_context) continue;
00335 #endif
00336       if (maxscore < tmp->backscore) {
00337         maxscore = tmp->backscore;
00338         best = tmp;
00339       }
00340     }
00341     if (maxscore != LOG_ZERO) break;
00342 #else  
00343     
00344     
00345     maxscore = LOG_ZERO;
00346     for (i=0;i<backtrellis->num[last_time];i++) {
00347       tmp = backtrellis->rw[last_time][i];
00348 #ifdef WORD_GRAPH
00349       
00350       if (!tmp->within_context) continue;
00351 #endif
00352       if (tmp->wid == winfo->tail_silwid && maxscore < tmp->backscore) {
00353         maxscore = tmp->backscore;
00354         best = tmp;
00355         break;
00356       }
00357     }
00358     if (maxscore != LOG_ZERO) break;
00359 #endif
00360 #else  
00361     
00362     
00363     maxscore = LOG_ZERO;
00364     for (i=0;i<backtrellis->num[last_time];i++) {
00365       tmp = backtrellis->rw[last_time][i];
00366 #ifdef WORD_GRAPH
00367       
00368       if (!tmp->within_context) continue;
00369 #endif
00370       
00371         if (maxscore < tmp->backscore) {
00372           maxscore = tmp->backscore;
00373           best = tmp;
00374         }
00375         
00376     }
00377     if (maxscore != LOG_ZERO) break;
00378 #endif 
00379   }
00380   if (last_time < 0) {          
00381     j_printerr("[no sentence-end word survived on last beam]\n");
00382     
00383     result_pass1_final(NULL, 0, LOG_ZERO, LOG_ZERO, winfo);
00384     return(LOG_ZERO);
00385   }
00386   
00387   
00388   total_lscore = trace_backptr(wordseq, &wordlen, best, backtrellis, winfo);
00389 
00390   if (progout_flag) {           
00391     result_pass1_current(last_time, wordseq, wordlen, best->backscore, total_lscore, winfo);
00392   }
00393 
00394       
00395   if (verbose_flag || !progout_flag) {
00396     result_pass1_final(wordseq, wordlen, best->backscore, total_lscore, winfo);
00397   }
00398   result_pass1_end();
00399   
00400   
00401   for(i=0;i<wordlen;i++) pass1_wseq[i] = wordseq[i];
00402   pass1_wnum = wordlen;
00403   pass1_score = best->backscore;
00404 
00405 #ifdef WORD_GRAPH
00406   
00407   
00408   
00409   
00410 
00411   glevel = 0;
00412   gnodes = 0;                   
00413   garcs = 0;
00414   j_printf("--- begin wordgraph data pass1 ---\n");
00415   generate_lattice(last_time, backtrellis, winfo);
00416   if (verbose_flag) j_printf("word graph generated (nodes=%d,arcs=%d)\n",gnodes, garcs);
00417   j_printf("--- end wordgraph data pass1 ---\n");
00418 #endif
00419 
00420   
00421   return(best->backscore);
00422 }
00423 
00441 static void
00442 bt_current_max(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00443 {
00444   static WORD_ID wordseq[MAXSEQNUM];
00445   int wordlen;
00446   TRELLIS_ATOM *tre;
00447   TRELLIS_ATOM *tremax;
00448   LOGPROB maxscore;
00449   LOGPROB lscore;
00450 
00451   
00452   maxscore = LOG_ZERO;
00453   tremax = NULL;
00454   tre = bt->list;
00455   while (tre != NULL && tre->endtime == t) {
00456     if (maxscore < tre->backscore) {
00457       maxscore = tre->backscore;
00458       tremax = tre;
00459     }
00460     tre = tre->next;
00461   }
00462 
00463   if (maxscore != LOG_ZERO) {
00464     lscore = trace_backptr(wordseq, &wordlen, tremax, bt, winfo);
00465     result_pass1_current(t, wordseq, wordlen, tremax->backscore, lscore, winfo);
00466   } else {
00467     wordlen = 0;
00468     result_pass1_current(t, wordseq, wordlen, LOG_ZERO, LOG_ZERO, winfo);
00469   }
00470 }
00471 
00489 static void
00490 bt_current_max_word(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00491 {
00492   TRELLIS_ATOM *tre;
00493   TRELLIS_ATOM *tremax;
00494   LOGPROB maxscore;
00495   WORD_ID w;
00496 
00497   
00498   
00499   maxscore = LOG_ZERO;
00500   tremax = NULL;
00501   tre = bt->list;
00502   while (tre != NULL && tre->endtime == t) {
00503     if (maxscore < tre->backscore) {
00504       maxscore = tre->backscore;
00505       tremax = tre;
00506     }
00507     tre = tre->next;
00508   }
00509 
00510   if (maxscore != LOG_ZERO) {
00511     j_printf("%3d: ",t);
00512     w = tremax->wid;
00513     j_printf("\"%s [%s]\"(id=%d)",
00514            winfo->wname[w], winfo->woutput[w], w);
00515     j_printf(" [%d-%d] %f <- ", tremax->begintime, t, tremax->backscore);
00516     w = tremax->last_tre->wid;
00517     if (w != WORD_INVALID) {
00518       j_printf("\"%s [%s]\"(id=%d)\n",
00519              winfo->wname[w], winfo->woutput[w], w);
00520     } else {
00521       j_printf("bgn\n");
00522     }
00523   }
00524 }
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532    
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 static TOKEN2 *tlist[2];        
00546 static TOKENID *tindex[2];      
00547 static int maxtnum = 0;         
00548 static int expand_step = 0;     
00549 static int tnum[2];             
00550 static int n_start;             
00551 static int n_end;               
00552 static int tl;          
00553 static int tn;          
00554 
00555 
00556 static TOKENID *token;          
00557 static int totalnodenum;        
00558 
00559 
00560 static TRELLIS_ATOM bos;        
00561 static boolean nodes_malloced = FALSE; 
00562 
00581 static void
00582 malloc_nodes(int n, int ntoken_init, int ntoken_step)
00583 {
00584   totalnodenum = n;
00585   token        = mymalloc(sizeof(TOKENID)*totalnodenum);
00586   if (maxtnum < ntoken_init) maxtnum = ntoken_init;
00587   tlist[0]     = mymalloc(sizeof(TOKEN2)*maxtnum);
00588   tlist[1]     = mymalloc(sizeof(TOKEN2)*maxtnum);
00589   tindex[0]     = mymalloc(sizeof(TOKENID)*maxtnum);
00590   tindex[1]     = mymalloc(sizeof(TOKENID)*maxtnum);
00591   tnum[0] = tnum[1] = 0;
00592   if (expand_step < ntoken_step) expand_step = ntoken_step;
00593   nodes_malloced = TRUE;
00594 }
00595 
00604 static void
00605 expand_tlist()
00606 {
00607   maxtnum += expand_step;
00608   tlist[0]     = myrealloc(tlist[0],sizeof(TOKEN2)*maxtnum);
00609   tlist[1]     = myrealloc(tlist[1],sizeof(TOKEN2)*maxtnum);
00610   tindex[0]     = myrealloc(tindex[0],sizeof(TOKENID)*maxtnum);
00611   tindex[1]     = myrealloc(tindex[1],sizeof(TOKENID)*maxtnum);
00612   
00613 }
00614 
00623 static void
00624 free_nodes()
00625 {
00626   if (nodes_malloced) {
00627     free(token);
00628     free(tlist[0]);
00629     free(tlist[1]);
00630     free(tindex[0]);
00631     free(tindex[1]);
00632     nodes_malloced = FALSE;
00633   }
00634 }
00635 
00648 static void
00649 clear_tlist(int tt)
00650 {
00651   tnum[tt] = 0;
00652 }
00653 
00666 static void
00667 clear_tokens(int tt)
00668 {
00669   int j;
00670   
00671   for (j=0; j<tnum[tt]; j++) {
00672     token[tlist[tt][j].node] = TOKENID_UNDEFINED;
00673   }
00674 }
00675 
00688 static TOKENID
00689 create_token()
00690 {
00691   TOKENID newid;
00692   newid = tnum[tn];
00693   tnum[tn]++;
00694   if (tnum[tn]>=maxtnum) expand_tlist();
00695   tindex[tn][newid] = newid;
00696 #ifdef WPAIR
00697   
00698   tlist[tn][newid].next = TOKENID_UNDEFINED;
00699 #endif
00700   return(newid);
00701 }
00702 
00730 static void
00731 node_assign_token(int node, TOKENID tkid)
00732 {
00733 #ifdef WPAIR
00734   
00735   tlist[tn][tkid].next = token[node];
00736 #endif
00737   token[node] = tkid;
00738   tlist[tn][tkid].node = node;
00739 }
00740 
00775 static TOKENID
00776 node_exist_token(int tt, int node, WORD_ID wid)
00777 {
00778 #ifdef WPAIR
00779   
00780 
00781 #ifdef WPAIR_KEEP_NLIMIT
00782   
00783   
00784   
00785   int i = 0;
00786   TOKENID lowest_token = TOKENID_UNDEFINED;
00787 #endif
00788   TOKENID tmp;
00789   for(tmp=token[node]; tmp != TOKENID_UNDEFINED; tmp=tlist[tt][tmp].next) {
00790     if (tlist[tt][tmp].last_tre->wid == wid) {
00791       return(tmp);
00792     }
00793 #ifdef WPAIR_KEEP_NLIMIT
00794     if (lowest_token == TOKENID_UNDEFINED ||
00795         tlist[tt][lowest_token].score < tlist[tt][tmp].score)
00796       lowest_token = tmp;
00797     if (++i >= wpair_keep_nlimit) break;
00798 #endif
00799   }
00800 #ifdef WPAIR_KEEP_NLIMIT
00801   if (i >= wpair_keep_nlimit) { 
00802     return(lowest_token);
00803   } else {
00804     return(TOKENID_UNDEFINED);
00805   }
00806 #else 
00807   return(TOKENID_UNDEFINED);
00808 #endif
00809   
00810 #else  
00811   
00812   
00813 
00814   return(token[node]);
00815 #endif
00816 }
00817 
00818 #ifdef DEBUG
00819 
00820 
00821 
00822 
00823 
00824 static void
00825 node_check_token(int tt)
00826 {
00827   int i;
00828   for(i=0;i<tnum[tt];i++) {
00829     if (node_exist_token(tt, tlist[tt][i].node, tlist[tt][i].last_tre->wid) != i) {
00830       j_printerr("token %d not found on node %d\n", i, tlist[tt][i].node);
00831     }
00832   }
00833 }
00834 #endif
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 #define SD(A) tindex[tn][A-1]   
00848 #define SCOPY(D,S) D = S        
00849 #define SVAL(A) (tlist[tn][tindex[tn][A-1]].score) 
00850 #define STVAL (tlist[tn][s].score) 
00851 
00852 
00874 static void
00875 sort_token_upward(int neednum, int totalnum)
00876 {
00877   int n,root,child,parent;
00878   TOKENID s;
00879   for (root = totalnum/2; root >= 1; root--) {
00880     SCOPY(s, SD(root));
00881     parent = root;
00882     while ((child = parent * 2) <= totalnum) {
00883       if (child < totalnum && SVAL(child) < SVAL(child+1)) {
00884         child++;
00885       }
00886       if (STVAL >= SVAL(child)) {
00887         break;
00888       }
00889       SCOPY(SD(parent), SD(child));
00890       parent = child;
00891     }
00892     SCOPY(SD(parent), s);
00893   }
00894   n = totalnum;
00895   while ( n > totalnum - neednum) {
00896     SCOPY(s, SD(n));
00897     SCOPY(SD(n), SD(1));
00898     n--;
00899     parent = 1;
00900     while ((child = parent * 2) <= n) {
00901       if (child < n && SVAL(child) < SVAL(child+1)) {
00902         child++;
00903       }
00904       if (STVAL >= SVAL(child)) {
00905         break;
00906       }
00907       SCOPY(SD(parent), SD(child));
00908       parent = child;
00909     }
00910     SCOPY(SD(parent), s);
00911   }
00912 }
00913 
00938 static void
00939 sort_token_downward(int neednum, int totalnum)
00940 {
00941   int n,root,child,parent;
00942   TOKENID s;
00943   for (root = totalnum/2; root >= 1; root--) {
00944     SCOPY(s, SD(root));
00945     parent = root;
00946     while ((child = parent * 2) <= totalnum) {
00947       if (child < totalnum && SVAL(child) > SVAL(child+1)) {
00948         child++;
00949       }
00950       if (STVAL <= SVAL(child)) {
00951         break;
00952       }
00953       SCOPY(SD(parent), SD(child));
00954       parent = child;
00955     }
00956     SCOPY(SD(parent), s);
00957   }
00958   n = totalnum;
00959   while ( n > totalnum - neednum) {
00960     SCOPY(s, SD(n));
00961     SCOPY(SD(n), SD(1));
00962     n--;
00963     parent = 1;
00964     while ((child = parent * 2) <= n) {
00965       if (child < n && SVAL(child) > SVAL(child+1)) {
00966         child++;
00967       }
00968       if (STVAL <= SVAL(child)) {
00969         break;
00970       }
00971       SCOPY(SD(parent), SD(child));
00972       parent = child;
00973     }
00974     SCOPY(SD(parent), s);
00975   }
00976 }
00977 
01008 static void
01009 sort_token_no_order(int neednum, int *start, int *end)
01010 {
01011   int totalnum = tnum[tn];
01012   int restnum;
01013 
01014   restnum = totalnum - neednum;
01015 
01016   if (neednum >= totalnum) {
01017     
01018     *start = 0;
01019     *end = totalnum - 1;
01020   } else if (neednum < restnum)  {
01021     
01022     sort_token_upward(neednum,totalnum);
01023     *start = totalnum - neednum;
01024     *end = totalnum - 1;
01025   } else {
01026     
01027     sort_token_downward(restnum,totalnum);
01028     *start = 0;
01029     *end = neednum - 1;
01030   }
01031 }
01032     
01033 
01034 #ifdef SP_BREAK_CURRENT_FRAME
01035 
01036 
01037 
01038 
01039 
01040 
01041 
01042 
01043 
01044 
01045 
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054 
01055 static boolean in_sparea;       
01056 static int sparea_start;        
01057 static int tmp_sparea_start;
01058 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01059 static WORD_ID tmp_sp_break_last_word;
01060 #else
01061 static WORD_ID last_tre_word;
01062 #endif
01063 static boolean first_sparea;    
01064 static int sp_duration;         
01065 
01092 boolean
01093 is_sil(WORD_ID w, WORD_INFO *winfo, HTK_HMM_INFO *hmm)
01094 {
01095   
01096   if (winfo->wlen[w] > 1) return FALSE;
01097 
01098   
01099   if (winfo->wseq[w][0] == hmm->sp) return TRUE;
01100 
01101   
01102   if (w == winfo->head_silwid || w == winfo->tail_silwid) return TRUE;
01103 
01104   
01105   return FALSE;
01106 }
01107 
01131 static boolean
01132 detect_end_of_segment(BACKTRELLIS *backtrellis, int time, WCHMM_INFO *wchmm)
01133 {
01134   TRELLIS_ATOM *tre;
01135   LOGPROB maxscore = LOG_ZERO;
01136   TRELLIS_ATOM *tremax = NULL;
01137   int count = 0;
01138   boolean detected = FALSE;
01139 
01140   
01141   for(tre = backtrellis->list; tre != NULL && tre->endtime == time; tre = tre->next) {
01142     if (maxscore < tre->backscore) {
01143       maxscore = tre->backscore;
01144       tremax = tre;
01145     }
01146     count++;
01147   }
01148   if (tremax == NULL) { 
01149     detected = TRUE;            
01150   } else if (count > 0) {       
01151     if (is_sil(tremax->wid, wchmm->winfo, wchmm->hmminfo)) {
01152       detected = TRUE;
01153     }
01154   }
01155   
01156   
01157   
01158   if (in_sparea && detected) {  
01159     sp_duration++;              
01160 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01161     
01162     
01163 
01164 
01165     if (tmp_sp_break_last_word == WORD_INVALID) {
01166       if (tremax != NULL) tmp_sp_break_last_word = tremax->wid;
01167     }
01168 #else
01169     
01170     
01171     if (tremax != NULL) last_tre_word = tremax->wid;
01172 #endif
01173   }
01174 
01175   
01176   
01177   else if (!in_sparea && detected) {
01178     
01179     
01180     tmp_sparea_start = time;
01181 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01182     
01183     
01184     tmp_sp_break_last_word = tremax ? tremax->wid : WORD_INVALID;
01185 #endif
01186     in_sparea = TRUE;           
01187     sp_duration = 1;            
01188 #ifdef SP_BREAK_DEBUG
01189     printf("sp start %d\n", time);
01190 #endif 
01191   }
01192   
01193   
01194   
01195   else if (in_sparea && !detected) {
01196     
01197     in_sparea = FALSE;          
01198 #ifdef SP_BREAK_DEBUG
01199     printf("sp end %d\n", time);
01200 #endif 
01201     
01202     
01203     if (sp_duration < sp_frame_duration) {
01204       
01205       
01206 #ifdef SP_BREAK_DEBUG
01207       printf("too short (%d<%d), ignored\n", sp_duration, sp_frame_duration);
01208 #endif 
01209     } else if (first_sparea) {
01210       
01211       
01212       first_sparea = FALSE;
01213 #ifdef SP_BREAK_DEBUG
01214       printf("first silence, ignored\n");
01215 #endif 
01216     } else {
01217       
01218       
01219 #ifdef SP_BREAK_DEBUG
01220       printf(">> segment [%d..%d]\n", sparea_start, time-1);
01221 #else
01222       if (idc_on) j_printerr("|");
01223 #endif 
01224       
01225       sparea_start = tmp_sparea_start;
01226 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01227       
01228       sp_break_last_word = tmp_sp_break_last_word;
01229 #else
01230       
01231       sp_break_last_word = last_tre_word;
01232 #endif
01233 
01234       
01235       return(TRUE);
01236     }
01237   }
01238     
01239 #ifdef SP_BREAK_EVAL
01240   printf("[%d %d %d]\n", time, count, (detected) ? 50 : 0);
01241 #endif
01242   return (FALSE);
01243 }
01244 
01245 #endif 
01246 
01247 
01248 
01249 
01250 
01251 
01252 
01253 
01272 static void
01273 init_nodescore(HTK_Param *param, WCHMM_INFO *wchmm)
01274 {
01275   TOKENID newid;
01276   TOKEN2 *new;
01277 #ifdef USE_NGRAM
01278   WORD_ID beginword;
01279 #endif
01280   int node;
01281 #ifdef USE_DFA
01282   int i;
01283 #endif
01284 
01285   
01286   
01287 #ifdef SP_BREAK_CURRENT_FRAME
01288   
01289   if (sp_break_last_nword == wchmm->winfo->tail_silwid) {
01290     
01291     bos.wid = WORD_INVALID;
01292   } else {
01293     bos.wid = sp_break_last_nword;
01294   }
01295 #else
01296   bos.wid = WORD_INVALID;       
01297 #endif
01298   bos.begintime = bos.endtime = -1;
01299 
01300   
01301   
01302   for(node=0;node<totalnodenum;node++) {
01303     token[node] = TOKENID_UNDEFINED;
01304   }
01305   tnum[0] = tnum[1]  = 0;
01306   
01307 #ifdef PASS1_IWCD
01308   
01309   
01310   outprob_style_cache_init(wchmm);
01311 #endif
01312 
01313   
01314   
01315 #ifdef USE_NGRAM
01316   
01317 #ifdef SP_BREAK_CURRENT_FRAME
01318   if (sp_break_last_word != WORD_INVALID) { 
01319     
01320     
01321     
01322     
01323     
01324     if (sp_break_last_word == wchmm->winfo->tail_silwid) {
01325       beginword = wchmm->winfo->head_silwid;
01326       bos.wid = WORD_INVALID;   
01327     } else {
01328       beginword = sp_break_last_word;
01329     }
01330   } else {
01331     
01332     beginword = wchmm->winfo->head_silwid;
01333   }
01334 #else
01335   
01336   beginword = wchmm->winfo->head_silwid;
01337 #endif
01338 #ifdef SP_BREAK_DEBUG
01339   printf("startword=[%s], last_nword=[%s]\n",
01340          (beginword == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[beginword],
01341          (bos.wid == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[bos.wid]);
01342 #endif
01343   
01344   newid = create_token();
01345   new = &(tlist[tn][newid]);
01346   
01347 #ifdef MULTIPATH_VERSION
01348   node = wchmm->wordbegin[beginword];
01349 #else
01350   node = wchmm->offset[beginword][0];
01351 #endif 
01352   
01353   if (wchmm->state[node].scid != 0) {
01354     
01355     new->last_lscore = max_successor_prob(wchmm, bos.wid, node);
01356   } else {
01357     
01358     new->last_lscore = 0.0;
01359   }
01360 #ifdef FIX_PENALTY
01361   new->last_lscore = new->last_lscore * lm_weight;
01362 #else
01363   new->last_lscore = new->last_lscore * lm_weight + lm_penalty;
01364 #endif
01365   
01366   new->last_tre = &bos;
01367   new->last_cword = bos.wid;
01368 #ifdef MULTIPATH_VERSION
01369   
01370   new->score = new->last_lscore;
01371 #else
01372   
01373   new->score = outprob_style(wchmm, node, bos.wid, 0, param) + new->last_lscore;
01374 #endif 
01375   
01376   node_assign_token(node, newid);
01377   
01378 #else  
01379   
01380   
01381   
01382   
01383   
01384   {
01385     MULTIGRAM *m;
01386     int t,tb,te;
01387     WORD_ID iw;
01388     boolean flag;
01389 
01390     flag = FALSE;
01391     
01392     for(m = gramlist; m; m = m->next) {
01393       if (m->active) {
01394         tb = m->cate_begin;
01395         te = tb + m->dfa->term_num;
01396         for(t=tb;t<te;t++) {
01397           
01398           if (dfa_cp_begin(dfa, t) == TRUE) {
01399             
01400             flag = TRUE;
01401             for (iw=0;iw<dfa->term.wnum[t];iw++) {
01402               
01403               i = dfa->term.tw[t][iw];
01404 #ifdef MULTIPATH_VERSION
01405               node = wchmm->wordbegin[i];
01406 #else
01407               node = wchmm->offset[i][0];
01408 #endif 
01409               
01410               if (node_exist_token(tn, node, bos.wid) != TOKENID_UNDEFINED) continue;
01411               newid = create_token();
01412               new = &(tlist[tn][newid]);
01413               new->last_tre = &bos;
01414 #ifdef MULTIPATH_VERSION
01415               new->score = 0.0;
01416 #else
01417               new->score = outprob_style(wchmm, node, bos.wid, 0, param);
01418 #endif 
01419               node_assign_token(node, newid);
01420             }
01421           }
01422         }
01423       }
01424     }
01425     if (!flag) {
01426       j_printerr("Error: no initial state found in active DFA grammar!\n");
01427     }
01428   }
01429 
01430 
01431 
01432 
01433 
01434 
01435 
01436 
01437 
01438 
01439 
01440 
01441 
01442   
01443 #endif 
01444 }
01445 
01446 
01447 
01448 
01449 
01450 
01476 void
01477 get_back_trellis_init(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
01478 {
01479   
01480   
01481   
01482   
01483   
01484   tn = 0;
01485   tl = 1;
01486 
01487   
01488   
01489   bt_prepare(backtrellis);
01490 
01491   
01492   
01493   
01494 
01495 
01496   
01497 
01498 
01499   
01500   malloc_nodes(wchmm->n, trellis_beam_width * 2 + wchmm->startnum, trellis_beam_width);
01501   
01502   
01503   
01504   init_nodescore(param, wchmm);
01505   sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01506 
01507   
01508   
01509   result_pass1_begin();
01510   
01511   
01512   progout_interval_frame = (int)((float)progout_interval / ((float)param->header.wshift / 10000.0));
01513 
01514   
01515   
01516   if (!realtime_flag && verbose_flag && (!progout_flag) && isatty(1)) {
01517     idc_on = TRUE;
01518   } else { 
01519     idc_on = FALSE;
01520   }
01521   
01522 #ifdef SP_BREAK_CURRENT_FRAME
01523   
01524   
01525   in_sparea = TRUE;             
01526   sparea_start = tmp_sparea_start = 0; 
01527 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01528   tmp_sp_break_last_word = WORD_INVALID;
01529 #endif
01530   sp_break_last_word = WORD_INVALID;
01531   
01532   
01533 
01534   first_sparea = TRUE;
01535   sp_break_2_begin_word = WORD_INVALID;
01536 #endif
01537 
01538   if (gmm != NULL) {
01539     
01540     gmm_prepare(gmm);
01541   }
01542 }
01543 
01544 
01545 static TRELLIS_ATOM *tre; 
01546 static int node; 
01547 static int stid; 
01548 static A_CELL *ac; 
01549 static int next_node2;          
01550 #ifdef USE_NGRAM
01551 static LOGPROB tmpprob; 
01552 static LOGPROB *iwparray; 
01553 #endif
01554 #ifdef UNIGRAM_FACTORING
01555 
01556 static LOGPROB wordend_best_score; 
01557 static int wordend_best_node;   
01558 static TRELLIS_ATOM *wordend_best_tre; 
01559 static WORD_ID wordend_best_last_cword; 
01560 static int isoid; 
01561 #endif
01562 
01563 
01564 
01565 
01566 
01567 
01607 boolean
01608 get_back_trellis_proceed(int t, HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis
01609 #ifdef MULTIPATH_VERSION
01610                          , boolean final 
01611 #endif
01612                          )
01613 {
01614   LOGPROB tmpsum;
01615   int j, next_node, sword;
01616   TOKEN2  *tk, *tknext;
01617   TOKENID  tknextid;
01618 #ifdef USE_NGRAM
01619   LOGPROB ngram_score_cache;
01620 #endif
01621 
01622   
01623   
01624   
01625   
01626 
01627   
01628   
01629   
01630   
01631   tl = tn;
01632   if (tn == 0) tn = 1; else tn = 0;
01633 
01634   
01635   
01636   if (idc_on) {
01637 #ifdef SP_BREAK_CURRENT_FRAME
01638     if (in_sparea) j_printerr("."); else j_printerr("-");
01639 #else  
01640     j_printerr(".");
01641 #endif 
01642   }
01643 
01644 #ifdef UNIGRAM_FACTORING
01645   
01646 
01647 
01648 
01649 
01650 
01651   
01652 
01653 
01654 
01655 
01656 
01657 
01658 
01659 
01660 
01661   
01662   wordend_best_score = LOG_ZERO;
01663 #endif
01664 
01665 #ifdef DEBUG
01666   
01667   
01668 #endif
01669 
01670   
01671   
01672   clear_tokens(tl);
01673 
01674   
01675   
01676   
01677   
01678   
01679   
01680   
01681   
01682   for (j=n_start;j<=n_end;j++) {
01683 
01684     
01685     
01686     tk = &(tlist[tl][tindex[tl][j]]);
01687     node = tk->node;
01688     if (tk->score <= LOG_ZERO) continue; 
01689 
01690     
01691     
01692     
01693     
01694     for (ac = wchmm->state[node].ac; ac; ac = ac->next) {
01695       next_node = ac->arc;
01696       
01697 
01698       
01699 
01700       
01701       
01702       
01703       
01704       tmpsum = tk->score + ac->a;
01705 #ifdef USE_NGRAM
01706       ngram_score_cache = LOG_ZERO;
01707 #endif
01708       
01709 
01710 
01711 #ifndef CATEGORY_TREE
01712       
01713 
01714 
01715       
01716 
01717 
01718 
01719       if (next_node != node) {
01720         if (wchmm->state[next_node].scid != 0
01721 #ifdef UNIGRAM_FACTORING
01722             
01723 
01724 
01725 
01726 
01727 
01728             
01729 
01730 
01731 
01732 
01733 
01734 
01735 
01736 #endif
01737             ){
01738 #ifdef USE_NGRAM
01739           
01740           
01741           
01742           
01743 #ifdef FIX_PENALTY
01744           
01745           if (tk->last_cword == WORD_INVALID) {
01746             ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight;
01747           } else {
01748             ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01749           }
01750 #else
01751           ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01752 #endif
01753           
01754 
01755 
01756           
01757 
01758 
01759           tmpsum -= tk->last_lscore;
01760           tmpsum += ngram_score_cache;
01761           
01762 #else  
01763           
01764 
01765 
01766 
01767           
01768 
01769 
01770 
01771 
01772 
01773 
01774 
01775 
01776 
01777           
01778           
01779 
01780           
01781 
01782 
01783 
01784 
01785           if (!can_succeed(wchmm, tk->last_tre->wid, next_node)) {
01786             tmpsum = LOG_ZERO;
01787           }
01788           
01789 #endif 
01790         }
01791       }
01792 #endif 
01793       
01794 
01795       
01796       
01797       
01798       
01799 
01800       if ((tknextid = node_exist_token(tn, next_node, tk->last_tre->wid)) != TOKENID_UNDEFINED) {
01801         
01802         
01803         tknext = &(tlist[tn][tknextid]);
01804         if (tknext->score < tmpsum) {
01805           
01806           
01807           tknext->last_tre = tk->last_tre; 
01808 #ifdef USE_NGRAM
01809           tknext->last_cword = tk->last_cword; 
01810           tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore; 
01811 #endif 
01812           tknext->score = tmpsum; 
01813         }
01814       } else {
01815         
01816         
01817         if (tmpsum > LOG_ZERO) { 
01818           tknextid = create_token(); 
01819           tknext = &(tlist[tn][tknextid]);
01820           
01821 
01822 
01823           tk = &(tlist[tl][tindex[tl][j]]);
01824           tknext->last_tre = tk->last_tre; 
01825 #ifdef USE_NGRAM
01826           tknext->last_cword = tk->last_cword; 
01827           tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore; 
01828 #endif 
01829           tknext->score = tmpsum; 
01830           node_assign_token(next_node, tknextid); 
01831         }
01832       }
01833     } 
01834 
01835 #ifdef MULTIPATH_VERSION
01836     
01837   }
01838   
01839   
01840   
01841   
01842   
01843   
01844   sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01845   
01846   
01847   
01848   
01849   
01850   
01851   for(j=n_start; j<=n_end; j++) {
01852     tk = &(tlist[tn][tindex[tn][j]]);
01853     node = tk->node;
01854      
01855 #endif 
01856 
01857     
01858     
01859     if (wchmm->stend[node] != WORD_INVALID) {
01860 
01861       sword = wchmm->stend[node];
01862 
01863       
01864       
01865       
01866       
01867 
01868       
01869 
01870 
01871 
01872       
01873 
01874 
01875 
01876       tre = (TRELLIS_ATOM *)mybmalloc2(sizeof(TRELLIS_ATOM), &(backtrellis->root));
01877       tre->wid = sword;         
01878       tre->backscore = tk->score; 
01879       tre->begintime = tk->last_tre->endtime + 1; 
01880       tre->endtime   = t-1;     
01881       tre->last_tre  = tk->last_tre; 
01882 #ifdef USE_NGRAM
01883       tre->lscore    = tk->last_lscore; 
01884 #endif
01885       bt_store(backtrellis, tre); 
01886 #ifdef WORD_GRAPH
01887       if (tre->last_tre != NULL) {
01888         
01889         tre->last_tre->within_context = TRUE;
01890       }
01891 #ifdef MULTIPATH_VERSION
01892       if (final) {
01893         
01894         if (tre->wid == winfo->tail_silwid) {
01895           tre->within_context = TRUE;
01896         }
01897       }
01898 #endif
01899 #endif 
01900       
01901       
01902       
01903       
01904       
01905 
01906 #ifdef MULTIPATH_VERSION
01907       
01908       
01909       if (final) continue;
01910 #endif
01911 
01912       
01913 
01914       
01915 
01916 
01917 #ifdef UNIGRAM_FACTORING
01918       
01919 
01920       
01921 
01922 
01923 #endif
01924 
01925 #ifdef USE_NGRAM
01926       
01927       
01928       if (sword == wchmm->winfo->tail_silwid) continue;
01929 
01930 #ifdef UNIGRAM_FACTORING
01931       
01932       
01933       
01934 
01935 
01936       if (wordend_best_score < tk->score
01937 #ifndef MULTIPATH_VERSION
01938           + wchmm->wordend_a[sword]
01939 #endif
01940           ) {
01941         wordend_best_score = tk->score
01942 #ifndef MULTIPATH_VERSION
01943           + wchmm->wordend_a[sword]
01944 #endif
01945           ;
01946         wordend_best_node = node;
01947         wordend_best_tre = tre;
01948         wordend_best_last_cword = tk->last_cword;
01949       }
01950 #endif
01951       
01952       
01953 
01954 
01955       
01956 
01957 
01958       if (wchmm->winfo->is_transparent[sword]) {
01959         iwparray = max_successor_prob_iw(wchmm, tk->last_cword);
01960       } else {
01961         iwparray = max_successor_prob_iw(wchmm, sword);
01962       }
01963 #endif
01964 
01965       
01966       
01967       
01968       
01969       for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
01970         next_node = wchmm->startnode[stid];
01971 #ifdef MULTIPATH_VERSION
01972 #ifdef USE_NGRAM
01973         
01974         if (wchmm->wordbegin[wchmm->winfo->head_silwid] == next_node) continue;
01975 #endif
01976 #endif
01977 
01978         
01979         
01980         
01981         
01982         
01983 #ifdef USE_NGRAM
01984         
01985         
01986 #ifdef UNIGRAM_FACTORING
01987         
01988 
01989 
01990 
01991 
01992 
01993         
01994 
01995 
01996 
01997 
01998 
01999 
02000 
02001         
02002 
02003         
02004 
02005 
02006 
02007 
02008         isoid = wchmm->start2isolate[stid];
02009         
02010 
02011         
02012 
02013         if (isoid == -1) continue;
02014         tmpprob = iwparray[isoid];
02015 #else
02016         tmpprob = iwparray[stid];
02017 #endif
02018 #endif
02019 
02020 #ifdef USE_NGRAM
02021         
02022 
02023 
02024         
02025 
02026 
02027 
02028 
02029 #endif
02030         
02031 #ifdef CATEGORY_TREE
02032         
02033         
02034 
02035 
02036 
02037         if (dfa_cp(dfa, wchmm->winfo->wton[sword],
02038 #ifdef MULTIPATH_VERSION
02039                    wchmm->winfo->wton[wchmm->start2wid[stid]]
02040 #else
02041                    wchmm->winfo->wton[wchmm->ststart[next_node]]
02042 #endif 
02043                    ) == FALSE) continue;
02044 #endif
02045 
02046         
02047         
02048         
02049         
02050         tmpsum = tk->score
02051 #ifndef MULTIPATH_VERSION
02052           + wchmm->wordend_a[sword]
02053 #endif
02054           ;
02055         
02056 #ifdef USE_NGRAM
02057         
02058         
02059         ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02060         tmpsum += ngram_score_cache;
02061         if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[tk->last_cword]) {
02062           
02063           tmpsum += lm_penalty_trans;
02064         }
02065 #else  
02066         
02067         
02068         tmpsum += penalty1;
02069 
02070         
02071 #ifdef CATEGORY_TREE
02072         
02073 #else
02074         if (!can_succeed(wchmm, sword, next_node)) {
02075           tmpsum = LOG_ZERO;
02076         }
02077 #endif 
02078 #endif 
02079 
02080 
02081         
02082         
02083         
02084         
02085 
02086 #ifndef MULTIPATH_VERSION
02087         next_node2 = next_node;
02088 #else
02089         for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02090           next_node2 = ac->arc;
02091 #endif
02092           
02093           if ((tknextid = node_exist_token(tn, next_node2, tre->wid)) != TOKENID_UNDEFINED) {
02094             
02095             
02096             tknext = &(tlist[tn][tknextid]);
02097             if (tknext->score < tmpsum) {
02098               
02099               
02100 #ifdef USE_NGRAM
02101               tknext->last_lscore = ngram_score_cache; 
02102               
02103               if (wchmm->winfo->is_transparent[sword]) {
02104                 
02105 
02106 
02107                 tknext->last_cword = tk->last_cword;
02108               } else {
02109                 
02110                 tknext->last_cword = sword;
02111               }
02112 #endif
02113               
02114               tknext->score = tmpsum;
02115 #ifdef MULTIPATH_VERSION
02116               tknext->score += ac->a;
02117 #endif
02118               
02119 
02120               
02121 
02122               tknext->last_tre = tre;
02123             }
02124           } else {
02125             
02126             
02127             if (tmpsum > LOG_ZERO) { 
02128               tknextid = create_token();
02129               tknext = &(tlist[tn][tknextid]);
02130               
02131 
02132 
02133 #ifdef MULTIPATH_VERSION
02134               tk = &(tlist[tn][tindex[tn][j]]);
02135 #else
02136               tk = &(tlist[tl][tindex[tl][j]]);
02137 #endif
02138 #ifdef USE_NGRAM
02139               tknext->last_lscore = ngram_score_cache; 
02140               
02141               if (wchmm->winfo->is_transparent[sword]) {
02142                 
02143 
02144 
02145                 tknext->last_cword = tk->last_cword;
02146               } else {
02147                 
02148                 tknext->last_cword = sword;
02149               }
02150 #endif
02151               tknext->score = tmpsum;
02152 #ifdef MULTIPATH_VERSION
02153               tknext->score += ac->a;
02154 #endif
02155             
02156 
02157             
02158 
02159               tknext->last_tre = tre;
02160               
02161               node_assign_token(next_node2, tknextid);
02162             }
02163           }
02164 #ifdef MULTIPATH_VERSION
02165         }
02166 #endif
02167         
02168       } 
02169     } 
02170     
02171   } 
02172 #ifdef UNIGRAM_FACTORING
02173   
02174   
02175   
02176   
02177   
02178   if (wordend_best_score > LOG_ZERO) {
02179     node = wordend_best_node;
02180     sword = wchmm->stend[node];
02181     for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
02182       next_node = wchmm->startnode[stid];
02183       
02184       
02185       if (wchmm->start2isolate[stid] != -1) continue;
02186       
02187       if (wchmm->state[next_node].scid >= 0) {
02188         j_error("InternalError: scid mismatch at 1-gram factoring of shared states\n");
02189       }
02190       tmpprob = wchmm->fscore[- wchmm->state[next_node].scid];
02191       ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02192       tmpsum = wordend_best_score;
02193       tmpsum += ngram_score_cache;
02194       if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[wordend_best_last_cword]) {
02195         tmpsum += lm_penalty_trans;
02196       }
02197       
02198 #ifndef MULTIPATH_VERSION
02199       next_node2 = next_node;
02200 #else
02201       for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02202         next_node2 = ac->arc;
02203 #endif
02204         if ((tknextid = node_exist_token(tn, next_node2, sword)) != TOKENID_UNDEFINED) {
02205           tknext = &(tlist[tn][tknextid]);
02206           if (tknext->score < tmpsum) {
02207             tknext->last_lscore = ngram_score_cache;
02208             if (wchmm->winfo->is_transparent[sword]) {
02209               tknext->last_cword = wordend_best_last_cword;
02210             } else {
02211               tknext->last_cword = sword;
02212             }
02213             tknext->score = tmpsum;
02214 #ifdef MULTIPATH_VERSION
02215             tknext->score += ac->a;
02216 #endif
02217             tknext->last_tre = wordend_best_tre;
02218           }
02219         } else {
02220           if (tmpsum > LOG_ZERO) { 
02221             tknextid = create_token();
02222             tknext = &(tlist[tn][tknextid]);
02223             tknext->last_lscore = ngram_score_cache;
02224             if (wchmm->winfo->is_transparent[sword]) {
02225               tknext->last_cword = wordend_best_last_cword;
02226             } else {
02227               tknext->last_cword = sword;
02228             }
02229             tknext->score = tmpsum;
02230 #ifdef MULTIPATH_VERSION
02231             tknext->score += ac->a;
02232 #endif
02233             tknext->last_tre = wordend_best_tre;
02234             node_assign_token(next_node2, tknextid);
02235           }
02236         }
02237 #ifdef MULTIPATH_VERSION
02238       }
02239 #endif
02240       
02241     }
02242   }
02243 #endif 
02244 
02245   
02246   
02247   
02248   
02249 
02250   
02251   
02252 #ifdef MULTIPATH_VERSION
02253   
02254   
02255   if (! final) {
02256 #endif
02257     for (j=0;j<tnum[tn];j++) {
02258       tk = &(tlist[tn][tindex[tn][j]]);
02259 #ifdef MULTIPATH_VERSION
02260       
02261       if (wchmm->state[tk->node].out.state == NULL) continue;
02262 #endif
02263       tk->score += outprob_style(wchmm, tk->node, tk->last_tre->wid, t, param);
02264     }
02265 #ifdef MULTIPATH_VERSION
02266   }
02267 #endif
02268 
02269   if (gmm != NULL) {
02270     
02271     gmm_proceed(gmm, param, t);
02272   }
02273 
02274   
02275   
02276   
02277   
02278 
02279   
02280   clear_tlist(tl);
02281 
02282   
02283   
02284   sort_token_no_order(trellis_beam_width, &n_start, &n_end);
02285 
02286   
02287 
02288 
02289 
02290   
02291 
02292 
02293 
02294 
02295 
02296 
02297 
02298   
02299   
02300   
02301   
02302   
02303   if (progout_flag) {
02304     
02305     
02306     if ((t % progout_interval_frame) == 0) {
02307       bt_current_max(backtrellis, t-1, wchmm->winfo);
02308     }
02309   }
02310   
02311   
02312   if (debug2_flag) {
02313     bt_current_max_word(backtrellis, t-1, wchmm->winfo);
02314   }
02315 
02316 #ifdef SP_BREAK_CURRENT_FRAME
02317   
02318   if (detect_end_of_segment(backtrellis, t-1, wchmm)) {
02319     
02320     return FALSE;               
02321   }
02322 #endif
02323 
02324   
02325   if (tnum[tn] == 0) {
02326     j_printerr("Error: %dth frame: no nodes left in beam! model mismatch or wrong input?\n", t);
02327     return(FALSE);
02328   }
02329 
02330   return(TRUE);
02331     
02332 }
02333 
02334 
02335 
02336 
02337 
02338 
02362 void
02363 get_back_trellis_end(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
02364 {
02365   int t, node, j;
02366   TOKEN2 *tk;
02367 
02368   
02369   
02370 
02371 #ifdef MULTIPATH_VERSION
02372   
02373   
02374   
02375   get_back_trellis_proceed(param->samplenum, param, wchmm, backtrellis, TRUE);
02376   
02377 #else  
02378   
02379   t = param->samplenum;
02380   tl = tn;
02381   if (tn == 0) tn = 1; else tn = 0;
02382   for (j=n_start; j<=n_end; j++) {
02383     tk = &(tlist[tl][tindex[tl][j]]);
02384     node = tk->node;
02385     if (wchmm->stend[node] != WORD_INVALID) {
02386       tre = (TRELLIS_ATOM *)mybmalloc2(sizeof(TRELLIS_ATOM), &(backtrellis->root));
02387       tre->wid = wchmm->stend[node];
02388       tre->backscore = tk->score;
02389       tre->begintime = tk->last_tre->endtime + 1;
02390       tre->endtime   = t-1;
02391       tre->last_tre  = tk->last_tre;
02392 #ifdef USE_NGRAM
02393       tre->lscore    = tk->last_lscore;
02394 #endif
02395       bt_store(backtrellis, tre);
02396 #ifdef WORD_GRAPH
02397       if (tre->last_tre != NULL) {
02398         
02399         tre->last_tre->within_context = TRUE;
02400       }
02401       
02402       if (tre->wid == winfo->tail_silwid) {
02403         tre->within_context = TRUE;
02404       }
02405 #endif
02406     }
02407   }
02408 
02409 #endif 
02410 
02411 #ifdef SP_BREAK_CURRENT_FRAME
02412   
02413 
02414 
02415 #endif
02416 }
02417 
02418 
02419 
02420 
02421 
02454 LOGPROB
02455 finalize_1st_pass(BACKTRELLIS *backtrellis, WORD_INFO *winfo, int len)
02456 {
02457   LOGPROB lastscore;
02458   int mseclen;
02459   boolean ok_p;
02460  
02461   backtrellis->framelen = len;
02462 
02463   
02464   
02465   
02466   
02467   ok_p = TRUE;
02468   if (rejectshortlen > 0) {
02469     mseclen = (float)len * (float)para.smp_period * (float)para.frameshift / 10000.0;
02470     if (mseclen < rejectshortlen) {
02471       ok_p = FALSE;
02472     }
02473   }
02474   
02475   
02476   
02477   if (ok_p) {
02478     bt_relocate_rw(backtrellis);
02479     bt_sort_rw(backtrellis);
02480     if (backtrellis->num == NULL) {
02481       if (backtrellis->framelen > 0) j_printerr("no survived word!\n");
02482       ok_p = FALSE;
02483     }
02484   }
02485 
02486   
02487   
02488   if (verbose_flag && (!progout_flag)) j_printerr("\n");
02489   if (ok_p) {
02490     lastscore = print_1pass_result(backtrellis, len, winfo);
02491   } else {
02492     lastscore = LOG_ZERO;
02493   }
02494 
02495 #ifdef USE_NGRAM
02496   
02497   
02498   
02499   
02500 #endif
02501   
02502   free_nodes();
02503   
02504   if (ok_p) {
02505     if (gmm != NULL) {
02506       
02507       gmm_end(gmm);
02508     }
02509   }
02510 
02511   
02512   return(lastscore);
02513 }
02514 
02515 #ifdef SP_BREAK_CURRENT_FRAME
02516 
02517 
02518 
02519 
02549 void
02550 finalize_segment(BACKTRELLIS *backtrellis, HTK_Param *param, int len)
02551 {
02552   int t;
02553 
02554   
02555   
02556 
02557   set_terminal_words(backtrellis);
02558 
02559   
02560 
02561 
02562   
02563 
02564 
02565 
02566   
02567 
02568 
02569 
02570 
02571   if (len != param->samplenum) {
02572 
02573     VERMES("segmented: processed length=%d\n", len);
02574     VERMES("segmented: next decoding will restart from %d\n", sparea_start);
02575     
02576     
02577     rest_param = new_param();
02578     memcpy(&(rest_param->header), &(param->header), sizeof(HTK_Param_Header));
02579     rest_param->samplenum = param->samplenum - sparea_start;
02580     rest_param->header.samplenum = rest_param->samplenum;
02581     rest_param->veclen = param->veclen;
02582     rest_param->parvec = (VECT **)mymalloc(sizeof(VECT *) * rest_param->samplenum);
02583     
02584     for(t=sparea_start;t<len;t++) {
02585       rest_param->parvec[t-sparea_start] = (VECT *)mymalloc(sizeof(VECT) * rest_param->veclen);
02586       memcpy(rest_param->parvec[t-sparea_start], param->parvec[t], sizeof(VECT) * rest_param->veclen);
02587     }
02588     
02589     for(t=len;t<param->samplenum;t++) {
02590       rest_param->parvec[t-sparea_start] = param->parvec[t];
02591     }
02592 
02593     
02594     
02595     param->samplenum = len;
02596     param->parvec = (VECT **)myrealloc(param->parvec, sizeof(VECT *) * param->samplenum);
02597     sp_break_last_nword_allow_override = TRUE;
02598     
02599   } else {
02600     
02601     
02602     rest_param = NULL;
02603     
02604     sp_break_last_word = WORD_INVALID;
02605     sp_break_last_nword = WORD_INVALID;
02606     sp_break_last_nword_allow_override = FALSE;
02607   }
02608 }
02609 #endif 
02610   
02611 
02612 
02613 
02614 
02615 
02616 
02617 
02655 void
02656 get_back_trellis(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis,
02657 LOGPROB *backmax)
02658 {
02659   int t;
02660 
02661   
02662   
02663   get_back_trellis_init(param, wchmm, backtrellis);
02664 
02665   
02666   
02667   for (
02668 #ifdef MULTIPATH_VERSION
02669        
02670        t = 0
02671 #else
02672        
02673        t = 1
02674 #endif
02675          ; t < param->samplenum; t++) {
02676     if (get_back_trellis_proceed(t, param, wchmm, backtrellis
02677 #ifdef MULTIPATH_VERSION
02678                                  ,FALSE
02679 #endif
02680                                  ) == FALSE
02681         || (module_mode && module_wants_terminate())) {
02682       
02683       
02684       
02685       
02686       *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, t-1);
02687 #ifdef SP_BREAK_CURRENT_FRAME
02688       
02689 
02690       
02691       finalize_segment(backtrellis, param, t-1);
02692 #endif
02693       
02694       return;
02695     }
02696   }
02697   
02698   
02699   get_back_trellis_end(param, wchmm, backtrellis);
02700   
02701   
02702   *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, param->samplenum);
02703 #ifdef SP_BREAK_CURRENT_FRAME
02704   
02705 
02706   
02707   finalize_segment(backtrellis, param, param->samplenum);
02708 #endif
02709 }
02710 
02711