📄 time_align.c
字号:
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 + -