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