Compartilhar via


Ditado contínuo

Saiba como capturar e reconhecer entradas de falas ditadas continuamente de forma extensa.

APIs importantes: SpeechContinuousRecognitionSession, ContinuousRecognitionSession

No reconhecimento de fala, você aprendeu a capturar e reconhecer entradas de fala relativamente curtas usando os métodos RecognizeAsync ou RecognizeWithUIAsync de um objeto SpeechRecognizer , por exemplo, ao redigir uma mensagem sms (serviço de mensagem curta) ou ao fazer uma pergunta.

Para sessões contínuas de reconhecimento de fala mais longas, como ditado ou email, use a propriedade ContinuousRecognitionSession de um SpeechRecognizer para obter um objeto SpeechContinuousRecognitionSession.

Observação

O suporte à linguagem de ditado depende do dispositivo em que seu aplicativo está em execução. Para computadores e laptops, somente en-US é reconhecido, enquanto Xbox e telefones podem reconhecer todos os idiomas compatíveis com o reconhecimento de fala. Para obter mais informações, consulte Especificar o idioma do reconhecedor de fala.

Configuração

Seu aplicativo precisa de alguns objetos para gerenciar uma sessão de ditado contínuo:

  • Uma instância de um objeto SpeechRecognizer .
  • Uma referência a um dispatcher de interface do usuário para atualizar a UI durante o ditado.
  • Uma maneira de acompanhar as palavras acumuladas faladas pelo usuário.

Aqui, declaramos uma instância speechRecognizer como um campo privado da classe code-behind. Seu aplicativo precisará armazenar uma referência em outro lugar se você quiser que o ditado contínuo persista além de uma única página XAML (Extensible Application Markup Language).

private SpeechRecognizer speechRecognizer;

Durante o ditado, o reconhecedor gera eventos a partir de uma thread em plano de fundo. Como um thread em segundo plano não pode atualizar diretamente a interface do usuário no XAML, seu aplicativo deve usar um dispatcher para atualizar a interface do usuário em resposta a eventos de reconhecimento.

Aqui, declaramos um campo privado que será inicializado posteriormente com o dispatcher de UI.

// Speech events may originate from a thread other than the UI thread.
// Keep track of the UI thread dispatcher so that we can update the
// UI in a thread-safe manner.
private CoreDispatcher dispatcher;

Para acompanhar o que o usuário está dizendo, você precisa lidar com eventos de reconhecimento gerados pelo reconhecedor de fala. Esses eventos fornecem os resultados de reconhecimento para partes de enunciados de usuário.

Aqui, usamos um objeto StringBuilder para manter todos os resultados de reconhecimento obtidos durante a sessão. Novos resultados são acrescentados ao StringBuilder à medida que são processados.

private StringBuilder dictatedTextBuilder;

Inicialização

Durante a inicialização do reconhecimento contínuo de fala, você deve:

  • Busque o dispatcher para o thread de interface do usuário se você atualizar a interface do usuário do seu aplicativo nos manipuladores de eventos de reconhecimento contínuo.
  • Inicialize o reconhecedor de fala.
  • Compile a gramática de ditado integrada. Nota O reconhecimento de fala requer pelo menos uma restrição para definir um vocabulário reconhecível. Se nenhuma restrição for especificada, uma gramática de ditado predefinida será usada. Consulte o reconhecimento de fala.
  • Configure os escutadores para eventos de reconhecimento.

Neste exemplo, inicializamos o reconhecimento de fala no evento de página OnNavigatedTo .

  1. Como os eventos gerados pelo reconhecedor de fala ocorrem em um thread em segundo plano, crie uma referência ao dispatcher para atualizações no thread da interface do usuário. OnNavigatedTo é sempre invocado no thread da interface do usuário.
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
  1. Em seguida, inicializamos a instância speechRecognizer .
this.speechRecognizer = new SpeechRecognizer();
  1. Em seguida, adicionamos e compilamos a gramática que define todas as palavras e frases que podem ser reconhecidas pelo SpeechRecognizer.

    Se você não especificar uma gramática explicitamente, uma gramática de ditado predefinida será usada por padrão. Normalmente, a gramática padrão é melhor para ditado geral.

    Aqui, chamamos CompileConstraintsAsync imediatamente sem adicionar uma gramática.

SpeechRecognitionCompilationResult result =
      await speechRecognizer.CompileConstraintsAsync();

Manipular eventos de reconhecimento

Você pode capturar um único enunciado breve ou frase chamando RecognizeAsync ou RecognizeWithUIAsync.

