Share via


Dictée continue

Découvrez comment capturer et reconnaître une entrée vocale dictée en continu et sur une longue durée.

API importantes : SpeechContinuousRecognitionSession, ContinuousRecognitionSession

Dans Reconnaissance vocale, vous avez appris à capturer et à reconnaître des saisies vocales de durée relativement courte à l’aide des méthodes RecognizeAsync ou RecognizeWithUIAsync d’un objet SpeechRecognizer, par exemple, lorsque l’utilisateur compose un SMS ou pose une question.

Pour les sessions de reconnaissance vocale en continu plus longues, tel qu’un texte dicté ou un e-mail, utilisez la propriété ContinuousRecognitionSession d’un SpeechRecognizer afin d’obtenir un objet SpeechContinuousRecognitionSession.

Notes

La prise en charge de la langue de dictée dépend de l’appareil sur lequel votre application s’exécute. Pour les PC et les ordinateurs portables, seul en-US est reconnu, tandis que xbox et téléphones peuvent reconnaître toutes les langues prises en charge par la reconnaissance vocale. Pour plus d’informations, consultez Spécifier la langue du module de reconnaissance vocale.

Configurer

Votre application a besoin de plusieurs objets pour gérer une session de dictée continue :

  • Instance d’un objet SpeechRecognizer.
  • une référence de répartiteur d’interface utilisateur afin de mettre à jour l’interface utilisateur lors de la dictée ;
  • un dispositif de suivi des mots ajoutés par l’utilisateur.

Dans cet exemple, nous déclarons une instance SpeechRecognizer comme un champ privé de la classe code-behind. Votre application doit stocker une référence à un autre emplacement, si vous voulez que la dictée en continu se poursuive sur d’autres pages XAML.

private SpeechRecognizer speechRecognizer;

Lors de la dictée, le module de reconnaissance déclenche des événements à partir d’un thread d’arrière-plan. Dans la mesure où un thread d’arrière-plan ne peut pas mettre à jour directement l’interface utilisateur en XAML, votre application doit utiliser un répartiteur pour mettre à jour l’interface utilisateur en réponse aux événements de reconnaissance.

Nous déclarons ici un champ privé, qui sera initialisé ultérieurement avec le répartiteur d’interface utilisateur.

// 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;

Pour suivre ce que dit l’utilisateur, vous devez gérer les événements de reconnaissance déclenchés par le module de reconnaissance vocale. Ces événements fournissent les résultats de reconnaissance des différents blocs d’énoncés de l’utilisateur.

Ici, nous utilisons un objet StringBuilder pour contenir tous les résultats de reconnaissance obtenus pendant la session. Les nouveaux résultats sont ajoutés à l’objet StringBuilder lors de leur traitement.

private StringBuilder dictatedTextBuilder;

Initialisation

Pendant l’initialisation de la reconnaissance vocale en continu, vous devez :

  • Si vous mettez à jour l’interface utilisateur de votre application dans les gestionnaires d’événements de reconnaissance continue, récupérez le répartiteur pour le thread d’interface utilisateur.
  • Initialisez le module de reconnaissance vocale.
  • Compilez la grammaire de dictée intégrée. Remarque La reconnaissance vocale requiert au moins une contrainte pour définir un vocabulaire reconnaissable. Si aucune contrainte n’est spécifiée, une grammaire de dictée prédéfinie est utilisée. Voir Reconnaissance vocale.
  • Configurez les détecteurs d’événements pour les événements de reconnaissance.

Nous initialisons la reconnaissance vocale dans l’événement de page OnNavigatedTo.

  1. Comme les événements déclenchés par le module de reconnaissance vocale se produisent sur un thread d’arrière-plan, créez une référence pour le répartiteur pour les mises à jour du thread d’interface utilisateur. OnNavigatedTo est toujours appelé sur le thread d’interface utilisateur.
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
  1. Nous initialisons ensuite l’instance SpeechRecognizer.
