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 + -
显示快捷键?