00001
00052
00053
00054
00055
00056
00057
00058
00059 #include <julius/julius.h>
00060
00078 void
00079 bt_init(BACKTRELLIS *bt)
00080 {
00081 bt->num = NULL;
00082 bt->rw = NULL;
00083 bt->list = NULL;
00084 bt->root = NULL;
00085 }
00086
00103 void
00104 bt_prepare(BACKTRELLIS *bt)
00105 {
00106
00107 mybfree2(&(bt->root));
00108
00109
00110 bt->num = NULL;
00111 bt->rw = NULL;
00112 bt->list = NULL;
00113 bt->root = NULL;
00114 }
00115
00130 void
00131 bt_free(BACKTRELLIS *bt)
00132 {
00133 if (bt->root) mybfree2(&(bt->root));
00134 free(bt);
00135 }
00136
00153 TRELLIS_ATOM *
00154 bt_new(BACKTRELLIS *bt)
00155 {
00156 TRELLIS_ATOM *new;
00157
00158 new = (TRELLIS_ATOM *)mybmalloc2(sizeof(TRELLIS_ATOM), &(bt->root));
00159 return new;
00160 }
00161
00162
00163
00189 void
00190 bt_store(BACKTRELLIS *bt, TRELLIS_ATOM *tatom)
00191 {
00192 #ifdef WORD_GRAPH
00193 tatom->within_context = FALSE;
00194 tatom->within_wordgraph = FALSE;
00195 #endif
00196 tatom->next = bt->list;
00197 bt->list = tatom;
00198 }
00199
00217 void
00218 bt_relocate_rw(BACKTRELLIS *bt)
00219 {
00220 TRELLIS_ATOM *tre;
00221 int t;
00222 int totalnum, n;
00223 TRELLIS_ATOM **tmp;
00224
00225 if (bt->framelen == 0) {
00226 bt->num = NULL;
00227 return;
00228 }
00229
00230 bt->num = (int *)mybmalloc2(sizeof(int) * bt->framelen, &(bt->root));
00231
00232
00233 for (t=0;t<bt->framelen;t++) bt->num[t] = 0;
00234 totalnum = 0;
00235 for (tre=bt->list;tre;tre=tre->next) {
00236
00237 if (tre->endtime >= bt->framelen) continue;
00238 bt->num[tre->endtime]++;
00239 totalnum++;
00240 }
00241
00242 if (totalnum <= 0) {
00243 bt->num = NULL;
00244 return;
00245 }
00246
00247
00248 bt->rw = (TRELLIS_ATOM ***)mybmalloc2(sizeof(TRELLIS_ATOM **) * bt->framelen, &(bt->root));
00249 tmp = (TRELLIS_ATOM **)mybmalloc2(sizeof(TRELLIS_ATOM *) * totalnum, &(bt->root));
00250 n = 0;
00251 for (t=0;t<bt->framelen;t++) {
00252 if (bt->num[t] > 0) {
00253 bt->rw[t] = (TRELLIS_ATOM **)&(tmp[n]);
00254 n += bt->num[t];
00255 }
00256 }
00257
00258 for (t=0;t<bt->framelen;t++) bt->num[t] = 0;
00259 for (tre=bt->list;tre;tre=tre->next) {
00260
00261 if (tre->endtime >= bt->framelen) continue;
00262 t = tre->endtime;
00263
00264 bt->rw[t][bt->num[t]] = tre;
00265 bt->num[t]++;
00266 }
00267 }
00268
00269
00270
00271
00272
00294 void
00295 set_terminal_words(RecogProcess *r)
00296 {
00297 LOGPROB maxscore;
00298 int i,t;
00299 BACKTRELLIS *bt;
00300
00301 bt = r->backtrellis;
00302
00303 if (bt->num == NULL) return;
00304
00305 maxscore = LOG_ZERO;
00306
00307 for(t=bt->framelen-1;t>=0;t--) {
00308 if (bt->num[t] > 0) break;
00309 }
00310
00311 for(i=0;i<bt->num[t];i++) {
00312 if (maxscore < (bt->rw[t][i])->backscore) {
00313 maxscore = (bt->rw[t][i])->backscore;
00314 r->sp_break_2_begin_word = (bt->rw[t][i])->wid;
00315 }
00316 }
00317 maxscore = LOG_ZERO;
00318
00319 for(t=0;t<bt->framelen;t++) {
00320 if (bt->num[t] > 0) break;
00321 }
00322
00323 for(i=0;i<bt->num[t];i++) {
00324 if (maxscore < (bt->rw[t][i])->backscore) {
00325 maxscore = (bt->rw[t][i])->backscore;
00326 r->sp_break_2_end_word = (bt->rw[t][i])->wid;
00327 }
00328 }
00329 #ifdef SP_BREAK_DEBUG
00330 jlog("DEBUG: 2nd pass begin word: %s\n",
00331 (r->sp_break_2_begin_word == WORD_INVALID) ? "WORD_INVALID" : r->lm->winfo->wname[r->sp_break_2_begin_word]);
00332 jlog("DEBUG: 2nd pass end word: %s\n",
00333 (r->sp_break_2_end_word == WORD_INVALID) ? "WORD_INVALID" : r->lm->winfo->wname[r->sp_break_2_end_word]);
00334 #endif
00335 }
00336
00337
00338
00366 void
00367 bt_discount_pescore(WCHMM_INFO *wchmm, BACKTRELLIS *bt, HTK_Param *param)
00368 {
00369 int t,i;
00370 TRELLIS_ATOM *tre;
00371
00372 if (bt->num == NULL) return;
00373
00374 for (t=0; t<bt->framelen; t++) {
00375 for (i=0; i<bt->num[t]; i++) {
00376 tre = bt->rw[t][i];
00377
00378
00379
00380
00381 tre->backscore -= outprob_style(wchmm, wchmm->wordend[tre->wid], tre->last_tre->wid, t, param);
00382 }
00383 }
00384 }
00385
00400 void
00401 bt_discount_lm(BACKTRELLIS *bt)
00402 {
00403 int t,i;
00404 TRELLIS_ATOM *tre;
00405
00406 if (bt->num == NULL) return;
00407
00408
00409
00410 for (t=0; t<bt->framelen; t++) {
00411 for (i=0; i<bt->num[t]; i++) {
00412 tre = bt->rw[t][i];
00413 tre->backscore -= tre->lscore;
00414 }
00415 }
00416 }
00417
00438 static int
00439 compare_wid(TRELLIS_ATOM **a, TRELLIS_ATOM **b)
00440 {
00441 if ((*a)->wid > (*b)->wid) return 1;
00442 if ((*a)->wid < (*b)->wid) return -1;
00443 return 0;
00444 }
00445
00467 void
00468 bt_sort_rw(BACKTRELLIS *bt)
00469 {
00470 int t;
00471
00472 if (bt->num == NULL) return;
00473
00474 for (t=0;t<bt->framelen;t++) {
00475 qsort(bt->rw[t], bt->num[t], sizeof(TRELLIS_ATOM *),
00476 (int (*)(const void *,const void *))compare_wid);
00477 }
00478 }
00479
00480
00481
00482
00508 TRELLIS_ATOM *
00509 bt_binsearch_atom(BACKTRELLIS *bt, int t, WORD_ID wkey)
00510 {
00511
00512
00513 int left, right, mid;
00514 TRELLIS_ATOM *tmp;
00515 #ifdef WPAIR
00516 int i;
00517 LOGPROB maxscore;
00518 TRELLIS_ATOM *maxtre;
00519 #endif
00520
00521 if (bt->num[t] == 0) return(NULL);
00522
00523 left = 0;
00524 right = bt->num[t] - 1;
00525 while (left < right) {
00526 mid = (left + right) / 2;
00527 if ((bt->rw[t][mid])->wid < wkey) {
00528 left = mid + 1;
00529 } else {
00530 right = mid;
00531 }
00532 }
00533 tmp = bt->rw[t][left];
00534 if (tmp->wid == wkey) {
00535 #ifdef WPAIR
00536
00537
00538 maxscore = LOG_ZERO;
00539 maxtre = NULL;
00540 i = left;
00541 while (i >= 0) {
00542 tmp = bt->rw[t][i];
00543 if (tmp->wid != wkey) break;
00544 #ifdef WORD_GRAPH
00545
00546 if (!tmp->within_wordgraph) {
00547 i--; continue;
00548 }
00549 #endif
00550 if (maxscore < tmp->backscore) {
00551 maxscore = tmp->backscore;
00552 maxtre = tmp;
00553 }
00554 i--;
00555 }
00556 i = left;
00557 while (i < bt->num[t]) {
00558 tmp = bt->rw[t][i];
00559 if (tmp->wid != wkey) break;
00560 #ifdef WORD_GRAPH
00561
00562 if (!tmp->within_wordgraph) {
00563 i++; continue;
00564 }
00565 #endif
00566 if (maxscore < tmp->backscore) {
00567 maxscore = tmp->backscore;
00568 maxtre = tmp;
00569 }
00570 i++;
00571 }
00572 tmp = maxtre;
00573 #else
00574 #ifdef WORD_GRAPH
00575
00576 if (! tmp->within_wordgraph) {
00577 return NULL;
00578 }
00579 #endif
00580 #endif
00581
00582 return(tmp);
00583 } else {
00584 return(NULL);
00585 }
00586 }
00587
00588