Beispiel #1
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;
}
  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;
  }
Beispiel #3
0
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);
}
Beispiel #6
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;
}
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;
    }
}
Beispiel #8
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"));
    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;
    }
}
Beispiel #10
0
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;
}