私は中級の C# プログラマーですが、System.Speech はまったくの初心者です。API がどのように機能するかを理解するために、いくつかの例に取り組んでいますが、最初の例にすでに夢中になっています...ユーザーがこれらの選択肢のいずれかに値を明示的に指定しない場合。(用語が正しくない場合は申し訳ありません...) Visual Studio 2010 (試用版) と .NET 4.0 がインストールされた Windows Vista を使用しています。
次の記事の「ピザの注文」の例から始めました。これは、フォーラムでかなり話題になっているようです。
http://msdn.microsoft.com/en-us/magazine/cc163663.aspx#S5
私が始めたコードは、その記事の図 9 にあります。残念ながら、何らかの理由 (SAPI のあるバージョンから次のバージョンに変更された可能性がありますか?) で、.NET 4.0/SAPI 5.3 では多くの関数呼び出しが実際には有効ではありません。たとえば、GrammarBuilder.AppendChoices() および GrammarBuilder.AppendResultKeyValue() . 後者の呼び出しは、ユーザーがトッピングのみを指定した場合に「サイズ」キーと「クラスト」キーのデフォルトの選択肢を提供することになっています (つまり、「チーズ ピザをお願いします」とサイズ = 大、クラスト = 厚、トッピング = を返します)。チーズ)...だから私はこれを機能させる方法を理解しようとしています。
私のコードの関連セクションは次のとおりです(上記の記事のコードを書き直しただけであるはずです):
// [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 インスタンスが 1 つだけ存在する必要があります」という警告が含まれていることを認識しています。そうしないと、例外が発生します。実際、レコグナイザーに「チーズ ピザ」などと言うと、ここで TargetInvocationException が発生します。
私の最初の質問は、誰かがここで何が起こっているのか説明してもらえますか? (a) skeyDefaultSize と skeyDefaultCrust の宣言が実際に SemanticResultValues を SemanticResultKeys に関連付けていると考えたため、この制約がここで適用されるとは必ずしも予想していなかったので、これらの値は「タグなし」と見なされるべきではありません。(b) 問題の 2 つの SemanticResultValues は、実際には異なる SemanticResultKeys の内部にある異なる GrammarBuilders からのものであり、MSDN ページで説明されているシナリオではないようです。
次に、2 番目の質問は、次のコードが機能するのはなぜですか? 唯一の違いは、2 つの「デフォルト」キーが文法に連続して追加されないように、いくつかの行の順序を変更したことです。
//choose topping only, and assume the rest
GrammarBuilder toppingOnly = new GrammarBuilder();
toppingOnly += skeyDefaultSize;
toppingOnly += skeyTopping;
toppingOnly += skeyDefaultCrust;
これにより、たとえば「チーズ ピザ」と言うと、正確に望ましい結果が得られます。すべてのキー (「サイズ」、「クラスト」、「トッピング」) は、SpeechRecognided ハンドラーでキャッチした SemanticValue に存在し、目的の既定値が設定されています。サイズとクラストの値に加えて、トッピングのユーザー指定の値。
3 番目の最も重要な質問は次のとおりだと思います。これを適切に行う方法はありますか? 明らかに、追加の順序を微調整することは「魔法」であり、常に実行可能な解決策になるとは限りません。
大変な質問で申し訳ありません。ご協力ありがとうございます。