teaching machines

Simplifying PocketSphinx demo

Following the PocketSphinx Android instructions¬†left me with a demo that did more than I wanted and I didn’t really understand. I pruned away it to simplify it and eliminate the step where I had to copy over the model files with adb. Now, I put the model in my project’s assets directory and mirror that on to storage. My first change, then, was to RecognizerTask. I made it reference the app’s external storage directory where the assets are mirrored to.

public RecognizerTask(File sphinxDirectory,
                      String dictionary,
                      String lm) {
  pocketsphinx.setLogfile(sphinxDirectory.getAbsolutePath() + "/pocketsphinx.log");

  Config c = new Config();
  c.setString("-hmm", sphinxDirectory + "/hmm/en_US/hub4wsj_sc_8k");
  c.setString("-dict", sphinxDirectory + "/lm/en_US/" + dictionary);
  c.setString("-lm", sphinxDirectory + "/lm/en_US/" + lm);
  c.setString("-rawlogdir", sphinxDirectory.getAbsolutePath());

Only the constructor changed. This should allow for us to use other dictionaries and lm files fairly easily without having to muck with RecognizerTask.

The next step was to eliminate the unnecessary functionality of PocketSphinxDemo. I removed the performance calculations and edited the code. The author did something funny with making “that” references—which were final references tothis. I’m not sure the reasoning and would welcome explanation from the erudite among you. I changed the IDs of the widgets to more meaningful ones. I also triggered the asset-to-storage copy. This class was the result:

package edu.cmu.pocketsphinx.demo;

import java.io.File;
import org.twodee.android.utils.Log;
import org.twodee.android.utils.Utilities;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;

public class PocketSphinxDemo extends Activity implements RecognitionListener {
  static {

  /** Recognizer task, which runs in a worker thread. */
  RecognizerTask recognizer;

  /** Are we listening? */
  boolean isListening;

  /** Text box for results. */
  EditText editText;

  public void onCreate(Bundle savedInstanceState) {


    // Copy out assets directory to storage. TODO: condition this on files
    // missing.
    Utilities.copyAsset(this, "pocketsphinx");

    // Set up widgets.
    editText = (EditText) findViewById(R.id.resultsText);

    Button b = (Button) findViewById(R.id.listenButton);
    b.setOnTouchListener(new OnTouchListener() {
      public boolean onTouch(View v,
                             MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
          isListening = true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
          isListening = false;
        return false;

    isListening = false;
    recognizer = new RecognizerTask(new File(getExternalFilesDir(null), "pocketsphinx"), "digger_dict.dic", "digger_lm.lm");
    new Thread(recognizer).start();

  public void onPartialResults(Bundle b) {
    final String hyp = b.getString("hyp");
    editText.post(new Runnable() {
      public void run() {

  public void onResults(Bundle b) {
    final String hyp = b.getString("hyp");
    editText.post(new Runnable() {
      public void run() {

  public void onError(int err) {
    Log.d("Error: %d", err);

It works, once. Subsequent listens fail.


  1. Sejal says:

    I’m not getting this. what is RecognizerTask and twodee?

    1. Chris Johnson says:

      RecognizerTask is a class that shipped with PocketSphinx’s Android demo. This post won’t make any sense without that demo.

  2. Dominik says:

    I can’t find it too. I’m using demo project from official site. Can you give us relative directory in project or your sorce code?

    1. Chris Johnson says:

      My original post is from 2012. I’m not sure what’s happened in the PocketSphinx project since then.

Leave a Reply

Your email address will not be published. Required fields are marked *