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 
00109 static void
00110 generate_lattice(int endtime, WORD_ID wid, BACKTRELLIS *bt, WORD_INFO *winfo)
00111 {
00112   TRELLIS_ATOM *ta, *ta_last;
00113   int i,j;
00114   boolean new_node = FALSE;
00115 
00116   glevel++;
00117 
00118   if (endtime >= 0) {
00119     for (i=0;i<bt->num[endtime];i++) {
00120       ta = bt->rw[endtime][i];
00121       if (ta->wid == wid) {
00122         if (ta->within_wordgraph) {
00123           
00124         } else {
00125           
00126           ta->within_wordgraph = TRUE;
00127           garcs++;
00128           new_node = TRUE;      
00129           ta_last = ta->last_tre;
00130           if (debug2_flag) {
00131             for(j=0;j<glevel;j++) j_printf(" ");
00132             j_printf("%s: %d->", winfo->wname[ta->wid], ta->endtime);
00133             if (ta_last->wid == WORD_INVALID) {
00134               j_printf("%d(WORD_INVALID)\n", ta_last->endtime);
00135             } else {
00136               j_printf("%d(%s)\n", ta_last->endtime, winfo->wname[ta_last->wid]);
00137             }
00138           }
00139           
00140           generate_lattice(ta_last->endtime, ta_last->wid, bt, winfo);
00141         }
00142       }
00143     }
00144   }
00145   if (new_node) {
00146     gnodes++;
00147   }
00148   glevel--;
00149 }
00150 #endif
00151 
00166 static void
00167 put_atom(TRELLIS_ATOM *atom, WORD_INFO *winfo)
00168 {
00169   int i;
00170   j_printf("%3d,%3d %f %16s (id=%5d)", atom->begintime, atom->endtime,
00171          atom->backscore, winfo->wname[atom->wid], atom->wid);
00172   for (i=0;i<winfo->wlen[atom->wid]; i++) {
00173     j_printf(" %s",winfo->wseq[atom->wid][i]->name);
00174   }
00175   j_printf("\n");
00176 }
00177 
00210 static LOGPROB
00211 trace_backptr(WORD_ID wordseq_rt[MAXSEQNUM], int *rt_wordlen, TRELLIS_ATOM *atom, BACKTRELLIS *backtrellis, WORD_INFO *winfo)
00212 {
00213   int wordlen = 0;              
00214   TRELLIS_ATOM *tretmp;
00215   LOGPROB langscore = 0.0;
00216   static WORD_ID wordseq[MAXSEQNUM];    
00217   int i;
00218   
00219   
00220   wordseq[0] = atom->wid;       
00221   wordlen = 1;
00222   tretmp = atom;
00223 #ifdef USE_NGRAM
00224   langscore += tretmp->lscore;
00225 #endif
00226   if (debug2_flag) {
00227     put_atom(tretmp, winfo);
00228   }
00229   
00230   
00231   while (tretmp->begintime > 0) {
00232     tretmp = tretmp->last_tre;
00233 
00234 
00235     if (tretmp == NULL) {       
00236       j_error("ERROR: BackTrellis Pass missing??\n");
00237     }
00238 #ifdef USE_NGRAM
00239     langscore += tretmp->lscore;
00240 #endif
00241     wordseq[wordlen] = tretmp->wid;
00242     wordlen++;
00243     if (debug2_flag) {
00244       put_atom(tretmp, winfo);
00245     }
00246     if (wordlen >= MAXSEQNUM) {
00247       j_error("sentence length exceeded ( > %d)\n",MAXSEQNUM);
00248     }
00249   }
00250   *rt_wordlen = wordlen;
00251   
00252   for(i=0;i<wordlen;i++) wordseq_rt[i] = wordseq[wordlen-i-1];
00253   return(langscore);
00254 }
00255 
00305 static LOGPROB
00306 print_1pass_result(BACKTRELLIS *backtrellis, int framelen, WORD_INFO *winfo)
00307 {
00308   WORD_ID wordseq[MAXSEQNUM];
00309   int wordlen;
00310   int i;
00311   TRELLIS_ATOM *best;
00312   int last_time;
00313   LOGPROB total_lscore;
00314 #if defined(USE_DFA) || defined(SP_BREAK_CURRENT_FRAME)
00315   LOGPROB maxscore;
00316   TRELLIS_ATOM *tmp;
00317 #endif
00318 
00319   
00320   for (last_time = framelen - 1; last_time >= 0; last_time--) {
00321 #ifdef USE_NGRAM
00322 #ifdef SP_BREAK_CURRENT_FRAME   
00323     
00324     
00325     maxscore = LOG_ZERO;
00326     for (i=0;i<backtrellis->num[last_time];i++) {
00327       tmp = backtrellis->rw[last_time][i];
00328       if (maxscore < tmp->backscore) {
00329         maxscore = tmp->backscore;
00330         best = tmp;
00331       }
00332     }
00333     if (maxscore != LOG_ZERO) break;
00334 #else  
00335     
00336     
00337     best = bt_binsearch_atom(backtrellis, last_time, winfo->tail_silwid);
00338     if (best != NULL) break;
00339 #endif
00340 #else  
00341     
00342     
00343     maxscore = LOG_ZERO;
00344     for (i=0;i<backtrellis->num[last_time];i++) {
00345       tmp = backtrellis->rw[last_time][i];
00346       
00347         if (maxscore < tmp->backscore) {
00348           maxscore = tmp->backscore;
00349           best = tmp;
00350         }
00351         
00352     }
00353     if (maxscore != LOG_ZERO) break;
00354 #endif 
00355   }
00356   if (last_time < 0) {          
00357     j_printerr("[no sentence-end word survived on last beam]\n");
00358     
00359     result_pass1_final(NULL, 0, LOG_ZERO, LOG_ZERO, winfo);
00360     return(LOG_ZERO);
00361   }
00362   
00363   
00364   total_lscore = trace_backptr(wordseq, &wordlen, best, backtrellis, winfo);
00365 
00366   if (progout_flag) {           
00367     result_pass1_current(last_time, wordseq, wordlen, best->backscore, total_lscore, winfo);
00368   }
00369 
00370       
00371   if (verbose_flag || !progout_flag) {
00372     result_pass1_final(wordseq, wordlen, best->backscore, total_lscore, winfo);
00373   }
00374   result_pass1_end();
00375   
00376   
00377   for(i=0;i<wordlen;i++) pass1_wseq[i] = wordseq[i];
00378   pass1_wnum = wordlen;
00379   pass1_score = best->backscore;
00380 
00381 #ifdef WORD_GRAPH
00382   
00383   
00384   
00385   
00386 
00387   glevel = 0;
00388   gnodes = 1;                   
00389   garcs = 0;
00390   generate_lattice(last_time, winfo->tail_silwid, backtrellis, winfo);
00391   if (verbose_flag) j_printf("word graph generated (nodes=%d,arcs=%d)\n",gnodes, garcs);
00392 #endif
00393 
00394   
00395   return(best->backscore);
00396 }
00397 
00415 static void
00416 bt_current_max(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00417 {
00418   static WORD_ID wordseq[MAXSEQNUM];
00419   int wordlen;
00420   TRELLIS_ATOM *tre;
00421   TRELLIS_ATOM *tremax;
00422   LOGPROB maxscore;
00423   LOGPROB lscore;
00424 
00425   
00426   maxscore = LOG_ZERO;
00427   tremax = NULL;
00428   tre = bt->list;
00429   while (tre != NULL && tre->endtime == t) {
00430     if (maxscore < tre->backscore) {
00431       maxscore = tre->backscore;
00432       tremax = tre;
00433     }
00434     tre = tre->next;
00435   }
00436 
00437   if (maxscore != LOG_ZERO) {
00438     lscore = trace_backptr(wordseq, &wordlen, tremax, bt, winfo);
00439     result_pass1_current(t, wordseq, wordlen, tremax->backscore, lscore, winfo);
00440   } else {
00441     wordlen = 0;
00442     result_pass1_current(t, wordseq, wordlen, LOG_ZERO, LOG_ZERO, winfo);
00443   }
00444 }
00445 
00463 static void
00464 bt_current_max_word(BACKTRELLIS *bt, int t, WORD_INFO *winfo)
00465 {
00466   TRELLIS_ATOM *tre;
00467   TRELLIS_ATOM *tremax;
00468   LOGPROB maxscore;
00469   WORD_ID w;
00470 
00471   
00472   
00473   maxscore = LOG_ZERO;
00474   tremax = NULL;
00475   tre = bt->list;
00476   while (tre != NULL && tre->endtime == t) {
00477     if (maxscore < tre->backscore) {
00478       maxscore = tre->backscore;
00479       tremax = tre;
00480     }
00481     tre = tre->next;
00482   }
00483 
00484   if (maxscore != LOG_ZERO) {
00485     j_printf("%3d: ",t);
00486     w = tremax->wid;
00487     j_printf("\"%s [%s]\"(id=%d)",
00488            winfo->wname[w], winfo->woutput[w], w);
00489     j_printf(" [%d-%d] %f <- ", tremax->begintime, t, tremax->backscore);
00490     w = tremax->last_tre->wid;
00491     if (w != WORD_INVALID) {
00492       j_printf("\"%s [%s]\"(id=%d)\n",
00493              winfo->wname[w], winfo->woutput[w], w);
00494     } else {
00495       j_printf("bgn\n");
00496     }
00497   }
00498 }
00499 
00500 
00501 
00502 
00503 
00504 
00505 
00506    
00507 
00508 
00509 
00510 
00511 
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 static TOKEN2 *tlist[2];        
00520 static TOKENID *tindex[2];      
00521 static int maxtnum = 0;         
00522 static int expand_step = 0;     
00523 static int tnum[2];             
00524 static int n_start;             
00525 static int n_end;               
00526 static int tl;          
00527 static int tn;          
00528 
00529 
00530 static TOKENID *token;          
00531 static int totalnodenum;        
00532 
00533 
00534 static TRELLIS_ATOM bos;        
00535 static boolean nodes_malloced = FALSE; 
00536 
00555 static void
00556 malloc_nodes(int n, int ntoken_init, int ntoken_step)
00557 {
00558   totalnodenum = n;
00559   token        = mymalloc(sizeof(TOKENID)*totalnodenum);
00560   if (maxtnum < ntoken_init) maxtnum = ntoken_init;
00561   tlist[0]     = mymalloc(sizeof(TOKEN2)*maxtnum);
00562   tlist[1]     = mymalloc(sizeof(TOKEN2)*maxtnum);
00563   tindex[0]     = mymalloc(sizeof(TOKENID)*maxtnum);
00564   tindex[1]     = mymalloc(sizeof(TOKENID)*maxtnum);
00565   tnum[0] = tnum[1] = 0;
00566   if (expand_step < ntoken_step) expand_step = ntoken_step;
00567   nodes_malloced = TRUE;
00568 }
00569 
00578 static void
00579 expand_tlist()
00580 {
00581   maxtnum += expand_step;
00582   tlist[0]     = myrealloc(tlist[0],sizeof(TOKEN2)*maxtnum);
00583   tlist[1]     = myrealloc(tlist[1],sizeof(TOKEN2)*maxtnum);
00584   tindex[0]     = myrealloc(tindex[0],sizeof(TOKENID)*maxtnum);
00585   tindex[1]     = myrealloc(tindex[1],sizeof(TOKENID)*maxtnum);
00586   
00587 }
00588 
00597 static void
00598 free_nodes()
00599 {
00600   if (nodes_malloced) {
00601     free(token);
00602     free(tlist[0]);
00603     free(tlist[1]);
00604     free(tindex[0]);
00605     free(tindex[1]);
00606     nodes_malloced = FALSE;
00607   }
00608 }
00609 
00622 static void
00623 clear_tlist(int tt)
00624 {
00625   tnum[tt] = 0;
00626 }
00627 
00640 static void
00641 clear_tokens(int tt)
00642 {
00643   int j;
00644   
00645   for (j=0; j<tnum[tt]; j++) {
00646     token[tlist[tt][j].node] = TOKENID_UNDEFINED;
00647   }
00648 }
00649 
00662 static TOKENID
00663 create_token()
00664 {
00665   TOKENID newid;
00666   newid = tnum[tn];
00667   tnum[tn]++;
00668   if (tnum[tn]>=maxtnum) expand_tlist();
00669   tindex[tn][newid] = newid;
00670 #ifdef WPAIR
00671   
00672   tlist[tn][newid].next = TOKENID_UNDEFINED;
00673 #endif
00674   return(newid);
00675 }
00676 
00704 static void
00705 node_assign_token(int node, TOKENID tkid)
00706 {
00707 #ifdef WPAIR
00708   
00709   tlist[tn][tkid].next = token[node];
00710 #endif
00711   token[node] = tkid;
00712   tlist[tn][tkid].node = node;
00713 }
00714 
00749 static TOKENID
00750 node_exist_token(int tt, int node, WORD_ID wid)
00751 {
00752 #ifdef WPAIR
00753   
00754 
00755 #ifdef WPAIR_KEEP_NLIMIT
00756   
00757   
00758   
00759   int i = 0;
00760   TOKENID lowest_token = TOKENID_UNDEFINED;
00761 #endif
00762   TOKENID tmp;
00763   for(tmp=token[node]; tmp != TOKENID_UNDEFINED; tmp=tlist[tt][tmp].next) {
00764     if (tlist[tt][tmp].last_tre->wid == wid) {
00765       return(tmp);
00766     }
00767 #ifdef WPAIR_KEEP_NLIMIT
00768     if (lowest_token == TOKENID_UNDEFINED ||
00769         tlist[tt][lowest_token].score < tlist[tt][tmp].score)
00770       lowest_token = tmp;
00771     if (++i >= wpair_keep_nlimit) break;
00772 #endif
00773   }
00774 #ifdef WPAIR_KEEP_NLIMIT
00775   if (i >= wpair_keep_nlimit) { 
00776     return(lowest_token);
00777   } else {
00778     return(TOKENID_UNDEFINED);
00779   }
00780 #else 
00781   return(TOKENID_UNDEFINED);
00782 #endif
00783   
00784 #else  
00785   
00786   
00787 
00788   return(token[node]);
00789 #endif
00790 }
00791 
00792 #ifdef DEBUG
00793 
00794 
00795 
00796 
00797 
00798 static void
00799 node_check_token(int tt)
00800 {
00801   int i;
00802   for(i=0;i<tnum[tt];i++) {
00803     if (node_exist_token(tt, tlist[tt][i].node, tlist[tt][i].last_tre->wid) != i) {
00804       j_printerr("token %d not found on node %d\n", i, tlist[tt][i].node);
00805     }
00806   }
00807 }
00808 #endif
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 #define SD(A) tindex[tn][A-1]   
00822 #define SCOPY(D,S) D = S        
00823 #define SVAL(A) (tlist[tn][tindex[tn][A-1]].score) 
00824 #define STVAL (tlist[tn][s].score) 
00825 
00826 
00848 static void
00849 sort_token_upward(int neednum, int totalnum)
00850 {
00851   int n,root,child,parent;
00852   TOKENID s;
00853   for (root = totalnum/2; root >= 1; root--) {
00854     SCOPY(s, SD(root));
00855     parent = root;
00856     while ((child = parent * 2) <= totalnum) {
00857       if (child < totalnum && SVAL(child) < SVAL(child+1)) {
00858         child++;
00859       }
00860       if (STVAL >= SVAL(child)) {
00861         break;
00862       }
00863       SCOPY(SD(parent), SD(child));
00864       parent = child;
00865     }
00866     SCOPY(SD(parent), s);
00867   }
00868   n = totalnum;
00869   while ( n > totalnum - neednum) {
00870     SCOPY(s, SD(n));
00871     SCOPY(SD(n), SD(1));
00872     n--;
00873     parent = 1;
00874     while ((child = parent * 2) <= n) {
00875       if (child < n && SVAL(child) < SVAL(child+1)) {
00876         child++;
00877       }
00878       if (STVAL >= SVAL(child)) {
00879         break;
00880       }
00881       SCOPY(SD(parent), SD(child));
00882       parent = child;
00883     }
00884     SCOPY(SD(parent), s);
00885   }
00886 }
00887 
00912 static void
00913 sort_token_downward(int neednum, int totalnum)
00914 {
00915   int n,root,child,parent;
00916   TOKENID s;
00917   for (root = totalnum/2; root >= 1; root--) {
00918     SCOPY(s, SD(root));
00919     parent = root;
00920     while ((child = parent * 2) <= totalnum) {
00921       if (child < totalnum && SVAL(child) > SVAL(child+1)) {
00922         child++;
00923       }
00924       if (STVAL <= SVAL(child)) {
00925         break;
00926       }
00927       SCOPY(SD(parent), SD(child));
00928       parent = child;
00929     }
00930     SCOPY(SD(parent), s);
00931   }
00932   n = totalnum;
00933   while ( n > totalnum - neednum) {
00934     SCOPY(s, SD(n));
00935     SCOPY(SD(n), SD(1));
00936     n--;
00937     parent = 1;
00938     while ((child = parent * 2) <= n) {
00939       if (child < n && SVAL(child) > SVAL(child+1)) {
00940         child++;
00941       }
00942       if (STVAL <= SVAL(child)) {
00943         break;
00944       }
00945       SCOPY(SD(parent), SD(child));
00946       parent = child;
00947     }
00948     SCOPY(SD(parent), s);
00949   }
00950 }
00951 
00982 static void
00983 sort_token_no_order(int neednum, int *start, int *end)
00984 {
00985   int totalnum = tnum[tn];
00986   int restnum;
00987 
00988   restnum = totalnum - neednum;
00989 
00990   if (neednum >= totalnum) {
00991     
00992     *start = 0;
00993     *end = totalnum - 1;
00994   } else if (neednum < restnum)  {
00995     
00996     sort_token_upward(neednum,totalnum);
00997     *start = totalnum - neednum;
00998     *end = totalnum - 1;
00999   } else {
01000     
01001     sort_token_downward(restnum,totalnum);
01002     *start = 0;
01003     *end = neednum - 1;
01004   }
01005 }
01006     
01007 
01008 #ifdef SP_BREAK_CURRENT_FRAME
01009 
01010 
01011 
01012 
01013 
01014 
01015 
01016 
01017 
01018 
01019 
01020 
01021 
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 static boolean in_sparea;       
01030 static int sparea_start;        
01031 static int tmp_sparea_start;
01032 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01033 static WORD_ID tmp_sp_break_last_word;
01034 #else
01035 static WORD_ID last_tre_word;
01036 #endif
01037 static boolean first_sparea;    
01038 static int sp_duration;         
01039 
01066 boolean
01067 is_sil(WORD_ID w, WORD_INFO *winfo, HTK_HMM_INFO *hmm)
01068 {
01069   
01070   if (winfo->wlen[w] > 1) return FALSE;
01071 
01072   
01073   if (winfo->wseq[w][0] == hmm->sp) return TRUE;
01074 
01075   
01076   if (w == winfo->head_silwid || w == winfo->tail_silwid) return TRUE;
01077 
01078   
01079   return FALSE;
01080 }
01081 
01105 static boolean
01106 detect_end_of_segment(BACKTRELLIS *backtrellis, int time, WCHMM_INFO *wchmm)
01107 {
01108   TRELLIS_ATOM *tre;
01109   LOGPROB maxscore = LOG_ZERO;
01110   TRELLIS_ATOM *tremax = NULL;
01111   int count = 0;
01112   boolean detected = FALSE;
01113 
01114   
01115   for(tre = backtrellis->list; tre != NULL && tre->endtime == time; tre = tre->next) {
01116     if (maxscore < tre->backscore) {
01117       maxscore = tre->backscore;
01118       tremax = tre;
01119     }
01120     count++;
01121   }
01122   if (tremax == NULL) { 
01123     detected = TRUE;            
01124   } else if (count > 0) {       
01125     if (is_sil(tremax->wid, wchmm->winfo, wchmm->hmminfo)) {
01126       detected = TRUE;
01127     }
01128   }
01129   
01130   
01131   
01132   if (in_sparea && detected) {  
01133     sp_duration++;              
01134 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01135     
01136     
01137 
01138 
01139     if (tmp_sp_break_last_word == WORD_INVALID) {
01140       if (tremax != NULL) tmp_sp_break_last_word = tremax->wid;
01141     }
01142 #else
01143     
01144     
01145     if (tremax != NULL) last_tre_word = tremax->wid;
01146 #endif
01147   }
01148 
01149   
01150   
01151   else if (!in_sparea && detected) {
01152     
01153     
01154     tmp_sparea_start = time;
01155 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01156     
01157     
01158     tmp_sp_break_last_word = tremax ? tremax->wid : WORD_INVALID;
01159 #endif
01160     in_sparea = TRUE;           
01161     sp_duration = 1;            
01162 #ifdef SP_BREAK_DEBUG
01163     printf("sp start %d\n", time);
01164 #endif 
01165   }
01166   
01167   
01168   
01169   else if (in_sparea && !detected) {
01170     
01171     in_sparea = FALSE;          
01172 #ifdef SP_BREAK_DEBUG
01173     printf("sp end %d\n", time);
01174 #endif 
01175     
01176     
01177     if (sp_duration < sp_frame_duration) {
01178       
01179       
01180 #ifdef SP_BREAK_DEBUG
01181       printf("too short (%d<%d), ignored\n", sp_duration, sp_frame_duration);
01182 #endif 
01183     } else if (first_sparea) {
01184       
01185       
01186       first_sparea = FALSE;
01187 #ifdef SP_BREAK_DEBUG
01188       printf("first silence, ignored\n");
01189 #endif 
01190     } else {
01191       
01192       
01193 #ifdef SP_BREAK_DEBUG
01194       printf(">> segment [%d..%d]\n", sparea_start, time-1);
01195 #else
01196       if (idc_on) j_printerr("|");
01197 #endif 
01198       
01199       sparea_start = tmp_sparea_start;
01200 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01201       
01202       sp_break_last_word = tmp_sp_break_last_word;
01203 #else
01204       
01205       sp_break_last_word = last_tre_word;
01206 #endif
01207 
01208       
01209       return(TRUE);
01210     }
01211   }
01212     
01213 #ifdef SP_BREAK_EVAL
01214   printf("[%d %d %d]\n", time, count, (detected) ? 50 : 0);
01215 #endif
01216   return (FALSE);
01217 }
01218 
01219 #endif 
01220 
01221 
01222 
01223 
01224 
01225 
01226 
01227 
01246 static void
01247 init_nodescore(HTK_Param *param, WCHMM_INFO *wchmm)
01248 {
01249   TOKENID newid;
01250   TOKEN2 *new;
01251 #ifdef USE_NGRAM
01252   WORD_ID beginword;
01253 #endif
01254   int node;
01255 #ifdef USE_DFA
01256   int i;
01257 #endif
01258 
01259   
01260   
01261 #ifdef SP_BREAK_CURRENT_FRAME
01262   
01263   if (sp_break_last_nword == wchmm->winfo->tail_silwid) {
01264     
01265     bos.wid = WORD_INVALID;
01266   } else {
01267     bos.wid = sp_break_last_nword;
01268   }
01269 #else
01270   bos.wid = WORD_INVALID;       
01271 #endif
01272   bos.begintime = bos.endtime = -1;
01273 
01274   
01275   
01276   for(node=0;node<totalnodenum;node++) {
01277     token[node] = TOKENID_UNDEFINED;
01278   }
01279   tnum[0] = tnum[1]  = 0;
01280   
01281 #ifdef PASS1_IWCD
01282   
01283   
01284   outprob_style_cache_init(wchmm);
01285 #endif
01286 
01287   
01288   
01289 #ifdef USE_NGRAM
01290   
01291 #ifdef SP_BREAK_CURRENT_FRAME
01292   if (sp_break_last_word != WORD_INVALID) { 
01293     
01294     
01295     
01296     
01297     
01298     if (sp_break_last_word == wchmm->winfo->tail_silwid) {
01299       beginword = wchmm->winfo->head_silwid;
01300       bos.wid = WORD_INVALID;   
01301     } else {
01302       beginword = sp_break_last_word;
01303     }
01304   } else {
01305     
01306     beginword = wchmm->winfo->head_silwid;
01307   }
01308 #else
01309   
01310   beginword = wchmm->winfo->head_silwid;
01311 #endif
01312 #ifdef SP_BREAK_DEBUG
01313   printf("startword=[%s], last_nword=[%s]\n",
01314          (beginword == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[beginword],
01315          (bos.wid == WORD_INVALID) ? "WORD_INVALID" : wchmm->winfo->wname[bos.wid]);
01316 #endif
01317   
01318   newid = create_token();
01319   new = &(tlist[tn][newid]);
01320   
01321 #ifdef MULTIPATH_VERSION
01322   node = wchmm->wordbegin[beginword];
01323 #else
01324   node = wchmm->offset[beginword][0];
01325 #endif 
01326   
01327   if (wchmm->state[node].scid != 0) {
01328     
01329     new->last_lscore = max_successor_prob(wchmm, bos.wid, node);
01330   } else {
01331     
01332     new->last_lscore = 0.0;
01333   }
01334 #ifdef FIX_PENALTY
01335   new->last_lscore = new->last_lscore * lm_weight;
01336 #else
01337   new->last_lscore = new->last_lscore * lm_weight + lm_penalty;
01338 #endif
01339   
01340   new->last_tre = &bos;
01341   new->last_cword = bos.wid;
01342 #ifdef MULTIPATH_VERSION
01343   
01344   new->score = new->last_lscore;
01345 #else
01346   
01347   new->score = outprob_style(wchmm, node, bos.wid, 0, param) + new->last_lscore;
01348 #endif 
01349   
01350   node_assign_token(node, newid);
01351   
01352 #else  
01353   
01354   
01355   
01356   
01357   
01358   {
01359     MULTIGRAM *m;
01360     int t,tb,te;
01361     WORD_ID iw;
01362 
01363     
01364     for(m = gramlist; m; m = m->next) {
01365       if (m->active) {
01366         tb = m->cate_begin;
01367         te = tb + m->dfa->term_num;
01368         for(t=tb;t<te;t++) {
01369           
01370           if (dfa_cp_begin(dfa, t) == TRUE) {
01371             
01372             for (iw=0;iw<dfa->term.wnum[t];iw++) {
01373               
01374               i = dfa->term.tw[t][iw];
01375 #ifdef MULTIPATH_VERSION
01376               node = wchmm->wordbegin[i];
01377 #else
01378               node = wchmm->offset[i][0];
01379 #endif 
01380               
01381               if (node_exist_token(tn, node, bos.wid) != TOKENID_UNDEFINED) continue;
01382               newid = create_token();
01383               new = &(tlist[tn][newid]);
01384               new->last_tre = &bos;
01385 #ifdef MULTIPATH_VERSION
01386               new->score = 0.0;
01387 #else
01388               new->score = outprob_style(wchmm, node, bos.wid, 0, param);
01389 #endif 
01390               node_assign_token(node, newid);
01391             }
01392           }
01393         }
01394       }
01395     }
01396   }
01397 
01398 
01399 
01400 
01401 
01402 
01403 
01404 
01405 
01406 
01407 
01408 
01409 
01410   
01411 #endif 
01412 }
01413 
01414 
01415 
01416 
01417 
01418 
01444 void
01445 get_back_trellis_init(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
01446 {
01447   
01448   
01449   
01450   
01451   
01452   tn = 0;
01453   tl = 1;
01454 
01455   
01456   
01457   bt_prepare(backtrellis);
01458 
01459   
01460   
01461   
01462 
01463 
01464   
01465 
01466 
01467   
01468   malloc_nodes(wchmm->n, trellis_beam_width * 2 + wchmm->startnum, trellis_beam_width);
01469   
01470   
01471   
01472   init_nodescore(param, wchmm);
01473   sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01474 
01475   
01476   
01477   result_pass1_begin();
01478   
01479   
01480   progout_interval_frame = (int)((float)progout_interval / ((float)param->header.wshift / 10000.0));
01481 
01482   
01483   
01484   if (!realtime_flag && verbose_flag && (!progout_flag) && isatty(1)) {
01485     idc_on = TRUE;
01486   } else { 
01487     idc_on = FALSE;
01488   }
01489   
01490 #ifdef SP_BREAK_CURRENT_FRAME
01491   
01492   
01493   in_sparea = TRUE;             
01494   sparea_start = tmp_sparea_start = 0; 
01495 #ifdef SP_BREAK_RESUME_WORD_BEGIN
01496   tmp_sp_break_last_word = WORD_INVALID;
01497 #endif
01498   sp_break_last_word = WORD_INVALID;
01499   
01500   
01501 
01502   first_sparea = TRUE;
01503   sp_break_2_begin_word = WORD_INVALID;
01504 #endif
01505 
01506   if (gmm != NULL) {
01507     
01508     gmm_prepare(gmm);
01509   }
01510 }
01511 
01512 
01513 static TRELLIS_ATOM *tre; 
01514 static int node; 
01515 static int stid; 
01516 static A_CELL *ac; 
01517 static int next_node2;          
01518 #ifdef USE_NGRAM
01519 static LOGPROB tmpprob; 
01520 static LOGPROB *iwparray; 
01521 #endif
01522 #ifdef UNIGRAM_FACTORING
01523 
01524 static LOGPROB wordend_best_score; 
01525 static int wordend_best_node;   
01526 static TRELLIS_ATOM *wordend_best_tre; 
01527 static WORD_ID wordend_best_last_cword; 
01528 static int isoid; 
01529 #endif
01530 
01531 
01532 
01533 
01534 
01535 
01575 boolean
01576 get_back_trellis_proceed(int t, HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis
01577 #ifdef MULTIPATH_VERSION
01578                          , boolean final 
01579 #endif
01580                          )
01581 {
01582   LOGPROB tmpsum;
01583   int j, next_node, sword;
01584   TOKEN2  *tk, *tknext;
01585   TOKENID  tknextid;
01586 #ifdef USE_NGRAM
01587   LOGPROB ngram_score_cache;
01588 #endif
01589 
01590   
01591   
01592   
01593   
01594 
01595   
01596   
01597   
01598   
01599   tl = tn;
01600   if (tn == 0) tn = 1; else tn = 0;
01601 
01602   
01603   
01604   if (idc_on) {
01605 #ifdef SP_BREAK_CURRENT_FRAME
01606     if (in_sparea) j_printerr("."); else j_printerr("-");
01607 #else  
01608     j_printerr(".");
01609 #endif 
01610   }
01611 
01612 #ifdef UNIGRAM_FACTORING
01613   
01614 
01615 
01616 
01617 
01618 
01619   
01620 
01621 
01622 
01623 
01624 
01625 
01626 
01627 
01628 
01629   
01630   wordend_best_score = LOG_ZERO;
01631 #endif
01632 
01633 #ifdef DEBUG
01634   
01635   
01636 #endif
01637 
01638   
01639   
01640   clear_tokens(tl);
01641 
01642   
01643   
01644   
01645   
01646   
01647   
01648   
01649   
01650   for (j=n_start;j<=n_end;j++) {
01651 
01652     
01653     
01654     tk = &(tlist[tl][tindex[tl][j]]);
01655     node = tk->node;
01656     if (tk->score <= LOG_ZERO) continue; 
01657 
01658     
01659     
01660     
01661     
01662     for (ac = wchmm->state[node].ac; ac; ac = ac->next) {
01663       next_node = ac->arc;
01664       
01665 
01666       
01667 
01668       
01669       
01670       
01671       
01672       tmpsum = tk->score + ac->a;
01673 #ifdef USE_NGRAM
01674       ngram_score_cache = LOG_ZERO;
01675 #endif
01676       
01677 
01678 
01679 #ifndef CATEGORY_TREE
01680       
01681 
01682 
01683       
01684 
01685 
01686 
01687       if (next_node != node) {
01688         if (wchmm->state[next_node].scid != 0
01689 #ifdef UNIGRAM_FACTORING
01690             
01691 
01692 
01693 
01694 
01695 
01696             
01697 
01698 
01699 
01700 
01701 
01702 
01703 
01704 #endif
01705             ){
01706 #ifdef USE_NGRAM
01707           
01708           
01709           
01710           
01711 #ifdef FIX_PENALTY
01712           
01713           if (tk->last_cword == WORD_INVALID) {
01714             ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight;
01715           } else {
01716             ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01717           }
01718 #else
01719           ngram_score_cache = max_successor_prob(wchmm, tk->last_cword, next_node) * lm_weight + lm_penalty;
01720 #endif
01721           
01722 
01723 
01724           
01725 
01726 
01727           tmpsum -= tk->last_lscore;
01728           tmpsum += ngram_score_cache;
01729           
01730 #else  
01731           
01732 
01733 
01734 
01735           
01736 
01737 
01738 
01739 
01740 
01741 
01742 
01743 
01744 
01745           
01746           
01747 
01748           
01749 
01750 
01751 
01752 
01753           if (!can_succeed(wchmm, tk->last_tre->wid, next_node)) {
01754             tmpsum = LOG_ZERO;
01755           }
01756           
01757 #endif 
01758         }
01759       }
01760 #endif 
01761       
01762 
01763       
01764       
01765       
01766       
01767 
01768       if ((tknextid = node_exist_token(tn, next_node, tk->last_tre->wid)) != TOKENID_UNDEFINED) {
01769         
01770         
01771         tknext = &(tlist[tn][tknextid]);
01772         if (tknext->score < tmpsum) {
01773           
01774           
01775           tknext->last_tre = tk->last_tre; 
01776 #ifdef USE_NGRAM
01777           tknext->last_cword = tk->last_cword; 
01778           tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore; 
01779 #endif 
01780           tknext->score = tmpsum; 
01781         }
01782       } else {
01783         
01784         
01785         if (tmpsum > LOG_ZERO) { 
01786           tknextid = create_token(); 
01787           tknext = &(tlist[tn][tknextid]);
01788           
01789 
01790 
01791           tk = &(tlist[tl][tindex[tl][j]]);
01792           tknext->last_tre = tk->last_tre; 
01793 #ifdef USE_NGRAM
01794           tknext->last_cword = tk->last_cword; 
01795           tknext->last_lscore = (ngram_score_cache != LOG_ZERO) ? ngram_score_cache : tk->last_lscore; 
01796 #endif 
01797           tknext->score = tmpsum; 
01798           node_assign_token(next_node, tknextid); 
01799         }
01800       }
01801     } 
01802 
01803 #ifdef MULTIPATH_VERSION
01804     
01805   }
01806   
01807   
01808   
01809   
01810   
01811   
01812   sort_token_no_order(trellis_beam_width, &n_start, &n_end);
01813   
01814   
01815   
01816   
01817   
01818   
01819   for(j=n_start; j<=n_end; j++) {
01820     tk = &(tlist[tn][tindex[tn][j]]);
01821     node = tk->node;
01822      
01823 #endif 
01824 
01825     
01826     
01827     if (wchmm->stend[node] != WORD_INVALID) {
01828 
01829       sword = wchmm->stend[node];
01830 
01831       
01832       
01833       
01834       
01835 
01836       
01837 
01838 
01839 
01840       
01841 
01842 
01843 
01844       tre = (TRELLIS_ATOM *)mymalloc(sizeof(TRELLIS_ATOM));
01845       tre->wid = sword;         
01846       tre->backscore = tk->score; 
01847       tre->begintime = tk->last_tre->endtime + 1; 
01848       tre->endtime   = t-1;     
01849       tre->last_tre  = tk->last_tre; 
01850 #ifdef USE_NGRAM
01851       tre->lscore    = tk->last_lscore; 
01852 #endif
01853       bt_store(backtrellis, tre); 
01854       
01855       
01856       
01857       
01858       
01859 
01860 #ifdef MULTIPATH_VERSION
01861       
01862       
01863       if (final) continue;
01864 #endif
01865 
01866       
01867 
01868       
01869 
01870 
01871 #ifdef UNIGRAM_FACTORING
01872       
01873 
01874       
01875 
01876 
01877 #endif
01878 
01879 #ifdef USE_NGRAM
01880       
01881       
01882       if (sword == wchmm->winfo->tail_silwid) continue;
01883 
01884 #ifdef UNIGRAM_FACTORING
01885       
01886       
01887       
01888 
01889 
01890       if (wordend_best_score < tk->score
01891 #ifndef MULTIPATH_VERSION
01892           + wchmm->wordend_a[sword]
01893 #endif
01894           ) {
01895         wordend_best_score = tk->score
01896 #ifndef MULTIPATH_VERSION
01897           + wchmm->wordend_a[sword]
01898 #endif
01899           ;
01900         wordend_best_node = node;
01901         wordend_best_tre = tre;
01902         wordend_best_last_cword = tk->last_cword;
01903       }
01904 #endif
01905       
01906       
01907 
01908 
01909       
01910 
01911 
01912       if (wchmm->winfo->is_transparent[sword]) {
01913         iwparray = max_successor_prob_iw(wchmm, tk->last_cword);
01914       } else {
01915         iwparray = max_successor_prob_iw(wchmm, sword);
01916       }
01917 #endif
01918 
01919       
01920       
01921       
01922       
01923       for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
01924         next_node = wchmm->startnode[stid];
01925 #ifdef MULTIPATH_VERSION
01926 #ifdef USE_NGRAM
01927         
01928         if (wchmm->wordbegin[wchmm->winfo->head_silwid] == next_node) continue;
01929 #endif
01930 #endif
01931 
01932         
01933         
01934         
01935         
01936         
01937 #ifdef USE_NGRAM
01938         
01939         
01940 #ifdef UNIGRAM_FACTORING
01941         
01942 
01943 
01944 
01945 
01946 
01947         
01948 
01949 
01950 
01951 
01952 
01953 
01954 
01955         
01956 
01957         
01958 
01959 
01960 
01961 
01962         isoid = wchmm->start2isolate[stid];
01963         
01964 
01965         
01966 
01967         if (isoid == -1) continue;
01968         tmpprob = iwparray[isoid];
01969 #else
01970         tmpprob = iwparray[stid];
01971 #endif
01972 #endif
01973 
01974 #ifdef USE_NGRAM
01975         
01976 
01977 
01978         
01979 
01980 
01981 
01982 
01983 #endif
01984         
01985 #ifdef CATEGORY_TREE
01986         
01987         
01988 
01989 
01990 
01991         if (dfa_cp(dfa, wchmm->winfo->wton[sword],
01992 #ifdef MULTIPATH_VERSION
01993                    wchmm->winfo->wton[wchmm->start2wid[stid]]
01994 #else
01995                    wchmm->winfo->wton[wchmm->ststart[next_node]]
01996 #endif 
01997                    ) == FALSE) continue;
01998 #endif
01999 
02000         
02001         
02002         
02003         
02004         tmpsum = tk->score
02005 #ifndef MULTIPATH_VERSION
02006           + wchmm->wordend_a[sword]
02007 #endif
02008           ;
02009         
02010 #ifdef USE_NGRAM
02011         
02012         
02013         ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02014         tmpsum += ngram_score_cache;
02015         if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[tk->last_cword]) {
02016           
02017           tmpsum += lm_penalty_trans;
02018         }
02019 #else  
02020         
02021         
02022         tmpsum += penalty1;
02023 
02024         
02025 #ifdef CATEGORY_TREE
02026         
02027 #else
02028         if (!can_succeed(wchmm, sword, next_node)) {
02029           tmpsum = LOG_ZERO;
02030         }
02031 #endif 
02032 #endif 
02033 
02034 
02035         
02036         
02037         
02038         
02039 
02040 #ifndef MULTIPATH_VERSION
02041         next_node2 = next_node;
02042 #else
02043         for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02044           next_node2 = ac->arc;
02045 #endif
02046           
02047           if ((tknextid = node_exist_token(tn, next_node2, tre->wid)) != TOKENID_UNDEFINED) {
02048             
02049             
02050             tknext = &(tlist[tn][tknextid]);
02051             if (tknext->score < tmpsum) {
02052               
02053               
02054 #ifdef USE_NGRAM
02055               tknext->last_lscore = ngram_score_cache; 
02056               
02057               if (wchmm->winfo->is_transparent[sword]) {
02058                 
02059 
02060 
02061                 tknext->last_cword = tk->last_cword;
02062               } else {
02063                 
02064                 tknext->last_cword = sword;
02065               }
02066 #endif
02067               
02068               tknext->score = tmpsum;
02069 #ifdef MULTIPATH_VERSION
02070               tknext->score += ac->a;
02071 #endif
02072               
02073 
02074               
02075 
02076               tknext->last_tre = tre;
02077             }
02078           } else {
02079             
02080             
02081             if (tmpsum > LOG_ZERO) { 
02082               tknextid = create_token();
02083               tknext = &(tlist[tn][tknextid]);
02084               
02085 
02086 
02087 #ifdef MULTIPATH_VERSION
02088               tk = &(tlist[tn][tindex[tn][j]]);
02089 #else
02090               tk = &(tlist[tl][tindex[tl][j]]);
02091 #endif
02092 #ifdef USE_NGRAM
02093               tknext->last_lscore = ngram_score_cache; 
02094               
02095               if (wchmm->winfo->is_transparent[sword]) {
02096                 
02097 
02098 
02099                 tknext->last_cword = tk->last_cword;
02100               } else {
02101                 
02102                 tknext->last_cword = sword;
02103               }
02104 #endif
02105               tknext->score = tmpsum;
02106 #ifdef MULTIPATH_VERSION
02107               tknext->score += ac->a;
02108 #endif
02109             
02110 
02111             
02112 
02113               tknext->last_tre = tre;
02114               
02115               node_assign_token(next_node2, tknextid);
02116             }
02117           }
02118 #ifdef MULTIPATH_VERSION
02119         }
02120 #endif
02121         
02122       } 
02123     } 
02124     
02125   } 
02126 #ifdef UNIGRAM_FACTORING
02127   
02128   
02129   
02130   
02131   
02132   if (wordend_best_score > LOG_ZERO) {
02133     node = wordend_best_node;
02134     sword = wchmm->stend[node];
02135     for (stid = wchmm->startnum - 1; stid >= 0; stid--) {
02136       next_node = wchmm->startnode[stid];
02137       
02138       
02139       if (wchmm->start2isolate[stid] != -1) continue;
02140       
02141       if (wchmm->state[next_node].scid >= 0) {
02142         j_error("InternalError: scid mismatch at 1-gram factoring of shared states\n");
02143       }
02144       tmpprob = wchmm->fscore[- wchmm->state[next_node].scid];
02145       ngram_score_cache = tmpprob * lm_weight + lm_penalty;
02146       tmpsum = wordend_best_score;
02147       tmpsum += ngram_score_cache;
02148       if (wchmm->winfo->is_transparent[sword] && wchmm->winfo->is_transparent[wordend_best_last_cword]) {
02149         tmpsum += lm_penalty_trans;
02150       }
02151       
02152 #ifndef MULTIPATH_VERSION
02153       next_node2 = next_node;
02154 #else
02155       for(ac=wchmm->state[next_node].ac; ac; ac=ac->next) {
02156         next_node2 = ac->arc;
02157 #endif
02158         if ((tknextid = node_exist_token(tn, next_node2, sword)) != TOKENID_UNDEFINED) {
02159           tknext = &(tlist[tn][tknextid]);
02160           if (tknext->score < tmpsum) {
02161             tknext->last_lscore = ngram_score_cache;
02162             if (wchmm->winfo->is_transparent[sword]) {
02163               tknext->last_cword = wordend_best_last_cword;
02164             } else {
02165               tknext->last_cword = sword;
02166             }
02167             tknext->score = tmpsum;
02168 #ifdef MULTIPATH_VERSION
02169             tknext->score += ac->a;
02170 #endif
02171             tknext->last_tre = wordend_best_tre;
02172           }
02173         } else {
02174           if (tmpsum > LOG_ZERO) { 
02175             tknextid = create_token();
02176             tknext = &(tlist[tn][tknextid]);
02177             tknext->last_lscore = ngram_score_cache;
02178             if (wchmm->winfo->is_transparent[sword]) {
02179               tknext->last_cword = wordend_best_last_cword;
02180             } else {
02181               tknext->last_cword = sword;
02182             }
02183             tknext->score = tmpsum;
02184 #ifdef MULTIPATH_VERSION
02185             tknext->score += ac->a;
02186 #endif
02187             tknext->last_tre = wordend_best_tre;
02188             node_assign_token(next_node2, tknextid);
02189           }
02190         }
02191 #ifdef MULTIPATH_VERSION
02192       }
02193 #endif
02194       
02195     }
02196   }
02197 #endif 
02198 
02199   
02200   
02201   
02202   
02203 
02204   
02205   
02206 #ifdef MULTIPATH_VERSION
02207   
02208   
02209   if (! final) {
02210 #endif
02211     for (j=0;j<tnum[tn];j++) {
02212       tk = &(tlist[tn][tindex[tn][j]]);
02213 #ifdef MULTIPATH_VERSION
02214       
02215       if (wchmm->state[tk->node].out.state == NULL) continue;
02216 #endif
02217       tk->score += outprob_style(wchmm, tk->node, tk->last_tre->wid, t, param);
02218     }
02219 #ifdef MULTIPATH_VERSION
02220   }
02221 #endif
02222 
02223   if (gmm != NULL) {
02224     
02225     gmm_proceed(gmm, param, t);
02226   }
02227 
02228   
02229   
02230   
02231   
02232 
02233   
02234   clear_tlist(tl);
02235 
02236   
02237   
02238   sort_token_no_order(trellis_beam_width, &n_start, &n_end);
02239 
02240   
02241 
02242 
02243 
02244   
02245 
02246 
02247 
02248 
02249 
02250 
02251 
02252   
02253   
02254   
02255   
02256   
02257   if (progout_flag) {
02258     
02259     
02260     if ((t % progout_interval_frame) == 0) {
02261       bt_current_max(backtrellis, t-1, wchmm->winfo);
02262     }
02263   }
02264   
02265   
02266   if (debug2_flag) {
02267     bt_current_max_word(backtrellis, t-1, wchmm->winfo);
02268   }
02269 
02270 #ifdef SP_BREAK_CURRENT_FRAME
02271   
02272   if (detect_end_of_segment(backtrellis, t-1, wchmm)) {
02273     
02274     return FALSE;               
02275   }
02276 #endif
02277 
02278   
02279   if (tnum[tn] == 0) {
02280     j_printerr("Error: %dth frame: no nodes left in beam! model mismatch or wrong input?\n", t);
02281     return(FALSE);
02282   }
02283 
02284   return(TRUE);
02285     
02286 }
02287 
02288 
02289 
02290 
02291 
02292 
02316 void
02317 get_back_trellis_end(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis)
02318 {
02319   int t, node, j;
02320   TOKEN2 *tk;
02321 
02322   
02323   
02324 
02325 #ifdef MULTIPATH_VERSION
02326   
02327   
02328   
02329   get_back_trellis_proceed(param->samplenum, param, wchmm, backtrellis, TRUE);
02330   
02331 #else  
02332   
02333   t = param->samplenum;
02334   tl = tn;
02335   if (tn == 0) tn = 1; else tn = 0;
02336   for (j=n_start; j<=n_end; j++) {
02337     tk = &(tlist[tl][tindex[tl][j]]);
02338     node = tk->node;
02339     if (wchmm->stend[node] != WORD_INVALID) {
02340       tre = (TRELLIS_ATOM *)mymalloc(sizeof(TRELLIS_ATOM));
02341       tre->wid = wchmm->stend[node];
02342       tre->backscore = tk->score;
02343       tre->begintime = tk->last_tre->endtime + 1;
02344       tre->endtime   = t-1;
02345       tre->last_tre  = tk->last_tre;
02346 #ifdef USE_NGRAM
02347       tre->lscore    = tk->last_lscore;
02348 #endif
02349       bt_store(backtrellis, tre);
02350     }
02351   }
02352 
02353 #endif 
02354 
02355 #ifdef SP_BREAK_CURRENT_FRAME
02356   
02357 
02358 
02359 #endif
02360 }
02361 
02362 
02363 
02364 
02365 
02398 LOGPROB
02399 finalize_1st_pass(BACKTRELLIS *backtrellis, WORD_INFO *winfo, int len)
02400 {
02401   LOGPROB lastscore;
02402   int mseclen;
02403   boolean ok_p;
02404  
02405   backtrellis->framelen = len;
02406 
02407   
02408   
02409   
02410   
02411   ok_p = TRUE;
02412   if (rejectshortlen > 0) {
02413     mseclen = (float)len * (float)smpPeriod * (float)fshift / 10000.0;
02414     if (mseclen < rejectshortlen) {
02415       ok_p = FALSE;
02416     }
02417   }
02418   
02419   
02420   
02421   if (ok_p) {
02422     bt_relocate_rw(backtrellis);
02423     bt_sort_rw(backtrellis);
02424     if (backtrellis->num == NULL) {
02425       if (backtrellis->framelen > 0) j_printerr("no survived word!\n");
02426       ok_p = FALSE;
02427     }
02428   }
02429 
02430   
02431   
02432   if (verbose_flag && (!progout_flag)) j_printerr("\n");
02433   if (ok_p) {
02434     lastscore = print_1pass_result(backtrellis, len, winfo);
02435   } else {
02436     lastscore = LOG_ZERO;
02437   }
02438 
02439 #ifdef USE_NGRAM
02440   
02441   
02442   
02443   
02444 #endif
02445   
02446   free_nodes();
02447   
02448   if (ok_p) {
02449     if (gmm != NULL) {
02450       
02451       gmm_end(gmm);
02452     }
02453   }
02454 
02455   
02456   return(lastscore);
02457 }
02458 
02459 #ifdef SP_BREAK_CURRENT_FRAME
02460 
02461 
02462 
02463 
02493 void
02494 finalize_segment(BACKTRELLIS *backtrellis, HTK_Param *param, int len)
02495 {
02496   int t;
02497 
02498   
02499   
02500 
02501   set_terminal_words(backtrellis);
02502 
02503   
02504 
02505 
02506   
02507 
02508 
02509 
02510   
02511 
02512 
02513 
02514 
02515   if (len != param->samplenum) {
02516 
02517     VERMES("segmented: processed length=%d\n", len);
02518     VERMES("segmented: next decoding will restart from %d\n", sparea_start);
02519     
02520     
02521     rest_param = new_param();
02522     memcpy(&(rest_param->header), &(param->header), sizeof(HTK_Param_Header));
02523     rest_param->samplenum = param->samplenum - sparea_start;
02524     rest_param->header.samplenum = rest_param->samplenum;
02525     rest_param->veclen = param->veclen;
02526     rest_param->parvec = (VECT **)mymalloc(sizeof(VECT *) * rest_param->samplenum);
02527     
02528     for(t=sparea_start;t<len;t++) {
02529       rest_param->parvec[t-sparea_start] = (VECT *)mymalloc(sizeof(VECT) * rest_param->veclen);
02530       memcpy(rest_param->parvec[t-sparea_start], param->parvec[t], sizeof(VECT) * rest_param->veclen);
02531     }
02532     
02533     for(t=len;t<param->samplenum;t++) {
02534       rest_param->parvec[t-sparea_start] = param->parvec[t];
02535     }
02536 
02537     
02538     
02539     param->samplenum = len;
02540     param->parvec = (VECT **)myrealloc(param->parvec, sizeof(VECT *) * param->samplenum);
02541     sp_break_last_nword_allow_override = TRUE;
02542     
02543   } else {
02544     
02545     
02546     rest_param = NULL;
02547     
02548     sp_break_last_word = WORD_INVALID;
02549     sp_break_last_nword = WORD_INVALID;
02550     sp_break_last_nword_allow_override = FALSE;
02551   }
02552 }
02553 #endif 
02554   
02555 
02556 
02557 
02558 
02559 
02560 
02561 
02599 void
02600 get_back_trellis(HTK_Param *param, WCHMM_INFO *wchmm, BACKTRELLIS *backtrellis,
02601 LOGPROB *backmax)
02602 {
02603   int t;
02604 
02605   
02606   
02607   get_back_trellis_init(param, wchmm, backtrellis);
02608 
02609   
02610   
02611   for (
02612 #ifdef MULTIPATH_VERSION
02613        
02614        t = 0
02615 #else
02616        
02617        t = 1
02618 #endif
02619          ; t < param->samplenum; t++) {
02620     if (get_back_trellis_proceed(t, param, wchmm, backtrellis
02621 #ifdef MULTIPATH_VERSION
02622                                  ,FALSE
02623 #endif
02624                                  ) == FALSE
02625         || catch_intr_flag
02626         || (module_mode && module_wants_terminate())) {
02627       
02628       
02629       
02630       
02631       *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, t-1);
02632 #ifdef SP_BREAK_CURRENT_FRAME
02633       
02634 
02635       
02636       finalize_segment(backtrellis, param, t-1);
02637 #endif
02638       
02639       return;
02640     }
02641   }
02642   
02643   
02644   get_back_trellis_end(param, wchmm, backtrellis);
02645   
02646   
02647   *backmax = finalize_1st_pass(backtrellis, wchmm->winfo, param->samplenum);
02648 #ifdef SP_BREAK_CURRENT_FRAME
02649   
02650 
02651   
02652   finalize_segment(backtrellis, param, param->samplenum);
02653 #endif
02654 }
02655 
02656