问题
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