flat_fwd.c
来自「CMU大名鼎鼎的SPHINX-3大词汇量连续语音识别系统」· C语言 代码 · 共 2,212 行 · 第 1/5 页
C
2,212 行
printf ("[%4d] %-24s", n_frm, dict->word[w].word); last = dict->word[w].pronlen - 1; bestlast = (int32) 0x80000000; for (h = whmm[w]; h; h = h->next) { if (h->pos < last) printf (" %9d.%2d", -h->score[n_state-1], h->pos); else if (bestlast < h->score[n_state-1]) bestlast = h->score[n_state-1]; } if (bestlast > (int32) 0x80000000) printf (" %9d.%2d", -bestlast, last); printf ("\n"); } }}/** * Check model tprob matrices that they conform to upper-diagonal assumption. */static void chk_tp_uppertri ( void ){ int32 i, from, to; assert (n_state > 0); /* Check that each tmat is upper-triangular */ for (i = 0; i < tmat->n_tmat; i++) { for (to = 0; to < n_state-1; to++) for (from = to+1; from < n_state-1; from++) if (tmat->tp[i][from][to] > S3_LOGPROB_ZERO) E_FATAL("HMM transition matrix not upper triangular\n"); }}/** For partial evaluation of incoming state score (prev state score + senone score) */static int32 *st_sen_scr;#define ANYHMMTOPO 1#if (! ANYHMMTOPO)/** * Like the general eval_nonmpx_whmm and eval_mpx_whmm below, but hardwired for * the Sphinx-II 5-state Bakis topology. */static void eval_nonmpx_whmm (s3wid_t w, whmm_t *h, int32 *senscr){ register int32 s0, s1, s2, s3, s4; register int32 scr, newscr1, newscr2, bestscr; register int32 *tp; s3pid_t p; s3senid_t *senp; p = *(h->pid); senp = mdef->phone[p].state; tp = tmat->tp[mdef->phone[p].tmat][0]; /* HACK!! Assumes tp 2-D data allocated contiguously */ if ((s0 = h->score[0] + senscr[senp[0]]) < S3_LOGPROB_ZERO) s0 = S3_LOGPROB_ZERO; if ((s1 = h->score[1] + senscr[senp[1]]) < S3_LOGPROB_ZERO) s1 = S3_LOGPROB_ZERO; if ((s2 = h->score[2] + senscr[senp[2]]) < S3_LOGPROB_ZERO) s2 = S3_LOGPROB_ZERO; if ((s3 = h->score[3] + senscr[senp[3]]) < S3_LOGPROB_ZERO) s3 = S3_LOGPROB_ZERO; if ((s4 = h->score[4] + senscr[senp[4]]) < S3_LOGPROB_ZERO) s4 = S3_LOGPROB_ZERO; newscr1 = s4 + tp[29]; /* [4][5] */ newscr2 = s3 + tp[23]; /* [3][5] */ if (newscr1 > newscr2) { h->score[5] = bestscr = newscr1; h->history[5] = h->history[4]; } else { h->score[5] = bestscr = newscr2; h->history[5] = h->history[3]; } scr = s4 + tp[28]; /* [4][4] */ newscr1 = s3 + tp[22]; /* [3][4] */ newscr2 = s2 + tp[16]; /* [2][4] */ if (newscr2 > newscr1) { if (newscr2 > scr) { h->score[4] = newscr2; h->history[4] = h->history[2]; } else h->score[4] = scr; } else { if (newscr1 > scr) { h->score[4] = newscr1; h->history[4] = h->history[3]; } else h->score[4] = scr; } if (bestscr < h->score[4]) bestscr = h->score[4]; scr = s3 + tp[21]; /* [3][3] */ newscr1 = s2 + tp[15]; /* [2][3] */ newscr2 = s1 + tp[9]; /* [1][3] */ if (newscr2 > newscr1) { if (newscr2 > scr) { h->score[3] = newscr2; h->history[3] = h->history[1]; } else h->score[3] = scr; } else { if (newscr1 > scr) { h->score[3] = newscr1; h->history[3] = h->history[2]; } else h->score[3] = scr; } if (bestscr < h->score[3]) bestscr = h->score[3]; scr = s2 + tp[14]; /* [2][2] */ newscr1 = s1 + tp[8]; /* [1][2] */ newscr2 = s0 + tp[2]; /* [0][2] */ if (newscr2 > newscr1) { if (newscr2 > scr) { h->score[2] = newscr2; h->history[2] = h->history[0]; } else h->score[2] = scr; } else { if (newscr1 > scr) { h->score[2] = newscr1; h->history[2] = h->history[1]; } else h->score[2] = scr; } if (bestscr < h->score[2]) bestscr = h->score[2]; scr = s1 + tp[7]; /* [1][1] */ newscr1 = s0 + tp[1]; /* [0][1] */ if (newscr1 > scr) { h->score[1] = newscr1; h->history[1] = h->history[0]; } else h->score[1] = scr; if (bestscr < h->score[1]) bestscr = h->score[1]; h->score[0] = scr = s0 + tp[0]; /* [0][0] */ if (bestscr < scr) bestscr = scr; h->bestscore = bestscr;}static void eval_mpx_whmm (s3wid_t w, whmm_t *h, int32 *senscr){ register int32 s0, s1, s2, s3, s4; register int32 *tp0, *tp1, *tp2, *tp3, *tp4; register int32 scr, newscr1, newscr2, bestscr; s3senid_t *senp; s3pid_t p0, p1, p2, p3, p4; p0 = h->pid[0]; p1 = h->pid[1]; p2 = h->pid[2]; p3 = h->pid[3]; p4 = h->pid[4]; senp = mdef->phone[p0].state; if ((s0 = h->score[0] + senscr[senp[0]]) < S3_LOGPROB_ZERO) s0 = S3_LOGPROB_ZERO; tp0 = tmat->tp[mdef->phone[p0].tmat][0]; /* HACK!! See eval_nonmpx_whmm */ if (p1 != p0) { senp = mdef->phone[p1].state; tp1 = tmat->tp[mdef->phone[p1].tmat][0];/* HACK!! See eval_nonmpx_whmm */ } else tp1 = tp0; if ((s1 = h->score[1] + senscr[senp[1]]) < S3_LOGPROB_ZERO) s1 = S3_LOGPROB_ZERO; if (p2 != p1) { senp = mdef->phone[p2].state; tp2 = tmat->tp[mdef->phone[p2].tmat][0];/* HACK!! See eval_nonmpx_whmm */ } else tp2 = tp1; if ((s2 = h->score[2] + senscr[senp[2]]) < S3_LOGPROB_ZERO) s2 = S3_LOGPROB_ZERO; if (p3 != p2) { senp = mdef->phone[p3].state; tp3 = tmat->tp[mdef->phone[p3].tmat][0];/* HACK!! See eval_nonmpx_whmm */ } else tp3 = tp2; if ((s3 = h->score[3] + senscr[senp[3]]) < S3_LOGPROB_ZERO) s3 = S3_LOGPROB_ZERO; if (p4 != p3) { senp = mdef->phone[p4].state; tp4 = tmat->tp[mdef->phone[p4].tmat][0];/* HACK!! See eval_nonmpx_whmm */ } else tp4 = tp3; if ((s4 = h->score[4] + senscr[senp[4]]) < S3_LOGPROB_ZERO) s4 = S3_LOGPROB_ZERO; newscr1 = s4 + tp4[29]; /* [4][5] */ newscr2 = s3 + tp3[23]; /* [3][5] */ if (newscr1 > newscr2) { h->score[5] = bestscr = newscr1; h->history[5] = h->history[4]; } else { h->score[5] = bestscr = newscr2; h->history[5] = h->history[3]; } scr = s4 + tp4[28]; /* [4][4] */ newscr1 = s3 + tp3[22]; /* [3][4] */ newscr2 = s2 + tp2[16]; /* [2][4] */ if (newscr2 > newscr1) { if (newscr2 > scr) { h->score[4] = newscr2; h->history[4] = h->history[2]; h->pid[4] = h->pid[2]; } else h->score[4] = scr; } else { if (newscr1 > scr) { h->score[4] = newscr1; h->history[4] = h->history[3]; h->pid[4] = h->pid[3]; } else h->score[4] = scr; } if (bestscr < h->score[4]) bestscr = h->score[4]; scr = s3 + tp3[21]; /* [3][3] */ newscr1 = s2 + tp2[15]; /* [2][3] */ newscr2 = s1 + tp1[9]; /* [1][3] */ if (newscr2 > newscr1) { if (newscr2 > scr) { h->score[3] = newscr2; h->history[3] = h->history[1]; h->pid[3] = h->pid[1]; } else h->score[3] = scr; } else { if (newscr1 > scr) { h->score[3] = newscr1; h->history[3] = h->history[2]; h->pid[3] = h->pid[2]; } else h->score[3] = scr; } if (bestscr < h->score[3]) bestscr = h->score[3]; scr = s2 + tp2[14]; /* [2][2] */ newscr1 = s1 + tp1[8]; /* [1][2] */ newscr2 = s0 + tp0[2]; /* [0][2] */ if (newscr2 > newscr1) { if (newscr2 > scr) { h->score[2] = newscr2; h->history[2] = h->history[0]; h->pid[2] = h->pid[0]; } else h->score[2] = scr; } else { if (newscr1 > scr) { h->score[2] = newscr1; h->history[2] = h->history[1]; h->pid[2] = h->pid[1]; } else h->score[2] = scr; } if (bestscr < h->score[2]) bestscr = h->score[2]; scr = s1 + tp1[7]; /* [1][1] */ newscr1 = s0 + tp0[1]; /* [0][1] */ if (newscr1 > scr) { h->score[1] = newscr1; h->history[1] = h->history[0]; h->pid[1] = h->pid[0]; } else h->score[1] = scr; if (bestscr < h->score[1]) bestscr = h->score[1]; h->score[0] = scr = s0 + tp0[0]; /* [0][0] */ if (bestscr < scr) bestscr = scr; h->bestscore = bestscr;}#else/** * Evaluate non-multiplexed word HMM (ie, the entire whmm really represents one * phone rather than each state representing a potentially different phone. */static void eval_nonmpx_whmm (s3wid_t w, whmm_t *h, int32 *senscr){ s3pid_t pid; s3senid_t *sen; int32 **tp; int32 to, from, bestfrom; int32 newscr, scr, bestscr; pid = *(h->pid); sen = mdef->phone[pid].state; tp = tmat->tp[mdef->phone[pid].tmat]; /* Compute previous state-score + observation output prob for each state */ for (from = n_state-2; from >= 0; --from) { if ((st_sen_scr[from] = h->score[from] + senscr[sen[from]]) < S3_LOGPROB_ZERO) st_sen_scr[from] = S3_LOGPROB_ZERO; } /* Evaluate final-state first, which does not have a self-transition */ to = final_state; scr = S3_LOGPROB_ZERO; bestfrom = -1; for (from = to-1; from >= 0; --from) { if ((tp[from][to] > S3_LOGPROB_ZERO) && ((newscr = st_sen_scr[from] + tp[from][to]) > scr)) { scr = newscr; bestfrom = from; } } h->score[to] = scr; if (bestfrom >= 0) h->history[to] = h->history[bestfrom]; bestscr = scr; /* Evaluate all other states, which might have self-transitions */ for (to = final_state-1; to >= 0; --to) { /* Score from self-transition, if any */ scr = (tp[to][to] > S3_LOGPROB_ZERO) ? st_sen_scr[to] + tp[to][to] : S3_LOGPROB_ZERO; /* Scores from transitions from other states */ bestfrom = -1; for (from = to-1; from >= 0; --from) { if ((tp[from][to] > S3_LOGPROB_ZERO) && ((newscr = st_sen_scr[from] + tp[from][to]) > scr)) { scr = newscr; bestfrom = from; } } /* Update new result for state to */ h->score[to] = scr; if (bestfrom >= 0) h->history[to] = h->history[bestfrom]; if (bestscr < scr) bestscr = scr; } h->bestscore = bestscr;}/** Like eval_nonmpx_whmm, except there's a different pid associated with each state */static void eval_mpx_whmm (s3wid_t w, whmm_t *h, int32 *senscr){ s3pid_t pid, prevpid; s3senid_t *senp; int32 **tp; int32 to, from, bestfrom; int32 newscr, scr, bestscr; senp=NULL; tp=NULL; /* Compute previous state-score + observation output prob for each state */ prevpid = BAD_S3PID; for (from = n_state-2; from >= 0; --from) { if ((pid = h->pid[from]) != prevpid) { senp = mdef->phone[pid].state; prevpid = pid; } if ((st_sen_scr[from] = h->score[from] + senscr[senp[from]]) < S3_LOGPROB_ZERO) st_sen_scr[from] = S3_LOGPROB_ZERO; } /* Evaluate final-state first, which does not have a self-transition */ to = final_state; scr = S3_LOGPROB_ZERO; bestfrom = -1; prevpid = BAD_S3PID; for (from = to-1; from >= 0; --from) { if ((pid = h->pid[from]) != prevpid) { tp = tmat->tp[mdef->phone[pid].tmat]; prevpid = pid; } if ((tp[from][to] > S3_LOGPROB_ZERO) && ((newscr = st_sen_scr[from] + tp[from][to]) > scr)) { scr = newscr; bestfrom = from; } } h->score[to] = scr; if (bestfrom >= 0) { h->history[to] = h->history[bestfrom]; h->pid[to] = h->pid[bestfrom]; } bestscr = scr; /* Evaluate all other states, which might have self-transitions */ for (to = final_state-1; to >= 0; --to) { /* Score from self-transition, if any */ if ((pid = h->pid[to]) != prevpid) { tp = tmat->tp[mdef->phone[pid].tmat]; prevpid = pid; } scr = (tp[to][to] > S3_LOGPROB_ZERO) ? st_sen_scr[to] + tp[to][to] : S3_LOGPROB_ZERO; /* Scores from transitions from other states */ bestfrom = -1; for (from = to-1; from >= 0; --from) { if ((pid = h->pid[from]) != prevpid) { tp = tmat->tp[mdef->phone[pid].tmat]; prevpid = pid; } if ((tp[from][to] > S3_LOGPROB_ZERO) && ((newscr = st_sen_scr[from] + tp[from][to]) > scr)) { scr = newscr; bestfrom = from; } } /* Update new result for state to */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?