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