⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.c

📁 WinCE平台上的语音识别程序
💻 C
📖 第 1 页 / 共 5 页
字号:
           thresh, newphone_thresh, lastphn_thresh, BestScore);#endif    nacl = active_chan_list[nf & 0x1];    for (i = 0, rhmm = root_chan; i < n_root_chan; i++, rhmm++) {        /* First check if this channel was active in current frame */        if (rhmm->active < cf)            continue;        if (rhmm->bestscore > thresh) {            rhmm->active = nf;  /* rhmm will be active in next frame */            if (skip_alt_frm && (!(cf % skip_alt_frm)))                continue;            /* transitions out of this root channel */            newphone_score = rhmm->score[HMM_LAST_STATE] + pip;            if (newphone_score > newphone_thresh) {                /* transition to all next-level channels in the HMM tree */                for (hmm = rhmm->next; hmm; hmm = hmm->alt) {                    if (npa[hmm->ciphone]) {                        if ((hmm->active < cf)                            || (hmm->score[0] < newphone_score)) {                            hmm->score[0] = newphone_score;                            hmm->path[0] = rhmm->path[HMM_LAST_STATE];                            hmm->active = nf;                            *(nacl++) = hmm;                        }                    }                }                /*                 * Transition to last phone of all words for which this is the                 * penultimate phone (the last phones may need multiple right contexts).                 * Remember to remove the temporary newword_penalty.                 */                if (newphone_score > lastphn_thresh) {                    for (w = rhmm->penult_phn_wid; w >= 0;                         w = homophone_set[w]) {                        de = word_dict->dict_list[w];                        if (npa[de->ci_phone_ids[de->len - 1]]) {                            candp = lastphn_cand + n_lastphn_cand;                            n_lastphn_cand++;                            candp->wid = w;                            candp->score =                                newphone_score - newword_penalty;                            candp->bp = rhmm->path[HMM_LAST_STATE];                        }                    }                }            }        }    }    n_active_chan[nf & 0x1] = nacl - active_chan_list[nf & 0x1];}/* * Prune currently active nonroot channels in HMM tree for next frame.  Also, perform * exit transitions out of such channels and activate successors. */voidprune_nonroot_chan(void){    CHAN_T *hmm, *nexthmm;    int32 cf, nf, w, i, pip;    int32 thresh, newphone_thresh, lastphn_thresh, newphone_score;    CHAN_T **acl, **nacl;       /* active list, next active list */    lastphn_cand_t *candp;    dict_entry_t *de;    cf = CurrentFrame;    nf = cf + 1;    thresh = BestScore + DynamicLogBeamWidth;    newphone_thresh =        BestScore + (DynamicLogBeamWidth >                     NewPhoneLogBeamWidth ? DynamicLogBeamWidth :                     NewPhoneLogBeamWidth);    lastphn_thresh =        BestScore + (DynamicLogBeamWidth >                     LastPhoneLogBeamWidth ? DynamicLogBeamWidth :                     LastPhoneLogBeamWidth);    pip = logPhoneInsertionPenalty;    acl = active_chan_list[cf & 0x1];   /* currently active HMMs in tree */    nacl = active_chan_list[nf & 0x1] + n_active_chan[nf & 0x1];    for (i = n_active_chan[cf & 0x1], hmm = *(acl++); i > 0;         --i, hmm = *(acl++)) {        assert(hmm->active >= cf);        if (hmm->bestscore > thresh) {            /* retain this channel in next frame */            if (hmm->active != nf) {                hmm->active = nf;                *(nacl++) = hmm;            }            if (skip_alt_frm && (!(cf % skip_alt_frm)))                continue;            /* transitions out of this channel */            newphone_score = hmm->score[HMM_LAST_STATE] + pip;            if (newphone_score > newphone_thresh) {                /* transition to all next-level channel in the HMM tree */                for (nexthmm = hmm->next; nexthmm; nexthmm = nexthmm->alt) {                    if (npa[nexthmm->ciphone]) {                        if ((nexthmm->active < cf)                            || (nexthmm->score[0] < newphone_score)) {                            nexthmm->score[0] = newphone_score;                            nexthmm->path[0] = hmm->path[HMM_LAST_STATE];                            if (nexthmm->active != nf) {                                nexthmm->active = nf;                                *(nacl++) = nexthmm;                            }                        }                    }                }                /*                 * Transition to last phone of all words for which this is the                 * penultimate phone (the last phones may need multiple right contexts).                 * Remember to remove the temporary newword_penalty.                 */                if (newphone_score > lastphn_thresh) {                    for (w = hmm->info.penult_phn_wid; w >= 0;                         w = homophone_set[w]) {                        de = word_dict->dict_list[w];                        if (npa[de->ci_phone_ids[de->len - 1]]) {                            candp = lastphn_cand + n_lastphn_cand;                            n_lastphn_cand++;                            candp->wid = w;                            candp->score =                                newphone_score - newword_penalty;                            candp->bp = hmm->path[HMM_LAST_STATE];                        }                    }                }            }        }        else if (hmm->active != nf) {            /* hmm->active = -1; */            hmm->bestscore = WORST_SCORE;            hmm->score[0] = WORST_SCORE;            hmm->score[1] = WORST_SCORE;            hmm->score[2] = WORST_SCORE;#if HMM_5_STATE            hmm->score[3] = WORST_SCORE;            hmm->score[4] = WORST_SCORE;#endif        }    }    n_active_chan[nf & 0x1] = nacl - active_chan_list[nf & 0x1];}/* * Since the same instance of a word (i.e., <word,start-frame>) reaches its last * phone several times, we can compute its best BP and LM transition score info * just the first time and cache it for future occurrences.  Structure for such * a cache. */typedef struct {    int32 sf;                   /* Start frame */    int32 dscr;                 /* Delta-score upon entering last phone */    int32 bp;                   /* Best BP */} last_ltrans_t;static last_ltrans_t *last_ltrans;      /* one per word */#define CAND_SF_ALLOCSIZE	32typedef struct {    int32 bp_ef;    int32 cand;} cand_sf_t;static int32 cand_sf_alloc = 0;static cand_sf_t *cand_sf;/* * Execute the transition into the last phone for all candidates words emerging from * the HMM tree.  Attach LM scores to such transitions. * (Executed after pruning root and non-root, but before pruning word-chan.) */voidlast_phone_transition(void){    int32 i, j, k, cf, nf, bp, bplast, w;    lastphn_cand_t *candp;    int32 *nawl;    int32 fwid2, thresh;    int32 *rcpermtab, ciph0;    int32 bestscore, dscr;    dict_entry_t *de;    CHAN_T *hmm;    BPTBL_T *bpe;    int32 n_cand_sf = 0;    cf = CurrentFrame;    nf = cf + 1;    nawl = active_word_list[nf & 0x1];#if SEARCH_PROFILE    n_lastphn_cand_utt += n_lastphn_cand;#endif    /* If best LM score and bp for candidate known use it, else sort cands by startfrm */    for (i = 0, candp = lastphn_cand; i < n_lastphn_cand; i++, candp++) {        bpe = &(BPTable[candp->bp]);        rcpermtab =            (bpe->r_diph >=             0) ? RightContextFwdPerm[bpe->r_diph] : zeroPermTab;        /* Subtract starting score for candidate, leave it with only word score */        de = word_dict->dict_list[candp->wid];        ciph0 = de->ci_phone_ids[0];        candp->score -= BScoreStack[bpe->s_idx + rcpermtab[ciph0]];        /*         * If this candidate not occurred in an earlier frame, prepare for finding         * best transition score into last phone; sort by start frame.         */        if (last_ltrans[candp->wid].sf != bpe->frame + 1) {            for (j = 0; j < n_cand_sf; j++) {                if (cand_sf[j].bp_ef == bpe->frame)                    break;            }            if (j < n_cand_sf)                candp->next = cand_sf[j].cand;            else {                if (n_cand_sf >= cand_sf_alloc) {                    if (cand_sf_alloc == 0) {                        cand_sf =                            ckd_calloc(CAND_SF_ALLOCSIZE,                                                    sizeof(cand_sf_t));                        cand_sf_alloc = CAND_SF_ALLOCSIZE;                    }                    else {                        cand_sf_alloc += CAND_SF_ALLOCSIZE;                        cand_sf = ckd_realloc(cand_sf,                                              cand_sf_alloc * sizeof(cand_sf_t));                        E_INFO("cand_sf[] increased to %d entries\n",                               cand_sf_alloc);                    }                }                j = n_cand_sf++;                candp->next = -1;                cand_sf[j].bp_ef = bpe->frame;            }            cand_sf[j].cand = i;            last_ltrans[candp->wid].dscr = WORST_SCORE;            last_ltrans[candp->wid].sf = bpe->frame + 1;        }    }    /* Compute best LM score and bp for new cands entered in the sorted lists above */    for (i = 0; i < n_cand_sf; i++) {        /* For the i-th unique end frame... */        bp = BPTableIdx[cand_sf[i].bp_ef];        bplast = BPTableIdx[cand_sf[i].bp_ef + 1] - 1;        for (bpe = &(BPTable[bp]); bp <= bplast; bp++, bpe++) {            if (!bpe->valid)                continue;            /* For each bp entry in the i-th end frame... */            rcpermtab = (bpe->r_diph >= 0) ?                RightContextFwdPerm[bpe->r_diph] : zeroPermTab;            /* For each candidate at the start frame find bp->cand transition-score */            for (j = cand_sf[i].cand; j >= 0; j = candp->next) {                candp = &(lastphn_cand[j]);                de = word_dict->dict_list[candp->wid];                ciph0 = de->ci_phone_ids[0];                fwid2 = de->fwid;                dscr = BScoreStack[bpe->s_idx + rcpermtab[ciph0]];                dscr +=                    lm_tg_score(bpe->prev_real_fwid, bpe->real_fwid,                                fwid2);                if (last_ltrans[candp->wid].dscr < dscr) {                    last_ltrans[candp->wid].dscr = dscr;                    last_ltrans[candp->wid].bp = bp;                }            }        }    }    /* Update best transitions for all candidates; also update best lastphone score */    bestscore = LastPhoneBestScore;    for (i = 0, candp = lastphn_cand; i < n_lastphn_cand; i++, candp++) {        candp->score += last_ltrans[candp->wid].dscr;        candp->bp = last_ltrans[candp->wid].bp;        if (bestscore < candp->score)            bestscore = candp->score;    }    LastPhoneBestScore = bestscore;    /* At this pt, we know the best entry score (with LM component) for all candidates */    thresh = bestscore + LastPhoneAloneLogBeamWidth;    for (i = n_lastphn_cand, candp = lastphn_cand; i > 0; --i, candp++) {        if (candp->score > thresh) {            w = candp->wid;            alloc_all_rc(w);            k = 0;            for (hmm = word_chan[w]; hmm; hmm = hmm->next) {                if ((hmm->active < cf) || (hmm->score[0] < candp->score)) {                    hmm->score[0] = candp->score;                    hmm->path[0] = candp->bp;                    assert(hmm->active != nf);                    hmm->active = nf;                    k++;                }            }            if (k > 0) {                assert(!word_active[w]);                *(nawl++) = w;                word_active[w] = 1;            }        }    }    n_active_word[nf & 0x1] = nawl - active_word_list[nf & 0x1];}/* * Prune currently active word channels for next frame.  Also, perform exit * transitions out of such channels and active successors. */voidprune_word_chan(void){    ROOT_CHAN_T *rhmm;    CHAN_T *hmm, *thmm;    CHAN_T **phmmp;             /* previous HMM-pointer */    int32 cf, nf, w, i, k;    int32 newword_thresh, lastphn_thresh;    int32 *awl, *nawl;    cf = CurrentFrame;    nf = cf + 1;    newword_thresh =        LastPhoneBestScore + (DynamicLogBeamWidth >                              NewWordLogBeamWidth ? DynamicLogBeamWidth :                              NewWordLogBeamWidth);    lastphn_thresh =        LastPhoneBestScore + (DynamicLogBeamWidth >                              LastPhoneAloneLogBeamWidth ?                              DynamicLogBeamWidth :                              LastPhoneAloneLogBeamWidth);    awl = active_word_list[cf & 0x1];    nawl = active_word_list[nf & 0x1] + n_active_word[nf & 0x1];    /* Dynamically allocated last channels of multi-phone words */    for (i = n_active_word[cf & 0x1], w = *(awl++); i > 0;         --i, w = *(awl++)) {        k = 0;        phmmp = &(word_chan[w]);        for (hmm = word_chan[w]; hmm; hmm = thmm) {            assert(hmm->active >= cf);            thmm = hmm->next;            if (hmm->bestscore > lastphn_thresh) {                /* retain this channel in next frame */                hmm->active = nf;                k++;                phmmp = &(hmm->next);                /* Could if ((! skip_alt_frm) || (cf & 0x1)) the following */                if (hmm->score[HMM_LAST_STATE] > newword_thresh) {                    /* can exit channel and recognize word */                    save_bwd_ptr(w, hmm->score[HMM_LAST_STATE],                                 hmm->path[HMM_LAST_STATE],                                 hmm->info.rc_id);                }            }            else if (hmm->active == nf) {                phmmp = &(hmm->next);            }            else {                listelem_free(hmm, sizeof(CHAN_T));                *phmmp = thmm;            }        }        if ((k > 0) && (!word_active[w])) {            *(nawl++) = w;            word_active[w] = 1;        }    }

⌨️ 快捷键说明

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