this.speechRecognizer = new SpeechRecognizer();
  1. Nous ajoutons et compilons ensuite la grammaire qui définit tous les mots et expressions qui peuvent être reconnus par SpeechRecognizer.

    Si vous ne spécifiez explicitement de grammaire, la grammaire de dictée continue est utilisée par défaut. En règle générale, la grammaire par défaut est préférable pour la dictée générale.

    Ici, nous appelons CompileConstraintsAsync immédiatement sans ajouter de grammaire.

SpeechRecognitionCompilationResult result =
      await speechRecognizer.CompileConstraintsAsync();

Gérer les événements de reconnaissance

Vous pouvez capturer un seul et bref énoncé ou une expression en appelant RecognizeAsync ou RecognizeWithUIAsync.

Toutefois, pour capturer une session de reconnaissance plus longue, continue, nous indiquons des détecteurs d’événements à exécuter en arrière-plan pendant que l’utilisateur parle et définissons des gestionnaires afin de créer la chaîne de dictée.

Nous pouvons ensuite utiliser la propriété ContinuousRecognitionSession de notre module de reconnaissance vocale pour obtenir un objet SpeechContinuousRecognitionSession qui fournit des méthodes et des événements pour la gestion d’une session de reconnaissance vocale en continu.

Deux événements sont particulièrement essentiels :

  • ResultGenerated, qui se produit lorsque le module de reconnaissance a généré des résultats.
  • Terminé, qui se produit lorsque la session de reconnaissance continue est terminée.

L’événement ResultGenerated est déclenché à mesure que l’utilisateur parle. Le module de reconnaissance écoute l’utilisateur en continu et déclenche périodiquement un événement qui transmet un segment d’entrée vocale. Examinez l’entrée vocale à l’aide de la propriété Result de l’argument d’événement et prenez les mesures appropriées dans le gestionnaire d’événements, par exemple en ajoutant du texte à un objet StringBuilder.

En tant que instance de SpeechRecognitionResult, la propriété Result est utile pour déterminer si vous souhaitez accepter l’entrée vocale. Un objet SpeechRecognitionResult fournit deux propriétés pour ceci :

  • L’état indique si la reconnaissance a réussi. La reconnaissance peut échouer pour diverses raisons.
  • Confiance indique la confiance relative selon laquelle le module de reconnaissance a compris les mots corrects.

Voici les étapes de base associées à la prise en charge de la reconnaissance continue :

  1. Ici, nous inscrivons le gestionnaire de l’événement de reconnaissance continue ResultGenerated dans l’événement de page OnNavigatedTo .
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
        ContinuousRecognitionSession_ResultGenerated;
  1. Nous vérifions ensuite la propriété Confidence. Si la valeur de Confiance est Moyenne ou supérieure, nous ajoutons le texte à StringBuilder. Nous mettons également à jour l’interface utilisateur lorsque nous collectons des entrées.

    Remarque L’événement ResultGenerated est déclenché sur un thread d’arrière-plan qui ne peut pas mettre à jour l’interface utilisateur directement. Si un gestionnaire doit mettre à jour l’interface utilisateur (comme le fait l’exemple [Speech et TTS], vous devez distribuer les mises à jour au thread d’interface utilisateur via la méthode RunAsync du répartiteur.

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. Ensuite, nous gérons l’événement Completed, qui indique la fin de la dictée continue.

    La session se termine lorsque vous appelez le StopAsync ou les méthodes CancelAsync (voir la section suivante). La session peut également se terminer lorsqu’une erreur se produit, ou lorsque l’utilisateur cesse de parler. Vérifiez la propriété Status de l’argument d’événement afin de déterminer pourquoi la session s’est terminée (SpeechRecognitionResultStatus).

    Ici, nous inscrivons le gestionnaire pour l’événement de reconnaissance en continu Completed de l’événement de page OnNavigatedTo.

speechRecognizer.ContinuousRecognitionSession.Completed +=
      ContinuousRecognitionSession_Completed;
  1. Le gestionnaire d’événements vérifie la propriété d’état afin de savoir si la reconnaissance a réussi. Il gère également le cas où l’utilisateur cesse de parler. Souvent, un TimeoutExceeded est considéré comme une reconnaissance réussie, car cela signifie que l’utilisateur a fini de parler. Vous devez gérer ce cas dans votre code afin d’offrir une expérience optimale.

    Remarque L’événement ResultGenerated est déclenché sur un thread d’arrière-plan qui ne peut pas mettre à jour l’interface utilisateur directement. Si un gestionnaire doit mettre à jour l’interface utilisateur (comme le fait l’exemple [Speech et TTS], vous devez distribuer les mises à jour au thread d’interface utilisateur via la méthode RunAsync du répartiteur.

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";
            });
          }
        }
      }

