我正在使用 Sphinx 库开发一个项目,我想动态修改语法规则。例如,假设我想添加规则open (Safari|Firefox)
,但我只想在发生某些事情后添加它。在我在JSGFGrammer
源文件中看到这条评论之前,我认为这是不可能的:
与 JSAPI 识别器不同,JSGF 语法只维护一个规则语法。未来可能会放宽这一限制。在识别过程中不应修改语法对 JSGFGrammar.loadJSGF 的调用将加载一个全新的语法,丢弃任何旧语法或更改。不需要调用 commitChanges(尽管在这种情况下这样的调用是无害的)。可以通过调用 RuleGrammar.setEnabled 和 RuleGrammar.setRule 来修改 RuleGrammars。为了使这些更改发生,必须在进行所有语法更改后调用 JSFGGrammar.commitChanges。
我试图将其添加到我的 Sphinx 相关对象的构造中:
public SphinxBridge() {
this.cm = new ConfigurationManager(SphinxBridge.class.getResource("input.config.xml"));
this.recognizer = (Recognizer) cm.lookup("recognizer");
this.microphone = (Microphone) cm.lookup("microphone");
try {
JSGFGrammar grammar = (JSGFGrammar) cm.lookup("jsgfGrammar");
grammar.getRuleGrammar().setRule("test", new JSGFRule(), true);
grammar.commitChanges();
}
catch (Exception e) { e.printStackTrace(); }
recognizer.allocate();
}
我想添加这个词test
作为一个规则,所以它会识别它。但是,当我开始时,我得到一个 NullPointerException 导致与jsgfGrammar
. 我该如何正确地做到这一点?
更新 1:
在做了一些调整之后,我现在在这条线上得到了一个 NPE:
grammar.getRuleGrammar().setRule("test", new JSGFRule(), true);
我做了一些测试,结果getRuleGrammar()
是返回null。我该怎么办?
更新 2:
我发现我可以通过分配语法来摆脱 NPE。但是,我现在得到了这个异常:
edu.cmu.sphinx.jsgf.JSGFGrammarException: Unknown rule type
at edu.cmu.sphinx.jsgf.JSGFRuleGrammar.resolveRule(JSGFRuleGrammar.java:459)
at edu.cmu.sphinx.jsgf.JSGFRuleGrammar.resolveAllRules(JSGFRuleGrammar.java:396)
at edu.cmu.sphinx.jsgf.JSGFRuleGrammarManager.linkGrammars(JSGFRuleGrammarManager.java:62)
at edu.cmu.sphinx.jsgf.JSGFGrammar.commitChanges(JSGFGrammar.java:618)
at me.nrubin29.jtalk.SphinxBridge.<init>(SphinxBridge.java:28)
这是新代码:
public SphinxBridge() {
this.cm = new ConfigurationManager(SphinxBridge.class.getResource("input.config.xml"));
this.recognizer = (Recognizer) cm.lookup("recognizer");
this.microphone = (Microphone) cm.lookup("microphone");
try {
JSGFGrammar grammar = (JSGFGrammar) cm.lookup("jsgfGrammar");
grammar.allocate();
grammar.getRuleGrammar().setRule("test", new JSGFRule(), true); // "test" is the name.
grammar.commitChanges();
}
catch (Exception e) { e.printStackTrace(); }
recognizer.allocate();
}