2

I am working on a project using the Sphinx library and I wanted to dynamically modify the grammar rules. For example, say I want to add the rule open (Safari|Firefox), but I wanted to add it only after something happens. I didn't think this was possible until I came across this comment in the JSGFGrammer source file:

Unlike a JSAPI recognizer, the JSGF Grammar only maintains one Rule Grammar. This restriction may be relaxed in the future. The grammar should not be modified while a recognition is in process The call to JSGFGrammar.loadJSGF will load in a completely new grammar, tossing any old grammars or changes. No call to commitChanges is necessary (although such a call would be harmless in this situation). RuleGrammars can be modified via calls to RuleGrammar.setEnabled and RuleGrammar.setRule). In order for these changes to take place, JSGFGrammar.commitChanges must be called after all grammar changes have been made.

I attempted to add this to my construction of the Sphinx-related objects:

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

I want to add the word test as a rule, so it would recognize it. However, when I start, I get a NullPointerException leading to the lookup line pertaining to jsgfGrammar. How do I correctly go about doing this?


Update 1:

After doing some tweaking, I am now getting an NPE on this line:

grammar.getRuleGrammar().setRule("test", new JSGFRule(), true);

I did some testing, and it turns out getRuleGrammar() is returning null. What do I do?


Update 2:

I have discovered that I can get rid of the NPE by allocating the grammar. However, I now get this exception:

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)

This is the new code:

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();
    }
nrubin29
  • 1,522
  • 5
  • 25
  • 53

0 Answers0