【问题标题】:Cant start service? (Speech recog)无法启动服务? (语音识别)
【发布时间】:2016-02-14 05:35:38
【问题描述】:

我想在服务中使用 pocketsphinx 连续收听 hello 这个词

我得到了错误。这是full stack trace。这是其中的一小部分。

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

是这样造成的:

            setupRecognizer(assetDir); //SETUP

还有这个:

                .getRecognizer();

在我的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();
        }

这是我的setupRecognizer 方法:

  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


    }

这是其中一种已实现的方法:

@Override
    public void onPartialResult(Hypothesis hypothesis) {

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

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

    }

如有任何反馈,我将不胜感激。正面的,负面的,甚至是评论。在这一点上,我很绝望,尝试了 2 天!

【问题讨论】:

  • 只是一个想法:您是否在清单中注册了麦克风权限?
  • @luxer 不,我没有
  • 您的应用需要获得收听麦克风的权限,即使您使用库也是如此。你试过添加它吗?
  • @luxer 我应该添加这些权限吗? <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • @luxer 那我为什么得到service can't start,我不应该得到security exception吗?

标签: java android speech-recognition voice-recognition cmusphinx


【解决方案1】:

你有这个:

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 
    } 

尝试将其更改为:

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);
    } 

要开始语音侦察,请从按钮调用它。当它工作时,从服务中调用它,以使事情变得更简单:

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

现在,创建一个名为 digits.gram 的新文件,并将其放入名为此处的文件夹中:/youProjectRootFolder/grammar/digits.gram 这个文件实际上是一个 .txt 文件,但是当你把这个文本放进去后,把扩展名改为 .gram:

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

在这里你会发现类似的情况:Recognizing multiple keywords using PocketSphinx 祝你好运!

【讨论】:

  • 非常感谢您的回答!我似乎在我的根目录中找不到grammar 文件夹...我需要创建它吗? Here is a screenshot of my directories in project view.我应该制作语法文件吗?此外,我对setAcousticModelsetDictionary 方法以及它们为何采用文件参数感到有些困惑。为什么我们甚至需要assetDir 文件?我只是从演示中得到的。请让我知道 :) 非常感谢乔希!
  • 是的,如果您的项目没有“语法”文件夹,则需要创建自己的“语法”文件夹,然后自己制作语法文件:只需复制粘贴我上面提到的文本,然后更改扩展名从 .txt 到 .gram,。我不确定assetDir 在下面是如何工作的,但我知道它允许你从他们的文件中加载字典和声学模型。 @RuchirBaronia
  • 嗯...我在这条线上仍然遇到同样的问题.getRecognizer();。正在发生相同的新解码器返回 -1 错误......我不知道为什么!也许我没有正确添加digits.gram文件,是这样的吗? snag.gy/VCCBH.jpg
  • 另外,我注意到资产文件夹中还有另一个 digits.gram 文件...我们应该引用那个文件吗?
  • 请让我知道问题可能是什么。如果您需要更多信息,请随时询问。我已经坚持了很长时间,非常感谢您的帮助。非常感谢乔希!
【解决方案2】:

对于命令,下面的代码是我所做的并且效果很好。如果您只进行关键字识别,请查看 Sphinx 下载中的关键字识别示例包并修改以下代码。

确保assets --> sync 文件夹仅包含以下文件

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

如果您允许用户设置命令,那么您不需要命令和 your_preferred_name.dict。您可以稍后将其添加到代码中,并将其保存在下面的相应目录中。对于关键字发现,将 command.gram 替换为 Sphinx 示例中的任何名称。

assets --> sync 文件夹中修改列出的文件,使其具有以下内容。您可以使用 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/

如果应用程序无法理解,请调整阈值参数,即 /1e-8/ 阈值越小,识别器越容易识别单词,但也更容易误报。对于关键字发现,请将 Sphinx 关键字示例替换为您的关键字。

your_prefered_name.dict
复制 cmudict-en-us.dict 中包含 command.gram 中的单词的整行,在此示例中它是单词 hello。我有一个单独的字典,因此文件要小得多,因此字典搜索会有所改进。所以你的 your_prefered_name.dict 应该看起来像

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

对于关键字发现,我认为您可以将单词串在一起(不确定您是否必须尝试看看它是否有效),例如 hello world 将是

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

在您的应用开始时创建一个目录,说“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;
}

然后无论你在哪里启动语音识别器

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)
            {

            }
        }

对于关键字发现,只需将上面的内容更改为 Sphinx 示例中的内容即可。

【讨论】:

  • Hey Hoan,我花了很多时间来研究它并试图理解它,但我仍然遇到一些错误。我已经创建了这个要点,并评论了所有有错误的地方。请让我知道我应该如何解决这些问题,或者我做错了什么。非常感谢。 gist.github.com/anonymous/e67e876dc1a33df25b2c
  • gist.github.com/anonymous/e67e876dc1a33df25b2c
  • 嘿,我试过了,错误消失了!问题是,它仍然无法正常工作......
  • 基本上,没有一个回调方法被调用(onResult、onPartialResult、onBeginingOfSpeech 等)我能做些什么来解决这个问题?这是代码:gist.github.com/anonymous/2fa9085937ad8106856a
  • 我知道没有任何回调方法被调用,因为我没有得到我放置的日志。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 1970-01-01
  • 2014-10-04
相关资源
最近更新 更多