Fournir des commentaires en cours de reconnaissance

Lorsque des individus discutent, ces derniers s’appuient généralement sur le contexte pour déterminer le sens de la conversation. De la même manière, le module de reconnaissance vocale a souvent besoin de contexte pour fournir des résultats de reconnaissance très fiables. Par exemple, la différence entre les mots « poids » et « pois » est imperceptible tant qu’un contexte plus précis ne révèle leur sens. Tant que le module de reconnaissance n’est pas certain qu’un mot a été reconnu correctement, il ne déclenche pas l’événement ResultGenerated .

Cela peut entraîner une expérience moins qu’idéale pour l’utilisateur à mesure qu’il continue à parler et aucun résultat n’est fourni tant que le module de reconnaissance n’a pas suffisamment de confiance pour déclencher l’événement ResultGenerated .

Gérez l’événement HypothesisGenerated pour améliorer ce manque apparent de réactivité. Cet événement est déclenché chaque fois que le moteur de reconnaissance vocale génère un nouveau jeu de correspondances potentielles pour le mot en cours de traitement. L’argument événement fournit une propriété Hypothèse qui contient les correspondances actuelles. Affichez ces correspondances à mesure que l’utilisateur continue de parler afin de leur montrer que le traitement est toujours actif. Une fois le niveau confiance est suffisamment élevé et que le résultat de la reconnaissance a été déterminé, remplacez les résultats Hypothesis temporaires par le dernier Result indiqué dans l’événement ResultGenerated.

Ici, nous ajoutons le texte hypothétique et les points de suspension (« ... ») à la valeur actuelle de la zone de texte de sortie. Le contenu de la zone de texte est mis à jour à mesure que de nouvelles hypothèses sont générées et jusqu’à ce que les résultats finaux soient obtenus à partir de l’événement 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;
    });
  }

Démarrer et arrêter la reconnaissance

Avant de démarrer une session de reconnaissance, vérifiez la valeur de la propriété State du module de reconnaissance vocale. Le module de reconnaissance vocale doit être dans un état Inactif .

Après avoir vérifié l’état du module de reconnaissance vocale, nous commençons la session en appelant la méthode StartAsync de la propriété ContinuousRecognitionSession du module de reconnaissance vocale.

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

La reconnaissance peut être arrêtée de deux façons :

  • StopAsync permet à tous les événements de reconnaissance en attente de se terminer (ResultGenerated continue d’être déclenché jusqu’à ce que toutes les opérations de reconnaissance en attente soient terminées).
  • CancelAsync met immédiatement fin à la session de reconnaissance et ignore les résultats en attente.

Une fois la vérification de l’état du module de reconnaissance vocale terminée, nous arrêtons la session en appelant la méthode CancelAsync de la propriété ContinuousRecognitionSession du module de reconnaissance vocale.

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

Notes

Un événement ResultGenerated peut se produire après un appel à CancelAsync.
En raison du multithreading, un événement ResultGenerated peut rester sur la pile quand CancelAsync est appelé. Dans ce cas, l’événement ResultGenerated est quand même déclenché.
Si vous définissez des champs privés lors de l’annulation de la session de reconnaissance, vérifiez toujours leurs valeurs dans le gestionnaire ResultGenerated . Par exemple, ne supposez pas qu’un champ est initialisé dans votre gestionnaire si vous définissez ces champs comme nuls lorsque vous annulez la session.

 

Exemples