int ps_set_jsgf_string(ps_decoder_t *ps, const char *name, const char *jsgf_string) { fsg_model_t *fsg; jsgf_rule_t *rule; char const *toprule; jsgf_t *jsgf = jsgf_parse_string(jsgf_string, NULL); float lw; int result; if (!jsgf) return -1; rule = NULL; /* Take the -toprule if specified. */ if ((toprule = cmd_ln_str_r(ps->config, "-toprule"))) { rule = jsgf_get_rule(jsgf, toprule); if (rule == NULL) { E_ERROR("Start rule %s not found\n", toprule); return -1; } } else { rule = jsgf_get_public_rule(jsgf); if (rule == NULL) { E_ERROR("No public rules found in input string\n"); return -1; } } lw = cmd_ln_float32_r(ps->config, "-lw"); fsg = jsgf_build_fsg(jsgf, rule, ps->lmath, lw); result = ps_set_fsg(ps, name, fsg); fsg_model_free(fsg); return result; }
ReturnType Recognizer::addGrammar(Integers& id, const Grammar& grammar) { if (decoder == NULL) return BAD_STATE; std::ostringstream grammar_name; grammar_name << grammar_index; grammar_names.push_back(grammar_name.str()); current_grammar = fsg_model_init(grammar_names.back().c_str(), logmath, 1.0, grammar.numStates); if (current_grammar == NULL) return RUNTIME_ERROR; current_grammar->start_state = grammar.start; current_grammar->final_state = grammar.end; for (int i=0;i<grammar.transitions.size();i++) { if (grammar.transitions.at(i).word.size() == 0) fsg_model_null_trans_add(current_grammar, grammar.transitions.at(i).from, grammar.transitions.at(i).to, grammar.transitions.at(i).logp); else fsg_model_trans_add(current_grammar, grammar.transitions.at(i).from, grammar.transitions.at(i).to, grammar.transitions.at(i).logp, fsg_model_word_add(current_grammar, grammar.transitions.at(i).word.c_str())); } fsg_model_add_silence(current_grammar, "<sil>", -1, 1.0); if(ps_set_fsg(decoder, grammar_names.back().c_str(), current_grammar)) { return RUNTIME_ERROR; } if (id.size() == 0) id.push_back(grammar_index); else id.at(0) = grammar_index; grammar_index++; // We switch to the newly added grammar right away if (ps_set_search(decoder, grammar_names.back().c_str())) { return RUNTIME_ERROR; } return SUCCESS; }
void Recognizer::addModelJsgf(const std::string& key, const std::string& jsgfData, bool setActive) { // Create model: fsg_model_t* model = jsgf_read_string( jsgfData.c_str(), ps_get_logmath( mDecoder ), 7.5 ); // Verify model creation: if( model == NULL ) throw std::runtime_error( "Could not parse JSGF model" ); // Add entry: mModelMap[ key ] = ModelRef( new ModelFsg( model ) ); // Add model to decoder: ps_set_fsg( mDecoder, key.c_str(), model ); // Set active, if flagged: if( setActive ) ps_set_search( mDecoder, key.c_str() ); }
int ps_set_jsgf_file(ps_decoder_t *ps, const char *name, const char *path) { fsg_model_t *fsg; jsgf_rule_t *rule; char const *toprule; jsgf_t *jsgf = jsgf_parse_file(path, NULL); float lw; int result; if (!jsgf) return -1; rule = NULL; /* Take the -toprule if specified. */ if ((toprule = cmd_ln_str_r(ps->config, "-toprule"))) { char *ruletok; ruletok = string_join("<", toprule, ">", NULL); rule = jsgf_get_rule(jsgf, ruletok); ckd_free(ruletok); if (rule == NULL) { E_ERROR("Start rule %s not found\n", toprule); return -1; } } else { /* Otherwise, take the first public rule. */ jsgf_rule_iter_t *itor; for (itor = jsgf_rule_iter(jsgf); itor; itor = jsgf_rule_iter_next(itor)) { rule = jsgf_rule_iter_rule(itor); if (jsgf_rule_public(rule)) { jsgf_rule_iter_free(itor); break; } } if (rule == NULL) { E_ERROR("No public rules found in %s\n", path); return -1; } } lw = cmd_ln_float32_r(ps->config, "-lw"); fsg = jsgf_build_fsg(jsgf, rule, ps->lmath, lw); result = ps_set_fsg(ps, name, fsg); fsg_model_free(fsg); return result; }
static void test_set_search() { cmd_ln_t *config = default_config(); ps_decoder_t *ps = ps_init(config); ps_search_iter_t *itor; jsgf_t *jsgf = jsgf_parse_file(DATADIR "/goforward.gram", NULL); fsg_model_t *fsg = jsgf_build_fsg(jsgf, jsgf_get_rule(jsgf, "goforward.move"), ps->lmath, cmd_ln_int32_r(config, "-lw")); TEST_ASSERT(!ps_set_fsg(ps, "goforward", fsg)); fsg_model_free(fsg); TEST_ASSERT(!ps_set_jsgf_file(ps, "goforward_other", DATADIR "/goforward.gram")); ngram_model_t *lm = ngram_model_read(config, DATADIR "/tidigits/lm/tidigits.lm.dmp", NGRAM_AUTO, ps->lmath); TEST_ASSERT(!ps_set_lm(ps, "tidigits", lm)); ngram_model_free(lm); TEST_ASSERT(!ps_set_search(ps, "tidigits")); TEST_ASSERT(!ps_set_search(ps, "goforward")); itor = ps_search_iter(ps); TEST_EQUAL(0, strcmp("goforward_other", ps_search_iter_val(itor))); itor = ps_search_iter_next(itor); TEST_EQUAL(0, strcmp("tidigits", ps_search_iter_val(itor))); itor = ps_search_iter_next(itor); TEST_EQUAL(0, strcmp("goforward", ps_search_iter_val(itor))); itor = ps_search_iter_next(itor); TEST_EQUAL(0, strcmp("phone_loop", ps_search_iter_val(itor))); itor = ps_search_iter_next(itor); TEST_EQUAL(NULL, itor); TEST_ASSERT(!ps_start_utt(ps)); TEST_ASSERT(!ps_end_utt(ps)); ps_free(ps); cmd_ln_free_r(config); }
static int process_fsgctl_line(ps_decoder_t *ps, cmd_ln_t *config, char const *fname) { fsg_model_t *fsg; int err; char *path = NULL; const char *fsgdir = cmd_ln_str_r(config, "-fsgdir"); const char *fsgext = cmd_ln_str_r(config, "-fsgext"); if (fname == NULL) return 0; if (fsgdir) path = string_join(fsgdir, "/", fname, fsgext ? fsgext : "", NULL); else if (fsgext) path = string_join(fname, fsgext, NULL); else path = ckd_salloc(fname); fsg = fsg_model_readfile(path, ps_get_logmath(ps), cmd_ln_float32_r(config, "-lw")); err = 0; if (!fsg) { err = -1; goto error_out; } if (ps_set_fsg(ps, fname, fsg)) { err = -1; goto error_out; } E_INFO("Using FSG: %s\n", fname); if (ps_set_search(ps, fname)) err = -1; error_out: fsg_model_free(fsg); ckd_free(path); return err; }
static void gst_pocketsphinx_set_property(GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstPocketSphinx *ps = GST_POCKETSPHINX(object); switch (prop_id) { case PROP_CONFIGURED: ps_reinit(ps->ps, ps->config); break; case PROP_HMM_DIR: gst_pocketsphinx_set_string(ps, "-hmm", value); break; case PROP_LM_FILE: /* FSG and LM are mutually exclusive. */ gst_pocketsphinx_set_string(ps, "-fsg", NULL); gst_pocketsphinx_set_string(ps, "-lmctl", NULL); gst_pocketsphinx_set_string(ps, "-lm", value); break; case PROP_LMCTL_FILE: /* FSG and LM are mutually exclusive. */ gst_pocketsphinx_set_string(ps, "-fsg", NULL); gst_pocketsphinx_set_string(ps, "-lmctl", value); gst_pocketsphinx_set_string(ps, "-lm", NULL); break; case PROP_LM_NAME: gst_pocketsphinx_set_string(ps, "-fsg", NULL); gst_pocketsphinx_set_string(ps, "-lm", NULL); gst_pocketsphinx_set_string(ps, "-lmname", value); /** * Chances are that lmctl is already loaded and all * corresponding searches are configured, so we simply * try to set the search */ if (value != NULL) { ps_set_search(ps->ps, g_value_get_string(value)); } break; case PROP_DICT_FILE: gst_pocketsphinx_set_string(ps, "-dict", value); break; case PROP_MLLR_FILE: gst_pocketsphinx_set_string(ps, "-mllr", value); break; case PROP_FSG_MODEL: { fsg_model_t *fsg = g_value_get_pointer(value); const char *name = fsg_model_name(fsg); ps_set_fsg(ps->ps, name, fsg); ps_set_search(ps->ps, name); } break; case PROP_FSG_FILE: /* FSG and LM are mutually exclusive */ gst_pocketsphinx_set_string(ps, "-lm", NULL); gst_pocketsphinx_set_string(ps, "-fsg", value); break; case PROP_FWDFLAT: gst_pocketsphinx_set_boolean(ps, "-fwdflat", value); break; case PROP_BESTPATH: gst_pocketsphinx_set_boolean(ps, "-bestpath", value); break; case PROP_LATDIR: if (ps->latdir) g_free(ps->latdir); ps->latdir = g_strdup(g_value_get_string(value)); break; case PROP_MAXHMMPF: gst_pocketsphinx_set_int(ps, "-maxhmmpf", value); break; case PROP_MAXWPF: gst_pocketsphinx_set_int(ps, "-maxwpf", value); break; case PROP_BEAM: gst_pocketsphinx_set_double(ps, "-beam", value); break; case PROP_PBEAM: gst_pocketsphinx_set_double(ps, "-pbeam", value); break; case PROP_WBEAM: gst_pocketsphinx_set_double(ps, "-wbeam", value); break; case PROP_DSRATIO: gst_pocketsphinx_set_int(ps, "-ds", value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); return; } }
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; }
static void gst_pocketsphinx_set_property(GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstPocketSphinx *ps = GST_POCKETSPHINX(object); switch (prop_id) { case PROP_HMM_DIR: gst_pocketsphinx_set_string(ps, "-hmm", value); if (ps->ps) { /* Reinitialize the decoder with the new acoustic model. */ ps_reinit(ps->ps, NULL); } break; case PROP_LM_FILE: /* FSG and LM are mutually exclusive. */ gst_pocketsphinx_set_string(ps, "-fsg", NULL); gst_pocketsphinx_set_string(ps, "-lmctl", NULL); gst_pocketsphinx_set_string(ps, "-lm", value); break; case PROP_LMCTL_FILE: /* FSG and LM are mutually exclusive. */ gst_pocketsphinx_set_string(ps, "-fsg", NULL); gst_pocketsphinx_set_string(ps, "-lmctl", value); gst_pocketsphinx_set_string(ps, "-lm", NULL); break; case PROP_LM_NAME: gst_pocketsphinx_set_string(ps, "-fsg", NULL); gst_pocketsphinx_set_string(ps, "-lmname", value); break; case PROP_DICT_FILE: gst_pocketsphinx_set_string(ps, "-dict", value); if (ps->ps) { /* Reinitialize the decoder with the new dictionary. */ ps_reinit(ps->ps, NULL); } break; case PROP_MLLR_FILE: gst_pocketsphinx_set_string(ps, "-mllr", value); /* Reinitialize the decoder with the new MLLR transform. */ if (ps->ps) ps_reinit(ps->ps, NULL); break; case PROP_FSG_MODEL: { fsg_model_t *fsg = g_value_get_pointer(value); const char *name = fsg_model_name(fsg); ps_set_fsg(ps->ps, name, fsg); ps_set_search(ps->ps, name); } break; case PROP_FSG_FILE: /* FSG and LM are mutually exclusive */ gst_pocketsphinx_set_string(ps, "-lm", NULL); gst_pocketsphinx_set_string(ps, "-fsg", value); break; case PROP_FWDFLAT: gst_pocketsphinx_set_boolean(ps, "-fwdflat", value); break; case PROP_BESTPATH: gst_pocketsphinx_set_boolean(ps, "-bestpath", value); break; case PROP_LATDIR: if (ps->latdir) g_free(ps->latdir); ps->latdir = g_strdup(g_value_get_string(value)); break; case PROP_NBEST_SIZE: ps->n_best_size = g_value_get_int(value); break; case PROP_MAXHMMPF: gst_pocketsphinx_set_int(ps, "-maxhmmpf", value); break; case PROP_MAXWPF: gst_pocketsphinx_set_int(ps, "-maxwpf", value); break; case PROP_BEAM: gst_pocketsphinx_set_float(ps, "-beam", value); break; case PROP_PBEAM: gst_pocketsphinx_set_float(ps, "-pbeam", value); break; case PROP_WBEAM: gst_pocketsphinx_set_float(ps, "-wbeam", value); break; case PROP_DSRATIO: gst_pocketsphinx_set_int(ps, "-ds", value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); return; } }
int main(int argc, char *argv[]) { ps_decoder_t *ps; cmd_ln_t *config; acmod_t *acmod; fsg_search_t *fsgs; jsgf_t *jsgf; jsgf_rule_t *rule; fsg_model_t *fsg; ps_seg_t *seg; ps_lattice_t *dag; FILE *rawfh; char const *hyp, *uttid; int32 score, prob; clock_t c; int i; TEST_ASSERT(config = cmd_ln_init(NULL, ps_args(), TRUE, "-hmm", MODELDIR "/hmm/en_US/hub4wsj_sc_8k", "-dict", MODELDIR "/lm/en/turtle.dic", "-input_endian", "little", "-samprate", "16000", NULL)); TEST_ASSERT(ps = ps_init(config)); jsgf = jsgf_parse_file(DATADIR "/goforward.gram", NULL); TEST_ASSERT(jsgf); rule = jsgf_get_rule(jsgf, "<goforward.move2>"); TEST_ASSERT(rule); fsg = jsgf_build_fsg(jsgf, rule, ps->lmath, 7.5); TEST_ASSERT(fsg); fsg_model_write(fsg, stdout); ps_set_fsg(ps, "<goforward.move2>", fsg); ps_set_search(ps, "<goforward.move2>"); acmod = ps->acmod; fsgs = (fsg_search_t *) fsg_search_init(fsg, config, acmod, ps->dict, ps->d2p); setbuf(stdout, NULL); c = clock(); for (i = 0; i < 5; ++i) { int16 buf[2048]; size_t nread; int16 const *bptr; int nfr; int is_final; TEST_ASSERT(rawfh = fopen(DATADIR "/goforward.raw", "rb")); TEST_EQUAL(0, acmod_start_utt(acmod)); fsg_search_start(ps_search_base(fsgs)); is_final = FALSE; while (!feof(rawfh)) { nread = fread(buf, sizeof(*buf), 2048, rawfh); bptr = buf; while ((nfr = acmod_process_raw(acmod, &bptr, &nread, FALSE)) > 0) { while (acmod->n_feat_frame > 0) { fsg_search_step(ps_search_base(fsgs), acmod->output_frame); acmod_advance(acmod); } } hyp = fsg_search_hyp(ps_search_base(fsgs), &score, &is_final); printf("FSG: %s (%d) frame %d final %s\n", hyp, score, acmod->output_frame, is_final ? "FINAL" : ""); TEST_EQUAL (is_final, (acmod->output_frame > 170)); } fsg_search_finish(ps_search_base(fsgs)); hyp = fsg_search_hyp(ps_search_base(fsgs), &score, NULL); printf("FSG: %s (%d)\n", hyp, score); TEST_ASSERT(acmod_end_utt(acmod) >= 0); fclose(rawfh); } TEST_EQUAL(0, strcmp("go forward ten meters", fsg_search_hyp(ps_search_base(fsgs), &score, NULL))); ps->search = (ps_search_t *)fsgs; for (seg = ps_seg_iter(ps, &score); seg; seg = ps_seg_next(seg)) { char const *word; int sf, ef; word = ps_seg_word(seg); ps_seg_frames(seg, &sf, &ef); printf("%s %d %d\n", word, sf, ef); } c = clock() - c; printf("5 * fsg search in %.2f sec\n", (double)c / CLOCKS_PER_SEC); dag = ps_get_lattice(ps); ps_lattice_write(dag, "test_jsgf.lat"); jsgf_grammar_free(jsgf); fsg_search_free(ps_search_base(fsgs)); ps_free(ps); cmd_ln_free_r(config); TEST_ASSERT(config = cmd_ln_init(NULL, ps_args(), TRUE, "-hmm", MODELDIR "/hmm/en_US/hub4wsj_sc_8k", "-dict", MODELDIR "/lm/en/turtle.dic", "-jsgf", DATADIR "/goforward.gram", "-input_endian", "little", "-samprate", "16000", NULL)); TEST_ASSERT(ps = ps_init(config)); TEST_ASSERT(rawfh = fopen(DATADIR "/goforward.raw", "rb")); ps_decode_raw(ps, rawfh, "goforward", -1); hyp = ps_get_hyp(ps, &score, &uttid); prob = ps_get_prob(ps, &uttid); printf("%s: %s (%d, %d)\n", uttid, hyp, score, prob); TEST_EQUAL(0, strcmp("go forward ten meters", hyp)); ps_free(ps); fclose(rawfh); cmd_ln_free_r(config); TEST_ASSERT(config = cmd_ln_init(NULL, ps_args(), TRUE, "-hmm", MODELDIR "/hmm/en_US/hub4wsj_sc_8k", "-dict", MODELDIR "/lm/en/turtle.dic", "-jsgf", DATADIR "/goforward.gram", "-toprule", "goforward.move2", "-input_endian", "little", "-samprate", "16000", NULL)); TEST_ASSERT(ps = ps_init(config)); TEST_ASSERT(rawfh = fopen(DATADIR "/goforward.raw", "rb")); ps_decode_raw(ps, rawfh, "goforward", -1); hyp = ps_get_hyp(ps, &score, &uttid); prob = ps_get_prob(ps, &uttid); printf("%s: %s (%d, %d)\n", uttid, hyp, score, prob); TEST_EQUAL(0, strcmp("go forward ten meters", hyp)); ps_free(ps); cmd_ln_free_r(config); fclose(rawfh); TEST_ASSERT(config = cmd_ln_init(NULL, ps_args(), TRUE, "-hmm", MODELDIR "/hmm/en_US/hub4wsj_sc_8k", "-dict", MODELDIR "/lm/en/turtle.dic", "-jsgf", DATADIR "/defective.gram", NULL)); TEST_ASSERT(NULL == ps_init(config)); cmd_ln_free_r(config); return 0; }