Cant start service? (Speech recog)

与世无争的帅哥 提交于 2019-12-28 02:18:32

问题


I want to listen for the word hello using pocketsphinx in a service continuously

I get the error. Here is the full stack trace. Here is a small portion of it.

Unable to create service curlybrace.ruchir.myApp.MyService: java.lang.RuntimeException: new_Decoder returned -1

It is caused by this:

            setupRecognizer(assetDir); //SETUP

and this:

                .getRecognizer();

In my onCreate:

 Log.v(TAG, "Voice recognition activated!");

        //Register voice recog listener :)

        Assets assets = null;
        try {
            assets = new Assets(MyService.this);
            File assetDir = assets.syncAssets();
            setupRecognizer(assetDir); //SETUP

            Log.v(TAG, "Set up listener");
        } catch (IOException e) {
            e.printStackTrace();
        }

Here is my setupRecognizer method:

  private void setupRecognizer(File assetDir) throws IOException {

        recognizer = defaultSetup()
                .setAcousticModel(new File(assetDir, "hmm/en-us-semi"))
                .setDictionary(new File(assetDir, "lm/cmu07a.dic"))
                .setKeywordThreshold(1e-5f)
                .getRecognizer();

        recognizer.addListener(this);
       // recognizer.addKeywordSearch("Hello", assetDir); //I don't know what this does...
    recognizer.startListening("Hello"); //Start listeneing


    }

Here is one of the implemented methods:

@Override
    public void onPartialResult(Hypothesis hypothesis) {

        String text = hypothesis.getHypstr();
        if (text.equals("Hello")) {
            //  do something

            Log.v(TAG, "SPEECH RECOGNIZED HELLO!");
        }

    }

I would appreciate any feedback. Positive, negative, even a comment. At this point I am desperate, after trying for 2 days!


回答1:


You have this:

private void setupRecognizer(File assetDir) throws IOException {
        recognizer = defaultSetup() 
                .setAcousticModel(new File(assetDir, "hmm/en-us-semi"))
                .setDictionary(new File(assetDir, "lm/cmu07a.dic"))
                .setKeywordThreshold(1e-5f) 
                .getRecognizer(); 
        recognizer.addListener(this);
       // recognizer.addKeywordSearch("Hello", assetDir); //I don't know what this does... 
    recognizer.startListening("Hello"); //Start listeneing 
    } 

Try changing it to this:

private void setupRecognizer(File assetDir) throws IOException {
        recognizer = defaultSetup() 
                .setAcousticModel(new File(assetDir, "hmm/en-us-semi"))
                .setDictionary(new File(assetDir, "lm/cmu07a.dic"))
                .setKeywordThreshold(1e-5f) 
                .getRecognizer(); 
        recognizer.addListener(this);

    //Add this:
    File digitsGrammar = new File(modelsDir, "grammar/digits.gram");
    recognizer.addKeywordSearch(DIGITS_SEARCH, digitsGrammar);
    } 

To begin speech recon, call this from button. When it works, call it from a service, to keep things simpler:

    recognizer.startListening("Hello"); //Start listeneing 

Now, create a new file called digits.gram, and put it inside a folder called here: /youProjectRootFolder/grammar/digits.gram This file is really a .txt file, but change the extension to .gram when you are done putting this text inside:

hello /1e-1/
hi /1e-1/
bye /1e-1/
goodbye /1e-1/
...etc. /1e-1/

Here you will find a similar situation: Recognizing multiple keywords using PocketSphinx Good Luck!




回答2:


For command, the code below is what I did and it works well. If you do only keyword spotting then look at the keyword spotting example bundle in the Sphinx download and modify the code below.

Make sure that the assets --> sync folder contains only the following files

folder en-us-ptm
assets.lst 
cmudict-en-us.dict
cmudict-en-us.dict.md5
command.gram
your_preferred_name.dict

If you allow user to set the command then you do not need the command and your_preferred_name.dict. You can add it in code later and save it in the appropriate directory below. For keyword spotting replace the command.gram with whatever the name in the Sphinx example.

In the assets --> sync folder modify the files listed to have the content below. You can edit these file with notepad++

assets.lst

cmudict-en-us.dict
en-us-ptm/README
en-us-ptm/feat.params
en-us-ptm/mdef
en-us-ptm/means
en-us-ptm/noisedict
en-us-ptm/sendump
en-us-ptm/transition_matrices
en-us-ptm/variances 

command.gram

hello /1/

If the app has trouble understanding adjust the threshold parameter i.e. /1e-8/ The smaller the threshold the easier for the recognizer to pick up the word but also it is easier to get false positive. For keyword spotting replace the Sphinx keyword example with your keyword.

your_prefered_name.dict
Copy the whole line in the cmudict-en-us.dict having the word in command.gram in this example it is the word hello. I have a separate dict so that the file is much smaller so that the dict search is improved a bit. So your your_prefered_name.dict should looks like

hello HH AH L OW
hello(2) HH EH L OW

For keyword spotting I think you can string the words together (not sure you have to try to see if it will work) so for example hello world will be

hello world HH AH L OW .... (the dot is for world)

At the start of your app create a directory say "sphinx"

String createSphinxDir()
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    String sphinxDir = prefs.getString("sphinx", null);
    if (sphinxDir == null)
    {
        Assets assets;
        try
        {
            assets = new Assets(this);
            File sphinxDirFile = assets.syncAssets();
            if (sphinxDirFile != null)
            {
                sphinxDir = sphinxDirFile.getAbsolutePath();
                Editor editor = prefs.edit();
                editor.putString("sphinx", sphinxDir);
                editor.commit();
                // Also save the command.gram and your_preferred_name.dict
                // to the sphinx dir here. Or save the them later to this
                // dir if you allow user to set the command or keyword
            }
        }
        catch (IOException e)
        {

        }
    }
    return sphinxDir;
}

Then wherever you initiate the speech recognizer

String sphinxDir = createSphinxDir();
        if (sphinxDir != null)
        {
            try
            {
                mSpeechRecognizer = defaultSetup()
                        .setAcousticModel(new File(sphinxDir, "en-us-ptm"))
                        .setDictionary(new File(sphinxDir, "your_preferred_name.dict"))
                        .setBoolean("-allphone_ci", true)
                        .getRecognizer();
                mSpeechRecognizer.addListener(your listener);

// check if file exists here I have a util called FileIOUtils, you should create a method to check.                 
if ((new File(sphinxDir + File.separator + "command.gram")).isFile())
                {
                    mSpeechRecognizer.addKeywordSearch("wakeup", 
                            new File(sphinxDir + File.separator + "command.gram"));
                }

                // Or wherever appropriate
                 startListening("wakeup");
            }
            catch (IOException e)
            {

            }
        }

For keyword spotting just change the above to the one in the Sphinx example.



来源:https://stackoverflow.com/questions/35388720/cant-start-service-speech-recog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!