📄 fsg_search.c
字号:
search->frame = -1; search->bestscore = 0; fsg_history_entry_add(search->history, NULL, -1, 0, -1, silcipid, ctxt); search->bpidx_start = 0; /* Propagate dummy history entry through NULL transitions from start state */ fsg_search_null_prop(search); /* Perform word transitions from this dummy history entry */ fsg_search_word_trans(search); /* Make the next-frame active list the current one */ search->pnode_active = search->pnode_active_next; search->pnode_active_next = NULL; (search->frame)++; fsg_search_hyp_free(search); search->n_hmm_eval = 0; search->n_sen_eval = 0; search->state = FSG_SEARCH_BUSY;}static voidfsg_search_hyp_dump(fsg_search_t * search, FILE * fp){ search_hyp_t *hyp; int32 nf; /* Print backtrace */ fprintf(fp, "\t%4s %4s %10s %11s %9s %11s %10s %6s %s (FSG) (%s)\n", "SFrm", "EFrm", "AScr/Frm", "AScr", "LScr", "AScr+LScr", "(A-BS)/Frm", "State", "Word", uttproc_get_uttid()); fprintf(fp, "\t-------------------------------------------------------------------------------\n"); for (hyp = search->hyp; hyp; hyp = hyp->next) { nf = hyp->ef - hyp->sf + 1; fprintf(fp, "\t%4d %4d %10d %11d %9d %11d %10d %6d %s\n", hyp->sf, hyp->ef, (nf > 0) ? hyp->ascr / nf : 0, hyp->ascr, hyp->lscr, hyp->ascr + hyp->lscr, ((nf > 0) && (hyp-> ascr != 0)) ? (seg_topsen_score(hyp->sf, hyp->ef) - hyp->ascr) / nf : 0, hyp->fsg_state, hyp->word); } fprintf(fp, "\t-------------------------------------------------------------------------------\n"); fprintf(fp, "\t%4d %4d %10d %11d %9d %11d %10d %6dF %s(TOTAL)\n", 0, search->frame - 1, (search->frame > 0) ? (search->ascr / search->frame) : 0, search->ascr, search->lscr, search->ascr + search->lscr, (search->frame > 0) ? (seg_topsen_score(0, search->frame - 1) - search->ascr) / search->frame : 0, word_fsg_final_state(search->fsg), uttproc_get_uttid()); fflush(fp);}/* Fill in hyp_str in search.c; filtering out fillers and null trans */static voidfsg_search_hyp_filter(fsg_search_t * search){ search_hyp_t *hyp, *filt_hyp; int32 i; int32 startwid, finishwid; int32 altpron; filt_hyp = search_get_hyp(); startwid = kb_get_word_id(cmd_ln_str("-lmstartsym")); finishwid = kb_get_word_id(cmd_ln_str("-lmendsym")); altpron = cmd_ln_boolean("-reportpron"); i = 0; for (hyp = search->hyp; hyp; hyp = hyp->next) { if ((hyp->wid < 0) || (hyp->wid == startwid) || (hyp->wid >= finishwid)) continue; /* Copy this hyp entry to filtered result */ filt_hyp[i] = *hyp; /* Replace specific word pronunciation ID with base ID */ if (!altpron) filt_hyp[i].wid = dictid_to_baseid(word_dict, filt_hyp[i].wid); i++; if ((i + 1) >= HYP_SZ) E_FATAL("Hyp array overflow; increase HYP_SZ in search.h\n"); } filt_hyp[i].wid = -1; /* Sentinel */}/* * Push result into old search module, from where we can obtain the result * using the old API. */static voidfsg_search_set_result(fsg_search_t * search){ fsg_search_hyp_filter(search); searchSetFrame(search->frame); search_set_hyp_wid(search->hyp); search_hyp_to_str(); search_set_hyp_total_score(search->ascr + search->lscr); search_set_hyp_total_lscr(search->lscr);}voidfsg_search_history_backtrace(fsg_search_t * search, boolean check_fsg_final_state){ word_fsg_t *fsg; fsg_hist_entry_t *hist_entry; word_fsglink_t *fl; int32 bestscore, bestscore_finalstate, besthist_finalstate, besthist; int32 bpidx, score, frm, last_frm; search_hyp_t *hyp, *head; /* Free any existing search hypothesis */ fsg_search_hyp_free(search); search->ascr = 0; search->lscr = 0; fsg = search->fsg; /* Find most recent bestscoring history entry */ bpidx = fsg_history_n_entries(search->history) - 1; if (bpidx > 0) { hist_entry = fsg_history_entry_get(search->history, bpidx); last_frm = frm = fsg_hist_entry_frame(hist_entry); assert(frm < search->frame); } else { hist_entry = NULL; last_frm = frm = -1; } if ((bpidx <= 0) || (last_frm < 0)) { /* Only the dummy root entry, or null transitions from it, exist */ if (check_fsg_final_state) E_WARN("Empty utterance: %s\n", uttproc_get_uttid()); /* Set result (empty recognition) in backward compatible format */ fsg_search_set_result(search); return; } if (check_fsg_final_state) { if (frm < (search->frame - 1)) { E_WARN ("No history entry in the final frame %d; using last entry at frame %d\n", search->frame - 1, frm); } } /* * Find best history entry, as well as best entry leading to FSG final state * in final frame. */ bestscore = bestscore_finalstate = (int32) 0x80000000; besthist = besthist_finalstate = -1; while (frm == last_frm) { fl = fsg_hist_entry_fsglink(hist_entry); score = fsg_hist_entry_score(hist_entry); if (word_fsglink_to_state(fl) == word_fsg_final_state(fsg)) { if (score > bestscore_finalstate) { bestscore_finalstate = score; besthist_finalstate = bpidx; } } if (score > bestscore) { bestscore = score; besthist = bpidx; } --bpidx; if (bpidx < 0) break; hist_entry = fsg_history_entry_get(search->history, bpidx); frm = fsg_hist_entry_frame(hist_entry); } if (check_fsg_final_state) { if (besthist_finalstate > 0) { /* * Final state entry found; discard the plain best entry. * (Policy decision! Is this the right thing to do??) */ if (bestscore > bestscore_finalstate) E_INFO ("Best score (%d) > best final state score (%d); but using latter\n", bestscore, bestscore_finalstate); bestscore = bestscore_finalstate; besthist = besthist_finalstate; } else E_ERROR ("Final state not reached; backtracing from best scoring entry\n"); } /* Backtrace through the search history, starting from besthist */ head = NULL; for (bpidx = besthist; bpidx > 0;) { hist_entry = fsg_history_entry_get(search->history, bpidx); hyp = (search_hyp_t *) ckd_calloc(1, sizeof(search_hyp_t)); if (fsg_history_entry_hyp_extract(search->history, bpidx, hyp) <= 0) E_FATAL("fsg_history_entry_hyp_extract() returned <= 0\n"); hyp->next = head; head = hyp; search->lscr += hyp->lscr; search->ascr += hyp->ascr; bpidx = fsg_hist_entry_pred(hist_entry); } search->hyp = head; /* For backward compatibility with existing API for obtaining results */ fsg_search_set_result(search);}/* * Cleanup at the end of each utterance. */voidfsg_search_utt_end(fsg_search_t * search){ gnode_t *gn; fsg_pnode_t *pnode; CHAN_T *hmm; int32 n_hist, nfr; char *result; FILE *latfp; char file[4096]; /* Write history table if needed */ if (cmd_ln_str("-dumplatdir")) { sprintf(file, "%s/%s.hist", cmd_ln_str("-dumplatdir"), uttproc_get_uttid()); if ((latfp = fopen(file, "w")) == NULL) E_ERROR("fopen(%s,w) failed\n", file); else { fsg_history_dump(search->history, uttproc_get_uttid(), latfp); fclose(latfp); } } /* * Backtrace through Viterbi history to get the best recognition. * First check if the final state has been reached; otherwise just use * the best scoring state. */ fsg_search_history_backtrace(search, cmd_ln_boolean("-fsgbfs")); if (cmd_ln_boolean("-backtrace")) fsg_search_hyp_dump(search, stdout); search_result(&nfr, &result); printf("FSGSRCH: %s (%s %d (A=%d L=%d))\n", result, uttproc_get_uttid(), search->ascr + search->lscr, search->ascr, search->lscr); fflush(stdout); n_hist = fsg_history_n_entries(search->history); fsg_history_reset(search->history); fsg_lextree_utt_end(search->lextree); /* Deactivate all nodes in the current and next-frame active lists */ for (gn = search->pnode_active; gn; gn = gnode_next(gn)) { pnode = (fsg_pnode_t *) gnode_ptr(gn); hmm = fsg_pnode_hmmptr(pnode); fsg_psubtree_pnode_deactivate(pnode); } for (gn = search->pnode_active_next; gn; gn = gnode_next(gn)) { pnode = (fsg_pnode_t *) gnode_ptr(gn); hmm = fsg_pnode_hmmptr(pnode); fsg_psubtree_pnode_deactivate(pnode); } glist_free(search->pnode_active); search->pnode_active = NULL; glist_free(search->pnode_active_next); search->pnode_active_next = NULL; /* Do NOT reset search->frame, or search->hyp */ search->state = FSG_SEARCH_IDLE; E_INFO ("Utt %s: %d frames, %d HMMs (%d/fr), %d senones (%d/fr), %d history entries (%d/fr)\n\n", uttproc_get_uttid(), search->frame, search->n_hmm_eval, (search->frame > 0) ? search->n_hmm_eval / search->frame : 0, search->n_sen_eval, (search->frame > 0) ? search->n_sen_eval / search->frame : 0, n_hist, (search->frame > 0) ? n_hist / search->frame : 0); /* Sanity check */ if (search->n_hmm_eval > fsg_lextree_n_pnode(search->lextree) * search->frame) { E_ERROR ("SANITY CHECK #HMMEval(%d) > %d (#HMMs(%d)*#frames(%d)) FAILED\n", search->n_hmm_eval, fsg_lextree_n_pnode(search->lextree) * search->frame, fsg_lextree_n_pnode(search->lextree), search->frame); }}int32fsg_search_get_start_state(fsg_search_t * search){ if ((!search) || (!search->fsg)) return -1; return word_fsg_start_state(search->fsg);}int32fsg_search_get_final_state(fsg_search_t * search){ if ((!search) || (!search->fsg)) return -1; return word_fsg_final_state(search->fsg);}int32fsg_search_set_start_state(fsg_search_t * search, int32 state){ if (!search) return -1; if (search->state != FSG_SEARCH_IDLE) { E_ERROR("Attempt to switch FSG start state inside an utterance\n"); return -1; } return (word_fsg_set_start_state(search->fsg, state));}int32fsg_search_set_final_state(fsg_search_t * search, int32 state){ if (!search) return -1; if (search->state != FSG_SEARCH_IDLE) { E_ERROR("Attempt to switch FSG start state inside an utterance\n"); return -1; } return (word_fsg_set_final_state(search->fsg, state));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -