我在Android上運行PocketSphinx(版本5prealpha)。我使用一個文件定義的關鍵字識別,通過下面的代碼片段規定(kwfile
是關鍵字定義文件,並mRecognizer
是SpeechRecognizer的一個實例):我可以修改PocketSphinx的關鍵字識別器「刷新率」嗎?
mRecognizer.addKeywordSearch(DESCRIPTOR, kwfile);
總體而言,識別性能是相當不錯的,後已經優化了關鍵字閾值。然而,如果我在一個關鍵字話語和下一個關鍵詞話語之間等待任意時間量(5秒到幾分鐘),則識別性能會受到第二話語的影響。例如,我會說「關鍵字」,它會被識別。如果我等待不到5秒並再次說出「關鍵字」,則第二個話語可能會被識別(識別率超過95%)。但是,如果我等待15秒,識別率會急劇下降,不到50%。
我的假設是,當我第二次說關鍵字時,識別器處於刷新的中間 - 就是在Stop Recognition
事件和Start Recognition
事件之間,並且我的講話超出了該事件。這是我的logcat的典型視圖。注意,5秒後,識別器「刷新」。這大概每5秒發生一次。有時在「刷新」之間可能長達30秒,但通常是5秒左右。
09-26 07:11:06.800 20397-20397/...﹕ Start recognition "kwfile"
09-26 07:11:06.815 20397-23642/...﹕ Starting decoding
09-26 07:11:11.310 20397-20397/...﹕ Stop recognition
09-26 07:11:11.315 20397-20397/...﹕ Start recognition "kwfile"
09-26 07:11:11.360 20397-23645/...﹕ Starting decoding
09-26 07:11:17.405 20397-20397/...﹕ Stop recognition
所以,我的問題是:我能做些什麼來控制這個「刷新率」?這是否是由於我在執行RecognitionListener
時出現了錯誤(請參閱下文,但請注意 - 我通常不會在話語之間獲得任何部分結果)。或者是否有PocketSphinx API調用,我不知道要設置此刷新率?或者,有什麼我可以改變在PocketSphinx源來改善這種行爲?
class VoiceListener implements RecognitionListener{
private boolean isCommand = false;
@Override
public void onBeginningOfSpeech() {
Log.d(TAG,"Beginning of Speech");
// do nothing
}
@Override
public void onEndOfSpeech() {
Log.d(TAG,"End of Speech");
// do nothing
}
@Override
public void onPartialResult(Hypothesis arg0) {
if(arg0 != null){
Log.d(TAG, "Partial results list: " + arg0.getHypstr());
isCommand = false;
// handle recognition results for keywords
for(String command : this.getCurrentCommands()) {
if (arg0.getHypstr().contains(command)) {
this.onRecognition(arg0.getHypStr());
isCommand = true;
mRecognizer.stop();
}
}
// call stop, and let onResults() handle grammar results
if(arg0.getHypstr().contains(Command.STOP_WORD))
mRecognizer.stop();
}
}
@Override
public void onResult(Hypothesis results) {
String data;
if(results == null){
data = null;
}else{
data = results.getHypstr();
}
Log.d(TAG,"Final results: " + data);
// handle grammar recognition results
if(!isCommand){
this.onRecognition(data);
}
return;
}
謝謝,尼古拉。實際上,我使用相同的RecognitionListener進行關鍵字和語法識別。所以,我可以取出stop()並查看是否改善了事情,或者我可以將它分解爲兩個SpeechRecognizer實例,一個用於關鍵字,另一個用於語法,然後有兩個單獨的監聽器,一個監聽器和停止另一個沒有它。無論如何,我會擺弄這些選項,並讓你知道它是如何運作的。如果我仍然遇到麻煩,我會添加一些音頻日誌。 –
使用兩個實例並不是一個好主意。您需要使用單個實例然後切換搜索,但是如果當前搜索是關鍵字,您還應該跟蹤當前搜索並避免識別器停止。 Android演示以正確的方式執行,您可以按照它進行。 –
好的。我知道了。我會用你的答案修改我的代碼塊。我將onEndOfSpeech()中的所有內容全部取出,並在onResult()中處理關鍵字onPartialResult()和語法。另外一個好處是,現在關鍵字識別的速度顯着提高,因爲它不必等待識別器調用onResult()。謝謝! –