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

📄 time_align.c

📁 WinCE平台上的语音识别程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        fchar = *(sp + 1);      /* should be the first character of the next word */        if (isspace(fchar) || (fchar == '\0')) {            E_FATAL("Please remove the extra spaces in:\n|%s|\n",                    rem_word_seq);        }        *out_rem_word_seq = sp + 1;        *sp = '\0';    }    else        *out_rem_word_seq = NULL;    return cur_word_str;}static intmk_phone_graph(short *amatrix,               char *boundary,               int32 * phone_id_map,               int *word_id_map,               int *final_model,               char const *left_word_str,               char *word_seq,               char const *right_word_str, int *out_word_cnt){    int i, k, m;    int left_word_id = kb_get_word_id(left_word_str);    int right_word_id = kb_get_word_id(right_word_str);    dict_entry_t *left_word;    dict_entry_t *right_word;    char const *cur_word_str;    char *rem_word_seq;    int new_node;    int end_node[MAX_COMPOUND_LEN][MAX_NODES];    int end_node_cnt[MAX_COMPOUND_LEN];    int end_list_index[MAX_COMPOUND_LEN];    int *prior_end;    int *prior_end_cnt;    int *next_end;    int *next_end_cnt;    int word_cnt;    if (left_word_id < 0) {        E_ERROR("Cannot find left word %s in the dictionary\n",                left_word_str);        return -1;    }    if (right_word_id < 0) {        E_ERROR("Cannot find right word %s in the dictionary\n",                right_word_str);        return -1;    }    left_word = word_dict->dict_list[left_word_id];    right_word = word_dict->dict_list[right_word_id];    for (i = 0; i < MAX_COMPOUND_LEN; i++) {        end_list_index[i] = i;        end_node_cnt[i] = 0;    }    word_cnt = 0;    new_node = 0;    prior_end = end_node[end_list_index[0]];    prior_end_cnt = &end_node_cnt[end_list_index[0]];    phone_id_map[new_node] = left_word->ci_phone_ids[left_word->len - 1];    boundary[new_node] = TRUE;    word_id_map[new_node] = left_word_id;    ++word_cnt;    amatrix[new_node * MAX_NODES + 1] = RIGHT_ADJACENT;    prior_end[*prior_end_cnt] = new_node;    (*prior_end_cnt)++;    ++new_node;    phone_id_map[new_node] = sil_phone_id;      /* sil_phone_id for train, FILLER_PHONE_SEQ for test */    word_id_map[new_node] = sil_word_id;    boundary[new_node] = TRUE;    amatrix[new_node * MAX_NODES + 0] = LEFT_ADJACENT;    prior_end[*prior_end_cnt] = new_node;    (*prior_end_cnt)++;    ++new_node;    /* loop over the words in the word sequence */    rem_word_seq = word_seq;    do {        prior_end = end_node[end_list_index[0]];        prior_end_cnt = &end_node_cnt[end_list_index[0]];        for (m = 0; m < compound_word_cnt; m++) {            if (strncmp(compound_word_list[m].match_str, rem_word_seq,                        strlen(compound_word_list[m].match_str)) == 0) {                /* if substring matches */                if ((rem_word_seq[strlen(compound_word_list[m].match_str)]                     == ' ')                    ||                    (rem_word_seq[strlen(compound_word_list[m].match_str)]                     == '\0')) {                    /* and end of word */                    E_INFOCONT("\t%s applies to %s\n",                               compound_word_list[m].match_str,                               rem_word_seq);                    next_end =                        end_node[end_list_index                                 [compound_word_list[m].word_cnt]];                    next_end_cnt =                        &end_node_cnt[end_list_index                                      [compound_word_list[m].word_cnt]];                    cur_word_str = compound_word_list[m].word_str;                    /* add compound word and alternates */                    add_word(amatrix, boundary, phone_id_map, word_id_map,                             &new_node, &word_cnt,                             cur_word_str,                             next_end,                             next_end_cnt, prior_end, prior_end_cnt);                    /* add optional filler phone sequence after words just added */                    phone_id_map[new_node] = sil_phone_id;                    word_id_map[new_node] = sil_word_id;                    ++word_cnt;                    boundary[new_node] = TRUE;                    for (k = 0; k < *next_end_cnt; k++) {                        i = next_end[k];                        amatrix[i * MAX_NODES + new_node] = 1;                        amatrix[new_node * MAX_NODES + i] = -1;                    }                    next_end[*next_end_cnt] = new_node;                    (*next_end_cnt)++;                    new_node++;                }            }        }        next_end = end_node[end_list_index[1]];        next_end_cnt = &end_node_cnt[end_list_index[1]];        cur_word_str = next_transcript_word(&rem_word_seq);        /* add word and alternates */        add_word(amatrix, boundary, phone_id_map, word_id_map,                 &new_node, &word_cnt,                 cur_word_str,                 next_end, next_end_cnt, prior_end, prior_end_cnt);        /* add optional filler phone sequence after words just added */        phone_id_map[new_node] = sil_phone_id;        word_id_map[new_node] = sil_word_id;        ++word_cnt;        boundary[new_node] = TRUE;        for (k = 0; k < *next_end_cnt; k++) {            i = next_end[k];            amatrix[i * MAX_NODES + new_node] = 1;            amatrix[new_node * MAX_NODES + i] = -1;        }        next_end[*next_end_cnt] = new_node;        (*next_end_cnt)++;        new_node++;        /* zero the end count for the one which will become           MAX_COMPOUND_LEN out */        *prior_end_cnt = 0;        /* advance the end node indices w/ wraparound */        for (i = 0; i < MAX_COMPOUND_LEN; i++) {            end_list_index[i]++;            end_list_index[i] %= MAX_COMPOUND_LEN;        }    } while (rem_word_seq);     /* while there are words left to do */    phone_id_map[new_node] = right_word->ci_phone_ids[0];    word_id_map[new_node] = right_word_id;    ++word_cnt;    boundary[new_node] = FALSE;    prior_end = end_node[end_list_index[0]];    prior_end_cnt = &end_node_cnt[end_list_index[0]];    for (i = 0; i < *prior_end_cnt; i++) {        amatrix[prior_end[i] * MAX_NODES + new_node] = 1;        amatrix[new_node * MAX_NODES + prior_end[i]] = -1;    }    *final_model = new_node;    ++new_node;    *out_word_cnt = word_cnt;    return new_node;            /* i.e. the node count */}static char *model_name[MAX_NODES];static int32 *saved_phone_id_map;voidprint_phone_graph(short *amatrix, int node_cnt, int32 * phone_id_map,                  int *word_id_map){#if SHOW&SHOW_MODEL_DAG    int i, j, a;    for (i = 0; i < node_cnt; i++) {        if (phone_id_map[i] != FILLER_PHONE_SEQ)            E_INFOCONT("\"%s:%d\"\t", phone_from_id(phone_id_map[i]), i);        else            E_INFOCONT("\"FILL:%d\"\t", i);        for (j = 0; j < node_cnt; j++) {            int a = amatrix[i * MAX_NODES + j];            if (a == RIGHT_ADJACENT) {                if (phone_id_map[j] != FILLER_PHONE_SEQ)                    E_INFOCONT("\"%s:%d\" ",                               phone_from_id(phone_id_map[j]), j);                else                    E_INFOCONT("\"FILL:%d\" ", j);            }        }        E_INFOCONT(";\n");    }#endif}static voidmk_model(short *amatrix,         int node,         int node_cnt,         DYNMODEL_T * model, int32 * phone_id_map, int *out_next_cnt){    int i, j;    int next_cnt;    DYNMODEL_T *cur_model;    short *amatrix_row;    int *next_array;    cur_model = &model[node];    amatrix_row = &amatrix[node * MAX_NODES];    cur_model->model_best_score = WORST_SCORE;    if (phone_id_map[node] == NO_EVAL) {        cur_model->sseq_id = NO_EVAL;        cur_model->tmat_id = 0; /* BOGUS */    }    else {        cur_model->sseq_id = bin_mdef_pid2ssid(mdef,phone_id_map[node]);        cur_model->tmat_id = bin_mdef_pid2ci(mdef,phone_id_map[node]);    }    for (i = 0; i < NODE_CNT; i++) {        cur_model->score[i] = WORST_SCORE;        cur_model->wbp[i] = NO_BP;        cur_model->pbp[i] = NO_BP;        cur_model->sbp[i] = NO_BP;    }    for (i = 0, next_cnt = 0; i < node_cnt; i++) {        if (amatrix_row[i] == RIGHT_ADJACENT)            next_cnt++;    }    next_array = calloc(next_cnt, sizeof(int32));    for (i = 0, j = 0; i < node_cnt; i++) {        if (amatrix_row[i] == RIGHT_ADJACENT) {            next_array[j] = i;            ++j;        }    }    cur_model->next_cnt = next_cnt;    cur_model->next = next_array;    *out_next_cnt = next_cnt;}DYNMODEL_T *mk_viterbi_decode_models(short *amatrix,                         int node_cnt, int32 * phone_id_map){    DYNMODEL_T *model;    int i;    int succ_cnt;    int sum_succ_cnt;    model = calloc(node_cnt, sizeof(DYNMODEL_T));    for (i = 0, sum_succ_cnt = 0; i < node_cnt; i++) {        model_name[i] = ckd_salloc(phone_from_id(phone_id_map[i]));        mk_model(amatrix, i, node_cnt, model, phone_id_map, &succ_cnt);        sum_succ_cnt += succ_cnt;    }    return model;}static DYNMODEL_T *mk_models(int32 ** out_phone_id_map,    /* mapping from graph node to associated phone id */          int32 ** out_word_id_map,     /* mapping from graph node to associated word id */          char **out_boundary,  /* mapping from graph node to TRUE if graph node is                                   before a word boundary (i.e. an end node for a word) */          int *out_model_cnt,   /* number of nodes in final graph */          int *out_word_cnt,    /* number of words (incl. alts) in final graph */          int *final_model,     /* final model in the dag */          char const *left_word_str,    /* the left context word */          char *word_seq,       /* the sequence of words between the left context                                   and right context words exclusive */          char const *right_word_str){                               /* the right context word */    short *amatrix = NULL;      /* adjacency matrix for a graph of phone models */    char *boundary = NULL;      /* TRUE indicates word boundary to the right */    int32 *phone_id_map = NULL; /* the phone id's of the models in the graph */    int32 *word_id_map = NULL;  /* the word id's associated w/ the models in the graph */    int word_cnt;    int ci_node_cnt;    int node_cnt;    DYNMODEL_T *model;    amatrix = (short *) calloc(MAX_NODES * MAX_NODES, sizeof(short));    boundary = (char *) calloc(MAX_NODES, sizeof(char));    phone_id_map = (int32 *) calloc(MAX_NODES, sizeof(int32));    word_id_map = (int32 *) calloc(MAX_NODES, sizeof(int32));    ci_node_cnt =        mk_phone_graph(amatrix, boundary, phone_id_map, word_id_map,                       final_model, left_word_str, word_seq,                       right_word_str, &word_cnt);    if (ci_node_cnt < 0) {        free(amatrix);        free(boundary);        free(phone_id_map);        free(word_id_map);        return NULL;    }    print_phone_graph(amatrix, ci_node_cnt, phone_id_map, word_id_map);    node_cnt =        expand_phone_graph(amatrix, boundary, phone_id_map, word_id_map,                           ci_node_cnt);    print_phone_graph(amatrix, node_cnt, phone_id_map, word_id_map);    model = mk_viterbi_decode_models(amatrix, node_cnt, phone_id_map);    free(amatrix);    *out_boundary = boundary;    *out_word_id_map = word_id_map;    *out_phone_id_map = phone_id_map;    *out_model_cnt = node_cnt;    *out_word_cnt = word_cnt;    return model;}static BACK_POINTER_T *ck_alloc(BACK_POINTER_T * bp_table,         int entries_needed, int *in_out_max_entries, int size_increment){    int max_entries = *in_out_max_entries;    if (entries_needed > max_entries) {        E_INFO("Increasing BPTable size from %dK by %dK\n",               max_entries * sizeof(BACK_POINTER_T) / 1024,               size_increment * sizeof(BACK_POINTER_T) / 1024);        max_entries += size_increment;        assert(max_entries >= entries_needed);        bp_table = ckd_realloc(bp_table, max_entries * sizeof(BACK_POINTER_T));        *in_out_max_entries = max_entries;    }    return bp_table;}intnew_word_bp(int32 word_id, int prior_bp, int prior_score){    int i = word_bp_table_next_free;    word_bp_table = ck_alloc(word_bp_table, i + 1,                             &max_word_bp_table_size,                             WORD_BP_TABLE_SIZE_INCREMENT);    word_bp_table[i].id = word_id;

⌨️ 快捷键说明

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