No entanto, para capturar uma sessão de reconhecimento contínua mais longa, especificamos ouvintes de eventos a serem executados em segundo plano à medida que o usuário fala e definimos manipuladores para construir a sequência de ditado.

Em seguida, usamos a propriedade ContinuousRecognitionSession de nosso reconhecedor para obter um objeto SpeechContinuousRecognitionSession que fornece métodos e eventos para gerenciar uma sessão de reconhecimento contínuo.

Dois eventos em particular são críticos:

  • ResultGenerated, que ocorre quando o reconhecedor gera alguns resultados.
  • Concluído, que ocorre quando a sessão de reconhecimento contínuo é encerrada.

O evento ResultGenerated é gerado conforme o usuário fala. O reconhecedor escuta continuamente o usuário e gera periodicamente um evento que passa uma parte da entrada de fala. Você deve examinar a entrada de fala, usando a propriedade Resultado do argumento de evento e tomar as medidas apropriadas no manipulador de eventos, como anexar o texto a um objeto StringBuilder.

Como uma instância de SpeechRecognitionResult, a propriedade Result é útil para determinar se você deseja aceitar a entrada de fala. Um SpeechRecognitionResult fornece duas propriedades para isso:

  • O status indica se o reconhecimento foi bem-sucedido. O reconhecimento pode falhar por vários motivos.
  • A confiança indica a confiança relativa de que o reconhecedor entendeu as palavras corretas.

Estas são as etapas básicas para dar suporte ao reconhecimento contínuo:

  1. Aqui, registramos o handler para o evento de reconhecimento contínuo ResultGenerated no evento da página OnNavigatedTo.
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
        ContinuousRecognitionSession_ResultGenerated;
  1. Em seguida, verificamos a propriedade Confidence . Se o valor de Confiança for Médio ou melhor, acrescentaremos o texto ao StringBuilder. Também atualizamos a interface do usuário à medida que coletamos a entrada.

    Observe que o evento ResultGenerated é gerado em um thread em segundo plano que não pode atualizar a interface do usuário diretamente. Se um manipulador precisar atualizar a interface do usuário (como o [exemplo de Fala e TTS]), você deverá expedir as atualizações para o thread da interface do usuário por meio do método RunAsync do dispatcher.

private async void ContinuousRecognitionSession_ResultGenerated(
      SpeechContinuousRecognitionSession sender,
      SpeechContinuousRecognitionResultGeneratedEventArgs args)
      {

        if (args.Result.Confidence == SpeechRecognitionConfidence.Medium ||
          args.Result.Confidence == SpeechRecognitionConfidence.High)
          {
            dictatedTextBuilder.Append(args.Result.Text + " ");

            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              dictationTextBox.Text = dictatedTextBuilder.ToString();
              btnClearText.IsEnabled = true;
            });
          }
        else
        {
          await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              dictationTextBox.Text = dictatedTextBuilder.ToString();
            });
        }
      }
  1. Em seguida, manipulamos o evento Concluído , que indica o fim do ditado contínuo.

    A sessão termina quando você chama os métodos StopAsync ou CancelAsync (descritos na próxima seção). A sessão também pode terminar quando ocorrer um erro ou quando o usuário tiver parado de falar. Verifique a propriedade Status do argumento de evento para determinar por que a sessão terminou (SpeechRecognitionResultStatus).

    Aqui, registramos o manipulador para o evento de reconhecimento contínuo Concluído no evento de página OnNavigatedTo .

speechRecognizer.ContinuousRecognitionSession.Completed +=
      ContinuousRecognitionSession_Completed;
  1. O manipulador de eventos verifica a propriedade Status para determinar se o reconhecimento foi bem-sucedido. Ele também lida com o caso em que o usuário parou de falar. Muitas vezes, um TimeoutExceededed é considerado um reconhecimento bem-sucedido, pois significa que o usuário terminou de falar. Você deve lidar com esse caso em seu código para proporcionar uma boa experiência.

    Observe que o evento ResultGenerated é gerado em um thread em segundo plano que não pode atualizar a interface do usuário diretamente. Se um manipulador precisar atualizar a interface do usuário (como o [exemplo de Fala e TTS]), você deverá expedir as atualizações para o thread da interface do usuário por meio do método RunAsync do dispatcher.

