ps_nbest_t * ps_nbest(ps_decoder_t *ps, int sf, int ef, char const *ctx1, char const *ctx2) { ps_lattice_t *dag; ngram_model_t *lmset; ps_astar_t *nbest; float32 lwf; int32 w1, w2; if (ps->search == NULL) return NULL; if ((dag = ps_get_lattice(ps)) == NULL) return NULL; /* FIXME: This is all quite specific to N-Gram search. Either we * should make N-best a method for each search module or it needs * to be abstracted to work for N-Gram and FSG. */ if (0 != strcmp(ps_search_name(ps->search), PS_SEARCH_NGRAM)) { lmset = NULL; lwf = 1.0f; } else { lmset = ((ngram_search_t *)ps->search)->lmset; lwf = ((ngram_search_t *)ps->search)->bestpath_fwdtree_lw_ratio; } w1 = ctx1 ? dict_wordid(ps_search_dict(ps->search), ctx1) : -1; w2 = ctx2 ? dict_wordid(ps_search_dict(ps->search), ctx2) : -1; nbest = ps_astar_start(dag, lmset, lwf, sf, ef, w1, w2); return (ps_nbest_t *)nbest; }
const char* ps_get_kws(ps_decoder_t *ps, const char* name) { ps_search_t *search = ps_find_search(ps, name); if (search && strcmp(PS_SEARCH_KWS, ps_search_name(search))) return NULL; return search ? kws_search_get_keywords(search) : NULL; }
fsg_model_t * ps_get_fsg(ps_decoder_t *ps, const char *name) { ps_search_t *search = ps_find_search(ps, name); if (search && strcmp(PS_SEARCH_FSG, ps_search_name(search))) return NULL; return search ? ((fsg_search_t *) search)->fsg : NULL; }
ngram_model_t * ps_get_lm(ps_decoder_t *ps, const char *name) { ps_search_t *search = ps_find_search(ps, name); if (search && strcmp(PS_SEARCH_NGRAM, ps_search_name(search))) return NULL; return search ? ((ngram_search_t *) search)->lmset : NULL; }
fsg_set_t * ps_get_fsgset(ps_decoder_t *ps) { if (ps->search == NULL || 0 != strcmp(ps_search_name(ps->search), "fsg")) return NULL; return (fsg_set_t *)ps->search; }
ngram_model_t * ps_get_lmset(ps_decoder_t *ps) { if (ps->search == NULL || 0 != strcmp(ps_search_name(ps->search), "ngram")) return NULL; return ((ngram_search_t *)ps->search)->lmset; }
static ps_search_t * ps_find_search(ps_decoder_t *ps, char const *name) { gnode_t *gn; for (gn = ps->searches; gn; gn = gnode_next(gn)) { if (0 == strcmp(ps_search_name(gnode_ptr(gn)), name)) return (ps_search_t *)gnode_ptr(gn); } return NULL; }
static int set_search_internal(ps_decoder_t *ps, ps_search_t *search) { ps_search_t *old_search; if (!search) return -1; search->pls = ps->phone_loop; old_search = (ps_search_t *) hash_table_replace(ps->searches, ps_search_name(search), search); if (old_search != search) ps_search_free(old_search); return 0; }
int ps_set_search(ps_decoder_t *ps, const char *name) { ps_search_t *search = ps_find_search(ps, name); if (search) ps->search = search; /* Set pl window depending on the search */ if (!strcmp(PS_SEARCH_NGRAM, ps_search_name(search))) { ps->pl_window = cmd_ln_int32_r(ps->config, "-pl_window"); } else { ps->pl_window = 0; } return search ? 0 : -1; }
int ps_add_word(ps_decoder_t *ps, char const *word, char const *phones, int update) { int32 wid; s3cipid_t *pron; hash_iter_t *search_it; char **phonestr, *tmp; int np, i, rv; /* Parse phones into an array of phone IDs. */ tmp = ckd_salloc(phones); np = str2words(tmp, NULL, 0); phonestr = ckd_calloc(np, sizeof(*phonestr)); str2words(tmp, phonestr, np); pron = ckd_calloc(np, sizeof(*pron)); for (i = 0; i < np; ++i) { pron[i] = bin_mdef_ciphone_id(ps->acmod->mdef, phonestr[i]); if (pron[i] == -1) { E_ERROR("Unknown phone %s in phone string %s\n", phonestr[i], tmp); ckd_free(phonestr); ckd_free(tmp); ckd_free(pron); return -1; } } /* No longer needed. */ ckd_free(phonestr); ckd_free(tmp); /* Add it to the dictionary. */ if ((wid = dict_add_word(ps->dict, word, pron, np)) == -1) { ckd_free(pron); return -1; } /* No longer needed. */ ckd_free(pron); /* Now we also have to add it to dict2pid. */ dict2pid_add_word(ps->d2p, wid); /* TODO: we definitely need to refactor this */ for (search_it = hash_table_iter(ps->searches); search_it; search_it = hash_table_iter_next(search_it)) { ps_search_t *search = hash_entry_val(search_it->ent); if (!strcmp(PS_SEARCH_NGRAM, ps_search_name(search))) { ngram_model_t *lmset = ((ngram_search_t *) search)->lmset; if (ngram_model_add_word(lmset, word, 1.0) == NGRAM_INVALID_WID) { hash_table_iter_free(search_it); return -1; } } if (update) { if ((rv = ps_search_reinit(search, ps->dict, ps->d2p) < 0)) { hash_table_iter_free(search_it); return rv; } } } /* Rebuild the widmap and search tree if requested. */ return wid; }
int ps_reinit(ps_decoder_t *ps, cmd_ln_t *config) { const char *path; const char *keyphrase; int32 lw; if (config && config != ps->config) { cmd_ln_free_r(ps->config); ps->config = cmd_ln_retain(config); } err_set_debug_level(cmd_ln_int32_r(ps->config, "-debug")); ps->mfclogdir = cmd_ln_str_r(ps->config, "-mfclogdir"); ps->rawlogdir = cmd_ln_str_r(ps->config, "-rawlogdir"); ps->senlogdir = cmd_ln_str_r(ps->config, "-senlogdir"); /* Fill in some default arguments. */ ps_init_defaults(ps); /* Free old searches (do this before other reinit) */ ps_free_searches(ps); ps->searches = hash_table_new(3, HASH_CASE_YES); /* Free old acmod. */ acmod_free(ps->acmod); ps->acmod = NULL; /* Free old dictionary (must be done after the two things above) */ dict_free(ps->dict); ps->dict = NULL; /* Free d2p */ dict2pid_free(ps->d2p); ps->d2p = NULL; /* Logmath computation (used in acmod and search) */ if (ps->lmath == NULL || (logmath_get_base(ps->lmath) != (float64)cmd_ln_float32_r(ps->config, "-logbase"))) { if (ps->lmath) logmath_free(ps->lmath); ps->lmath = logmath_init ((float64)cmd_ln_float32_r(ps->config, "-logbase"), 0, cmd_ln_boolean_r(ps->config, "-bestpath")); } /* Acoustic model (this is basically everything that * uttproc.c, senscr.c, and others used to do) */ if ((ps->acmod = acmod_init(ps->config, ps->lmath, NULL, NULL)) == NULL) return -1; if (cmd_ln_int32_r(ps->config, "-pl_window") > 0) { /* Initialize an auxiliary phone loop search, which will run in * "parallel" with FSG or N-Gram search. */ if ((ps->phone_loop = phone_loop_search_init(ps->config, ps->acmod, ps->dict)) == NULL) return -1; hash_table_enter(ps->searches, ckd_salloc(ps_search_name(ps->phone_loop)), ps->phone_loop); } /* Dictionary and triphone mappings (depends on acmod). */ /* FIXME: pass config, change arguments, implement LTS, etc. */ if ((ps->dict = dict_init(ps->config, ps->acmod->mdef, ps->acmod->lmath)) == NULL) return -1; if ((ps->d2p = dict2pid_build(ps->acmod->mdef, ps->dict)) == NULL) return -1; lw = cmd_ln_float32_r(config, "-lw"); /* Determine whether we are starting out in FSG or N-Gram search mode. * If neither is used skip search initialization. */ /* Load KWS if one was specified in config */ if ((keyphrase = cmd_ln_str_r(config, "-keyphrase"))) { if (ps_set_keyphrase(ps, PS_DEFAULT_SEARCH, keyphrase)) return -1; ps_set_search(ps, PS_DEFAULT_SEARCH); } if ((path = cmd_ln_str_r(config, "-kws"))) { if (ps_set_kws(ps, PS_DEFAULT_SEARCH, path)) return -1; ps_set_search(ps, PS_DEFAULT_SEARCH); } /* Load an FSG if one was specified in config */ if ((path = cmd_ln_str_r(config, "-fsg"))) { fsg_model_t *fsg = fsg_model_readfile(path, ps->lmath, lw); if (!fsg) return -1; if (ps_set_fsg(ps, PS_DEFAULT_SEARCH, fsg)) return -1; ps_set_search(ps, PS_DEFAULT_SEARCH); } /* Or load a JSGF grammar */ if ((path = cmd_ln_str_r(config, "-jsgf"))) { if (ps_set_jsgf_file(ps, PS_DEFAULT_SEARCH, path) || ps_set_search(ps, PS_DEFAULT_SEARCH)) return -1; } if ((path = cmd_ln_str_r(ps->config, "-allphone"))) { if (ps_set_allphone_file(ps, PS_DEFAULT_SEARCH, path) || ps_set_search(ps, PS_DEFAULT_SEARCH)) return -1; } if ((path = cmd_ln_str_r(ps->config, "-lm")) && !cmd_ln_boolean_r(ps->config, "-allphone")) { if (ps_set_lm_file(ps, PS_DEFAULT_SEARCH, path) || ps_set_search(ps, PS_DEFAULT_SEARCH)) return -1; } if ((path = cmd_ln_str_r(ps->config, "-lmctl"))) { const char *name; ngram_model_t *lmset; ngram_model_set_iter_t *lmset_it; if (!(lmset = ngram_model_set_read(ps->config, path, ps->lmath))) { E_ERROR("Failed to read language model control file: %s\n", path); return -1; } for(lmset_it = ngram_model_set_iter(lmset); lmset_it; lmset_it = ngram_model_set_iter_next(lmset_it)) { ngram_model_t *lm = ngram_model_set_iter_model(lmset_it, &name); E_INFO("adding search %s\n", name); if (ps_set_lm(ps, name, lm)) { ngram_model_free(lm); ngram_model_set_iter_free(lmset_it); return -1; } ngram_model_free(lm); } name = cmd_ln_str_r(config, "-lmname"); if (name) ps_set_search(ps, name); else { E_ERROR("No default LM name (-lmname) for `-lmctl'\n"); return -1; } } /* Initialize performance timer. */ ps->perf.name = "decode"; ptmr_init(&ps->perf); return 0; }