Создание синонимов голосовых команд в GRXML

Я создал голосовое приложение UWP в C++/CX (для Hololens, если это имеет значение). Очень простой, по некоторым примерам, это обработчик событий распознавания речи:

void MyAppMain::HasSpoken(SpeechContinuousRecognitionSession ^sender, SpeechContinuousRecognitionResultGeneratedEventArgs ^args)
{
    if (args->Result->Confidence == SpeechRecognitionConfidence::Medium
        || args->Result->Confidence == SpeechRecognitionConfidence::High)
    {
        process_voice_command(args->Result->Text);
    }
}

Пока все работает, результат распознавания в args->Result->Text переменная. Теперь мне нужно только поддерживать очень ограниченный набор голосовых команд и просто игнорировать все остальное, но в этом ограниченном наборе команд мне нужна некоторая изменчивость. Кажется, последний пример на этой странице как раз об этом. Поэтому я сделал следующий файл грамматики:

<grammar version="1.0" xml:lang="en-US" root="nextCommands" xmlns="http://www.w3.org/2001/06/grammar" tag-format="semantics/1.0">

  <rule id="nextCommands">
    <item>
      <one-of>
        <item>next</item>
        <item>go</item>        
        <item>advance</item>
      </one-of>
      <tag>out="next";</tag>
    </item>
  </rule>

</grammar>

Что я хочу с этим, так это то, что когда я говорю "следующий", "идти" или "продвижение", механизм распознавания просто возвращает "следующий", так что он находится в args->Result->Text выше. То, что он на самом деле делает для меня сейчас, - это ограничение набора распознанных слов этими тремя, но он просто возвращает слово, которое я говорю, без преобразования его в "следующий". Похоже, он либо игнорирует <tag> элемент, или я должен получить его содержимое по-другому в моей программе C++ / CX. Или же <tag> не работает так, как я думаю. Что я должен изменить, чтобы это работало?

2 ответа

Решение

Я нашел способ сделать то, что я хочу, с помощью SRGS (по крайней мере, для очень простого случая, описанного в вопросе). Ну, это похоже <tag> не меняет результат распознавания напрямую (по крайней мере, не с tag-format="semantics/1.0", Есть и другие tag-formatЭто, как описано, например, здесь, они могут сделать что-то еще). Вместо этого он заполняет некоторую дополнительную коллекцию свойств. Вот как я изменил свой код сейчас:

<grammar version="1.0" xml:lang="en-US" 
root="nextCommands" xmlns="http://www.w3.org/2001/06/grammar" 
tag-format="semantics/1.0">

  <rule id="nextCommands">
    <item>
      <one-of>
        <item>next</item>
        <item>go</item>        
        <item>advance</item>
      </one-of>
      <tag>out.HONEY="bunny";</tag>
    </item>
  </rule>

</grammar>

Теперь, когда распознается "next", "go" или "advance", оно все равно переходит к args->Result->Text без изменений, но также будет новая пара в args->Result->SemanticInterpretation->Properties с HONEY ключ и bunny значение. Я могу проверить, было ли это в случае с

args->Result->SemanticInterpretation->Properties->HasKey("HONEY");

и, если это так, получить его значение с

args->Result->SemanticInterpretation->Properties->Lookup("HONEY")->GetAt(0); //returns "bunny"

Или не работает так, как я думаю

Тег является расширением юридического правила. Теги не влияют на законные шаблоны слов, определенные грамматикой, или на процесс распознавания речи или другого ввода по грамматике. Подробности, пожалуйста, проверьте раздел Теги Спецификации грамматики распознавания речи.

Что я хочу с этим, так это то, что когда я говорю "следующий", "идти" или "продвижение", механизм распознавания просто возвращает "следующий"

Распознавание речи преобразует слова, сказанные пользователем в текст для ввода формы. Ограничения, или грамматики, определяют произнесенные слова и фразы, которые могут быть сопоставлены распознавателем речи. Используемая вами грамматика предназначена для определения миров совпадений. Если вы хотите, чтобы "next", "go" или "advance" выполняли одну и ту же команду, вы можете справиться с ними при обработке текстового результата. Например,

// Start recognition.
Windows.Media.SpeechRecognition.SpeechRecognitionResult speechRecognitionResult = await speechRecognizer.RecognizeWithUIAsync();
// Do something with the recognition result.
if (speechRecognitionResult.Text == "go" || speechRecognitionResult.Text == "next" || speechRecognitionResult.Text == "advance")
{

}

Подробности, пожалуйста, обратитесь к Scenario_SRGSConstraint официального образца, который содержит метод HandleRecognitionResult,

Другие вопросы по тегам