📄 search.c
字号:
static int32 TotalLangScore;static int32 hyp_alternates = FALSE;static WORD_ID *single_phone_wid; /* list of single-phone word ids */static int32 n_1ph_words; /* #single phone words in dict (total) */static int32 n_1ph_LMwords; /* #single phone dict words also in LM; these come first in single_phone_wid */static void seg_back_trace(int32, char const *);static void renormalize_scores(int32);static void fwdflat_renormalize_scores(int32);static int32 renormalized;static int32 skip_alt_frm = 0;/* * Two word context prior to utterance, to be used instead of <s>. Faked by entering * <s> and the context into BPTable before starting search (see search_start_fwd). * If no context, both should be -ve; if only one context word, [1] should be -ve. */static int32 context_word[2];#if 0static dump_search_tree_root();static dump_search_tree();#endif/* * Declarations for ci-phone prediction based on top senones (applied only if * topsen_window > 1). In each frame, lookahead topsen_window frames and pick the best * senones (i.e. senones within topsen_thresh of best senone in respective frames). * It is the potential set of future active phones. So restrict phone transitions in * the current frame to this set. (But filler phones are always active.) */static int32 topsen_window = 1; /* Lookahead window of frames over which top senones used to predict ciphones. No prediction if topsen_window == 1 */static int32 n_topsen_frm = 0; /* #frames evaluated so far (lookahead version of CurrentFrame) */static int32 topsen_thresh = -60000; /* Threshold for determining active phones from top senone (initial value is a HACK!!) */static int32 **npa_frm; /* per frame next-phone-active[ciphone] flag, as determined by top senones */static int32 *npa; /* npa_frm summed over topsen_window; next-phone-active flag for activating phone transitions. */static int32 *filler_phone; /* filler_phone[p] = 1 iff p is filler */static int32 *topsen_score; /* Top senone score in each frame */static int32 *bestpscr; /* Best senone score within each phone in frame */static void topsen_init(void);static void compute_phone_active(int32 topsenscr, int32 npa_th);int32context_frames(void){ if (context_word[0] < 0) return 0; if (context_word[1] < 0) return 2; return 3;}/* * Candidates words for entering their last phones. Cleared and rebuilt in each * frame. * NOTE: candidates can only be multi-phone, real dictionary words. */typedef struct lastphn_cand_s { int32 wid; int32 score; int32 bp; int32 next; /* next candidate starting at the same frame */} lastphn_cand_t;static lastphn_cand_t *lastphn_cand;static int32 n_lastphn_cand;/* Get senone indices and scores */#define mpx_sseq2sen(c,ss,st) \ (c->sseqid[ss] == -1 ? -1 : bin_mdef_sseq2sen(mdef, c->sseqid[ss], st))#define mpx_sseq2score(c,ss,st) \ (c->sseqid[ss] == -1 ? WORST_SCORE : senone_scores[mpx_sseq2sen(c,ss,st)])/* Node probability plus transition probability */#define NPA(tp,score,from,to) ((score) + tp[from][to])voidroot_chan_v_mpx_eval(ROOT_CHAN_T * chan){ int32 bestScore; int32 s5, s4, s3, s2, s1, s0, t2, t1, t0; int32 **tp; tp = tmat->tp[chan->ciphone]; /* Don't propagate WORST_SCORE */ if (chan->sseqid[4] == -1) s4 = t1 = WORST_SCORE; else { s4 = chan->score[4] + mpx_sseq2score(chan, 4, 4); t1 = NPA(tp, s4, 4, 5); } if (chan->sseqid[3] == -1) s3 = t2 = WORST_SCORE; else { s3 = chan->score[3] + mpx_sseq2score(chan, 3, 3); t2 = NPA(tp, s3, 3, 5); } if (t1 > t2) { s5 = t1; chan->path[5] = chan->path[4]; } else { s5 = t2; chan->path[5] = chan->path[3]; } chan->score[5] = s5; bestScore = s5; /* Don't propagate WORST_SCORE */ if (chan->sseqid[2] == -1) s2 = t2 = WORST_SCORE; else { s2 = chan->score[2] + mpx_sseq2score(chan, 2, 2); t2 = NPA(tp, s2, 2, 4); } t0 = t1 = WORST_SCORE; if (s4 != WORST_SCORE) t0 = NPA(tp, s4, 4, 4); if (s3 != WORST_SCORE) t1 = NPA(tp, s3, 3, 4); if (t0 > t1) { if (t2 > t0) { s4 = t2; chan->path[4] = chan->path[2]; chan->sseqid[4] = chan->sseqid[2]; } else s4 = t0; } else { if (t2 > t1) { s4 = t2; chan->path[4] = chan->path[2]; chan->sseqid[4] = chan->sseqid[2]; } else { s4 = t1; chan->path[4] = chan->path[3]; chan->sseqid[4] = chan->sseqid[3]; } } if (s4 > bestScore) bestScore = s4; chan->score[4] = s4; /* Don't propagate WORST_SCORE */ if (chan->sseqid[1] == -1) s1 = t2 = WORST_SCORE; else { s1 = chan->score[1] + mpx_sseq2score(chan, 1, 1); t2 = NPA(tp, s1, 1, 3); } t0 = t1 = WORST_SCORE; if (s3 != WORST_SCORE) t0 = NPA(tp, s3, 3, 3); if (s2 != WORST_SCORE) t1 = NPA(tp, s2, 2, 3); if (t0 > t1) { if (t2 > t0) { s3 = t2; chan->path[3] = chan->path[1]; chan->sseqid[3] = chan->sseqid[1]; } else s3 = t0; } else { if (t2 > t1) { s3 = t2; chan->path[3] = chan->path[1]; chan->sseqid[3] = chan->sseqid[1]; } else { s3 = t1; chan->path[3] = chan->path[2]; chan->sseqid[3] = chan->sseqid[2]; } } if (s3 > bestScore) bestScore = s3; chan->score[3] = s3; s0 = chan->score[0] + mpx_sseq2score(chan, 0, 0); /* Don't propagate WORST_SCORE */ t0 = t1 = WORST_SCORE; if (s2 != WORST_SCORE) t0 = NPA(tp, s2, 2, 2); if (s1 != WORST_SCORE) t1 = NPA(tp, s1, 1, 2); t2 = NPA(tp, s0, 0, 2); if (t0 > t1) { if (t2 > t0) { s2 = t2; chan->path[2] = chan->path[0]; chan->sseqid[2] = chan->sseqid[0]; } else s2 = t0; } else { if (t2 > t1) { s2 = t2; chan->path[2] = chan->path[0]; chan->sseqid[2] = chan->sseqid[0]; } else { s2 = t1; chan->path[2] = chan->path[1]; chan->sseqid[2] = chan->sseqid[1]; } } if (s2 > bestScore) bestScore = s2; chan->score[2] = s2; /* Don't propagate WORST_SCORE */ t0 = WORST_SCORE; if (s1 != WORST_SCORE) t0 = NPA(tp, s1, 1, 1); t1 = NPA(tp, s0, 0, 1); if (t0 > t1) { s1 = t0; } else { s1 = t1; chan->path[1] = chan->path[0]; chan->sseqid[1] = chan->sseqid[0]; } if (s1 > bestScore) bestScore = s1; chan->score[1] = s1; s0 = NPA(tp, s0, 0, 0); if (s0 > bestScore) bestScore = s0; chan->score[0] = s0; chan->bestscore = bestScore;}#define nmpx_sseq2score(ssid,st) \ (senone_scores[bin_mdef_sseq2sen(mdef, ssid, st)])#define CHAN_V_EVAL(chan,ssid,tp) { \ int32 bestScore; \ int32 s5, s4, s3, s2, s1, s0, t2, t1, t0; \ \ s4 = chan->score[4] + nmpx_sseq2score(ssid, 4); \ s3 = chan->score[3] + nmpx_sseq2score(ssid, 3); \ t1 = NPA(tp,s4,4,5); \ t2 = NPA(tp,s3,3,5); \ if (t1 > t2) { \ s5 = t1; \ chan->path[5] = chan->path[4]; \ } else { \ s5 = t2; \ chan->path[5] = chan->path[3]; \ } \ chan->score[5] = s5; \ bestScore = s5; \ \ s2 = chan->score[2] + nmpx_sseq2score(ssid, 2); \ t0 = NPA(tp,s4,4,4); \ t1 = NPA(tp,s3,3,4); \ t2 = NPA(tp,s2,2,4); \ if (t0 > t1) { \ if (t2 > t0) { \ s4 = t2; \ chan->path[4] = chan->path[2]; \ } else \ s4 = t0; \ } else { \ if (t2 > t1) { \ s4 = t2; \ chan->path[4] = chan->path[2]; \ } else { \ s4 = t1; \ chan->path[4] = chan->path[3]; \ } \ } \ if (s4 > bestScore) bestScore = s4; \ chan->score[4] = s4; \ \ s1 = chan->score[1] + nmpx_sseq2score(ssid, 1); \ t0 = NPA(tp,s3,3,3); \ t1 = NPA(tp,s2,2,3); \ t2 = NPA(tp,s1,1,3); \ if (t0 > t1) { \ if (t2 > t0) { \ s3 = t2; \ chan->path[3] = chan->path[1]; \ } else \ s3 = t0; \ } else { \ if (t2 > t1) { \ s3 = t2; \ chan->path[3] = chan->path[1]; \ } else { \ s3 = t1; \ chan->path[3] = chan->path[2]; \ } \ } \ if (s3 > bestScore) bestScore = s3; \ chan->score[3] = s3; \ \ s0 = chan->score[0] + nmpx_sseq2score(ssid, 0); \ t0 = NPA(tp,s2,2,2); \ t1 = NPA(tp,s1,1,2); \ t2 = NPA(tp,s0,0,2); \ if (t0 > t1) { \ if (t2 > t0) { \ s2 = t2; \ chan->path[2] = chan->path[0]; \ } else \ s2 = t0; \ } else { \ if (t2 > t1) { \ s2 = t2; \ chan->path[2] = chan->path[0]; \ } else { \ s2 = t1; \ chan->path[2] = chan->path[1]; \ } \ } \ if (s2 > bestScore) bestScore = s2; \ chan->score[2] = s2; \ \ t0 = NPA(tp,s1,1,1); \ t1 = NPA(tp,s0,0,1); \ if (t0 > t1) { \ s1 = t0; \ } else { \ s1 = t1; \ chan->path[1] = chan->path[0]; \ } \ if (s1 > bestScore) bestScore = s1; \ chan->score[1] = s1; \ \ s0 = NPA(tp,s0,0,0); \ if (s0 > bestScore) bestScore = s0; \ chan->score[0] = s0; \ \ chan->bestscore = bestScore; \} \#if __CHAN_DUMP__static voidroot_chan_dump(const char *msg, ROOT_CHAN_T * chan, int32 frame, FILE * fp){ if (chan->mpx) { fprintf(fp, "[%4d] %s CIPHONE %5d MPX (%5d %5d %5d %5d %5d)\n", frame, msg, chan->ciphone, mpx_sseq2sen(chan, 0, 0), mpx_sseq2sen(chan, 1, 1), mpx_sseq2sen(chan, 2, 2), mpx_sseq2sen(chan, 3, 3), mpx_sseq2sen(chan, 4, 4)); fprintf(fp, "\tSENSCR %11d %11d %11d %11d %11d\n", mpx_sseq2score(chan, 0, 0), mpx_sseq2score(chan, 1, 1), mpx_sseq2score(chan, 2, 2), mpx_sseq2score(chan, 3, 3), mpx_sseq2score(chan, 4, 4)); fprintf(fp, "\tSCORES %11d %11d %11d %11d %11d %11d\n", chan->score[0], chan->score[1], chan->score[2], chan->score[3], chan->score[4], chan->score[5]); fprintf(fp, "\tPATHS %11d %11d %11d %11d %11d %11d\n", chan->path[0], chan->path[1], chan->path[2], chan->path[3], chan->path[4], chan->path[5]); } else { fprintf(fp, "[%4d] %s ROOT CIPHONE %5d SSID %5d (%5d %5d %5d %5d %5d)\n", frame, msg, chan->ciphone, chan->sseqid[0], mpx_sseq2sen(chan, 0, 0), mpx_sseq2sen(chan, 0, 1), mpx_sseq2sen(chan, 0, 2),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -