【问题标题】:Set grammatical sequence UWP设置语法序列 UWP
【发布时间】:2019-09-17 19:04:59
【问题描述】:

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

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

现在我要说的话(我会用意大利语的话)在按下按钮后开始动作我必须先说出颜色,在红色和绿色之间,然后是背景才能开始动作。

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

此时我想通过说出以下句子来询问我必须进行哪些更改才能开始动作:红色背景或绿色背景......以便首先发音这个词背景(然后是 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;
    }

语法.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(我更新了我的帖子以用你的建议突出我的测试)问题是“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方法中

错误是这样的:

找不到与此错误代码相关的文本。

这是完整的项目:Test Grammar UWP

【问题讨论】:

    标签: c# xml uwp speech-recognition grammar


    【解决方案1】:

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

    语法.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&lt;ruleref uri="#color"/&gt; 的位置。在这种情况下,它将先执行 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>
    

    【讨论】:

    • 我已经更新了我的答案,你可以试试更新的方法。
    • 我在帖子末尾插入了修改后项目的链接,并附有您的建议
    • 该错误表示无法编译语法,您的语法文件似乎有一些格式问题。所以建议你可以直接复制我整个更新的grammar.xml来覆盖你的内容。我测试过,它有效。另外,请确保您当前使用的语言与您的 xml:lang 中设置的语言相同。
    • 感谢您按照您的指示,grammar.xml 文件可以正常工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多