📄 fsg_psubtree.c
字号:
root = pnode; search_chan_deactivate(&(pnode->hmm)); /* Mark HMM inactive */ } } else { /* Multi-phone word */ assert(dict_mpx(word_dict, wid)); /* S2 HACK: pronlen>1 => mpx?? */ ssid_pnode_map = (fsg_pnode_t **) ckd_calloc(n_ci, sizeof(fsg_pnode_t *)); lc_pnodelist = NULL; rc_pnodelist = NULL; for (p = 0; p < pronlen; p++) { did = ssid = dict_phone(word_dict, wid, p); if (p == 0) { /* Root phone, handle required left contexts */ for (i = 0; lclist[i] >= 0; i++) { lc = lclist[i]; j = lcbwdperm[did][lc]; ssid = lcbwd[did][j]; pnode = ssid_pnode_map[j]; if (!pnode) { /* Allocate pnode for this new ssid */ pnode = (fsg_pnode_t *) ckd_calloc(1, sizeof (fsg_pnode_t)); pnode->hmm.sseqid = ssid; pnode->logs2prob = word_fsglink_logs2prob(fsglink) + wip + pip; pnode->ci_ext = (int8) dict_ciphone(word_dict, wid, 0); pnode->ppos = 0; pnode->leaf = FALSE; pnode->sibling = root; /* All root nodes linked together */ pnode->alloc_next = head; head = pnode; root = pnode; search_chan_deactivate(&(pnode->hmm)); /* Mark HMM inactive */ lc_pnodelist = glist_add_ptr(lc_pnodelist, (void *) pnode); ssid_pnode_map[j] = pnode; } else { assert(pnode->hmm.sseqid == ssid); } fsg_pnode_add_ctxt(pnode, lc); } } else if (p != pronlen - 1) { /* Word internal phone */ pnode = (fsg_pnode_t *) ckd_calloc(1, sizeof(fsg_pnode_t)); pnode->hmm.sseqid = ssid; pnode->logs2prob = pip; pnode->ci_ext = (int8) dict_ciphone(word_dict, wid, p); pnode->ppos = p; pnode->leaf = FALSE; pnode->sibling = NULL; if (p == 1) { /* Predecessor = set of root nodes for left ctxts */ for (gn = lc_pnodelist; gn; gn = gnode_next(gn)) { pred = (fsg_pnode_t *) gnode_ptr(gn); pred->next.succ = pnode; } } else { /* Predecessor = word internal node */ pred->next.succ = pnode; } pnode->alloc_next = head; head = pnode; search_chan_deactivate(&(pnode->hmm)); /* Mark HMM inactive */ pred = pnode; } else { /* Leaf phone, handle required right contexts */ memset((void *) ssid_pnode_map, 0, n_ci * sizeof(fsg_pnode_t *)); for (i = 0; rclist[i] >= 0; i++) { rc = rclist[i]; j = rcfwdperm[did][rc]; ssid = rcfwd[did][j]; pnode = ssid_pnode_map[j]; if (!pnode) { /* Allocate pnode for this new ssid */ pnode = (fsg_pnode_t *) ckd_calloc(1, sizeof (fsg_pnode_t)); pnode->hmm.sseqid = ssid; pnode->logs2prob = pip; pnode->ci_ext = (int8) dict_ciphone(word_dict, wid, p); pnode->ppos = p; pnode->leaf = TRUE; pnode->sibling = rc_pnodelist ? (fsg_pnode_t *) gnode_ptr(rc_pnodelist) : NULL; pnode->next.fsglink = fsglink; pnode->alloc_next = head; head = pnode; search_chan_deactivate(&(pnode->hmm)); /* Mark HMM inactive */ rc_pnodelist = glist_add_ptr(rc_pnodelist, (void *) pnode); ssid_pnode_map[j] = pnode; } else { assert(pnode->hmm.sseqid == ssid); } fsg_pnode_add_ctxt(pnode, rc); } if (p == 1) { /* Predecessor = set of root nodes for left ctxts */ for (gn = lc_pnodelist; gn; gn = gnode_next(gn)) { pred = (fsg_pnode_t *) gnode_ptr(gn); pred->next.succ = (fsg_pnode_t *) gnode_ptr(rc_pnodelist); } } else { /* Predecessor = word internal node */ pred->next.succ = (fsg_pnode_t *) gnode_ptr(rc_pnodelist); } } } ckd_free((void *) ssid_pnode_map); glist_free(lc_pnodelist); glist_free(rc_pnodelist); } *alloc_head = head; return root;}/* * For now, this "tree" will be "flat" */fsg_pnode_t *fsg_psubtree_init(word_fsg_t * fsg, int32 from_state, fsg_pnode_t ** alloc_head){ int32 dst; gnode_t *gn; word_fsglink_t *fsglink; fsg_pnode_t *root; int32 n_ci; root = NULL; assert(*alloc_head == NULL); n_ci = phoneCiCount(); if (n_ci > (FSG_PNODE_CTXT_BVSZ * 32)) { E_FATAL ("#phones > %d; increase FSG_PNODE_CTXT_BVSZ and recompile\n", FSG_PNODE_CTXT_BVSZ * 32); } for (dst = 0; dst < word_fsg_n_state(fsg); dst++) { /* Add all links from from_state to dst */ for (gn = word_fsg_trans(fsg, from_state, dst); gn; gn = gnode_next(gn)) { /* Add word emitted by this transition (fsglink) to lextree */ fsglink = (word_fsglink_t *) gnode_ptr(gn); assert(word_fsglink_wid(fsglink) >= 0); /* Cannot be a null trans */ root = psubtree_add_trans(root, fsglink, word_fsg_lc(fsg, from_state), word_fsg_rc(fsg, dst), alloc_head); } } return root;}voidfsg_psubtree_free(fsg_pnode_t * head){ fsg_pnode_t *next; while (head) { next = head->alloc_next; ckd_free((void *) head); head = next; }}voidfsg_psubtree_dump(fsg_pnode_t * head, FILE * fp){ int32 i; word_fsglink_t *tl; for (; head; head = head->alloc_next) { /* Indentation */ for (i = 0; i <= head->ppos; i++) fprintf(fp, " "); fprintf(fp, "%08x.@", (int32) head); /* Pointer used as node ID */ fprintf(fp, " %5d.SS", head->hmm.sseqid); fprintf(fp, " %10d.LP", head->logs2prob); fprintf(fp, " %08x.SIB", (int32) head->sibling); fprintf(fp, " %s.%d", phone_from_id(head->ci_ext), head->ppos); if ((head->ppos == 0) || head->leaf) { fprintf(fp, " ["); for (i = 0; i < FSG_PNODE_CTXT_BVSZ; i++) fprintf(fp, "%08x", head->ctxt.bv[i]); fprintf(fp, "]"); } if (head->leaf) { tl = head->next.fsglink; fprintf(fp, " {%s[%d->%d](%d)}", kb_get_word_str(tl->wid), tl->from_state, tl->to_state, tl->logs2prob); } else { fprintf(fp, " %08x.NXT", (int32) head->next.succ); } fprintf(fp, "\n"); } fflush(fp);}#if 0booleanfsg_psubtree_pnode_enter(fsg_pnode_t * pnode, int32 score, int32 frame, int32 bpidx){ boolean activate; assert(pnode->hmm.active <= frame); score += pnode->logs2prob; activate = FALSE; if (pnode->hmm.score[0] < score) { if (pnode->hmm.active < frame) { activate = TRUE; pnode->hmm.active = frame; } pnode->hmm.score[0] = score; pnode->hmm.path[0] = bpidx; } return activate;}#endifvoidfsg_psubtree_pnode_deactivate(fsg_pnode_t * pnode){ search_chan_deactivate(&(pnode->hmm));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -