int32 vithist_utt_end(vithist_t * vh, ngram_model_t *lm, s3dict_t *dict, dict2pid_t *dict2pid, fillpen_t *fp) { int32 f, i; int32 sv, nsv, scr, bestscore, bestvh, vhid; vithist_entry_t *ve, *bestve = 0; int32 endwid = NGRAM_INVALID_WID; bestscore = MAX_NEG_INT32; bestvh = -1; /* Find last frame with entries in vithist table */ /* by ARCHAN 20050525, it is possible that the last frame will not be reached in decoding */ for (f = vh->n_frm - 1; f >= 0; --f) { sv = vh->frame_start[f]; /* First vithist entry in frame f */ nsv = vh->frame_start[f + 1]; /* First vithist entry in next frame (f+1) */ if (sv < nsv) break; } if (f < 0) return -1; if (f != vh->n_frm - 1) E_WARN("No word exit in frame %d, using exits from frame %d\n", vh->n_frm - 1, f); /* Terminate in a final </s> node (make this optional?) */ endwid = ngram_wid(lm, S3_FINISH_WORD); for (i = sv; i < nsv; i++) { int n_used; ve = vithist_id2entry(vh, i); scr = ve->path.score; scr += ngram_tg_score(lm, endwid, ve->lmstate.lm3g.lwid[0], ve->lmstate.lm3g.lwid[1], &n_used); if (bestscore < scr) { bestscore = scr; bestvh = i; bestve = ve; } } assert(bestvh >= 0); if (f != vh->n_frm - 1) { E_ERROR("No word exit in frame %d, using exits from frame %d\n", vh->n_frm - 1, f); /* Add a dummy silwid covering the remainder of the utterance */ assert(vh->frame_start[vh->n_frm - 1] == vh->frame_start[vh->n_frm]); vh->n_frm -= 1; vithist_rescore(vh, lm, dict, dict2pid, fp, s3dict_silwid(dict), vh->n_frm, bestve->path.score, bestvh, -1, -1); vh->n_frm += 1; vh->frame_start[vh->n_frm] = vh->n_entry; return vithist_utt_end(vh, lm, dict, dict2pid, fp); } /* vithist_dump(vh,-1,kbc,stdout); */ /* Create an </s> entry */ ve = vithist_entry_alloc(vh); ve->wid = s3dict_finishwid(dict); ve->sf = (bestve->ef == BAD_S3FRMID) ? 0 : bestve->ef + 1; ve->ef = vh->n_frm; ve->ascr = 0; ve->lscr = bestscore - bestve->path.score; ve->path.score = bestscore; ve->path.pred = bestvh; ve->type = 0; ve->valid = 1; ve->lmstate.lm3g.lwid[0] = endwid; ve->lmstate.lm3g.lwid[1] = ve->lmstate.lm3g.lwid[0]; vhid = vh->n_entry - 1; /* vithist_dump(vh,-1,kbc,stdout); */ return vhid; }
int32 vithist_utt_end (vithist_t *vh, kbcore_t *kbc) { int32 f, i, b, l; int32 sv, nsv, scr, bestscore, bestvh, vhid; vithist_entry_t *ve, *bestve=0; s3lmwid_t endwid; lm_t *lm; dict_t *dict; /* Find last frame with entries in vithist table */ for (f = vh->n_frm-1; f >= 0; --f) { sv = vh->frame_start[f]; /* First vithist entry in frame f */ nsv = vh->frame_start[f+1]; /* First vithist entry in next frame (f+1) */ if (sv < nsv) break; } if (f < 0) return -1; if (f != vh->n_frm-1) E_ERROR("No word exit in frame %d, using exits from frame %d\n", vh->n_frm-1, f); /* Terminate in a final </s> node (make this optional?) */ lm = kbcore_lm (kbc); endwid = lm_finishwid (lm); bestscore = MAX_NEG_INT32; bestvh = -1; for (i = sv; i < nsv; i++) { b = VITHIST_ID2BLK (i); l = VITHIST_ID2BLKOFFSET (i); ve = vh->entry[b] + l; scr = ve->score; scr += lm_tg_score (lm, ve->lmstate.lm3g.lwid[1], ve->lmstate.lm3g.lwid[0], endwid); if (bestscore < scr) { bestscore = scr; bestvh = i; bestve = ve; } } assert (bestvh >= 0); dict = kbcore_dict (kbc); if (f != vh->n_frm-1) { E_ERROR("No word exit in frame %d, using exits from frame %d\n", vh->n_frm-1, f); /* Add a dummy silwid covering the remainder of the utterance */ assert (vh->frame_start[vh->n_frm-1] == vh->frame_start[vh->n_frm]); vh->n_frm -= 1; vithist_rescore (vh, kbc, dict_silwid (dict), vh->n_frm, bestve->score, bestvh, -1); vh->n_frm += 1; vh->frame_start[vh->n_frm] = vh->n_entry; return vithist_utt_end (vh, kbc); } /* Create an </s> entry */ vhid = vh->n_entry; ve = vithist_entry_alloc (vh); ve->wid = dict_finishwid (dict); ve->sf = (bestve->ef == BAD_S3FRMID) ? 0 : bestve->ef + 1; ve->ef = vh->n_frm; ve->ascr = 0; ve->lscr = bestscore - bestve->score; ve->score = bestscore; ve->pred = bestvh; ve->type = 0; ve->valid = 1; ve->lmstate.lm3g.lwid[0] = endwid; ve->lmstate.lm3g.lwid[1] = ve->lmstate.lm3g.lwid[0]; return vhid; }