int s2_write_dhmm(float32 ***tmat, float32 ***mixw, model_def_t *mdef, const char *dir) { acmod_set_t *acmod_set; model_def_entry_t *defn; uint32 b, n_state, i, j, err; uint32 n_acmod; float32 ***omixw = NULL; err = 0; acmod_set = mdef->acmod_set; n_acmod = acmod_set_n_acmod(acmod_set); for (i = 0; i < n_acmod; i++) { defn = &mdef->defn[i]; b = (uint32)acmod_set_base_phone(acmod_set, (acmod_id_t)i); if (omixw) ckd_free((void *)omixw); n_state = defn->n_state; omixw = (float32 ***)ckd_calloc(n_state, sizeof(float32 **)); for (j = 0; j < n_state-1; j++) { omixw[j] = mixw[defn->state[j]]; } if (put_dhmm(tmat[b], omixw, dir, acmod_set_id2s2name(acmod_set, (acmod_id_t)i)) != S3_SUCCESS) err = 1; } if (omixw) ckd_free((void *)omixw); if (!err) { return S3_SUCCESS; } else { return S3_ERROR; } }
int main(int argc, char *argv[]) { model_def_t *imdef; model_def_t *omdef; pset_t *pset; uint32 n_pset; dtree_t ***tree; uint32 n_seno; uint32 n_ci; uint32 n_acmod; uint32 p; uint32 s; model_def_entry_t *idefn, *odefn; acmod_id_t b, l, r; word_posn_t wp; int allphones; parse_cmd_ln(argc, argv); if (init(&imdef, &pset, &n_pset, &tree, &n_seno) != S3_SUCCESS) return 1; omdef = (model_def_t *)ckd_calloc(1, sizeof(model_def_t)); omdef->acmod_set = imdef->acmod_set; /* same set of acoustic models */ omdef->n_total_state = imdef->n_total_state; omdef->n_tied_ci_state = imdef->n_tied_ci_state; omdef->n_tied_state = imdef->n_tied_ci_state + n_seno; omdef->n_tied_tmat = imdef->n_tied_tmat; omdef->defn = (model_def_entry_t *)ckd_calloc(imdef->n_defn, sizeof(model_def_entry_t)); /* * Define the context-independent models */ n_ci = acmod_set_n_ci(imdef->acmod_set); for (p = 0; p < n_ci; p++) { idefn = &imdef->defn[p]; odefn = &omdef->defn[p]; odefn->p = idefn->p; odefn->tmat = idefn->tmat; odefn->state = ckd_calloc(idefn->n_state, sizeof(uint32)); odefn->n_state = idefn->n_state; for (s = 0; s < idefn->n_state; s++) { if (idefn->state[s] == NO_ID) odefn->state[s] = NO_ID; else { odefn->state[s] = idefn->state[s]; } } } /* * Define the rest of the models */ allphones = cmd_ln_int32("-allphones"); n_acmod = acmod_set_n_acmod(omdef->acmod_set); for (; p < n_acmod; p++) { b = acmod_set_base_phone(omdef->acmod_set, p); assert(p != b); idefn = &imdef->defn[p]; odefn = &omdef->defn[p]; odefn->p = idefn->p; odefn->tmat = idefn->tmat; odefn->state = ckd_calloc(idefn->n_state, sizeof(uint32)); odefn->n_state = idefn->n_state; for (s = 0; s < idefn->n_state; s++) { if (idefn->state[s] == NO_ID) /* Non-emitting state */ odefn->state[s] = NO_ID; else { uint32 bb; /* emitting state: find the tied state */ acmod_set_id2tri(omdef->acmod_set, &b, &l, &r, &wp, p); #ifdef HORRIBLY_VERBOSE fprintf(stderr, "%s %u ", acmod_set_id2name(omdef->acmod_set, p), s); #endif bb = allphones ? 0 : b; odefn->state[s] = tied_state(&tree[bb][s]->node[0], b, l, r, wp, pset); #ifdef HORRIBLY_VERBOSE fprintf(stderr, "\t-> %u\n", odefn->state[s]); fprintf(stderr, "\n"); #endif } } } if (model_def_write(omdef, cmd_ln_str("-omoddeffn")) != S3_SUCCESS) { return 1; } return 0; }
/* Converts the state map, smap, into a global one-to-one mapping from model states onto consecutive integers from 0 to some max */ int s2_convert_smap_to_global(acmod_set_t *acmod_set, uint32 **smap, uint32 **out_state_of, uint32 *cluster_size) { uint32 i; uint32 t; uint32 offset; uint32 n_ci = acmod_set_n_ci(acmod_set); uint32 n = acmod_set_n_multi(acmod_set) + n_ci; acmod_id_t b; acmod_id_t id; uint32 state; uint32 *state_of; uint32 ci_seno; offset = n_ci * (S2_N_STATE-1); E_INFO("|CI states| == %d\n", offset); /* convert the cluster_size matrix into an offset table */ for (i = 0; i < n_ci; i++) { t = cluster_size[i]; cluster_size[i] = offset; offset += t; E_INFO("|%s| == %d (%d)\n", acmod_set_id2name(acmod_set, i), t, offset); } cluster_size[i] = offset; /* total # of states */ state_of = ckd_calloc(offset, sizeof(uint32)); /* map the ci phones to unshared distribution */ for (id = 0; id < n_ci; id++) { for (state = 0; state < S2_N_STATE-1; state++) { ci_seno = id * (S2_N_STATE-1) + state; smap[id][state] = ci_seno; state_of[ci_seno] = state; } } /* use the ci phone offsets to convert ci phone relative mappings to a global one-to-one mapping onto consecutive integers from 0 to some max */ for (; id < n; id++) { for (state = 0; state < S2_N_STATE-1; state++) { if (smap[id][state] == TYING_NO_ID) { uint32 base_id; base_id = acmod_set_base_phone(acmod_set, id); E_WARN("%s<%d> is unmapped, approximating with CI state <%d>.\n", acmod_set_id2name(acmod_set, id), state, state); smap[id][state] = smap[base_id][state]; /* no state_of[] assignment need bee done since it was done above */ } else { b = acmod_set_base_phone(acmod_set, id); smap[id][state] += cluster_size[b]; state_of[ smap[id][state] ] = state; } } } *out_state_of = state_of; return S3_SUCCESS; }
int main(int argc, char *argv[]) { model_def_t *mdef; model_def_entry_t *defn; uint32 n_defn; uint32 *cluster_offset; uint32 max_int; uint32 *state_of; uint32 max_state; uint32 sstate; int32 i; uint32 j; uint32 n_base_phone; acmod_id_t base; acmod_id_t p; float32 ***out; uint32 **smap; char comment[4192]; time_t t; parse_cmd_ln(argc, argv); printf("%s(%d): Reading model definition file %s\n", __FILE__, __LINE__, (const char *)cmd_ln_access("-moddeffn")); if (model_def_read(&mdef, cmd_ln_access("-moddeffn")) != S3_SUCCESS) { exit(1); } defn = mdef->defn; n_defn = mdef->n_defn; printf("%s(%d): %d models defined\n", __FILE__, __LINE__, n_defn); smap = ckd_calloc(n_defn, sizeof(uint32 *)); n_base_phone = acmod_set_n_ci(mdef->acmod_set); cluster_offset = ckd_calloc(n_base_phone+1, sizeof(uint32)); max_int = 0; --max_int; /* underflow offset values to max value */ for (i = 0; i < n_base_phone; i++) { cluster_offset[i] = max_int; } for (i = 0, max_state = 0; i < n_defn; i++) { for (j = 0; j < defn[i].n_state; j++) { sstate = defn[i].state[j]; if ((sstate != TYING_NON_EMITTING) && (defn[i].state[j] > max_state)) max_state = defn[i].state[j]; } } /* record the total # of senones */ cluster_offset[n_base_phone] = max_state+1; state_of = ckd_calloc(max_state+1, sizeof(uint32)); for (i = 0; i <= max_state; i++) state_of[i] = NO_STATE; for (i = 0; i < n_defn; i++) { p = defn[i].p; base = acmod_set_base_phone(mdef->acmod_set, defn[i].p); smap[i] = defn[i].state; for (j = 0; j < defn[i].n_state; j++) { sstate = defn[i].state[j]; if (sstate != TYING_NON_EMITTING) { if (state_of[sstate] == NO_STATE) state_of[sstate] = j; else if (state_of[sstate] != j) { printf("%s %d appears as %d%s and %d%s model states\n", acmod_set_id2name(mdef->acmod_set, acmod_set_base_phone(mdef->acmod_set, defn[i].p)), sstate, state_of[sstate], ord_suff(state_of[sstate]), j, ord_suff(j)); } if ((p != base) && (cluster_offset[base] > sstate)) { cluster_offset[base] = sstate; } } } } /* any untouched CLUSTER_OFFSET's implies a base phone without any CD states. So offset is same as next one */ for (i = (n_base_phone - 1); i >= 0 ; i--) { if (cluster_offset[i] == max_int) cluster_offset[i] = cluster_offset[i+1]; } fflush(stdout); for (i = 0; i < n_base_phone; i++) { if (cluster_offset[i] != max_int) { fprintf(stderr, "%s(%d): %s offset %d\n", __FILE__, __LINE__, acmod_set_id2name(mdef->acmod_set, i), cluster_offset[i]); } else { fprintf(stderr, "%s(%d): %s <no CD states>\n", __FILE__, __LINE__, acmod_set_id2name(mdef->acmod_set, i)); } } fflush(stderr); printf("%s(%d): Reading senone weights in %s with floor %e\n", __FILE__, __LINE__, (const char *)cmd_ln_access("-hmmdir"), *(float32 *)cmd_ln_access("-floor")); out = s2_read_seno_3(mdef->acmod_set, cluster_offset, cmd_ln_access("-hmmdir"), (*(int32 *)cmd_ln_access("-ci2cd") ? NULL : smap), *(float32 *)cmd_ln_access("-floor"), state_of); t = time(NULL); sprintf(comment, "Generated on %s\n\tmoddeffn: %s\n\tfloor: %e\n\thmmdir: %s\n\n\n\n\n\n\n\n\n", ctime(&t), (const char *)cmd_ln_access("-moddeffn"), *(float32 *)cmd_ln_access("-floor"), (const char *)cmd_ln_access("-hmmdir")); fflush(stdout); fprintf(stderr, "%s(%d): writing %s\n", __FILE__, __LINE__, (const char *)cmd_ln_access("-mixwfn")); fflush(stderr); if (s3mixw_write(cmd_ln_access("-mixwfn"), out, cluster_offset[n_base_phone], /* total # states */ S2_N_FEATURE, S2_N_CODEWORD) != S3_SUCCESS) { fflush(stdout); fprintf(stderr, "%s(%d): couldn't write mixture weight file\n", __FILE__, __LINE__); perror(cmd_ln_access("-mixwfn")); fflush(stderr); } ckd_free(state_of); ckd_free(cluster_offset); return 0; }
static int init_mixw() { model_def_t *src_mdef; float32 ***src_mixw; vector_t ***src_mean; vector_t ***src_var = NULL; vector_t ****src_fullvar = NULL; float32 ***src_tmat; model_def_t *dest_mdef; float32 ***dest_mixw; vector_t ***dest_mean; vector_t ***dest_var = NULL; vector_t ****dest_fullvar = NULL; float32 ***dest_tmat; uint32 n_mixw_src; uint32 n_mixw_dest; uint32 n_feat; uint32 tmp_n_feat; uint32 n_gau; uint32 tmp_n_gau; uint32 n_cb_src; uint32 n_cb_dest; uint32 n_state_pm; uint32 n_tmat_src; uint32 n_tmat_dest; uint32 *veclen; uint32 *tmp_veclen; uint32 m; uint32 dest_m; uint32 dest_m_base; uint32 src_m; acmod_id_t src_m_base; const char *dest_m_name; const char *dest_m_base_name; uint32 i; uint32 n_ts; uint32 n_cb; const char *ts2cbfn; E_INFO("Reading src %s\n", cmd_ln_str("-src_moddeffn")); /* read in the source model definition file */ if (model_def_read(&src_mdef, cmd_ln_str("-src_moddeffn")) != S3_SUCCESS) { return S3_ERROR; } ts2cbfn = cmd_ln_str("-src_ts2cbfn"); if (strcmp(SEMI_LABEL, ts2cbfn) == 0) { E_INFO("Generating semi-continous ts2cb mapping\n"); src_mdef->cb = semi_ts2cb(src_mdef->n_tied_state); n_ts = src_mdef->n_tied_state; n_cb = 1; } else if (strcmp(CONT_LABEL, ts2cbfn) == 0) { E_INFO("Generating continous ts2cb mapping\n"); src_mdef->cb = cont_ts2cb(src_mdef->n_tied_state); n_ts = src_mdef->n_tied_state; n_cb = src_mdef->n_tied_state; } else if (strcmp(PTM_LABEL, ts2cbfn) == 0) { E_INFO("Generating phonetically tied ts2cb mapping\n"); src_mdef->cb = ptm_ts2cb(src_mdef); n_ts = src_mdef->n_tied_state; n_cb = src_mdef->acmod_set->n_ci; } else { E_INFO("Reading src %s\n", cmd_ln_str("-src_ts2cbfn")); if (s3ts2cb_read(ts2cbfn, &src_mdef->cb, &n_ts, &n_cb) != S3_SUCCESS) { return S3_ERROR; } } E_INFO("Reading src %s\n", cmd_ln_str("-src_mixwfn")); /* read in the source mixing weight parameter file */ if (s3mixw_read(cmd_ln_str("-src_mixwfn"), &src_mixw, &n_mixw_src, &n_feat, &n_gau) != S3_SUCCESS) { return S3_ERROR; } E_INFO("Reading src %s\n", cmd_ln_str("-src_tmatfn")); if (s3tmat_read(cmd_ln_str("-src_tmatfn"), &src_tmat, &n_tmat_src, &n_state_pm) != S3_SUCCESS) { return S3_ERROR; } E_INFO("Reading src %s\n", cmd_ln_str("-src_meanfn")); if (s3gau_read(cmd_ln_str("-src_meanfn"), &src_mean, &n_cb_src, &tmp_n_feat, &tmp_n_gau, &veclen) != S3_SUCCESS) { return S3_ERROR; } if (tmp_n_feat != n_feat) { E_FATAL("src mean n_feat (== %u) != prior value (== %u)\n", tmp_n_feat, n_feat); } if (tmp_n_gau != n_gau) { E_FATAL("src mean n_gau (== %u) != prior value (== %u)\n", tmp_n_gau, n_gau); } if (n_cb_src != n_cb) { E_FATAL("src mean n_cb (== %u) is inconsistent with ts2cb mapping %u. Most probably phoneset has duplicated phones\n", n_cb_src, n_cb); } E_INFO("Reading src %s\n", cmd_ln_str("-src_varfn")); if (cmd_ln_int32("-fullvar")) { if (s3gau_read_full(cmd_ln_str("-src_varfn"), &src_fullvar, &n_cb_src, &tmp_n_feat, &tmp_n_gau, &tmp_veclen) != S3_SUCCESS) { return S3_ERROR; } } else { if (s3gau_read(cmd_ln_str("-src_varfn"), &src_var, &n_cb_src, &tmp_n_feat, &tmp_n_gau, &tmp_veclen) != S3_SUCCESS) { return S3_ERROR; } } if (tmp_n_feat != n_feat) { E_FATAL("src var n_feat (== %u) != prior value (== %u)\n", tmp_n_feat, n_feat); } if (tmp_n_gau != n_gau) { E_FATAL("src var n_gau (== %u) != prior value (== %u)\n", tmp_n_gau, n_gau); } if (n_cb_src != n_cb) { E_FATAL("src var n_cb (== %u) inconsistent w/ ts2cb mapping %u\n", n_cb_src, n_cb); } if (n_mixw_src < src_mdef->n_tied_state) { E_FATAL("Too few source mixing weights, %u, for the # of tied states, %u\n", n_mixw_src, src_mdef->n_tied_state); } for (i = 0; i < n_feat; i++) { if (veclen[i] != tmp_veclen[i]) { E_FATAL("src var veclen[%u] (== %u) != prior value (== %u)\n", i, tmp_veclen[i], veclen[i]); } } ckd_free(tmp_veclen); E_INFO("Reading dest %s\n", cmd_ln_str("-dest_moddeffn")); /* read in the destination model definition file */ if (model_def_read(&dest_mdef, cmd_ln_str("-dest_moddeffn")) < S3_SUCCESS) { return S3_ERROR; } ts2cbfn = cmd_ln_str("-dest_ts2cbfn"); if (strcmp(SEMI_LABEL, ts2cbfn) == 0) { E_INFO("Generating semi-continous ts2cb mapping\n"); dest_mdef->cb = semi_ts2cb(dest_mdef->n_tied_state); n_ts = dest_mdef->n_tied_state; n_cb = 1; } else if (strcmp(CONT_LABEL, ts2cbfn) == 0) { E_INFO("Generating continous ts2cb mapping\n"); dest_mdef->cb = cont_ts2cb(dest_mdef->n_tied_state); n_ts = dest_mdef->n_tied_state; n_cb = dest_mdef->n_tied_state; } else if (strcmp(PTM_LABEL, ts2cbfn) == 0) { E_INFO("Generating phonetically tied ts2cb mapping\n"); dest_mdef->cb = ptm_ts2cb(dest_mdef); n_ts = dest_mdef->n_tied_state; n_cb = dest_mdef->acmod_set->n_ci; } else { E_INFO("Reading dest %s\n", cmd_ln_str("-dest_ts2cbfn")); if (s3ts2cb_read(ts2cbfn, &dest_mdef->cb, &n_ts, &n_cb) != S3_SUCCESS) { return S3_ERROR; } } E_INFO("Calculating initial model parameters\n"); n_tmat_dest = dest_mdef->n_tied_tmat; tmat_dest_list = init_was_added(n_tmat_dest); E_INFO("Alloc %ux%ux%u dest tmat\n", n_tmat_dest, n_state_pm-1, n_state_pm); dest_tmat = (float32 ***)ckd_calloc_3d(n_tmat_dest, n_state_pm-1, n_state_pm, sizeof(float32)); n_mixw_dest = dest_mdef->n_tied_state; mixw_dest_list = init_was_added(n_mixw_dest); E_INFO("Alloc %ux%ux%u dest mixw\n", n_mixw_dest, n_feat, n_gau); dest_mixw = (float32 ***)ckd_calloc_3d(n_mixw_dest, n_feat, n_gau, sizeof(float32)); for (i = 0, n_cb_dest = 0; i < n_mixw_dest; i++) { if (dest_mdef->cb[i] > n_cb_dest) { n_cb_dest = dest_mdef->cb[i]; } } ++n_cb_dest; cb_dest_list = init_was_added(n_cb_dest); E_INFO("Alloc %ux%ux%u dest mean and var\n", n_cb_dest, n_feat, n_gau); dest_mean = gauden_alloc_param(n_cb_dest, n_feat, n_gau, veclen); if (src_var) dest_var = gauden_alloc_param(n_cb_dest, n_feat, n_gau, veclen); else if (src_fullvar) dest_fullvar = gauden_alloc_param_full(n_cb_dest, n_feat, n_gau, veclen); for (dest_m = 0; dest_m < dest_mdef->n_defn; dest_m++) { dest_m_name = acmod_set_id2name(dest_mdef->acmod_set, dest_m); src_m = acmod_set_name2id(src_mdef->acmod_set, dest_m_name); if (src_m == NO_ACMOD) { /* No corresponding phone model in the source set */ /* See if there is a source base phone corresponding to this destination model base phone */ dest_m_base = acmod_set_base_phone(dest_mdef->acmod_set, dest_m); dest_m_base_name = acmod_set_id2name(dest_mdef->acmod_set, dest_m_base); src_m_base = acmod_set_name2id(src_mdef->acmod_set, dest_m_base_name); if (src_m_base == NO_ACMOD) { /* No corresponding model or base model found. Use uniform distribution */ E_INFO("No source base phone %s found. Initializing %s using uniform distribution\n", dest_m_base_name, dest_m_name); if (src_tmat) { E_INFO("Uniform initialization of tmat not supported\n"); } init_uniform(dest_mixw, &dest_mdef->defn[dest_m], n_feat, n_gau); } else { /* No corresponding model, but a base model was found. Use base distribution. */ init_model(dest_mixw, dest_mean, dest_var, dest_fullvar, dest_tmat, &dest_mdef->defn[dest_m], dest_mdef->cb, dest_mdef->acmod_set, src_mixw, src_mean, src_var, src_fullvar, src_tmat, &src_mdef->defn[src_m_base], src_mdef->cb, src_mdef->acmod_set, n_feat, n_gau, n_state_pm, veclen); } } else { /* Found a corresponding model in the source set, so use source distributions to init the destination */ init_model(dest_mixw, dest_mean, dest_var, dest_fullvar, dest_tmat, &dest_mdef->defn[dest_m], dest_mdef->cb, dest_mdef->acmod_set, src_mixw, src_mean, src_var, src_fullvar, src_tmat, &src_mdef->defn[src_m], src_mdef->cb, src_mdef->acmod_set, n_feat, n_gau, n_state_pm, veclen); } } for (m = 0; m < n_mixw_dest; m++) { if (mixw_dest_list[m] == NULL) { E_WARN("Destination state %u has not been initialized!\n", m); } } for (m = 0; m < n_cb_dest; m++) { if (cb_dest_list[m] == NULL) { E_WARN("Destination cb %u has not been initialized!\n", m); } else if (cb_dest_list[m]->next != NULL) { E_WARN("dest cb %u has > 1 corresponding source cb\n", m); } } E_INFO("Writing dest %s\n", cmd_ln_str("-dest_tmatfn")); if (s3tmat_write(cmd_ln_str("-dest_tmatfn"), dest_tmat, n_tmat_dest, n_state_pm) != S3_SUCCESS) { return S3_ERROR; } E_INFO("Writing dest %s\n", cmd_ln_str("-dest_mixwfn")); if (s3mixw_write(cmd_ln_str("-dest_mixwfn"), dest_mixw, dest_mdef->n_tied_state, n_feat, n_gau) < S3_SUCCESS) { return S3_ERROR; } E_INFO("Writing dest %s\n", cmd_ln_str("-dest_meanfn")); if (s3gau_write(cmd_ln_str("-dest_meanfn"), (const vector_t ***)dest_mean, n_cb_dest, n_feat, n_gau, veclen) != S3_SUCCESS) { return S3_ERROR; } E_INFO("Writing dest %s\n", cmd_ln_str("-dest_varfn")); if (cmd_ln_int32("-fullvar")) { if (s3gau_write_full(cmd_ln_str("-dest_varfn"), (const vector_t ****)dest_fullvar, n_cb_dest, n_feat, n_gau, veclen) != S3_SUCCESS) { return S3_ERROR; } } else { if (s3gau_write(cmd_ln_str("-dest_varfn"), (const vector_t ***)dest_var, n_cb_dest, n_feat, n_gau, veclen) != S3_SUCCESS) { return S3_ERROR; } } ckd_free(veclen); return S3_SUCCESS; }