Exemplo n.º 1
0
int
main(int argc, char *argv[])
{
	logmath_t *lmath;
	fsg_model_t *fsg;

	/* Initialize a logmath object to pass to fsg_model_read */
	lmath = logmath_init(1.0001, 0, 0);
	/* Read a FSG. */
	fsg = fsg_model_readfile(LMDIR "/goforward.fsg", lmath, 7.5);
	TEST_ASSERT(fsg);

	TEST_ASSERT(fsg_model_add_silence(fsg, "<sil>", -1, 0.3));
	TEST_ASSERT(fsg_model_add_silence(fsg, "++NOISE++", -1, 0.3));
	TEST_ASSERT(fsg_model_add_alt(fsg, "FORWARD", "FORWARD(2)"));

	fsg_model_write(fsg, stdout);

	/* Test reference counting. */
	TEST_ASSERT(fsg = fsg_model_retain(fsg));
	TEST_EQUAL(1, fsg_model_free(fsg));
	fsg_model_write(fsg, stdout);

	TEST_EQUAL(0, fsg_model_free(fsg));
	logmath_free(lmath);

	return 0;
}
Exemplo n.º 2
0
int
main(int argc, char *argv[])
{
	logmath_t *lmath;
	fsg_model_t *fsg;
	jsgf_t *jsgf;
	jsgf_rule_t *rule;

	lmath = logmath_init(1.0001, 0, 0);

	/* Test loading */
	jsgf = jsgf_parse_file(LMDIR "/polite.gram", NULL);
	TEST_ASSERT(jsgf);
	rule = jsgf_get_rule(jsgf, "polite.startPolite");
	TEST_ASSERT(rule);
	fsg = jsgf_build_fsg(jsgf, rule, lmath, 7.5);
	TEST_ASSERT(fsg);
	TEST_EQUAL_STRING("polite", jsgf_grammar_name(jsgf));

	TEST_ASSERT(fsg_model_add_silence(fsg, "<sil>", -1, 0.3));
	TEST_ASSERT(fsg_model_add_silence(fsg, "++NOISE++", -1, 0.3));
	TEST_ASSERT(fsg_model_add_alt(fsg, "please", "please(2)"));

	jsgf_grammar_free(jsgf);
	fsg_model_write(fsg, stdout);
	fsg_model_free(fsg);

	/* Or do everything at once */
	fsg = jsgf_read_file(LMDIR "/public.gram", lmath, 1.0);
	fsg_model_free(fsg);

	/* Test grammar with keywords inside */
	jsgf = jsgf_parse_file(LMDIR "/public.gram", NULL);
	TEST_ASSERT(jsgf);
	jsgf_grammar_free(jsgf);

	jsgf = jsgf_parse_string("#JSGF V1.0; grammar test; public <choice> = yes | no;", NULL);
	TEST_ASSERT(jsgf);
	rule = jsgf_get_rule(jsgf, "test.choice");
	TEST_ASSERT(rule);
	fsg = jsgf_build_fsg(jsgf, rule, lmath, 7.5);
	fsg_model_write(fsg, stdout);
	fsg_model_free(fsg);
	jsgf_grammar_free(jsgf);

	logmath_free(lmath);

	return 0;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
int
main(int argc, char *argv[])
{
    jsgf_t *jsgf;
    fsg_model_t *fsg;
    cmd_ln_t *config;
    const char *rule;
        
    if ((config = cmd_ln_parse_r(NULL, defn, argc, argv, TRUE)) == NULL)
	return 1;

    if (cmd_ln_boolean_r(config, "-help")) {
        usagemsg(argv[0]);
    }

    jsgf = jsgf_parse_file(cmd_ln_str_r(config, "-jsgf"), NULL);
    if (jsgf == NULL) {
        return 1;
    }

    rule = cmd_ln_str_r(config, "-toprule") ? cmd_ln_str_r(config, "-toprule") : NULL;
    if (!(fsg = get_fsg(jsgf, rule))) {
        E_ERROR("No fsg was built for the given rule '%s'.\n"
                "Check rule name; it should be qualified (with grammar name)\n"
                "and not enclosed in angle brackets (e.g. 'grammar.rulename').",
                rule);
        return 1;
    }


    if (cmd_ln_boolean_r(config, "-compile")) {
	fsg_model_null_trans_closure(fsg, NULL);
    }

    
    if (cmd_ln_str_r(config, "-fsm")) {
	const char* outfile = cmd_ln_str_r(config, "-fsm");
	const char* symfile = cmd_ln_str_r(config, "-symtab");
        if (outfile)
            fsg_model_writefile_fsm(fsg, outfile);
        else
            fsg_model_write_fsm(fsg, stdout);
        if (symfile)
            fsg_model_writefile_symtab(fsg, symfile);
    }
    else {
        const char *outfile = cmd_ln_str_r(config, "-fsg");
        if (outfile)
            fsg_model_writefile(fsg, outfile);
        else
            fsg_model_write(fsg, stdout);
    }
    fsg_model_free(fsg);
    jsgf_grammar_free(jsgf);

    return 0;
}
Exemplo n.º 5
0
int
main(int argc, char *argv[])
{
    jsgf_t *jsgf;
    fsg_model_t *fsg;
    cmd_ln_t *config;
        
    if ((config = cmd_ln_parse_r(NULL, defn, argc, argv, TRUE)) == NULL)
	return 1;
		
    if (cmd_ln_boolean_r(config, "-help")) {
        usagemsg(argv[0]);
    }

    jsgf = jsgf_parse_file(cmd_ln_str_r(config, "-jsgf"), NULL);
    if (jsgf == NULL) {
        return 1;
    }

    fsg = get_fsg(jsgf, cmd_ln_str_r(config, "-rule") ? cmd_ln_str_r(config, "-rule") : NULL);
    
    if (cmd_ln_boolean_r(config, "-compile")) {
	fsg_model_null_trans_closure(fsg, NULL);
    }

    
    if (cmd_ln_str_r(config, "-fsm")) {
	const char* outfile = cmd_ln_str_r(config, "-fsm");
	const char* symfile = cmd_ln_str_r(config, "-symtab");
        if (outfile)
            fsg_model_writefile_fsm(fsg, outfile);
        else
            fsg_model_write_fsm(fsg, stdout);
        if (symfile)
            fsg_model_writefile_symtab(fsg, symfile);
    }
    else {
        const char *outfile = cmd_ln_str_r(config, "-fsg");
        if (outfile)
            fsg_model_writefile(fsg, outfile);
        else
            fsg_model_write(fsg, stdout);
    }
    fsg_model_free(fsg);
    jsgf_grammar_free(jsgf);

    return 0;
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
fsg_model_t *
fsg_model_read(FILE * fp, logmath_t * lmath, float32 lw)
{
    fsg_model_t *fsg;
    hash_table_t *vocab;
    hash_iter_t *itor;
    int32 lastwid;
    char **wordptr;
    char *lineptr;
    char *fsgname;
    int32 lineno;
    int32 n, i, j;
    int n_state, n_trans, n_null_trans;
    glist_t nulls;
    float32 p;

    lineno = 0;
    vocab = hash_table_new(32, FALSE);
    wordptr = NULL;
    lineptr = NULL;
    nulls = NULL;
    fsgname = NULL;
    fsg = NULL;

    /* Scan upto FSG_BEGIN header */
    for (;;) {
        n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
        if (n < 0) {
            E_ERROR("%s declaration missing\n", FSG_MODEL_BEGIN_DECL);
            goto parse_error;
        }

        if ((strcmp(wordptr[0], FSG_MODEL_BEGIN_DECL) == 0)) {
            if (n > 2) {
                E_ERROR("Line[%d]: malformed FSG_BEGIN declaration\n",
                        lineno);
                goto parse_error;
            }
            break;
        }
    }
    /* Save FSG name, or it will get clobbered below :(.
     * If name is missing, try the default.
     */
    if (n == 2) {
        fsgname = ckd_salloc(wordptr[1]);
    }
    else {
        E_WARN("FSG name is missing\n");
        fsgname = ckd_salloc("unknown");
    }

    /* Read #states */
    n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
    if ((n != 2)
        || ((strcmp(wordptr[0], FSG_MODEL_N_DECL) != 0)
            && (strcmp(wordptr[0], FSG_MODEL_NUM_STATES_DECL) != 0))
        || (sscanf(wordptr[1], "%d", &n_state) != 1)
        || (n_state <= 0)) {
        E_ERROR
            ("Line[%d]: #states declaration line missing or malformed\n",
             lineno);
        goto parse_error;
    }

    /* Now create the FSG. */
    fsg = fsg_model_init(fsgname, lmath, lw, n_state);
    ckd_free(fsgname);
    fsgname = NULL;

    /* Read start state */
    n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
    if ((n != 2)
        || ((strcmp(wordptr[0], FSG_MODEL_S_DECL) != 0)
            && (strcmp(wordptr[0], FSG_MODEL_START_STATE_DECL) != 0))
        || (sscanf(wordptr[1], "%d", &(fsg->start_state)) != 1)
        || (fsg->start_state < 0)
        || (fsg->start_state >= fsg->n_state)) {
        E_ERROR
            ("Line[%d]: start state declaration line missing or malformed\n",
             lineno);
        goto parse_error;
    }

    /* Read final state */
    n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
    if ((n != 2)
        || ((strcmp(wordptr[0], FSG_MODEL_F_DECL) != 0)
            && (strcmp(wordptr[0], FSG_MODEL_FINAL_STATE_DECL) != 0))
        || (sscanf(wordptr[1], "%d", &(fsg->final_state)) != 1)
        || (fsg->final_state < 0)
        || (fsg->final_state >= fsg->n_state)) {
        E_ERROR
            ("Line[%d]: final state declaration line missing or malformed\n",
             lineno);
        goto parse_error;
    }

    /* Read transitions */
    lastwid = 0;
    n_trans = n_null_trans = 0;
    for (;;) {
        int32 wid, tprob;

        n = nextline_str2words(fp, &lineno, &lineptr, &wordptr);
        if (n <= 0) {
            E_ERROR("Line[%d]: transition or FSG_END statement expected\n",
                    lineno);
            goto parse_error;
        }

        if ((strcmp(wordptr[0], FSG_MODEL_END_DECL) == 0)) {
            break;
        }

        if ((strcmp(wordptr[0], FSG_MODEL_T_DECL) == 0)
            || (strcmp(wordptr[0], FSG_MODEL_TRANSITION_DECL) == 0)) {


            if (((n != 4) && (n != 5))
                || (sscanf(wordptr[1], "%d", &i) != 1)
                || (sscanf(wordptr[2], "%d", &j) != 1)
                || (i < 0) || (i >= fsg->n_state)
                || (j < 0) || (j >= fsg->n_state)) {
                E_ERROR
                    ("Line[%d]: transition spec malformed; Expecting: from-state to-state trans-prob [word]\n",
                     lineno);
                goto parse_error;
            }

            p = atof_c(wordptr[3]);
            if ((p <= 0.0) || (p > 1.0)) {
                E_ERROR
                    ("Line[%d]: transition spec malformed; Expecting float as transition probability\n",
                     lineno);
                goto parse_error;
            }
        }
        else {
            E_ERROR("Line[%d]: transition or FSG_END statement expected\n",
                    lineno);
            goto parse_error;
        }

        tprob = (int32) (logmath_log(lmath, p) * fsg->lw);
        /* Add word to "dictionary". */
        if (n > 4) {
            if (hash_table_lookup_int32(vocab, wordptr[4], &wid) < 0) {
                (void) hash_table_enter_int32(vocab,
                                              ckd_salloc(wordptr[4]),
                                              lastwid);
                wid = lastwid;
                ++lastwid;
            }
            fsg_model_trans_add(fsg, i, j, tprob, wid);
            ++n_trans;
        }
        else {
            if (fsg_model_null_trans_add(fsg, i, j, tprob) == 1) {
                ++n_null_trans;
                nulls =
                    glist_add_ptr(nulls, fsg_model_null_trans(fsg, i, j));
            }
        }
    }

    E_INFO("FSG: %d states, %d unique words, %d transitions (%d null)\n",
           fsg->n_state, hash_table_inuse(vocab), n_trans, n_null_trans);


    /* Now create a string table from the "dictionary" */
    fsg->n_word = hash_table_inuse(vocab);
    fsg->n_word_alloc = fsg->n_word + 10;       /* Pad it a bit. */
    fsg->vocab = ckd_calloc(fsg->n_word_alloc, sizeof(*fsg->vocab));
    for (itor = hash_table_iter(vocab); itor;
         itor = hash_table_iter_next(itor)) {
        char const *word = hash_entry_key(itor->ent);
        int32 wid = (int32) (long) hash_entry_val(itor->ent);
        fsg->vocab[wid] = (char *) word;
    }
    hash_table_free(vocab);

    /* Do transitive closure on null transitions */
    nulls = fsg_model_null_trans_closure(fsg, nulls);
    glist_free(nulls);

    ckd_free(lineptr);
    ckd_free(wordptr);

    return fsg;

  parse_error:
    for (itor = hash_table_iter(vocab); itor;
         itor = hash_table_iter_next(itor))
        ckd_free((char *) hash_entry_key(itor->ent));
    glist_free(nulls);
    hash_table_free(vocab);
    ckd_free(fsgname);
    ckd_free(lineptr);
    ckd_free(wordptr);
    fsg_model_free(fsg);
    return NULL;
}
Exemplo n.º 10
0
int ofxSphinxASR::engineInit(ofAsrEngineArgs *e)
{
#if defined TARGET_WIN32
    char cfg_filename[] = "sphinx.cfg";
    char grammarJSGF_filename[] = "grammar.jsgf";
    char grammarFSG_filename[] = "grammar.fsg";
#else
	char cfg_filename[] = "/tmp/sphinx.cfg";
    char grammarJSGF_filename[] = "/tmp/grammar.jsgf";
    char grammarFSG_filename[] = "/tmp/grammar.fsg";
#endif	
    FILE *cfg_fp = fopen(cfg_filename, "wt");
    if (cfg_fp==NULL)
        return OFXASR_FAIL_WRITE_CONFIG;
    if ( access(e->sphinxmodel_am.c_str(), 0) != 0 )
		return OFXASR_FAIL_READ_FILES;
	if ( access(e->sphinxmodel_lm.c_str(), 0) != 0 )
		return OFXASR_FAIL_READ_FILES;
	if ( access(e->sphinxmodel_dict.c_str(), 0) != 0 )
		return OFXASR_FAIL_READ_FILES;
	if ( access(e->sphinxmodel_fdict.c_str(), 0) != 0 )
		return OFXASR_FAIL_READ_FILES;
	
	char cur_path[1024];
	getcwd(cur_path, 1024);

    fprintf(cfg_fp, "-samprate %d\n", e->samplerate);
    fprintf(cfg_fp, "-hmm %s/%s\n", cur_path, e->sphinxmodel_am.c_str());
    fprintf(cfg_fp, "-dict %s/%s\n", cur_path, e->sphinxmodel_dict.c_str());
    fprintf(cfg_fp, "-fdict %s/%s\n", cur_path, e->sphinxmodel_fdict.c_str());
    fprintf(cfg_fp, "-lm %s/%s\n", cur_path, e->sphinxmodel_lm.c_str());
    if (e->sphinx_mode == 2) {
        if(e->sphinx_candidate_sentences.size() < 1) {
            printf("Warning: The word list is empty! Use mode 4.\n");
            e->sphinx_mode = 4;
        }
        else {
            FILE *gram_fp = fopen(grammarJSGF_filename, "wt");
            if (gram_fp==NULL)
                return OFXASR_FAIL_WRITE_CONFIG;
            fprintf(gram_fp,
                "#JSGF V1.0;\n\ngrammar cca_gram;\n\npublic <cca_gram> = (\n");
            for (int i=0; i<e->sphinx_candidate_sentences.size()-1; i++) {
                fprintf(gram_fp, "%s |\n",
                 e->sphinx_candidate_sentences[i].c_str());
            }
            fprintf(gram_fp, "%s );\n\n",
                e->sphinx_candidate_sentences[e->sphinx_candidate_sentences.size()-1].c_str());
            fclose(gram_fp);
        }
        jsgf_t *jsgf = jsgf_parse_file(grammarJSGF_filename, NULL);
        if (jsgf == NULL) {
            printf("Bad jsgf file %s.\n", grammarJSGF_filename);
            return OFXASR_INVALID_JSGF_GRAMMAR;
        }
        fsg_model_t *fsg = get_fsg(jsgf, NULL);
        fsg_model_writefile(fsg, grammarFSG_filename);
        fsg_model_free(fsg);
        jsgf_grammar_free(jsgf);
        fprintf(cfg_fp, "-fsg %s\n", grammarFSG_filename);
    }
    fprintf(cfg_fp, "-op_mode %d\n", e->sphinx_mode);
    fclose(cfg_fp);
    err_set_logfp(NULL); // disable logs
    cmd_ln_t *config = NULL;
    config = cmd_ln_parse_file_r(config, S3_DECODE_ARG_DEFS, cfg_filename, TRUE);
    if (config == NULL) {
        return OFXASR_INVALID_CONFIG;
    }
    decoder = new s3_decode_t;
    if (s3_decode_init(decoder, config) != S3_DECODE_SUCCESS) {
        return OFXASR_FAIL_INIT_DECODER;
    }
    fe = fe_init_auto_r(config);
    if (fe == NULL) {
        return OFXASR_FAIL_INIT_FRONTEND;
    }
    bEngineInitialed = true;
    return OFXASR_SUCCESS;
}
Exemplo n.º 11
0
int
ps_reinit(ps_decoder_t *ps, cmd_ln_t *config)
{
    const char *path;
    const char *keyword_list;
    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 ((ps->pl_window = cmd_ln_int32_r(ps->config, "-pl_window"))) {
        /* 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)) == 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 ((keyword_list = cmd_ln_str_r(config, "-kws"))) {
        if (ps_set_kws(ps, PS_DEFAULT_SEARCH, keyword_list))
            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);
    }
    
    if ((path = cmd_ln_str_r(config, "-jsgf"))) {
        /* Or load a JSGF grammar */
        fsg_model_t *fsg;
        jsgf_rule_t *rule;
        char const *toprule;
        jsgf_t *jsgf = jsgf_parse_file(path, NULL);

        if (!jsgf)
            return -1;

        rule = NULL;
        /* Take the -toprule if specified. */
        if ((toprule = cmd_ln_str_r(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;
            }
        }

        fsg = jsgf_build_fsg(jsgf, rule, ps->lmath, lw);
        ps_set_fsg(ps, PS_DEFAULT_SEARCH, fsg);
        fsg_model_free(fsg);
        ps_set_search(ps, PS_DEFAULT_SEARCH);
    }

    if ((path = cmd_ln_str_r(ps->config, "-lm"))) {
        ngram_model_t *lm;

        lm = ngram_model_read(ps->config, path, NGRAM_AUTO, ps->lmath);
        if (!lm)
            return -1;

        if (ps_set_lm(ps, PS_DEFAULT_SEARCH, lm)) {
            ngram_model_free(lm);
            return -1;
        }
        ngram_model_free(lm);
        ps_set_search(ps, PS_DEFAULT_SEARCH);
    }

    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_WARN("No default LM name (-lmname) for `-lmctl'\n");
    }

    /* Initialize performance timer. */
    ps->perf.name = "decode";
    ptmr_init(&ps->perf);

    return 0;
}
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"));
    /* Set up logging. We need to do this earlier because we want to dump
     * the information to the configured log, not to the stderr. */
    if (config && cmd_ln_str_r(ps->config, "-logfn")) {
        if (err_set_logfile(cmd_ln_str_r(ps->config, "-logfn")) < 0) {
            E_ERROR("Cannot redirect log output\n");
    	    return -1;
        }
    }
    
    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_expand_model_config(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,
                         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)) == NULL)
        return -1;
    if ((ps->d2p = dict2pid_build(ps->acmod->mdef, ps->dict)) == NULL)
        return -1;

    lw = cmd_ln_float32_r(ps->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(ps->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(ps->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(ps->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)) {
            fsg_model_free(fsg);
            return -1;
        }
        fsg_model_free(fsg);
        ps_set_search(ps, PS_DEFAULT_SEARCH);
    }
    
    /* Or load a JSGF grammar */
    if ((path = cmd_ln_str_r(ps->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_set_iter_free(lmset_it);
        	ngram_model_free(lmset);
                return -1;
            }
        }
        ngram_model_free(lmset);

        name = cmd_ln_str_r(ps->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;
}