private async void ContinuousRecognitionSession_Completed(
      SpeechContinuousRecognitionSession sender,
      SpeechContinuousRecognitionCompletedEventArgs args)
      {
        if (args.Status != SpeechRecognitionResultStatus.Success)
        {
          if (args.Status == SpeechRecognitionResultStatus.TimeoutExceeded)
          {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              rootPage.NotifyUser(
                "Automatic Time Out of Dictation",
                NotifyType.StatusMessage);

              DictationButtonText.Text = " Continuous Recognition";
              dictationTextBox.Text = dictatedTextBuilder.ToString();
            });
          }
          else
          {
            await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
              rootPage.NotifyUser(
                "Continuous Recognition Completed: " + args.Status.ToString(),
                NotifyType.StatusMessage);

              DictationButtonText.Text = " Continuous Recognition";
            });
          }
        }
      }

Fornecer comentários de reconhecimento contínuos

Quando as pessoas conversam, muitas vezes dependem do contexto para entender completamente o que está sendo dito. Da mesma forma, o reconhecedor de fala geralmente precisa de contexto para fornecer resultados de reconhecimento de alta confiança. Por exemplo, por si só, as palavras "peso" e "espera" são indistinguíveis até que mais contexto possa ser obtido de palavras ao redor. Até que o reconhecedor tenha alguma confiança de que uma palavra ou palavras foram reconhecidas corretamente, ela não gerará o evento ResultGenerated .

Isso pode resultar em uma experiência menos que ideal para o usuário, pois ele continua falando e nenhum resultado é fornecido até que o reconhecedor tenha confiança suficiente para elevar o evento ResultGenerated .

Manipule o evento HypothesisGenerated para melhorar essa aparente falta de capacidade de resposta. Esse evento é gerado sempre que o reconhecedor gera um novo conjunto de possíveis correspondências para a palavra que está sendo processada. O argumento de evento fornece uma propriedade Hypothesis que contém as correspondências atuais. Mostre-os ao usuário enquanto eles continuam falando e tranquilize-os de que o processamento ainda está ativo. Depois que a confiança for alta e um resultado de reconhecimento for determinado, substitua os resultados provisórios da Hipótese pelo resultado final fornecido no evento ResultGenerated .

Aqui, acrescentamos o texto hipotético e uma reticência ("...") ao valor atual do TextBox de saída. O conteúdo da caixa de texto é atualizado à medida que novas hipóteses são geradas e até que os resultados finais sejam obtidos do evento ResultGenerated .

private async void SpeechRecognizer_HypothesisGenerated(
  SpeechRecognizer sender,
  SpeechRecognitionHypothesisGeneratedEventArgs args)
  {

    string hypothesis = args.Hypothesis.Text;
    string textboxContent = dictatedTextBuilder.ToString() + " " + hypothesis + " ...";

    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
      dictationTextBox.Text = textboxContent;
      btnClearText.IsEnabled = true;
    });
  }

Iniciar e interromper o reconhecimento

Antes de iniciar uma sessão de reconhecimento, verifique o valor da propriedade State do reconhecedor de fala. O reconhecedor de fala deve estar em um estado ocioso .

Depois de verificar o estado do reconhecedor de fala, iniciamos a sessão chamando o método StartAsync da propriedade ContinuousRecognitionSession do reconhecedor de fala.

if (speechRecognizer.State == SpeechRecognizerState.Idle)
{
  await speechRecognizer.ContinuousRecognitionSession.StartAsync();
}

O reconhecimento pode ser interrompido de duas maneiras:

  • StopAsync permite que todos os eventos de reconhecimento pendentes sejam concluídos (ResultGenerated continua a ser gerado até que todas as operações de reconhecimento pendentes sejam concluídas).
  • CancelAsync encerra a sessão de reconhecimento imediatamente e descarta todos os resultados pendentes.

Depois de verificar o estado do reconhecedor de fala, interrompemos a sessão chamando o método CancelAsync da propriedade ContinuousRecognitionSession do reconhecedor de fala.

if (speechRecognizer.State != SpeechRecognizerState.Idle)
{
  await speechRecognizer.ContinuousRecognitionSession.CancelAsync();
}

Observação

Um evento ResultGenerated pode ocorrer após uma chamada para CancelAsync.
Devido ao multithreading, um evento ResultGenerated ainda pode permanecer na pilha quando CancelAsync for chamado. Nesse caso, o evento ResultGenerated ainda é acionado.
Se você definir quaisquer campos privados ao cancelar a sessão de reconhecimento, sempre confirme seus valores no manipulador ResultGenerated . Por exemplo, não suponha que um campo já esteja inicializado no seu manipulador apenas porque ele foi definido como nulo ao cancelar a sessão.

 

  • Interações de fala

Amostras