我是一名中级 C# 程序员,但绝对是 System.Speech 的初学者。我正在通过一些示例来了解 API 的工作原理,并且我已经挂断了第一个示例......我想要做的是有一个语法,它返回一个或多个预期选择的默认语义如果用户没有明确地为这些选择之一提供值。(对不起,如果我的术语不太正确......)我在 Windows Vista 上安装了 Visual Studio 2010(试用版)和 .NET 4.0。
我从以下文章中的“披萨订购”示例开始,这似乎在论坛上出现了很多:
http://msdn.microsoft.com/en-us/magazine/cc163663.aspx#S5
我开始使用的代码在该文章的图 9 中。不幸的是,由于某种原因(可能从 SAPI 的一个版本更改为下一个版本?),许多函数调用在 .NET 4.0/SAPI 5.3 中实际上是无效的,例如 GrammarBuilder.AppendChoices() 和 GrammarBuilder.AppendResultKeyValue() . 如果用户只指定浇头(即“A cheese Pizza, please” 递回 size=large、crust=thick 和 topping=奶酪)...所以我想弄清楚如何使这项工作。
这是我的代码的相关部分(应该只是对上面文章中代码的重写):
// [I'd like] a [< size >] [< crust >] [< topping >] pizza [please]
// build the core set of choices
GrammarBuilder grbSizes = new GrammarBuilder(new Choices("small", "regular", "large"));
GrammarBuilder grbCrusts = new GrammarBuilder(new Choices("thin crust", "thick crust"));
GrammarBuilder grbToppings = new GrammarBuilder(new Choices("vegetarian", "pepperoni", "cheese"));
// Wrap them in semantic result keys
SemanticResultKey skeySize = new SemanticResultKey("size", grbSizes);
SemanticResultKey skeyCrust = new SemanticResultKey("crust", grbCrusts);
SemanticResultKey skeyTopping = new SemanticResultKey("topping", grbToppings);
// And some default values for later on...
SemanticResultKey skeyDefaultSize = new SemanticResultKey("size", new GrammarBuilder(new SemanticResultValue("large")));
SemanticResultKey skeyDefaultCrust = new SemanticResultKey("crust", new GrammarBuilder(new SemanticResultValue("thick crust")));
// [...snip...]
// Here's the builder for one of several sub-grammars, the one with two default
// values... This should allow "cheese" in "A cheese pizza" to be intepreted
// as large+thick-crust+cheese
//choose topping only, and assume the rest
GrammarBuilder toppingOnly = new GrammarBuilder();
toppingOnly += skeyTopping;
toppingOnly += skeyDefaultSize;
toppingOnly += skeyDefaultCrust;
// [...snip...]
// Later code builds up the full pattern just as in the original article
我知道SemanticResultKey 构造函数的 MSDN 页面包含一个警告,即“在由builders参数指定的 GrammarBuilder 对象中应该有一个且只有一个未标记的 SemanticResultValue 实例”,否则您将收到异常。事实上,当我在识别器中说“A cheese Pizza”之类的内容时,我确实在这里得到了 TargetInvocationException。
所以我的第一个问题是,有人可以向我解释这里发生了什么吗?我不一定期望此约束适用于此,因为 (a) 我认为我对 skeyDefaultSize 和 skeyDefaultCrust 的声明确实将 SemanticResultValues 与 SemanticResultKeys 相关联,因此不应将这些值视为“未标记”;(b) 有问题的两个 SemanticResultValues 实际上来自不同的 GrammarBuilders,它们又位于不同的 SemanticResultKeys 内部,这似乎不是 MSDN 页面上描述的场景。
那么我的第二个问题是,为什么下面的代码有效?唯一的区别是我重新排序了一些行,以便两个“默认”键不会连续附加到语法中。
//choose topping only, and assume the rest
GrammarBuilder toppingOnly = new GrammarBuilder();
toppingOnly += skeyDefaultSize;
toppingOnly += skeyTopping;
toppingOnly += skeyDefaultCrust;
当我说“A cheese Pizza”时,这给出了确切的期望结果——所有键(“size”、“crust”、“topping”)都存在于我在 SpeechRecognized 处理程序中捕获的 SemanticValue 中,具有所需的默认值大小和外壳的值加上用户指定的浇头值。
我想第三个也是最重要的问题是:有什么方法可以正确地做到这一点吗?显然,调整追加的顺序太“神奇”,并不总是可行的解决方案。
很抱歉这个大问题,非常感谢您的帮助!