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