Import grammar rules from string-based grammar

953 Views Asked by At

I'm using pocketsphinx in Android. And I've been able to import rules in one .gram file to another .gram file, and I've been able to use rules by specifying a String, but can't seem to be able to combine the two. That is, I can't import a file-based grammar from a string-based grammar; I keep getting Failed to find grammar errors.

When specifying the grammar as a string with:

private SpeechRecognizer mPsRecognizer;

//...

final StringGrammar sg = settings.getStringGrammar();
mPsRecognizer.getDecoder().setJsgfString(sg.getName(), sg.getString());

Where the string is something like:

name: "initial_grammar",

string: "#JSGF V1.0;\n"
    + "\n"
    + "grammar initial_grammar;\n"
    + "\n"
    + "import <digits.digits>;\n"
    + "import <actions.r_actions>;\n"
    + "import <help.r_help>;\n"
    + "\n"
    + "public <initial_grammar>\n"
    + "    = <r_actions>\n"
    + "    | <r_help>\n"
    + "    ;");

I get

com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar digits.gram
com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar actions.gram
com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar help.gram
com.sample.vr.commands I/cmusphinx: INFO: jsgf.c(691): Defined rule: PUBLIC <initial_step.initial_grammar>
com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 338: Undefined rule in RHS: <initial_step.digits>

Which is somehow expected since there is no base file to search relative to.

What I've tried: 1) using the full package name and 2) using the full path (what I get from pocketsphinx's own Asset sync utility).

Using package names If I change the import paths to

    //...
    + "import <com.sample.vr.commands/files/sync/actions.r_actions>;\n"
    + "import <com.sample.vr.commands/files/sync/help.r_help>;\n"
    //...

I get

com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar com/sample/vr/commands/files/sync/help.gram
com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar com/sample/vr/commands/files/sync/actions.gram

with full paths

#JSGF V1.0;

grammar initial_step;

import </storage/emulated/0/Android/data/com.sample.vr.commands/files/sync/actions.r_actions>;
import </storage/emulated/0/Android/data/com.sample.vr.commands/files/sync/help.r_help>;
public <initial_grammar>
    = <r_actions>
    | <r_help>
    ;

I get the following error (note the package part was converted to separate directories):

com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar /storage/emulated/0/Android/data/com/sample/vr/commands/files/sync/help.gram
com.sample.vr.commands E/cmusphinx: ERROR: "jsgf.c", line 775: Failed to find grammar /storage/emulated/0/Android/data/com/sample/vr/commands/files/sync/actions.gram
com.sample.vr.commands I/cmusphinx: INFO: jsgf.c(691): Defined rule: PUBLIC <initial_step.initial_grammar>

in pocketsphinx's source I see that they are replacing dots for slashes:

/* Construct a filename. */
for (c = path; *c; ++c)
    if (*c == '.')
        *c = '/';
strcat(path, ".gram");
newpath = path_list_search(jsgf->searchpath, path);
if (newpath == NULL) {
    E_ERROR("Failed to find grammar %s\n", path);
    ckd_free(path);
    return NULL;
}

What can I do to let pocketsphinx-android know where to find the files that I'm trying to import? I haven't found a function in SpeechRecognizer nor in Decoder. I'm thinking that there's perhaps a way to specify in the configuration where to look for grammar files, but I can't seem to find it. Add some parameter to SpeechRecognizerSetup or Config? Or is there a command line parameter in pocketsphinx that I can add as a string parameter to the Config/Setup object?

1

There are 1 best solutions below

5
On

In JSGF syntax package name maps to a location as coded, that means that if you write

 import com.package.name;

the corresponding grammar must be in folder com/package relative to the main grammar folder. Same as java packages. So, the layout must be:

main.jsgf
com
  package
    name.jsgf

In case JSGF is loaded from string, a current path is searched for imports. Search path is also configured by JSGF_PATH environment variable. However, it is not easy to set either current working folder or environment variables in Android in Java. For that reason it is better to recompile pocketsphinx-android with hardcoded changes you need or load jsgf from file instead of a string.