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

📄 time_align.c

📁 WinCE平台上的语音识别程序
💻 C
📖 第 1 页 / 共 5 页
字号:
{    int node;    int neighbor;    short *node_adjacency;    short *neighbor_adjacency;    /*     * sweep through the adjacency matrix pruning arcs     * that do not satisfy left and right context constraints.     *     * node 0 is either a SIL, SILb or a left context node.  No need to expand.     * node 1 is an optional sil     */    for (node = 2, node_adjacency = &amatrix[2 * MAX_NODES];         node < node_cnt; node++, node_adjacency += MAX_NODES) {        for (neighbor = 0; neighbor < node_cnt; neighbor++) {            neighbor_adjacency = &amatrix[neighbor * MAX_NODES];            /* sil phones are not expanded into triphones.  So, no need to remove any arcs               them up */            if (ci_map[node] != sil_phone_id) {                if (node_adjacency[neighbor] == LEFT_ADJACENT) {                    if (lc_map[node] != ci_map[neighbor]) {                        node_adjacency[neighbor] = NOT_ADJACENT;                        neighbor_adjacency[node] = NOT_ADJACENT;                    }                }                else if (node_adjacency[neighbor] == RIGHT_ADJACENT) {                    if (rc_map[node] != ci_map[neighbor]) {                        node_adjacency[neighbor] = NOT_ADJACENT;                        neighbor_adjacency[node] = NOT_ADJACENT;                    }                }            }        }    }}static intexpand_phone_graph(short *amatrix,                   char *boundary,                   int32 * phone_id_map, int *word_id_map, int in_node_cnt){    int32 *lc_phone_id;    int lc_cnt;    int lc_is_end_word;    int32 *rc_phone_id;    int rc_cnt;    int rc_is_start_word;    int ci_cnt = phoneCiCount();    char *is_in_lc;    char *is_in_rc;    int node;    short *amatrix_row;    int32 phone_id;    int i, j;    int out_node_cnt;    int num_expanded;    int32 triphone_id;    int32 *ci_phone_id_map;    int32 *lc_phone_id_map;    int32 *rc_phone_id_map;    out_node_cnt = in_node_cnt;    ci_phone_id_map = calloc(MAX_NODES, sizeof(int32));    lc_phone_id_map = calloc(MAX_NODES, sizeof(int32));    rc_phone_id_map = calloc(MAX_NODES, sizeof(int32));    memcpy(ci_phone_id_map, phone_id_map, in_node_cnt * sizeof(int32));    /* Map various between word non-speech as SIL for the       purposes of triphone creation */    for (i = 0; i < in_node_cnt; i++) {        if ((ci_phone_id_map[i] == sile_phone_id) ||            (ci_phone_id_map[i] == silb_phone_id) ||            (ci_phone_id_map[i] == FILLER_PHONE_SEQ)) {            ci_phone_id_map[i] = sil_phone_id;        }    }    is_in_lc = calloc(ci_cnt, sizeof(char));    lc_phone_id = calloc(ci_cnt, sizeof(int32));    is_in_rc = calloc(ci_cnt, sizeof(char));    rc_phone_id = calloc(ci_cnt, sizeof(int32));    /* node 0 is the left context ci phone */    /* node 1 is the optional filler phone sequence after the left context phone */    /* node 2 is the first node which is to be expanded */    for (node = 2, amatrix_row = &amatrix[2 * MAX_NODES];         node < in_node_cnt; node++, amatrix_row += MAX_NODES) {        memset(is_in_lc, 0, ci_cnt * sizeof(char));        memset(is_in_rc, 0, ci_cnt * sizeof(char));        amatrix_row = &amatrix[node * MAX_NODES];        if (ci_phone_id_map[node] != sil_phone_id) {            /* non-filler phones are expanded */#if SHOW&SHOW_NODE_EXPANSION            E_INFO("%s expands to ", phone_from_id(ci_phone_id_map[node]));#endif            lc_cnt = rc_cnt = 0;            lc_is_end_word = UNDEFINED;            if (boundary[node] == TRUE)                rc_is_start_word = TRUE;            else                rc_is_start_word = FALSE;            for (i = 0; i < in_node_cnt; i++) {                phone_id = ci_phone_id_map[i];                if (amatrix_row[i] == LEFT_ADJACENT) {                    if (lc_is_end_word == UNDEFINED) {                        if (boundary[i] == TRUE) {                            lc_is_end_word = TRUE;                        }                        else {                            lc_is_end_word = FALSE;                        }                    }                    if (!is_in_lc[phone_id]) {                        is_in_lc[phone_id] = TRUE;                        lc_phone_id[lc_cnt++] = phone_id;                    }                    else        /* ignore it since already there */                        ;                }                else if (amatrix_row[i] == RIGHT_ADJACENT) {                    if (!is_in_rc[phone_id]) {                        is_in_rc[phone_id] = TRUE;                        rc_phone_id[rc_cnt++] = phone_id;                    }                    else        /* ignore it since already there */                        ;                }            }            if (lc_is_end_word && rc_is_start_word) {                /* single phone word case */                num_expanded = 0;                for (i = 0; i < lc_cnt; i++) {                    for (j = 0; j < rc_cnt; j++) {                        triphone_id =                            single_phone_word_triphone(ci_phone_id_map                                                       [node],                                                       lc_phone_id[i],                                                       rc_phone_id[j]);#if SHOW&SHOW_NODE_EXPANSION                        E_INFOCONT(" %s", phone_from_id(triphone_id));#endif                        if (num_expanded == 0) {                            phone_id_map[node] = triphone_id;                            lc_phone_id_map[node] = lc_phone_id[i];                            rc_phone_id_map[node] = rc_phone_id[j];                        }                        else {                            ci_phone_id_map[out_node_cnt] =                                ci_phone_id_map[node];                            lc_phone_id_map[out_node_cnt] = lc_phone_id[i];                            rc_phone_id_map[out_node_cnt] = rc_phone_id[j];                            add_triphone(amatrix, phone_id_map,                                         word_id_map, boundary, node,                                         out_node_cnt++, triphone_id);                        }                        ++num_expanded;                    }                }#if SHOW&SHOW_NODE_EXPANSION                E_INFOCONT("\n");#endif            }            else if (lc_is_end_word) {                /* multi-phone word start */                num_expanded = 0;                for (i = 0; i < lc_cnt; i++) {                    for (j = 0; j < rc_cnt; j++) {                        triphone_id =                            begin_triphone(ci_phone_id_map[node],                                           lc_phone_id[i], rc_phone_id[j]);#if SHOW&SHOW_NODE_EXPANSION                        E_INFOCONT(" %s", phone_from_id(triphone_id));#endif                        if (num_expanded == 0) {                            phone_id_map[node] = triphone_id;                            lc_phone_id_map[node] = lc_phone_id[i];                            rc_phone_id_map[node] = rc_phone_id[j];                        }                        else {                            ci_phone_id_map[out_node_cnt] =                                ci_phone_id_map[node];                            lc_phone_id_map[out_node_cnt] = lc_phone_id[i];                            rc_phone_id_map[out_node_cnt] = rc_phone_id[j];                            add_triphone(amatrix, phone_id_map,                                         word_id_map, boundary, node,                                         out_node_cnt++, triphone_id);                        }                        ++num_expanded;                    }                }#if SHOW&SHOW_NODE_EXPANSION                E_INFOCONT("\n");#endif            }            else if (rc_is_start_word) {                /* multi-phone word end */                num_expanded = 0;                for (i = 0; i < lc_cnt; i++) {                    for (j = 0; j < rc_cnt; j++) {                        triphone_id =                            end_triphone(ci_phone_id_map[node],                                         lc_phone_id[i], rc_phone_id[j]);#if SHOW&SHOW_NODE_EXPANSION                        E_INFOCONT(" %s", phone_from_id(triphone_id));#endif                        if (num_expanded == 0) {                            phone_id_map[node] = triphone_id;                            lc_phone_id_map[node] = lc_phone_id[i];                            rc_phone_id_map[node] = rc_phone_id[j];                        }                        else {                            ci_phone_id_map[out_node_cnt] =                                ci_phone_id_map[node];                            lc_phone_id_map[out_node_cnt] = lc_phone_id[i];                            rc_phone_id_map[out_node_cnt] = rc_phone_id[j];                            add_triphone(amatrix, phone_id_map,                                         word_id_map, boundary, node,                                         out_node_cnt++, triphone_id);                        }                        ++num_expanded;                    }                }#if SHOW&SHOW_NODE_EXPANSION                E_INFOCONT("\n");#endif            }            else {                /* multi-phone word internal */                num_expanded = 0;                for (i = 0; i < lc_cnt; i++) {                    for (j = 0; j < rc_cnt; j++) {                        triphone_id =                            triphone(ci_phone_id_map[node], lc_phone_id[i],                                     rc_phone_id[j]);#if SHOW&SHOW_NODE_EXPANSION                        E_INFOCONT(" %s", phone_from_id(triphone_id));#endif                        if (num_expanded == 0) {                            phone_id_map[node] = triphone_id;                            lc_phone_id_map[node] = lc_phone_id[i];                            rc_phone_id_map[node] = rc_phone_id[j];                        }                        else {                            ci_phone_id_map[out_node_cnt] =                                ci_phone_id_map[node];                            lc_phone_id_map[out_node_cnt] = lc_phone_id[i];                            rc_phone_id_map[out_node_cnt] = rc_phone_id[j];                            add_triphone(amatrix, phone_id_map,                                         word_id_map, boundary, node,                                         out_node_cnt++, triphone_id);                        }                        ++num_expanded;                    }                }#if SHOW&SHOW_NODE_EXPANSION                E_INFOCONT("\n");#endif            }        }        else {#if SHOW&SHOW_NODE_EXPANSION            if (ci_phone_id_map[node] >= 0) {                E_INFO("%s:%d not expanded\n",                       phone_from_id(ci_phone_id_map[node]), node);            }            else {                E_INFO("FILL:%d not expanded\n", node);            }#endif        }    }    prune_invalid_adjacencies(amatrix, out_node_cnt,                              ci_phone_id_map, lc_phone_id_map,                              rc_phone_id_map);    free(ci_phone_id_map);    free(lc_phone_id_map);    free(rc_phone_id_map);    free(is_in_lc);    free(lc_phone_id);    free(is_in_rc);    free(rc_phone_id);    return out_node_cnt;}static intadd_word(short *amatrix,         char *boundary,         int32 * phone_id_map,         int32 * word_id_map,         int *out_new_node,         int *out_word_cnt,         char const *cur_word_str,         int *next_end,         int *next_end_cnt, int *prior_end, int *prior_end_cnt){    int i, k;                   /* If we really need a variable named 'j' we can declare one */    int32 cur_word_id;    dict_entry_t *cur_word;    int new_node = *out_new_node;    int word_cnt = *out_word_cnt;    cur_word_id = kb_get_word_id(cur_word_str);    if (cur_word_id < 0) {        E_ERROR("Unknown word: %s\n", cur_word_str);        return -1;    }    do {        cur_word = word_dict->dict_list[cur_word_id];        phone_id_map[new_node] = cur_word->ci_phone_ids[0];        word_id_map[new_node] = cur_word_id;        ++word_cnt;        if (cur_word->len > 1)            boundary[new_node] = FALSE;        else {            boundary[new_node] = TRUE;            next_end[*next_end_cnt] = new_node;            (*next_end_cnt)++;        }        for (k = 0; k < *prior_end_cnt; k++) {            i = prior_end[k];            amatrix[i * MAX_NODES + new_node] = RIGHT_ADJACENT;            amatrix[new_node * MAX_NODES + i] = LEFT_ADJACENT;        }        new_node++;        if (cur_word->len > 1) {            /* add the word internal nodes (if any) */            for (k = 1; k < cur_word->len - 1; k++, new_node++) {                phone_id_map[new_node] = cur_word->ci_phone_ids[k];                boundary[new_node] = FALSE;                word_id_map[new_node] = cur_word_id;                amatrix[(new_node - 1) * MAX_NODES + new_node] =                    RIGHT_ADJACENT;                amatrix[new_node * MAX_NODES + new_node - 1] =                    LEFT_ADJACENT;            }            /* add the last phone of the word */            phone_id_map[new_node] = cur_word->ci_phone_ids[k];            word_id_map[new_node] = cur_word_id;            boundary[new_node] = TRUE;            amatrix[(new_node - 1) * MAX_NODES + new_node] =                RIGHT_ADJACENT;            amatrix[new_node * MAX_NODES + new_node - 1] = LEFT_ADJACENT;            next_end[*next_end_cnt] = new_node;            (*next_end_cnt)++;            new_node++;        }        /* get the next alternative pronunication */        cur_word_id = cur_word->alt;    } while (cur_word_id >= 0);    *out_new_node = new_node;    *out_word_cnt = word_cnt;    return 0;}char *next_transcript_word(char **out_rem_word_seq){    char *cur_word_str;    char *rem_word_seq = *out_rem_word_seq;    char *sp;    int fchar;    /* after first space is converted to '\0', this will be the next word */    cur_word_str = rem_word_seq;    sp = strchr(rem_word_seq, ' ');    if (sp) {

⌨️ 快捷键说明

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