我在Android中使用pocketsphinx。我已经能够将一个.gram
文件中的规则导入另一个.gram
文件,并且我已经能够通过指定String
来使用规则,但似乎无法能够将两者结合起来。也就是说,我无法从基于字符串的语法中导入基于文件的语法;我一直收到Failed to find grammar
错误。
将语法指定为字符串时使用:
private SpeechRecognizer mPsRecognizer;
//...
final StringGrammar sg = settings.getStringGrammar();
mPsRecognizer.getDecoder().setJsgfString(sg.getName(), sg.getString());
字符串类似于:
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"
+ " ;");
我得到了
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>
由于没有要搜索的基本文件,因此可以预料到这一点。
我尝试了什么:1)使用完整的包名称和2)使用完整路径(我从pocketsphinx自己的资产同步实用程序获得的内容)。
使用包名称
如果我将import
路径更改为
//...
+ "import <com.sample.vr.commands/files/sync/actions.r_actions>;\n"
+ "import <com.sample.vr.commands/files/sync/help.r_help>;\n"
//...
我得到了
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
有完整路径
#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>
;
我收到以下错误(请注意包部分已转换为单独的目录):
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>
在pocketsphinx的来源中我看到他们正在用斜线替换点:
/* 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;
}
我能做什么让pocketphinx-android知道在哪里找到我要导入的文件?我在SpeechRecognizer
和Decoder
中找不到功能。
我想也许有一种方法可以在配置中指定哪里可以查找语法文件,但我似乎无法找到它。将一些参数添加到SpeechRecognizerSetup
或Config
?
或者在pocketsphinx中是否有一个命令行参数,我可以将其作为字符串参数添加到Config / Setup对象中?
答案 0 :(得分:0)
在JSGF语法包名称映射到编码的位置,这意味着如果你写
import com.package.name;
相应的语法必须位于相对于主语法文件夹的文件夹com/package
中。与java包相同。因此,布局必须是:
main.jsgf
com
package
name.jsgf
如果从字符串加载JSGF,则会搜索当前路径以查找导入。搜索路径也由JSGF_PATH环境变量配置。但是,在Java中用Android设置当前工作文件夹或环境变量并不容易。因此,最好使用您需要的硬编码更改重新编译pocketsphinx-android,或者从文件而不是字符串加载jsgf。