设置语法序列 UWP

Set grammatical sequence UWP

我使用我在名为语法的 xml 文件中创建的语法从 Scenario_SRGSConstraint.xaml.cs 场景中的 GitHub 的 SpeechRecognitionAndSynthesis 重新创建了一个最小示例。

我想解决的是开始动作的单词顺序。我重新创建了模型,以便可以选择两种颜色:矩形背景的红色和绿色。

现在我要说的是(我会根据需要使用意大利语单词)在按下按钮后开始动作我必须先说出颜色,在红色和绿色之间,然后是背景来开始动作。

我希望能先读出背景(然后是sfondo),然后是颜色(然后是rosso o verde),我尝试了各种方法多次修改grammar.xml都没有成功。

此时我想问一下我必须做哪些改变才能开始动作,例如说句子:red background or green background ...以便先读出 background(然后是 sfondo)这个词,然后然后是红色或绿色(然后是 rosso o verde)字样。

最后我想问一下我是否只需要更改 grammar.xml 甚至代码隐藏。

MainPage.xaml.cs:

    private SpeechRecognizer speechRecognizer;
    private IAsyncOperation<SpeechRecognitionResult> recognitionOperation;
    private ResourceContext speechContext;
    private ResourceMap speechResourceMap;

    private Dictionary<string, Color> colorLookup = new Dictionary<string, Color>
    {
        { "COLOR_RED",   Colors.Red }, {"COLOR_GREEN",  Colors.Green}

    };

    public MainPage()
    {
        InitializeComponent();
    }

    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        bool permissionGained = await AudioCapturePermissions.RequestMicrophonePermission();
        if (permissionGained)
        {
            Language speechLanguage = SpeechRecognizer.SystemSpeechLanguage;
            string langTag = speechLanguage.LanguageTag;
            speechContext = ResourceContext.GetForCurrentView();
            speechContext.Languages = new string[] { langTag };

            speechResourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("LocalizationSpeechResources");

            await InitializeRecognizer();
        }
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
        if (speechRecognizer != null)
        {
            if (speechRecognizer.State != SpeechRecognizerState.Idle)
            {
                if (recognitionOperation != null)
                {
                    recognitionOperation.Cancel();
                    recognitionOperation = null;
                }
            }

            speechRecognizer.StateChanged -= SpeechRecognizer_StateChanged;

            this.speechRecognizer.Dispose();
            this.speechRecognizer = null;
        }
    }

    private async Task InitializeRecognizer()
    {
        if (speechRecognizer != null)
        {
            speechRecognizer.StateChanged -= SpeechRecognizer_StateChanged;

            this.speechRecognizer.Dispose();
            this.speechRecognizer = null;
        }

        try
        {


            string languageTag = SpeechRecognizer.SystemSpeechLanguage.LanguageTag;
            StorageFile grammarFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///grammar.xml"));

            speechRecognizer = new SpeechRecognizer(SpeechRecognizer.SystemSpeechLanguage);

            speechRecognizer.StateChanged += SpeechRecognizer_StateChanged;

            SpeechRecognitionGrammarFileConstraint grammarConstraint = new SpeechRecognitionGrammarFileConstraint(grammarFile);
            speechRecognizer.Constraints.Add(grammarConstraint);
            SpeechRecognitionCompilationResult compilationResult = await speechRecognizer.CompileConstraintsAsync();
        }
        catch (Exception ex) { string message = ex.Message; }
    }

    private async void SpeechRecognizer_StateChanged(SpeechRecognizer sender, SpeechRecognizerStateChangedEventArgs args)
    {

    }


    private async void RecognizeWithoutUI_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            recognitionOperation = speechRecognizer.RecognizeAsync();
            SpeechRecognitionResult speechRecognitionResult = await recognitionOperation;
            if (speechRecognitionResult.Status == SpeechRecognitionResultStatus.Success)
            {
                HandleRecognitionResult(speechRecognitionResult);
            }
        }
        catch (TaskCanceledException exception)
        {
            System.Diagnostics.Debug.WriteLine("TaskCanceledException caught while recognition in progress (can be ignored):");
            System.Diagnostics.Debug.WriteLine(exception.ToString());
        }
    }

    /// <summary>
    /// Uses the result from the speech recognizer to change the colors of the shapes.
    /// </summary>
    /// <param name="recoResult">The result from the recognition event</param>
    private void HandleRecognitionResult(SpeechRecognitionResult recoResult)
    {
        // Check the confidence level of the recognition result.
        if (recoResult.Confidence == SpeechRecognitionConfidence.High ||
        recoResult.Confidence == SpeechRecognitionConfidence.Medium)
        {
            if (recoResult.SemanticInterpretation.Properties.ContainsKey("KEY_BACKGROUND") && recoResult.SemanticInterpretation.Properties["KEY_BACKGROUND"][0].ToString() != "...")
            {
                string backgroundColor = recoResult.SemanticInterpretation.Properties["KEY_BACKGROUND"][0].ToString();
                colorRectangle.Fill = new SolidColorBrush(getColor(backgroundColor));
            }
        }
    }

    /// <summary>
    /// Creates a color object from the passed in string.
    /// </summary>
    /// <param name="colorString">The name of the color</param>
    private Color getColor(string colorString)
    {
        Color newColor = Colors.Transparent;

        if (colorLookup.ContainsKey(colorString))
        {
            newColor = colorLookup[colorString];
        }

        return newColor;
    }

