00001 
00041 
00042 
00043 
00044 
00045 
00046 
00047    
00048 #include <julius.h>
00049 
00050 #ifdef USE_NGRAM
00051 
00070 static int
00071 compare_nw(NEXTWORD **a, NEXTWORD **b)
00072 {
00073   if ((*a)->id > (*b)->id) return 1;
00074   if ((*a)->id < (*b)->id) return -1;
00075   return 0;
00076 }
00077 
00099 
00100 static NEXTWORD *
00101 search_nw(NEXTWORD **nw, WORD_ID w, int num)
00102 {
00103   int left,right,mid;
00104   NEXTWORD *tmp;
00105 
00106   if (num == 0) return NULL;
00107   left = 0;
00108   right = num - 1;
00109   while (left < right) {
00110     mid = (left + right) / 2;
00111     if ((nw[mid])->id < w) {
00112       left = mid + 1;
00113     } else {
00114       right = mid;
00115     }
00116   }
00117   tmp = nw[left];
00118   if (tmp->id == w) {
00119     return tmp;
00120   } else {
00121     return NULL;
00122   }
00123 }
00124 
00125 
00126 static WORD_ID cnword[2];       
00127 static int cnnum;               
00128 static int last_trans;          
00129 
00146 static void
00147 set_word_context(WORD_ID *cseq, int n, WORD_INFO *winfo)
00148 {
00149   int i;
00150 
00151   cnnum = 0;
00152   last_trans = 0;
00153   for(i=n-1;i>=0;i--) {
00154     if (! winfo->is_transparent[cseq[i]]) {
00155       cnword[cnnum++] = winfo->wton[cseq[i]];
00156       if (cnnum >= 2) break;
00157     } else {
00158       last_trans++;
00159     }
00160   }
00161 }
00162 
00163 
00164 
00165 
00166 
00204 static int
00205 pick_backtrellis_words(BACKTRELLIS *bt, WORD_INFO *winfo, NGRAM_INFO *ngram, NEXTWORD **nw, int oldnum, NODE *hypo, short t)
00206 {
00207   int i;
00208   WORD_ID w;
00209   LOGPROB rawscore;
00210 #ifndef WORD_GRAPH
00211 #ifdef WPAIR
00212   int w_old = WORD_INVALID;
00213 #endif
00214 #endif
00215   int num;
00216 
00217   num = oldnum;
00218   
00219   set_word_context(hypo->seq, hypo->seqnum, winfo);
00220   
00221   for (i=0;i<bt->num[t];i++) {
00222     w = (bt->rw[t][i])->wid;
00223 #ifdef WORD_GRAPH
00224     
00225     if (!(bt->rw[t][i])->within_wordgraph) continue;
00226     
00227     if (w != ((hypo->tre)->last_tre)->wid) continue;
00228 #else 
00229 #ifdef WPAIR
00230     
00231 
00232 
00233     if (w == w_old) continue;   
00234     else w_old = w;
00235 #endif 
00236 #endif 
00237     
00238     if (search_nw(nw, w, oldnum) != NULL) continue;
00239     switch(cnnum) {             
00240     case 0:                     
00241       rawscore = uni_prob(ngram, winfo->wton[w]);
00242       break;
00243     case 1:                     
00244       rawscore = bi_prob_rl(ngram, winfo->wton[w], cnword[0]);
00245       break;
00246     default:                    
00247       rawscore = tri_prob_rl(ngram, winfo->wton[w], cnword[0], cnword[1]);
00248       break;
00249     }
00250 #ifdef CLASS_NGRAM
00251     rawscore += winfo->cprob[w];
00252 #endif
00253     nw[num]->tre   = bt->rw[t][i];
00254     nw[num]->id    = w;
00255     nw[num]->lscore = lm_weight2 * rawscore + lm_penalty2;
00256     if (winfo->is_transparent[w]) {
00257       
00258       if (winfo->is_transparent[hypo->seq[hypo->seqnum-1]]) {
00259         nw[num]->lscore += lm_penalty_trans;
00260       }
00261     }
00262     
00263     
00264     num++;
00265   }
00266   return num;
00267 }
00268 
00269 
00270 
00271 
00272 
00273 
00274 
00313 int
00314 get_backtrellis_words(BACKTRELLIS *bt, WORD_INFO *winfo, NGRAM_INFO *ngram, NEXTWORD **nw, NODE *hypo, short tm, short t_end)
00315 {
00316   int num = 0;
00317   int t, t_step;
00318   int oldnum=0;
00319 
00320   if (tm < 0) return(0);
00321 
00322 #ifdef PREFER_CENTER_ON_TRELLIS_LOOKUP
00323   
00324   
00325   for (t_step = 0; t_step < lookup_range; t_step++) {
00326     
00327     t = tm - t_step;
00328     if (t < 0 || t > bt->framelen - 1 || t >= t_end) continue;
00329     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00330     if (num > oldnum) {
00331       qsort(nw, num, sizeof(NEXTWORD *),
00332             (int (*)(const void *,const void *))compare_nw);
00333       oldnum = num;
00334     }
00335     if (t_step == 0) continue;  
00336     
00337     t = tm + t_step;
00338     if (t < 0 || t > bt->framelen - 1 || t >= t_end) continue;
00339     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00340     if (num > oldnum) {
00341       qsort(nw, num, sizeof(NEXTWORD *),
00342             (int (*)(const void *,const void *))compare_nw);
00343       oldnum = num;
00344     }
00345   }
00346 
00347 #else
00348 
00349   
00350   for(t = tm; t >= tm - lookup_range; t--) {
00351     if (t < 0) break;
00352     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00353     if (num > oldnum) {
00354       qsort(nw, num, sizeof(NEXTWORD *),
00355             (int (*)(const void *,const void *))compare_nw);
00356       oldnum = num;
00357     }
00358   }
00359   
00360   for(t = tm + 1; t < tm + lookup_range; t++) {
00361     if (t > bt->framelen - 1) break;
00362     if (t >= t_end) break;
00363     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00364     if (num > oldnum) {
00365       qsort(nw, num, sizeof(NEXTWORD *),
00366             (int (*)(const void *,const void *))compare_nw);
00367       oldnum = num;
00368     }
00369   }
00370 #endif
00371 
00372   return num;
00373 }
00374 
00395 int
00396 limit_nw(NEXTWORD **nw, NODE *hypo, int num)
00397 {
00398   int src,dst;
00399   int newnum;
00400 
00401   
00402   
00403   if (hypo->seq[hypo->seqnum-1] == winfo->head_silwid) {
00404     return(0);
00405   }
00406 
00407   dst = 0;
00408   for (src=0; src<num; src++) {
00409     if (nw[src]->id == winfo->tail_silwid) {
00410       
00411       
00412       continue;
00413     }
00414 #ifdef FIX_35_INHIBIT_SAME_WORD_EXPANSION
00415     
00416     
00417     if (nw[src]->tre == hypo->tre) continue;
00418 #endif
00419     
00420     if (src != dst) memcpy(nw[dst], nw[src], sizeof(NEXTWORD));
00421     dst++;
00422   }
00423   newnum = dst;
00424 
00425   return newnum;
00426 }
00427         
00428 
00429 
00430 
00431 
00432 
00466 int
00467 ngram_firstwords(NEXTWORD **nw, int peseqlen, int maxnw, WORD_INFO *winfo, BACKTRELLIS *bt)
00468 {
00469 #ifdef WORD_GRAPH
00470   int last_time;
00471 #endif
00472 
00473 #ifdef SP_BREAK_CURRENT_FRAME
00474   if (rest_param != NULL) {
00475     
00476     
00477 
00478     nw[0]->id = sp_break_2_begin_word;
00479   } else {
00480     
00481     
00482     nw[0]->id = winfo->tail_silwid;
00483   }
00484 #else
00485   
00486   nw[0]->id = winfo->tail_silwid;
00487 #endif
00488 #ifdef FIX_PENALTY
00489   nw[0]->lscore = 0.0;
00490 #else
00491   nw[0]->lscore = lm_penalty2;
00492 #endif
00493 #ifdef WORD_GRAPH
00494   
00495   
00496   for (last_time = peseqlen - 1; last_time >= 0; last_time--) {
00497     nw[0]->tre = bt_binsearch_atom(&backtrellis, last_time, winfo->tail_silwid);
00498     if (nw[0]->tre != NULL) break;
00499   }
00500   if (nw[0]->tre == NULL) {             
00501     j_printerr("no wordend left in beam!\n");
00502     j_printerr("beam width too small or input speech too short\n");
00503     return 0;
00504   }
00505 #endif
00506 
00507   return 1;                     
00508 }
00509 
00510 
00511 
00512 
00552 int
00553 ngram_nextwords(
00554                 NODE *hypo,
00555                 NEXTWORD **nw,
00556                 int maxnw,      
00557                 NGRAM_INFO *ngram, 
00558                 WORD_INFO *winfo, 
00559                 BACKTRELLIS *bt) 
00560 {
00561   int num, num2;
00562 
00563   if (hypo->seqnum == 0) {
00564     j_error("gs_get_next_words: hypo contains no word\n");
00565   }
00566 
00567   
00568   
00569   num = get_backtrellis_words(bt, winfo, ngram, nw, hypo, hypo->estimated_next_t, hypo->bestt);
00570 
00571   if (debug2_flag) j_printf("%d",num);
00572 
00573   
00574   
00575   num2 = limit_nw(nw, hypo, num);
00576 
00577   if (debug2_flag) j_printf("-%d=%d unfolded\n",num-num2,num2);
00578 
00579   return(num2);
00580 }
00581 
00582 
00605 boolean
00606 ngram_acceptable(NODE *hypo, WORD_INFO *winfo)
00607 {
00608   if (
00609 #ifdef SP_BREAK_CURRENT_FRAME
00610       
00611       
00612       hypo->seq[hypo->seqnum-1] == sp_break_2_end_word
00613 #else
00614       
00615       
00616       hypo->seq[hypo->seqnum-1] == winfo->head_silwid
00617 #endif
00618       ) {
00619     return TRUE;
00620   } else {
00621     return FALSE;
00622   }
00623 }
00624 
00625 #endif