📄 vithist.c
字号:
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); dict = kbcore_dict (kbc); 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,dict_finishwid(dict)); 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, 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;}int32 vithist_partialutt_end (vithist_t *vh, kbcore_t *kbc){ int32 f, i, b, l; int32 sv, nsv, scr, bestscore, bestvh; vithist_entry_t *ve, *bestve; 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 exits from in block with last frame= %d\n",vh->n_frm-1); return -1; } /* Terminate in a final </s> node (make this optional?) */ lm = kbcore_lm (kbc); dict = kbcore_dict (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, dict_finishwid(dict)); if (bestscore < scr) { bestscore = scr; bestvh = i; bestve = ve; } } return bestvh;}void vithist_utt_reset (vithist_t *vh){ int32 b; vithist_lmstate_reset (vh); for (b = VITHIST_ID2BLK(vh->n_entry-1); b >= 0; --b) { ckd_free ((void *) vh->entry[b]); vh->entry[b] = NULL; } vh->n_entry = 0; vh->bestscore[0] = MAX_NEG_INT32; vh->bestvh[0] = -1;}#if 0static void vithist_lmstate_subtree_dump (vithist_t *vh, kbcore_t *kbc, vh_lmstate2vithist_t *lms2vh, int32 level, FILE *fp){ gnode_t *gn; vh_lmstate2vithist_t *child; int32 i; lm_t *lm; lm = kbcore_lm (kbc); for (gn = lms2vh->children; gn; gn = gnode_next(gn)) { child = (vh_lmstate2vithist_t *) gnode_ptr (gn); for (i = 0; i < level; i++) fprintf (fp, "\t"); fprintf (fp, "\t%s -> %d\n", lm_wordstr(lm, child->state), child->vhid); vithist_lmstate_subtree_dump (vh, kbc, child, level+1, fp); }}static void vithist_lmstate_dump (vithist_t *vh, kbcore_t *kbc, FILE *fp){ glist_t gl; gnode_t *lgn, *gn; int32 i; vh_lmstate2vithist_t *lms2vh; mdef_t *mdef; lm_t *lm; mdef = kbcore_mdef (kbc); lm = kbcore_lm (kbc); fprintf (fp, "LMSTATE\n"); for (lgn = vh->lwidlist; lgn; lgn = gnode_next(lgn)) { i = (int32) gnode_int32 (lgn); gl = vh->lmstate_root[i]; assert (gl); for (gn = gl; gn; gn = gnode_next(gn)) { lms2vh = (vh_lmstate2vithist_t *) gnode_ptr (gn); fprintf (fp, "\t%s.%s -> %d\n", lm_wordstr(lm, i), mdef_ciphone_str (mdef, lms2vh->state), lms2vh->vhid); vithist_lmstate_subtree_dump (vh, kbc, lms2vh, 1, fp); } } fprintf (fp, "END_LMSTATE\n"); fflush (fp);}#endifvoid vithist_dump (vithist_t *vh, int32 frm, kbcore_t *kbc, FILE *fp){ int32 b, l, i, j; dict_t *dict; lm_t *lm; vithist_entry_t *ve; s3lmwid_t lwid; int32 sf, ef; dict = kbcore_dict (kbc); lm = kbcore_lm (kbc); if (frm >= 0) { sf = frm; ef = frm; fprintf (fp, "VITHIST frame %d #entries %d\n", frm, vh->frame_start[sf+1] - vh->frame_start[sf]); } else { sf = 0; ef = vh->n_frm - 1; fprintf (fp, "VITHIST #frames %d #entries %d\n", vh->n_frm, vh->n_entry); } fprintf (fp, "\t%7s %5s %5s %11s %9s %8s %7s %4s Word (LM-state)\n", "Seq/Val", "SFrm", "EFrm", "PathScr", "SegAScr", "SegLScr", "Pred", "Type"); for (i = sf; i <= ef; i++) { fprintf (fp, "%5d BS: %11d BV: %8d\n", i, vh->bestscore[i], vh->bestvh[i]); for (j = vh->frame_start[i]; j < vh->frame_start[i+1]; j++) { /* This entry */ b = VITHIST_ID2BLK(j); l = VITHIST_ID2BLKOFFSET (j); ve = vh->entry[b] + l; fprintf (fp, "\t%c%6d %5d %5d %11d %9d %8d %7d %4d %s", (ve->valid ? ' ' : '*'), j, ve->sf, ve->ef, ve->score, ve->ascr, ve->lscr, ve->pred, ve->type, dict_wordstr (dict, ve->wid)); fprintf (fp, " (%s", lm_wordstr (lm, ve->lmstate.lm3g.lwid[0])); lwid = ve->lmstate.lm3g.lwid[1]; if (IS_S3LMWID(lwid)) fprintf (fp, ", %s", lm_wordstr (lm, lwid)); fprintf (fp, ")\n"); } if (j == vh->frame_start[i]) fprintf (fp, "\n"); }#if 0 if (vh->lwidlist) vithist_lmstate_dump (vh, kbc, fp);#endif fprintf (fp, "END_VITHIST\n"); fflush (fp);}glist_t vithist_backtrace (vithist_t *vh, int32 id){ vithist_entry_t *ve; int32 b, l; glist_t hyp; hyp_t *h; hyp = NULL; while (id > 0) { b = VITHIST_ID2BLK(id); l = VITHIST_ID2BLKOFFSET(id); ve = vh->entry[b] + l; h = (hyp_t *) ckd_calloc (1, sizeof(hyp_t)); h->id = ve->wid; h->sf = ve->sf; h->ef = ve->ef; h->ascr = ve->ascr; h->lscr = ve->lscr; h->type = ve->type; h->vhid = id; hyp = glist_add_ptr (hyp, h); id = ve->pred; } return hyp;}typedef struct { s3wid_t wid; int32 fef, lef; int32 seqid; /* Node sequence no. */ glist_t velist; /* Vithist entries for this dagnode */} dagnode_t;/* * Header written BEFORE this function is called. */void vithist_dag_write (vithist_t *vh, glist_t hyp, dict_t *dict, int32 oldfmt, FILE *fp){ glist_t *sfwid; /* To maintain <start-frame, word-id> pair dagnodes */ vithist_entry_t *ve, *ve2; gnode_t *gn, *gn2, *gn3; dagnode_t *dn, *dn2; int32 sf, ef, n_node; int32 f, i; hyp_t *h; sfwid = (glist_t *) ckd_calloc (vh->n_frm+1, sizeof(glist_t)); n_node = 0; for (i = 0; i < vh->n_entry; i++) { /* This range includes the dummy <s> and </s> entries */ ve = vh->entry[VITHIST_ID2BLK(i)] + VITHIST_ID2BLKOFFSET(i); if (! ve->valid) continue; /* * The initial <s> entry (at 0) is a dummy, with start/end frame = -1. But the old S3 * code treats it like a real word, so we have to reintroduce it in the dag file with * a start time of 0. And shift the start time of words starting at frame 0 up by 1. * MAJOR HACK!! */ if (ve->sf <= 0) { assert (ve->sf >= -1); assert ((ve->ef == -1) || (ve->ef > 1)); sf = ve->sf + 1; ef = (ve->ef < 0) ? 0 : ve->ef; } else { sf = ve->sf; ef = ve->ef; } for (gn = sfwid[sf]; gn; gn = gnode_next(gn)) { dn = (dagnode_t *) gnode_ptr(gn); if (dn->wid == ve->wid) break; } if (! gn) { dn = (dagnode_t *) ckd_calloc (1, sizeof(dagnode_t)); dn->wid = ve->wid; dn->fef = ef; dn->lef = ef; dn->seqid = -1; /* Initially all invalid, selected ones validated below */ dn->velist = NULL; n_node++; sfwid[sf] = glist_add_ptr (sfwid[sf], (void *) dn); } else { dn->lef = ef; } /* * Check if an entry already exists under dn->velist (generated by a different * LM context; retain only the best scoring one. */ for (gn = dn->velist; gn; gn = gnode_next(gn)) { ve2 = (vithist_entry_t *) gnode_ptr (gn); if (ve2->ef == ve->ef) break; } if (gn) { if (ve->score > ve2->score) gnode_ptr(gn) = (void *)ve; } else dn->velist = glist_add_ptr (dn->velist, (void *) ve); } /* * Validate segments with >1 end times; if only 1 end time, can be pruned. * But keep segments in the original hypothesis, regardless; mark them first. */ for (gn = hyp; gn; gn = gnode_next(gn)) { h = (hyp_t *) gnode_ptr (gn); for (gn2 = sfwid[h->sf]; gn2; gn2 = gnode_next(gn2)) { dn = (dagnode_t *) gnode_ptr (gn2); if (h->id == dn->wid) dn->seqid = 0; /* Do not discard (prune) this dagnode */ } } /* Validate startwid and finishwid nodes */ dn = (dagnode_t *) gnode_ptr(sfwid[0]); assert (dn->wid == dict_startwid(dict)); dn->seqid = 0; dn = (dagnode_t *) gnode_ptr(sfwid[vh->n_frm]); assert (dn->wid == dict_finishwid(dict)); dn->seqid = 0; /* Now prune dagnodes with only 1 end frame if not validated above */ i = 0; for (f = vh->n_frm; f >= 0; --f) { for (gn = sfwid[f]; gn; gn = gnode_next(gn)) { dn = (dagnode_t *) gnode_ptr(gn); if ((dn->lef > dn->fef) || (dn->seqid >= 0)) dn->seqid = i++; else dn->seqid = -1; /* Flag: discard */ } } n_node = i; /* Write nodes info; the header should have been written before this function is called */ fprintf (fp, "Nodes %d (NODEID WORD STARTFRAME FIRST-ENDFRAME LAST-ENDFRAME)\n", n_node); for (f = vh->n_frm; f >= 0; --f) { for (gn = sfwid[f]; gn; gn = gnode_next(gn)) { dn = (dagnode_t *) gnode_ptr(gn); if (dn->seqid >= 0) { fprintf (fp, "%d %s %d %d %d\n", dn->seqid, dict_wordstr(dict, dn->wid), f, dn->fef, dn->lef); } } } fprintf (fp, "#\n"); fprintf (fp, "Initial %d\nFinal %d\n", n_node-1, 0); fprintf (fp, "#\n"); fprintf (fp, "BestSegAscr 0 (NODEID ENDFRAME ASCORE)\n"); fprintf (fp, "#\n"); /* Edges */ if (oldfmt) fprintf (fp, "Edges (FROM-NODEID TO-NODEID ASCORE)\n"); else fprintf (fp, "Edges (FROM-NODEID ENDFRAME ASCORE)\n"); for (f = vh->n_frm-1; f >= 0; --f) { for (gn = sfwid[f]; gn; gn = gnode_next(gn)) { dn = (dagnode_t *) gnode_ptr(gn); /* Look for transitions from this dagnode to later ones, if not discarded */ if (dn->seqid < 0) continue; for (gn2 = dn->velist; gn2; gn2 = gnode_next(gn2)) { ve = (vithist_entry_t *) gnode_ptr (gn2); sf = (ve->ef < 0) ? 1 : (ve->ef + 1); if (oldfmt) { for (gn3 = sfwid[sf]; gn3; gn3 = gnode_next(gn3)) { dn2 = (dagnode_t *) gnode_ptr(gn3); if (dn2->seqid >= 0) fprintf (fp, "%d %d %d\n", dn->seqid, dn2->seqid, ve->ascr); } } else { for (gn3 = sfwid[sf]; gn3; gn3 = gnode_next(gn3)) { dn2 = (dagnode_t *) gnode_ptr(gn3); if (dn2->seqid >= 0) { fprintf (fp, "%d %d %d\n", dn->seqid, sf-1, ve->ascr); break; } } } } } } fprintf (fp, "End\n"); /* Free dagnodes structure */ for (f = 0; f <= vh->n_frm; f++) { for (gn = sfwid[f]; gn; gn = gnode_next(gn)) { dn = (dagnode_t *) gnode_ptr(gn); glist_free (dn->velist); ckd_free ((void *) dn); } glist_free (sfwid[f]); } ckd_free ((void *) sfwid);}/* * RAH, free memory allocated in vithist_free */void vithist_free (vithist_t *v){ if (v) { ckd_free ((void *) v); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -