flat_fwd.c

来自「CMU大名鼎鼎的SPHINX-3大词汇量连续语音识别系统」· C语言 代码 · 共 2,212 行 · 第 1/5 页

C
2,212
字号
	if (s == n_state-1) {	    /* This state sequence same as a previous ones; just map to it */	    map[ctx] = i;	    return n;	}    }    /* This state sequence different from all previous ones; allocate new entry */    map[ctx] = n;    pid[n] = p;        return (n+1);}/** Temporary array used during the creation of lexical triphones lists */static s3pid_t *tmp_xwdpid = NULL;/** * Given base b, and right context rc, build left context cross-word triphones map * for all left context ciphones.  Compress map to unique list. */static void build_lcpid (s3cipid_t b, s3cipid_t rc){    s3cipid_t lc, *map;    s3pid_t p;    int32 n;        map = (s3cipid_t *) ckd_calloc (mdef->n_ciphone, sizeof(s3cipid_t));        n = 0;    for (lc = 0; lc < mdef->n_ciphone; lc++) {	p = mdef_phone_id_nearest (mdef, b, lc, rc, WORD_POSN_BEGIN);	if ((! mdef->ciphone[b].filler) && word_end_ci[lc] &&	    mdef_is_ciphone(mdef, p))	    n_backoff_ci++;		n = xwdpid_compress (p, tmp_xwdpid, map, lc, n);    }    /* Copy/Move to lcpid */    lcpid[b][rc].cimap = map;    lcpid[b][rc].n_pid = n;    lcpid[b][rc].pid = (s3pid_t *) ckd_calloc (n, sizeof(s3pid_t));    memcpy (lcpid[b][rc].pid, tmp_xwdpid, n*sizeof(s3pid_t));}/** * Given base b, and left context lc, build right context cross-word triphones map * for all right context ciphones.  Compress map to unique list. */static void build_rcpid (s3cipid_t b, s3cipid_t lc){    s3cipid_t rc, *map;    s3pid_t p;    int32 n;        map = (s3cipid_t *) ckd_calloc (mdef->n_ciphone, sizeof(s3cipid_t));        n = 0;    for (rc = 0; rc < mdef->n_ciphone; rc++) {	p = mdef_phone_id_nearest (mdef, b, lc, rc, WORD_POSN_END);	if ((! mdef->ciphone[b].filler) && word_start_ci[rc] &&	    mdef_is_ciphone(mdef, p))	    n_backoff_ci++;	n = xwdpid_compress (p, tmp_xwdpid, map, rc, n);    }    /* Copy/Move to rcpid */    rcpid[b][lc].cimap = map;    rcpid[b][lc].n_pid = n;    rcpid[b][lc].pid = (s3pid_t *) ckd_calloc (n, sizeof(s3pid_t));    memcpy (rcpid[b][lc].pid, tmp_xwdpid, n*sizeof(s3pid_t));}/** * Given base b for a single-phone word, build context cross-word triphones map * for all left and right context ciphones. */static void build_lrcpid (s3cipid_t b){    s3cipid_t rc, lc;        for (lc = 0; lc < mdef->n_ciphone; lc++) {	lrcpid[b][lc].pid = (s3pid_t *) ckd_calloc (mdef->n_ciphone, sizeof(s3pid_t));	lrcpid[b][lc].cimap = (s3cipid_t *) ckd_calloc (mdef->n_ciphone,sizeof(s3cipid_t));									for (rc = 0; rc < mdef->n_ciphone; rc++) {	    lrcpid[b][lc].cimap[rc] = rc;	    lrcpid[b][lc].pid[rc] = mdef_phone_id_nearest (mdef, b, lc, rc,							   WORD_POSN_SINGLE);	    if ((! mdef->ciphone[b].filler) &&		word_start_ci[rc] && word_end_ci[lc] &&		mdef_is_ciphone(mdef, lrcpid[b][lc].pid[rc]))		n_backoff_ci++;	}	lrcpid[b][lc].n_pid = mdef->n_ciphone;    }}/** * Build within-word triphones sequence for each word.  The extreme ends are not needed * since cross-word modelling is used for those.  (See lcpid, rcpid, lrcpid.) */static void build_wwpid ( void ){    s3wid_t w;    int32 pronlen, l;    s3cipid_t b, lc, rc;        E_INFO ("Building within-word triphones\n");        wwpid = (s3pid_t **) ckd_calloc (dict->n_word, sizeof(s3pid_t *));    for (w = 0; w < dict->n_word; w++) {	pronlen = dict->word[w].pronlen;	if (pronlen >= 3)	    wwpid[w] = (s3pid_t *) ckd_calloc (pronlen-1, sizeof(s3pid_t));	else	    continue;		lc = dict->word[w].ciphone[0];	b = dict->word[w].ciphone[1];	for (l = 1; l < pronlen-1; l++) {	    rc = dict->word[w].ciphone[l+1];	    wwpid[w][l] = mdef_phone_id_nearest (mdef, b, lc, rc, WORD_POSN_INTERNAL);	    if ((! mdef->ciphone[b].filler) && mdef_is_ciphone(mdef, wwpid[w][l]))		n_backoff_ci++;	    	    lc = b;	    b = rc;	}#if 0	printf ("%-25s ", dict->word[w].word);	for (l = 1; l < pronlen-1; l++)	    printf (" %5d", wwpid[w][l]);	printf ("\n");#endif    }}/** * Build cross-word triphones map for the entire dictionary. */static void build_xwdpid_map ( void ){    s3wid_t w;    int32 pronlen;    s3cipid_t b, lc, rc;        E_INFO ("Building cross-word triphones\n");        word_start_ci = (int8 *) ckd_calloc (mdef->n_ciphone, sizeof(int8));    word_end_ci = (int8 *) ckd_calloc (mdef->n_ciphone, sizeof(int8));    /* Mark word beginning and ending ciphones that occur in given dictionary */    for (w = 0; w < dict->n_word; w++) {	word_start_ci[dict->word[w].ciphone[0]] = 1;	word_end_ci[dict->word[w].ciphone[dict->word[w].pronlen-1]] = 1;    }    lcpid = (xwdpid_t **) ckd_calloc (mdef->n_ciphone, sizeof(xwdpid_t *));    rcpid = (xwdpid_t **) ckd_calloc (mdef->n_ciphone, sizeof(xwdpid_t *));    lrcpid = (xwdpid_t **) ckd_calloc (mdef->n_ciphone, sizeof(xwdpid_t *));    for (w = 0; w < dict->n_word; w++) {	pronlen = dict->word[w].pronlen;	if (pronlen > 1) {	    /* Multi-phone word; build rcmap and lcmap if not already present */	    b = dict->word[w].ciphone[pronlen-1];	    lc = dict->word[w].ciphone[pronlen-2];	    if (! rcpid[b])		rcpid[b] = (xwdpid_t *) ckd_calloc (mdef->n_ciphone, sizeof(xwdpid_t));	    if (! rcpid[b][lc].cimap)		build_rcpid (b, lc);	    b = dict->word[w].ciphone[0];	    rc = dict->word[w].ciphone[1];	    if (! lcpid[b])		lcpid[b] = (xwdpid_t *) ckd_calloc (mdef->n_ciphone, sizeof(xwdpid_t));	    if (! lcpid[b][rc].cimap)		build_lcpid (b, rc);	} else {	    /* Single-phone word; build lrcmap if not already present */	    b = dict->word[w].ciphone[0];	    if (! lrcpid[b]) {		lrcpid[b] = (xwdpid_t *) ckd_calloc (mdef->n_ciphone, sizeof(xwdpid_t));		build_lrcpid (b);	    }	}    }    ckd_free (word_start_ci);    ckd_free (word_end_ci);#if 0    E_INFO ("LCXWDPID\n");    dump_xwdpidmap (lcpid);        E_INFO ("RCXWDPID\n");    dump_xwdpidmap (rcpid);    E_INFO ("LRCXWDPID\n");    dump_xwdpidmap (lrcpid);#endif}static s3cipid_t *get_rc_cimap (s3wid_t w){    int32 pronlen;    s3cipid_t b, lc;        pronlen = dict->word[w].pronlen;    b = dict->word[w].ciphone[pronlen-1];    if (pronlen == 1) {	/* No known left context.  But all cimaps (for any l) are identical; pick one */	return (lrcpid[b][0].cimap);    } else {	lc = dict->word[w].ciphone[pronlen-2];	return (rcpid[b][lc].cimap);    }}static void get_rcpid (s3wid_t w, s3pid_t **pid, int32 *npid){    int32 pronlen;    s3cipid_t b, lc;        pronlen = dict->word[w].pronlen;    assert (pronlen > 1);        b = dict->word[w].ciphone[pronlen-1];    lc = dict->word[w].ciphone[pronlen-2];        *pid = rcpid[b][lc].pid;    *npid = rcpid[b][lc].n_pid;}static int32 get_rc_npid (s3wid_t w){    int32 pronlen;    s3cipid_t b, lc;        pronlen = dict->word[w].pronlen;    b = dict->word[w].ciphone[pronlen-1];    if (pronlen == 1) {	/* No known left context.  But all cimaps (for any l) are identical; pick one */	return (lrcpid[b][0].n_pid);    } else {	lc = dict->word[w].ciphone[pronlen-2];	return (rcpid[b][lc].n_pid);    }}static void lattice_dump (FILE *fp){    int32 i;        for (i = 0; i < n_lat_entry; i++) {	fprintf (fp, "%6d: %5d %6d %11d %s\n", i,		 lattice[i].frm, lattice[i].history, lattice[i].score,		 dict_wordstr (dict,lattice[i].wid));    }    fflush (fp);}/** * There are two sets of whmm freelists.  whmm_freelist[0] for word-initial HMMs * that need a separate HMM id every state, and whmm_freelist[1] for non-word-initial * HMMs that don't need that. */static whmm_t *whmm_freelist[2] = {NULL, NULL};static void whmm_free (whmm_t *h){    int32 k;        k = (h->pos == 0) ? 0 : 1;        h->next = whmm_freelist[k];    whmm_freelist[k] = h;}static whmm_t *whmm_alloc (int32 pos){    whmm_t *h;    int32 k, i, n, s;    int32 *tmp_scr;    s3latid_t *tmp_latid;    s3pid_t *tmp_pid;    tmp_pid=NULL;        k = (pos == 0) ? 0 : 1;    if (! whmm_freelist[k]) {	n = 16000/sizeof(whmm_t);	/* HACK!!  Hardwired allocation size */	whmm_freelist[k] = h = (whmm_t *) ckd_calloc (n, sizeof(whmm_t));	tmp_scr = (int32 *) ckd_calloc (n_state * n, sizeof(int32));	tmp_latid = (s3latid_t *) ckd_calloc (n_state * n, sizeof(s3latid_t));	if (pos == 0)	    tmp_pid = (s3pid_t *) ckd_calloc (n_state * n, sizeof(s3pid_t));	for (i = 0; i < n; i++) {	    h[i].next = &(h[i+1]);	    h[i].score = tmp_scr;	    tmp_scr += n_state;	    	    h[i].history = tmp_latid;	    tmp_latid += n_state;	    /* Allocate pid iff first phone position (for multiplexed left contexts) */	    if (pos == 0) {		h[i].pid = tmp_pid;		tmp_pid += n_state;	    }	}	h[n-1].next = NULL;    }        h = whmm_freelist[k];    whmm_freelist[k] = h->next;        for (s = 0; s < n_state; s++) {	h->score[s] = S3_LOGPROB_ZERO;	h->history[s] = BAD_S3LATID;    }    h->pos = pos;        return (h);}static void dump_whmm (s3wid_t w, whmm_t *h, int32 *senscr){    int32 s;    s3pid_t p;        printf ("[%4d]", n_frm);    printf (" [%s]", dict->word[w].word);    printf (" pos= %d, rc= %d, bestscore= %d\n",	    h->pos, h->rc, h->bestscore);        printf ("\tscore: ");    for (s = 0; s < n_state; s++)	printf (" %12d", h->score[s]);    printf ("\n");        printf ("\thist:  ");    for (s = 0; s < n_state; s++)	printf (" %12d", h->history[s]);    printf ("\n");        printf ("\tsenscr:");    for (s = 0; s < n_state-1; s++) {	p = (h->pos > 0) ? *(h->pid) : h->pid[s];	if (NOT_S3PID(p))	    printf (" %12s", "--");	else	    printf (" %12d", senscr[mdef->phone[p].state[s]]);    }    printf ("\n");        printf ("\ttpself:");    for (s = 0; s < n_state-1; s++) {	p = (h->pos > 0) ? *(h->pid) : h->pid[s];	if (NOT_S3PID(p))	    printf (" %12s", "--");	else	    printf (" %12d", tmat->tp[mdef->phone[p].tmat][s][s]);    }    printf ("\n");        printf ("\ttpnext:");    for (s = 0; s < n_state-1; s++) {	p = (h->pos > 0) ? *(h->pid) : h->pid[s];	if (NOT_S3PID(p))	    printf (" %12s", "--");	else	    printf (" %12d", tmat->tp[mdef->phone[p].tmat][s][s+1]);    }    printf ("\n");        printf ("\ttpskip:");    for (s = 0; s < n_state-2; s++) {	p = (h->pos > 0) ? *(h->pid) : h->pid[s];	if (NOT_S3PID(p))	    printf (" %12s", "--");	else	    printf (" %12d", tmat->tp[mdef->phone[p].tmat][s][s+2]);    }    printf ("\n");            if (h->pos == 0) {	printf ("\tpid:   ");	for (s = 0; s < n_state-1; s++)	    printf (" %12d", h->pid[s]);	printf ("\n");    }}static void dump_all_whmm (int32 *senscr){    s3wid_t w;    whmm_t *h;        for (w = 0; w < dict->n_word; w++) {	if (whmm[w]) {	    for (h = whmm[w]; h; h = h->next)		dump_whmm (w, h, senscr);	}    }}static void dump_all_word ( void ){    s3wid_t w;    whmm_t *h;    int32 last, bestlast;        for (w = 0; w < dict->n_word; w++) {	if (whmm[w]) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?