grammar.xml:

<?xml version="1.0" encoding="utf-8" ?>
<grammar xml:lang="it-IT" root="colorChooser"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">

  <rule id="background_Color">
    <item>
      <item>
        <ruleref uri="#color"/>
      </item>
      sfondo
    </item>
  </rule>

  <rule id="colorChooser">
    <one-of>

      <item>
        <item>
          <ruleref uri="#background_Color"/>
          <tag> out.KEY_BACKGROUND=rules.latest(); </tag>
        </item>
      </item>

    </one-of>
  </rule>

  <rule id="color">
    <one-of>

      <item>
        rosso <tag> out="COLOR_RED"; </tag>
      </item>
      <item>
        verde <tag> out="COLOR_GREEN"; </tag>
      </item>

    </one-of>
  </rule>

</grammar>

在此先感谢您的帮助。

--更新--

使用此设置是错误的...我还尝试使用具有退出标签的项目设置 playCommands 但它 运行 不正确(我更新了我的 post 以突出显示我的测试你的建议)问题是“ out.KEY_BACKGROUND = rules.latest (); ”必须插入某个地方才能开始操作,因为在它后面的代码中是通过这个键执行的:KEY_BACKGROUND.

Codice grammar.xml provato da me con il tuo suggerimento:

<?xml version="1.0" encoding="utf-8" ?>
 <grammar xml:lang="it-IT" root="playCommands"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">
    ​
    <rule id="background_Color">
      <item>
        sfondo​
      </item>​
    </rule>​
    ​
    <rule id="playCommands">
      <item>
        <ruleref uri="#background_Color" />​
      </item>
      <item>
        <ruleref uri="#color" />​
        <tag> out.KEY_BACKGROUND=rules.latest(); </tag>
      </item>
      
      
    </rule>​
    ​
    <rule id="color">
      <one-of>
        <item>
          rosso <tag> out="COLOR_RED"; </tag>​
        </item>​
        <item>
          verde <tag> out="COLOR_GREEN"; </tag>​
        </item>​
      </one-of>​
    </rule>
    ​
  </grammar>

--更新1--

我试过你的代码,我认为 grammar.xml 逻辑是正确的,但在它后面的代码中给我一个错误:

recognitionOperation = speechRecognizer.RecognizeAsync();

方法中RecognizeWithoutUI_Click

错误是这样的:

The text associated with this error code could not be found.

这是完整的项目:Test Grammar UWP

如果您希望元素必须按照用户说出命令的顺序列出,您可以创建一个引用背景和颜色规则的顶级规则元素,以创建一个灵活的命令集合,并将命令设置为根,如下所示:

grammar.xml:

<grammar xml:lang="it-IT" root="playCommands"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">
    ​
    <rule id="background_Color">
      <item>
        sfondo​
      </item>​
    </rule>​
    ​
    <rule id="playCommands">
      <ruleref uri="#background_Color" />​
      <ruleref uri="#color" />​
    </rule>​
    ​
    <rule id="color">
      <one-of>
        <item>
          rosso <tag> out="COLOR_RED"; </tag>​
        </item>​
        <item>
          verde <tag> out="COLOR_GREEN"; </tag>​
        </item>​
      </one-of>​
    </rule>
    ​
  </grammar>

更新:

如果你想使用"out.KEY_BACKGROUND = rules.latest();"你只需要改变sfondo<ruleref uri="#color"/>的位置。在这种情况下,它会先执行 backgroundColor,然后再执行 color.

<?xml version="1.0" encoding="utf-8" ?>
<grammar xml:lang="it-IT" root="colorChooser"
tag-format="semantics/1.0" version="1.0"
xmlns="http://www.w3.org/2001/06/grammar">

  <rule id="background_Color">
    <item>
      sfondo
      <item>
        <ruleref uri="#color"/>
      </item>
    </item>
  </rule>

  <rule id="colorChooser">
        <item>
          <ruleref uri="#background_Color"/>
          <tag> out.KEY_BACKGROUND=rules.latest(); </tag>
        </item>
  </rule>

  <rule id="color">
    <one-of>

      <item>
        rosso <tag> out="COLOR_RED"; </tag>
      </item>
      <item>
        verde <tag> out="COLOR_GREEN"; </tag>
      </item>

    </one-of>
  </rule>

</grammar>