void print_phone_list(acmod_id_t *p, uint32 n_p, char *btw, acmod_set_t *acmod_set) { uint32 i, j, k; uint32 mpl, l; char fmt[16]; uint32 ppl; for (i = 0, mpl = 0; i < n_p; i++) { l = strlen(acmod_set_id2name(acmod_set, p[i])); if (l > mpl) mpl = l; } sprintf(fmt, "%%%ds%%s", mpl); ppl = 80 / mpl; /* print out the phone sequence in rows of at most PPL phones */ for (i = 0; i < n_p; i += ppl) { for (j = i, k = (i + ppl > n_p ? n_p : i + ppl); j < k; j++) { printf(fmt, "", (btw[j] ? "+" : " ")); } printf("\n"); for (j = i, k = (i + ppl > n_p ? n_p : i + ppl); j < k; j++) { printf(fmt, acmod_set_id2name(acmod_set, p[j]), " "); } printf("\n"); printf("\n"); } }
int s3phseg_write(const char *fn, acmod_set_t *acmod_set, s3phseg_t *phseg) { FILE *fp; if ((fp = fopen(fn, "w")) == NULL) return S3_ERROR; fprintf (fp, "\t%5s %5s %9s %s\n", "SFrm", "EFrm", "SegAScr", "Phone"); for (; phseg; phseg = phseg->next) { fprintf(fp, "\t%5d %5d %9d %s\n", phseg->sf, phseg->ef, phseg->score, acmod_set_id2name(acmod_set, phseg->phone)); } fclose (fp); return S3_SUCCESS; }
void accum_global_tmat(model_inventory_t *inv, state_t *state, uint32 n_state) { float32 ***tmat_acc; /* global tmat accumulators */ float32 **l_tmat_acc; /* local tmat accumulators (indexed by sentence HMM state id) */ uint32 tmat; /* a transition matrix id */ uint32 model_i; /* a model source state */ uint32 model_j; /* a model destination state */ uint32 next_tmat; /* the transition matrix associated w/ the destination state */ uint32 i, u, j; /* iterators and temporary variables */ tmat_acc = inv->tmat_acc; l_tmat_acc = inv->l_tmat_acc; for (i = 0; i < n_state; i++) { tmat = state[i].tmat; model_i = state[i].m_state; for (u = 0; u < state[i].n_next; u++) { j = state[i].next_state[u]; next_tmat = state[j].tmat; model_j = state[j].m_state; if ((next_tmat == tmat) && (model_i <= model_j)) { /* internal phone model transition */ #ifdef ACCUM_VERBOSE printf("(%s %d %d) += (%d %d)\n", acmod_set_id2name(inv->acmod_set, tmat), model_i, model_j, i, j); #endif tmat_acc[tmat][model_i][model_j] += l_tmat_acc[i][j-i]; } } } }
int s2_write_hmm(float32 ***tmat, acmod_set_t *acmod_set, const char *out_dir_name) { uint32 n_ci; uint32 i; int err; n_ci = acmod_set_n_ci(acmod_set); E_INFO("Writing %d tied CI transition matrices to %s\n", n_ci, out_dir_name); err = 0; for (i = 0; i < n_ci; i++) { if (put_sdm(tmat[i], out_dir_name, acmod_set_id2name(acmod_set, i)) != S3_SUCCESS) err = 1; #ifdef S2_WRITE_HMM_VERBOSE if (!err) { print_tmat(stdout, tmat[i], S2_N_STATE); fflush(stdout); } #endif } if (!err) { return S3_SUCCESS; } else { return S3_ERROR; } }
uint32 setup_d2o_map(model_def_t *d_mdef, model_def_t *o_mdef) { model_def_entry_t *o_defn, *d_defn; uint32 d_ts; uint32 o_ts; uint32 *mapped; uint32 i, j, k, d; const char *nm; int did_warn = FALSE; if (d_mdef->n_tied_state < o_mdef-> n_tied_state) { E_FATAL("more tied states in output than in dump mdef (%u vs %u)\n", o_mdef->n_tied_state, d_mdef->n_tied_state); } if (d_mdef->n_tied_ci_state != o_mdef->n_tied_ci_state) { E_FATAL("# tied ci state in output, %u not equal to # in dmp, %u\n", o_mdef->n_tied_ci_state, d_mdef->n_tied_ci_state); } n_o2d = (uint32 *)ckd_calloc(o_mdef->n_tied_state, sizeof(uint32)); i_o2d = (uint32 *)ckd_calloc(o_mdef->n_tied_state, sizeof(uint32)); o2d = (uint32 **)ckd_calloc(o_mdef->n_tied_state, sizeof(uint32 *)); mapped = (uint32 *)ckd_calloc(d_mdef->n_tied_state, sizeof(uint32)); for (i = 0; i < o_mdef->n_defn; i++) { nm = acmod_set_id2name(o_mdef->acmod_set, i); d = acmod_set_name2id(d_mdef->acmod_set, nm); if (d == NO_ID) { if (!did_warn) { E_WARN("Some models in the output mdef not in the dump mdef\n"); did_warn = TRUE; } continue; } o_defn = &o_mdef->defn[i]; d_defn = &d_mdef->defn[d]; for (j = 0; j < o_defn->n_state; j++) { o_ts = o_defn->state[j]; d_ts = d_defn->state[j]; if ((o_ts != TYING_NO_ID) && (o_ts != TYING_NO_ID)) { if (mapped[d_ts] == FALSE) { ++n_o2d[o_ts]; mapped[d_ts] = TRUE; } } else { if (!((o_ts == TYING_NO_ID) && (o_ts == TYING_NO_ID))) { E_INFO("%s state is NULL but %s isn't.\n", (o_ts == TYING_NO_ID ? "output" : "dump"), (o_ts == TYING_NO_ID ? "dump" : "output")); } } } } for (i = 0; i < o_mdef->n_tied_state; i++) { o2d[i] = (uint32 *)ckd_calloc(n_o2d[i], sizeof(uint32)); } for (i = 0; i < o_mdef->n_defn; i++) { /* Figure out the index in the dump mdef for the model in the output mdef */ nm = acmod_set_id2name(o_mdef->acmod_set, i); d = acmod_set_name2id(d_mdef->acmod_set, nm); if (d == NO_ID) continue; o_defn = &o_mdef->defn[i]; d_defn = &d_mdef->defn[d]; for (j = 0; j < o_defn->n_state; j++) { o_ts = o_defn->state[j]; d_ts = d_defn->state[j]; if ((o_ts != TYING_NO_ID) && (o_ts != TYING_NO_ID)) { for (k = 0; k < i_o2d[o_ts]; k++) { if (o2d[o_ts][k] == d_ts) break; } if (k == i_o2d[o_ts]) { o2d[o_ts][i_o2d[o_ts]++] = d_ts; } } else { if (!((o_ts == TYING_NO_ID) && (o_ts == TYING_NO_ID))) { E_INFO("%s state is NULL but %s isn't.\n", (o_ts == TYING_NO_ID ? "output" : "dump"), (o_ts == TYING_NO_ID ? "dump" : "output")); } } } } for (i = 0; i < o_mdef->n_tied_state; i++) { if (i_o2d[i] != n_o2d[i]) { E_FATAL("%u != %u for %u\n", i_o2d[i], n_o2d[i], i); } } for (i = 0; i < o_mdef->n_tied_state; i++) { i_o2d[i] = 0; } return S3_SUCCESS; }
int32 model_def_write(model_def_t *mdef, const char *fn) { FILE *fp; uint32 n_ci; uint32 n_acmod; acmod_set_t *acmod_set; const char **attrib; acmod_id_t b; acmod_id_t l; acmod_id_t r; word_posn_t wp; uint32 p; char *wp2c = WORD_POSN_CHAR_MAP; uint32 i; fp = fopen(fn, "w"); if (fp == NULL) { E_ERROR_SYSTEM("Unable to open %s for writing", fn); return S3_ERROR; } acmod_set = mdef->acmod_set; fprintf(fp, "%s\n", MODEL_DEF_VERSION); n_ci = acmod_set_n_ci(acmod_set); fprintf(fp, "%u n_base\n", n_ci); fprintf(fp, "%u n_tri\n", acmod_set_n_multi(acmod_set)); fprintf(fp, "%u n_state_map\n", mdef->n_total_state); fprintf(fp, "%u n_tied_state\n", mdef->n_tied_state); fprintf(fp, "%u n_tied_ci_state\n", mdef->n_tied_ci_state); fprintf(fp, "%u n_tied_tmat\n", mdef->n_tied_tmat); fprintf(fp, "#\n# Columns definitions\n"); fprintf(fp, "#%4s %3s %3s %1s %6s %4s %s\n", "base", "lft", "rt", "p", "attrib", "tmat", " ... state id's ..."); n_acmod = acmod_set_n_acmod(acmod_set); for (p = 0; p < n_ci; p++) { fprintf(fp, "%5s %3s %3s %1s", acmod_set_id2name(acmod_set, p), "-", "-", "-"); attrib = acmod_set_attrib(acmod_set, p); if ((attrib == NULL) || (attrib[0] == NULL)) { fprintf(fp, " %6s", "n/a"); } else { fprintf(fp, " %6s", attrib[0]); for (i = 1; attrib[i]; i++) { fprintf(fp, ",%s", attrib[i]); } } fprintf(fp, " %4d", mdef->defn[p].tmat); for (i = 0; i < mdef->defn[p].n_state; i++) { if (mdef->defn[p].state[i] == NO_ID) { fprintf(fp, " N"); } else { fprintf(fp, " %6u", mdef->defn[p].state[i]); } } fprintf(fp, "\n"); } for (; p < n_acmod; p++) { acmod_set_id2tri(acmod_set, &b, &l, &r, &wp, p); fprintf(fp, "%5s %3s %3s %c", acmod_set_id2name(acmod_set, b), acmod_set_id2name(acmod_set, l), acmod_set_id2name(acmod_set, r), wp2c[(uint32)wp]); attrib = acmod_set_attrib(acmod_set, p); if ((attrib == NULL) || (attrib[0] == NULL)) { fprintf(fp, " %6s", "n/a"); } else { fprintf(fp, " %6s", attrib[0]); for (i = 1; attrib[i]; i++) { fprintf(fp, ",%s", attrib[i]); } } fprintf(fp, " %4d", mdef->defn[p].tmat); for (i = 0; i < mdef->defn[p].n_state; i++) { if (mdef->defn[p].state[i] == NO_ID) { fprintf(fp, " N"); } else { fprintf(fp, " %6u", mdef->defn[p].state[i]); } } fprintf(fp, "\n"); } fclose(fp); return S3_SUCCESS; }
int init(model_def_t **out_imdef, pset_t **out_pset, uint32 *out_n_pset, dtree_t ****out_tree, uint32 *out_n_seno) { model_def_t *imdef; uint32 p, s; uint32 n_ci, n_state; char fn[MAXPATHLEN+1]; const char *a_fn; FILE *fp; dtree_t ***tree, *tr; pset_t *pset; uint32 n_pset; uint32 n_seno; const char *treedir; uint32 ts_id; int allphones; a_fn = cmd_ln_str("-imoddeffn"); if (a_fn == NULL) E_FATAL("Specify -imoddeffn\n"); if (model_def_read(&imdef, a_fn) != S3_SUCCESS) { return S3_ERROR; } *out_imdef = imdef; a_fn = cmd_ln_str("-psetfn"); E_INFO("Reading: %s\n", a_fn); *out_pset = pset = read_pset_file(a_fn, imdef->acmod_set, &n_pset); *out_n_pset = n_pset; allphones = cmd_ln_int32("-allphones"); if (allphones) n_ci = 1; else n_ci = acmod_set_n_ci(imdef->acmod_set); treedir = cmd_ln_str("-treedir"); tree = (dtree_t ***)ckd_calloc(n_ci, sizeof(dtree_t **)); *out_tree = tree; ts_id = imdef->n_tied_ci_state; for (p = 0, n_seno = 0; p < n_ci; p++) { if (allphones || !acmod_set_has_attrib(imdef->acmod_set, p, "filler")) { const char *pname; if (allphones) { n_state = imdef->defn[acmod_set_n_ci(imdef->acmod_set)].n_state; pname = "ALLPHONES"; } else { n_state = imdef->defn[p].n_state; pname = acmod_set_id2name(imdef->acmod_set, p); } tree[p] = (dtree_t **)ckd_calloc(n_state, sizeof(dtree_t *)); for (s = 0; s < n_state-1; s++) { E_INFO("%s-%u: offset %u\n", pname, s, ts_id); sprintf(fn, "%s/%s-%u.dtree", treedir, pname, s); fp = fopen(fn, "r"); if (fp == NULL) { E_FATAL_SYSTEM("Unable to open %s for reading", fn); } tree[p][s] = tr = read_final_tree(fp, pset, n_pset); label_leaves(&tr->node[0], &ts_id); fclose(fp); n_seno += cnt_leaf(&tr->node[0]); } } } assert(n_seno == (ts_id - imdef->n_tied_ci_state)); E_INFO("n_seno= %u\n", ts_id); *out_n_seno = n_seno; return S3_SUCCESS; }
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; }
int cnt_phn_seg(model_def_t *mdef, lexicon_t *lex, uint32 **out_n_seg, uint32 ***out_n_frame_per) { uint32 seq_no = 0; uint16 *seg; uint32 n_frame; uint32 i, j; uint32 n_acmod; uint32 *phone; uint32 n_phone; uint32 *n_seg; uint32 **n_frame_per; uint32 *start; uint32 *len; seg_len_t *cur; seg_len_t *tmp; seg_len_t *phn_hd; seg_len_t *phn_tl; n_acmod = acmod_set_n_acmod(mdef->acmod_set); E_INFO("Counting # occ. for %u models\n", n_acmod); n_seg = ckd_calloc(n_acmod, sizeof(uint32)); hd = ckd_calloc(n_acmod, sizeof(seg_len_t *)); tl = ckd_calloc(n_acmod, sizeof(seg_len_t *)); for (seq_no = corpus_get_begin(); corpus_next_utt(); seq_no++) { if (!(seq_no % 250)) { fprintf(stderr, " cnt[%u]", seq_no); fflush(stderr); } corpus_get_seg(&seg, &n_frame); phone = get_next_phnseq(mdef, lex, &n_phone); ck_seg(mdef->acmod_set, phone, n_phone, seg, n_frame, corpus_utt()); start = ckd_calloc(n_phone, sizeof(uint32)); len = ckd_calloc(n_phone, sizeof(uint32)); mk_seg(mdef->acmod_set, seg, n_frame, phone, start, len, n_phone); ckd_free(start); ckd_free(seg); ckd_free(phone); for (i = 0; i < n_phone; i++) { /* insert the len for list phone[i] */ phn_hd = hd[phone[i]]; phn_tl = tl[phone[i]]; cur = (seg_len_t *)ckd_calloc(1, sizeof(seg_len_t)); cur->len = len[i]; if (phn_tl == NULL) { hd[phone[i]] = tl[phone[i]] = cur; } else { phn_tl->nxt = cur; tl[phone[i]] = cur; } } ckd_free(len); } n_frame_per = (uint32 **)ckd_calloc(n_acmod, sizeof(uint32 *)); for (i = 0; i < n_acmod; i++) { if (hd[i] == NULL) { n_seg[i] = 0; } else { for (cur = hd[i], j = 0; cur != NULL; j++, cur = cur->nxt); n_seg[i] = j; n_frame_per[i] = (uint32 *)ckd_calloc(n_seg[i], sizeof(uint32)); for (cur = hd[i], j = 0; cur != NULL; j++, cur = cur->nxt) n_frame_per[i][j] = cur->len; for (cur = hd[i]; cur != NULL; cur = tmp) { tmp = cur->nxt; ckd_free(cur); } E_INFO("phn= %s n_seg= %u\n", acmod_set_id2name(mdef->acmod_set, i), n_seg[i]); } } ckd_free(hd); ckd_free(tl); *out_n_seg = n_seg; *out_n_frame_per = n_frame_per; return S3_SUCCESS; }
/********************************************************************* * * File: viterbi.c * * Description: * * Authors: * David Huggins-Daines * Eric Thayer *********************************************************************/ #include "forward.h" #include "backward.h" #include "viterbi.h" #include "accum.h" #include <sphinxbase/ckd_alloc.h> #include <s3/profile.h> #include <s3/remap.h> #include <s3/corpus.h> #include <s3/err.h> #include <sphinxbase/cmd_ln.h> #include <s3/s3phseg_io.h> #include <s3/model_def.h> #include <s2/byteorder.h> #include <math.h> #include <string.h> #include <assert.h> #include <stdio.h> #define INVLOGS3 100000.5 /* (1.0/log(1.0001)) */ int32 write_phseg(const char *filename, model_inventory_t *modinv, state_t *state_seq, uint32 **active_astate, uint32 *n_active_astate, uint32 n_state, uint32 n_obs, float64 **active_alpha, float64 *scale, uint32 **bp) { FILE *fh; int32 t; uint32 q; s3phseg_t *phseg, *next; model_def_t *mdef; model_def_entry_t *defn; uint32 n_defn; float64 ascr; /* Find the non-emitting ending state */ for (q = 0; q < n_active_astate[n_obs-1]; ++q) { if (active_astate[n_obs-1][q] == n_state-1) break; } if (q == n_active_astate[n_obs-1]) { E_ERROR("Failed to align audio to trancript: final state of the search is not reached\n"); return S3_ERROR; } if ((fh = fopen(filename, "w")) == NULL) { return S3_ERROR; } /* Backtrace and build a phone segmentation */ mdef = modinv->mdef; defn = mdef->defn; n_defn = mdef->n_defn; phseg = NULL; ascr = 0; for (t = n_obs-1; t >= 0; --t) { uint32 j; j = active_astate[t][q]; /* Follow any non-emitting states at time t first. */ if (state_seq[j].mixw == TYING_NON_EMITTING) { s3phseg_t *prev; uint32 phn; int k, l; while (state_seq[j].mixw == TYING_NON_EMITTING) { j = active_astate[t][bp[t][q]]; q = bp[t][q]; } /* Do a rather nasty mdef scan to find the triphone in question. */ for (phn = 0; phn < n_defn; phn++) { for (k = defn[phn].n_state - 2, l = j; k >= 0 && l >= 0; k--, l--) { if (state_seq[l].mixw != defn[phn].state[k]) break; } if (k < 0) break; } if (phn == n_defn) { E_ERROR("Failed to find triphone for senone %u\n", state_seq[j].mixw); } /* Record ascr and sf for the next phone */ if (phseg) { phseg->score = (int32)(ascr * INVLOGS3); phseg->sf = t + 1; ascr = 0; } prev = ckd_calloc(1, sizeof(*prev)); prev->next = phseg; prev->phone = phn; prev->ef = t; phseg = prev; } /* Multiply alphas to get "acoustic score" for this phone */ ascr += (log(active_alpha[t][q]) + log(scale[t])); /* Backtrace. */ if (t > 0) { q = bp[t][q]; } } fprintf(fh, "\t%5s %5s %9s %s\n", "SFrm", "EFrm", "SegAScr", "Phone"); phseg->sf = 0; /* vacuous */ while (phseg) { next = phseg->next; fprintf(fh, "\t%5d %5d %9d %s\n", phseg->sf, phseg->ef, phseg->score, acmod_set_id2name(mdef->acmod_set, phseg->phone)); ckd_free(phseg); phseg = next; } fclose(fh); 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; }
/* 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; }
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; }
static int init_model(float32 ***dest_mixw, vector_t ***dest_mean, vector_t ***dest_var, vector_t ****dest_fullvar, float32 ***dest_tmat, model_def_entry_t *dest, uint32 *dest_cb_map, acmod_set_t *dest_acmod_set, float32 ***src_mixw, vector_t ***src_mean, vector_t ***src_var, vector_t ****src_fullvar, float32 ***src_tmat, model_def_entry_t *src, uint32 *src_cb_map, acmod_set_t *src_acmod_set, uint32 n_feat, uint32 n_gau, uint32 n_state_pm, const uint32 *veclen) { unsigned int s, i, j, k, l, ll; unsigned int s_m, s_mg; unsigned int d_m, d_mg; uint32 s_tmat, d_tmat; printf("%10s <- %-10s: ", acmod_set_id2name(dest_acmod_set, dest->p), acmod_set_id2name(src_acmod_set, src->p)); fflush(stdout); s_tmat = src->tmat; d_tmat = dest->tmat; if (!was_added(&tmat_dest_list[d_tmat], s_tmat)) { printf("[tm %5u += %5u]\n", d_tmat, s_tmat); for (i = 0; i < n_state_pm-1; i++) { for (j = 0; j < n_state_pm; j++) { dest_tmat[d_tmat][i][j] += src_tmat[s_tmat][i][j]; } } } for (s = 0; s < src->n_state; s++) { s_m = src->state[s]; d_m = dest->state[s]; if ((s_m == TYING_NON_EMITTING) && (d_m == TYING_NON_EMITTING)) continue; if ((s_m != TYING_NON_EMITTING) && (d_m != TYING_NON_EMITTING)) { if (!was_added(&mixw_dest_list[d_m], s_m)) { printf("[mx %5u(%1u) += %5u] ", d_m, s, s_m); for (j = 0; j < n_feat; j++) { for (k = 0; k < n_gau; k++) { dest_mixw[d_m][j][k] += src_mixw[s_m][j][k]; } } } s_mg = src_cb_map[s_m]; d_mg = dest_cb_map[d_m]; if (!was_added(&cb_dest_list[d_mg], s_mg)) { printf("[mg %5u(%1u) <- %5u] ", d_mg, s, s_mg); for (j = 0; j < n_feat; j++) { for (k = 0; k < n_gau; k++) { for (l = 0; l < veclen[j]; l++) { dest_mean[d_mg][j][k][l] = src_mean[s_mg][j][k][l]; if (dest_var) dest_var[d_mg][j][k][l] = src_var[s_mg][j][k][l]; else if (dest_fullvar) { for (ll = 0; ll < veclen[j]; ++ll) { dest_fullvar[d_mg][j][k][l][ll] = src_fullvar[s_mg][j][k][l][ll]; } } } } } } } else { E_ERROR("Source is %semitting and destination is %semitting\n", (s_m != TYING_NON_EMITTING ? "" : "non-"), (d_m != TYING_NON_EMITTING ? "" : "non-")); } } printf("\n"); return S3_SUCCESS; }