/* * Load and cross-check all models (acoustic/lexical/linguistic). */ static void models_init(void) { /* HMM model definition */ mdef = mdef_init(cmd_ln_str_r(config, "-mdef"), 1); /* Dictionary */ dict = dict_init(mdef, cmd_ln_str_r(config, "-dict"), cmd_ln_str_r(config, "-fdict"), cmd_ln_boolean_r(config, "-lts_mismatch"), cmd_ln_boolean_r(config, "-mdef_fillers"), FALSE, TRUE); lmset = lmset_init(cmd_ln_str_r(config, "-lm"), cmd_ln_str_r(config, "-lmctlfn"), cmd_ln_str_r(config, "-ctl_lm"), cmd_ln_str_r(config, "-lmname"), cmd_ln_str_r(config, "-lmdumpdir"), cmd_ln_float32_r(config, "-lw"), cmd_ln_float32_r(config, "-wip"), cmd_ln_float32_r(config, "-uw"), dict, logmath); fpen = fillpen_init(dict, cmd_ln_str_r(config, "-fillpen"), cmd_ln_float32_r(config, "-silprob"), cmd_ln_float32_r(config, "-fillprob"), cmd_ln_float32_r(config, "-lw"), cmd_ln_float32_r(config, "-wip"), logmath); }
main (int32 argc, char *argv[]) { char *reffile, *mdeffile, *dictfile, *fdictfile, *homfile; if (argc == 1) { cmd_ln_print_help (stderr, arglist); exit(0); } cmd_ln_parse (arglist, argc, argv); if ((mdeffile = (char *) cmd_ln_access ("-mdef")) == NULL) E_FATAL("-mdef argument missing\n"); if ((dictfile = (char *) cmd_ln_access ("-dict")) == NULL) E_FATAL("-dict argument missing\n"); if ((fdictfile = (char *) cmd_ln_access ("-fdict")) == NULL) E_FATAL("-fdict argument missing\n"); if ((reffile = (char *) cmd_ln_access ("-ref")) == NULL) E_FATAL("-ref argument missing\n"); unlimit(); mdef = mdef_init (mdeffile); if (mdef->n_ciphone <= 0) E_FATAL("0 CIphones in %s\n", mdeffile); dict = dict_init (mdef, dictfile, fdictfile); oovbegin = dict->n_word; startwid = dict_wordid (dict, "<s>"); finishwid = dict_wordid (dict, "</s>"); silwid = dict_wordid (dict, (char *) cmd_ln_access("-sil")); assert (dict_filler_word (dict, silwid)); homlist = NULL; if ((homfile = (char *) cmd_ln_access ("-hom")) != NULL) homfile_load (homfile); process_reffile (reffile); #if (0 && (! WIN32)) fflush (stdout); fflush (stderr); system ("ps aguxwww | grep dpalign"); #endif exit(0); }
main (int32 argc, char *argv[]) { mdef_t *mdef; dict_t *dict; dict2pid_t *d2p; if (argc != 4) usage(argv[0]); logs3_init (1.0003); mdef = mdef_init (argv[1]); dict = dict_init (mdef, argv[2], argv[3], 0); d2p = dict2pid_build (mdef, dict); dict2pid_dump (stdout, d2p, mdef, dict); }
main (int32 argc, char *argv[]) { char *reffile, *mdeffile, *dictfile, *fdictfile; if (argc == 1) { cmd_ln_print_help (stderr, arglist); exit(0); } cmd_ln_parse (arglist, argc, argv); if ((mdeffile = (char *) cmd_ln_access ("-mdef")) == NULL) E_FATAL("-mdef argument missing\n"); if ((dictfile = (char *) cmd_ln_access ("-dict")) == NULL) E_FATAL("-dict argument missing\n"); if ((fdictfile = (char *) cmd_ln_access ("-fdict")) == NULL) E_FATAL("-fdict argument missing\n"); if ((reffile = (char *) cmd_ln_access ("-ref")) == NULL) E_FATAL("-ref argument missing\n"); unlimit(); mdef = mdef_init (mdeffile); if (mdef->n_ciphone <= 0) E_FATAL("0 CIphones in %s\n", mdeffile); dict = dict_init (mdef, dictfile, fdictfile); process_reffile (reffile); #if (0 && (! WIN32)) fflush (stdout); fflush (stderr); system ("ps aguxwww | grep dpalign"); #endif exit(0); }
/* * Load and cross-check all models (acoustic/lexical/linguistic). */ static void models_init ( void ) { float32 varfloor, mixwfloor, tpfloor; int32 i, s; s3cipid_t ci; s3wid_t w; char *arg; dict_t *dict; /* HMM model definition */ mdef = mdef_init ((char *) cmd_ln_access("-mdeffn")); /* Dictionary */ dict = dict_init ((char *) cmd_ln_access("-dictfn"), (char *) cmd_ln_access("-fdictfn")); /* HACK!! Make sure SILENCE_WORD, START_WORD and FINISH_WORD are in dictionary */ silwid = dict_wordid (SILENCE_WORD); startwid = dict_wordid (START_WORD); finishwid = dict_wordid (FINISH_WORD); if (NOT_WID(silwid) || NOT_WID(startwid) || NOT_WID(finishwid)) { E_FATAL("%s, %s, or %s missing from dictionary\n", SILENCE_WORD, START_WORD, FINISH_WORD); } if ((dict->filler_start > dict->filler_end) || (! dict_filler_word (silwid))) E_FATAL("%s must occur (only) in filler dictionary\n", SILENCE_WORD); /* No check that alternative pronunciations for filler words are in filler range!! */ /* Codebooks */ varfloor = *((float32 *) cmd_ln_access("-varfloor")); g = gauden_init ((char *) cmd_ln_access("-meanfn"), (char *) cmd_ln_access("-varfn"), varfloor); /* Verify codebook feature dimensions against libfeat */ n_feat = feat_featsize (&featlen); if (n_feat != g->n_feat) E_FATAL("#feature mismatch: s2= %d, mean/var= %d\n", n_feat, g->n_feat); for (i = 0; i < n_feat; i++) if (featlen[i] != g->featlen[i]) E_FATAL("featlen[%d] mismatch: s2= %d, mean/var= %d\n", i, featlen[i], g->featlen[i]); /* Senone mixture weights */ mixwfloor = *((float32 *) cmd_ln_access("-mwfloor")); sen = senone_init ((char *) cmd_ln_access("-mixwfn"), (char *) cmd_ln_access("-senmgaufn"), mixwfloor); /* Verify senone parameters against gauden parameters */ if (sen->n_feat != g->n_feat) E_FATAL("#Feature mismatch: gauden= %d, senone= %d\n", g->n_feat, sen->n_feat); if (sen->n_cw != g->n_density) E_FATAL("#Densities mismatch: gauden= %d, senone= %d\n", g->n_density, sen->n_cw); if (sen->n_gauden > g->n_mgau) E_FATAL("Senones need more codebooks (%d) than present (%d)\n", sen->n_gauden, g->n_mgau); if (sen->n_gauden < g->n_mgau) E_ERROR("Senones use fewer codebooks (%d) than present (%d)\n", sen->n_gauden, g->n_mgau); /* Verify senone parameters against model definition parameters */ if (mdef->n_sen != sen->n_sen) E_FATAL("Model definition has %d senones; but #senone= %d\n", mdef->n_sen, sen->n_sen); /* CD/CI senone interpolation weights file, if present */ if ((arg = (char *) cmd_ln_access ("-lambdafn")) != NULL) { interp = interp_init (arg); /* Verify interpolation weights size with senones */ if (interp->n_sen != sen->n_sen) E_FATAL("Interpolation file has %d weights; but #senone= %d\n", interp->n_sen, sen->n_sen); } else interp = NULL; /* Transition matrices */ tpfloor = *((float32 *) cmd_ln_access("-tpfloor")); tmat = tmat_init ((char *) cmd_ln_access("-tmatfn"), tpfloor); /* Verify transition matrices parameters against model definition parameters */ if (mdef->n_tmat != tmat->n_tmat) E_FATAL("Model definition has %d tmat; but #tmat= %d\n", mdef->n_tmat, tmat->n_tmat); if (mdef->n_emit_state != tmat->n_state-1) E_FATAL("#Emitting states in model definition = %d, #states in tmat = %d\n", mdef->n_emit_state, tmat->n_state); arg = (char *) cmd_ln_access ("-agc"); if ((strcmp (arg, "max") != 0) && (strcmp (arg, "none") != 0)) E_FATAL("Unknown -agc argument: %s\n", arg); arg = (char *) cmd_ln_access ("-cmn"); if ((strcmp (arg, "current") != 0) && (strcmp (arg, "none") != 0)) E_FATAL("Unknown -cmn argument: %s\n", arg); }
bin_mdef_t * bin_mdef_read_text(cmd_ln_t *config, const char *filename) { bin_mdef_t *bmdef; mdef_t *mdef; int i, nodes, ci_idx, lc_idx, rc_idx; int nchars; if ((mdef = mdef_init((char *) filename, TRUE)) == NULL) return NULL; /* Enforce some limits. */ if (mdef->n_sen > BAD_SENID) { E_ERROR("Number of senones exceeds limit: %d > %d\n", mdef->n_sen, BAD_SENID); mdef_free(mdef); return NULL; } if (mdef->n_sseq > BAD_SSID) { E_ERROR("Number of senone sequences exceeds limit: %d > %d\n", mdef->n_sseq, BAD_SSID); mdef_free(mdef); return NULL; } /* We use uint8 for ciphones */ if (mdef->n_ciphone > 255) { E_ERROR("Number of phones exceeds limit: %d > %d\n", mdef->n_ciphone, 255); mdef_free(mdef); return NULL; } bmdef = ckd_calloc(1, sizeof(*bmdef)); bmdef->refcnt = 1; /* Easy stuff. The mdef.c code has done the heavy lifting for us. */ bmdef->n_ciphone = mdef->n_ciphone; bmdef->n_phone = mdef->n_phone; bmdef->n_emit_state = mdef->n_emit_state; bmdef->n_ci_sen = mdef->n_ci_sen; bmdef->n_sen = mdef->n_sen; bmdef->n_tmat = mdef->n_tmat; bmdef->n_sseq = mdef->n_sseq; bmdef->sseq = mdef->sseq; bmdef->cd2cisen = mdef->cd2cisen; bmdef->sen2cimap = mdef->sen2cimap; bmdef->n_ctx = 3; /* Triphones only. */ bmdef->sil = mdef->sil; mdef->sseq = NULL; /* We are taking over this one. */ mdef->cd2cisen = NULL; /* And this one. */ mdef->sen2cimap = NULL; /* And this one. */ /* Get the phone names. If they are not sorted * ASCII-betically then we are in a world of hurt and * therefore will simply refuse to continue. */ bmdef->ciname = ckd_calloc(bmdef->n_ciphone, sizeof(*bmdef->ciname)); nchars = 0; for (i = 0; i < bmdef->n_ciphone; ++i) nchars += strlen(mdef->ciphone[i].name) + 1; bmdef->ciname[0] = ckd_calloc(nchars, 1); strcpy(bmdef->ciname[0], mdef->ciphone[0].name); for (i = 1; i < bmdef->n_ciphone; ++i) { bmdef->ciname[i] = bmdef->ciname[i - 1] + strlen(bmdef->ciname[i - 1]) + 1; strcpy(bmdef->ciname[i], mdef->ciphone[i].name); if (i > 0 && strcmp(bmdef->ciname[i - 1], bmdef->ciname[i]) > 0) { /* FIXME: there should be a solution to this, actually. */ E_ERROR("Phone names are not in sorted order, sorry."); bin_mdef_free(bmdef); return NULL; } } /* Copy over phone information. */ bmdef->phone = ckd_calloc(bmdef->n_phone, sizeof(*bmdef->phone)); for (i = 0; i < mdef->n_phone; ++i) { bmdef->phone[i].ssid = mdef->phone[i].ssid; bmdef->phone[i].tmat = mdef->phone[i].tmat; if (i < bmdef->n_ciphone) { bmdef->phone[i].info.ci.filler = mdef->ciphone[i].filler; } else { bmdef->phone[i].info.cd.wpos = mdef->phone[i].wpos; bmdef->phone[i].info.cd.ctx[0] = mdef->phone[i].ci; bmdef->phone[i].info.cd.ctx[1] = mdef->phone[i].lc; bmdef->phone[i].info.cd.ctx[2] = mdef->phone[i].rc; } } /* Walk the wpos_ci_lclist once to find the total number of * nodes and the starting locations for each level. */ nodes = lc_idx = ci_idx = rc_idx = 0; for (i = 0; i < N_WORD_POSN; ++i) { int j; for (j = 0; j < mdef->n_ciphone; ++j) { ph_lc_t *lc; for (lc = mdef->wpos_ci_lclist[i][j]; lc; lc = lc->next) { ph_rc_t *rc; for (rc = lc->rclist; rc; rc = rc->next) { ++nodes; /* RC node */ } ++nodes; /* LC node */ ++rc_idx; /* Start of RC nodes (after LC nodes) */ } ++nodes; /* CI node */ ++lc_idx; /* Start of LC nodes (after CI nodes) */ ++rc_idx; /* Start of RC nodes (after CI and LC nodes) */ } ++nodes; /* wpos node */ ++ci_idx; /* Start of CI nodes (after wpos nodes) */ ++lc_idx; /* Start of LC nodes (after CI nodes) */ ++rc_idx; /* STart of RC nodes (after wpos, CI, and LC nodes) */ } E_INFO("Allocating %d * %d bytes (%d KiB) for CD tree\n", nodes, sizeof(*bmdef->cd_tree), nodes * sizeof(*bmdef->cd_tree) / 1024); bmdef->n_cd_tree = nodes; bmdef->cd_tree = ckd_calloc(nodes, sizeof(*bmdef->cd_tree)); for (i = 0; i < N_WORD_POSN; ++i) { int j; bmdef->cd_tree[i].ctx = i; bmdef->cd_tree[i].n_down = mdef->n_ciphone; bmdef->cd_tree[i].c.down = ci_idx; #if 0 E_INFO("%d => %c (%d@%d)\n", i, (WPOS_NAME)[i], bmdef->cd_tree[i].n_down, bmdef->cd_tree[i].c.down); #endif /* Now we can build the rest of the tree. */ for (j = 0; j < mdef->n_ciphone; ++j) { ph_lc_t *lc; bmdef->cd_tree[ci_idx].ctx = j; bmdef->cd_tree[ci_idx].c.down = lc_idx; for (lc = mdef->wpos_ci_lclist[i][j]; lc; lc = lc->next) { ph_rc_t *rc; bmdef->cd_tree[lc_idx].ctx = lc->lc; bmdef->cd_tree[lc_idx].c.down = rc_idx; for (rc = lc->rclist; rc; rc = rc->next) { bmdef->cd_tree[rc_idx].ctx = rc->rc; bmdef->cd_tree[rc_idx].n_down = 0; bmdef->cd_tree[rc_idx].c.pid = rc->pid; #if 0 E_INFO("%d => %s %s %s %c (%d@%d)\n", rc_idx, bmdef->ciname[j], bmdef->ciname[lc->lc], bmdef->ciname[rc->rc], (WPOS_NAME)[i], bmdef->cd_tree[rc_idx].n_down, bmdef->cd_tree[rc_idx].c.down); #endif ++bmdef->cd_tree[lc_idx].n_down; ++rc_idx; } /* If there are no triphones here, * this is considered a leafnode, so * set the pid to -1. */ if (bmdef->cd_tree[lc_idx].n_down == 0) bmdef->cd_tree[lc_idx].c.pid = -1; #if 0 E_INFO("%d => %s %s %c (%d@%d)\n", lc_idx, bmdef->ciname[j], bmdef->ciname[lc->lc], (WPOS_NAME)[i], bmdef->cd_tree[lc_idx].n_down, bmdef->cd_tree[lc_idx].c.down); #endif ++bmdef->cd_tree[ci_idx].n_down; ++lc_idx; } /* As above, so below. */ if (bmdef->cd_tree[ci_idx].n_down == 0) bmdef->cd_tree[ci_idx].c.pid = -1; #if 0 E_INFO("%d => %d=%s (%d@%d)\n", ci_idx, j, bmdef->ciname[j], bmdef->cd_tree[ci_idx].n_down, bmdef->cd_tree[ci_idx].c.down); #endif ++ci_idx; } } mdef_free(mdef); bmdef->alloc_mode = BIN_MDEF_FROM_TEXT; return bmdef; }
kbcore_t *kbcore_init (float64 logbase, char *feattype, char *cmn, char *varnorm, char *agc, char *mdeffile, char *dictfile, char *fdictfile, char *compsep, char *lmfile, char *fillpenfile, float64 silprob, float64 fillprob, float64 langwt, float64 inspen, float64 uw, char *meanfile, char *varfile, float64 varfloor, char *mixwfile, float64 mixwfloor, char *subvqfile, char *tmatfile, float64 tmatfloor) { kbcore_t *kb; E_INFO("Initializing core models:\n"); kb = (kbcore_t *) ckd_calloc (1, sizeof(kbcore_t)); kb->fcb = NULL; kb->mdef = NULL; kb->dict = NULL; kb->dict2pid = NULL; kb->lm = NULL; kb->fillpen = NULL; kb->dict2lmwid = NULL; kb->mgau = NULL; kb->svq = NULL; kb->tmat = NULL; logs3_init (logbase); if (feattype) { if ((kb->fcb = feat_init (feattype, cmn, varnorm, agc)) == NULL) E_FATAL("feat_init(%s) failed\n", feattype); if (feat_n_stream(kb->fcb) != 1) E_FATAL("#Feature streams(%d) != 1\n", feat_n_stream(kb->fcb)); } if (mdeffile) { if ((kb->mdef = mdef_init (mdeffile)) == NULL) E_FATAL("mdef_init(%s) failed\n", mdeffile); } if (dictfile) { if (! compsep) compsep = ""; else if ((compsep[0] != '\0') && (compsep[1] != '\0')) { E_FATAL("Compound word separator(%s) must be empty or single character string\n", compsep); } if ((kb->dict = dict_init (kb->mdef, dictfile, fdictfile, compsep[0])) == NULL) E_FATAL("dict_init(%s,%s,%s) failed\n", dictfile, fdictfile ? fdictfile : "", compsep); } if (lmfile) { if ((kb->lm = lm_read (lmfile, langwt, inspen, uw)) == NULL) E_FATAL("lm_read(%s, %e, %e, %e) failed\n", lmfile, langwt, inspen, uw); } if (fillpenfile || (lmfile && kb->dict)) { if (! kb->dict) /* Sic */ E_FATAL("No dictionary for associating filler penalty file(%s)\n", fillpenfile); if ((kb->fillpen = fillpen_init (kb->dict, fillpenfile, silprob, fillprob, langwt, inspen)) == NULL) E_FATAL("fillpen_init(%s) failed\n", fillpenfile); } if (meanfile) { if ((! varfile) || (! mixwfile)) E_FATAL("Varfile or mixwfile not specified along with meanfile(%s)\n", meanfile); kb->mgau = mgau_init (meanfile, varfile, varfloor, mixwfile, mixwfloor, TRUE); if (kb->mgau == NULL) E_FATAL("gauden_init(%s, %s, %e) failed\n", meanfile, varfile, varfloor); if (subvqfile) { if ((kb->svq = subvq_init (subvqfile, varfloor, -1, kb->mgau)) == NULL) E_FATAL("subvq_init (%s, %e, -1) failed\n", subvqfile, varfloor); } } if (tmatfile) { if ((kb->tmat = tmat_init (tmatfile, tmatfloor)) == NULL) E_FATAL("tmat_init (%s, %e) failed\n", tmatfile, tmatfloor); } if (kb->dict && kb->lm) { /* Initialize dict2lmwid */ if ((kb->dict2lmwid = wid_dict_lm_map (kb->dict, kb->lm)) == NULL) E_FATAL("Dict/LM word-id mapping failed\n"); } if (kb->mdef && kb->dict) { /* Initialize dict2pid */ kb->dict2pid = dict2pid_build (kb->mdef, kb->dict); } /* ***************** Verifications ***************** */ E_INFO("Verifying models consistency:\n"); if (kb->fcb && kb->mgau) { /* Verify feature streams against gauden codebooks */ if (feat_stream_len(kb->fcb, 0) != mgau_veclen(kb->mgau)) E_FATAL("Feature streamlen(%d) != mgau streamlen(%d)\n", feat_stream_len(kb->fcb, 0), mgau_veclen(kb->mgau)); } if (kb->mdef && kb->mgau) { /* Verify senone parameters against model definition parameters */ if (kb->mdef->n_sen != mgau_n_mgau(kb->mgau)) E_FATAL("Mdef #senones(%d) != mgau #senones(%d)\n", kb->mdef->n_sen, mgau_n_mgau(kb->mgau)); } if (kb->mdef && kb->tmat) { /* Verify transition matrices parameters against model definition parameters */ if (kb->mdef->n_tmat != kb->tmat->n_tmat) E_FATAL("Mdef #tmat(%d) != tmatfile(%d)\n", kb->mdef->n_tmat, kb->tmat->n_tmat); if (kb->mdef->n_emit_state != kb->tmat->n_state) E_FATAL("Mdef #states(%d) != tmat #states(%d)\n", kb->mdef->n_emit_state, kb->tmat->n_state); } return kb; }