Dictado continuoContinuous dictation

Obtén información sobre cómo capturar y reconocer la entrada de voz de dictado continuo de larga duración.Learn how to capture and recognize long-form, continuous dictation speech input.

API importantes: SpeechContinuousRecognitionSession, ContinuousRecognitionSessionImportant APIs: SpeechContinuousRecognitionSession, ContinuousRecognitionSession

En el Reconocimiento de voz aprendiste a capturar y reconocer entradas de voz relativamente cortas usando los métodos RecognizeAsync o RecognizeWithUIAsync de un objeto SpeechRecognizer; por ejemplo, al redactar un mensaje SMS o al realizar una pregunta.In Speech recognition, you learned how to capture and recognize relatively short speech input using the RecognizeAsync or RecognizeWithUIAsync methods of a SpeechRecognizer object, for example, when composing a short message service (SMS) message or when asking a question.

Para las sesiones de reconocimiento de voz más largas y continuas, como el dictado o el envío de correos electrónicos, puedes usar la propiedad ContinuousRecognitionSession de la clase SpeechRecognizer para obtener un objeto SpeechContinuousRecognitionSession.For longer, continuous speech recognition sessions, such as dictation or email, use the ContinuousRecognitionSession property of a SpeechRecognizer to obtain a SpeechContinuousRecognitionSession object.

Nota

La compatibilidad con el lenguaje de dictado depende del dispositivo en el que se ejecuta la aplicación.Dictation language support depends on the device where your app is running. En el caso de equipos y portátiles, solo se reconoce en-US, mientras que Xbox y teléfonos pueden reconocer todos los idiomas compatibles con el reconocimiento de voz.For PCs and laptops, only en-US is recognized, while Xbox and phones can recognize all languages supported by speech recognition. Para obtener más información, vea especificar el idioma del reconocedor de voz.For more info, see Specify the speech recognizer language.

ConfiguraciónSet up

La aplicación necesita unos pocos objetos para administrar una sesión de dictado continuo:Your app needs a few objects to manage a continuous dictation session:

  • Una instancia de un objeto SpeechRecognizer.An instance of a SpeechRecognizer object.
  • Una referencia a un distribuidor de interfaz de usuario, para actualizar la interfaz de usuario durante el dictado.A reference to a UI dispatcher to update the UI during dictation.
  • Una manera de realizar el seguimiento de las palabras acumuladas que haya dicho el usuario.A way to track the accumulated words spoken by the user.

En este apartado, debemos declarar una instancia SpeechRecognizer a modo de campo privado de la clase de código subyacente.Here, we declare a SpeechRecognizer instance as a private field of the code-behind class. Si deseas que el dictado continuo dure más allá de una sola página de lenguaje XAML, la aplicación necesitará almacenar una referencia en otra parte.Your app needs to store a reference elsewhere if you want continuous dictation to persist beyond a single Extensible Application Markup Language (XAML) page.

private SpeechRecognizer speechRecognizer;

Durante el dictado, el reconocedor genera eventos desde un subproceso en segundo plano.During dictation, the recognizer raises events from a background thread. Dado que un subproceso en segundo plano no puede actualizar directamente la interfaz de usuario en XAML, la aplicación debe usar un distribuidor para actualizar la interfaz de usuario en respuesta a eventos de reconocimiento.Because a background thread cannot directly update the UI in XAML, your app must use a dispatcher to update the UI in response to recognition events.

Aquí declaramos un campo privado que se inicializará más tarde con el distribuidor de la interfaz de usuario.Here, we declare a private field that will be initialized later with the UI dispatcher.

// 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 realizar un seguimiento de lo que dice el usuario, necesitas controlar eventos de reconocimiento generados por el reconocedor de voz.To track what the user is saying, you need to handle recognition events raised by the speech recognizer. Estos eventos proporcionan los resultados del reconocimiento de fragmentos de voz del usuario.These events provide the recognition results for chunks of user utterances.

En este apartado, usaremos un objeto StringBuilder para guardar todos los resultados del reconocimiento obtenidos durante la sesión.Here, we use a StringBuilder object to hold all the recognition results obtained during the session. Los resultados nuevos se anexan a StringBuilder cuando se procesan.New results are appended to the StringBuilder as they are processed.

private StringBuilder dictatedTextBuilder;

InicializaciónInitialization

Durante la inicialización del reconocimiento de voz continuo, debes:During the initialization of continuous speech recognition, you must:

  • Obtener el distribuidor del subproceso de interfaz de usuario si actualizas la interfaz de usuario de la aplicación en los controladores de eventos de reconocimiento continuo.Fetch the dispatcher for the UI thread if you update the UI of your app in the continuous recognition event handlers.
  • Inicializar el reconocedor de voz.Initialize the speech recognizer.
  • Compilar la gramática de dictado integrada.Compile the built-in dictation grammar. Nota:    El reconocimiento de voz requiere al menos una restricción para definir un vocabulario reconocible.Note   Speech recognition requires at least one constraint to define a recognizable vocabulary. Si no se especifica ninguna restricción, se usa una gramática de dictado predefinida.If no constraint is specified, a predefined dictation grammar is used. Consulta la información sobre Reconocimiento de vozSee Speech recognition.
  • Configura las escuchas de eventos para eventos de reconocimiento.Set up the event listeners for recognition events.

En este ejemplo, inicializamos el reconocimiento de voz en el evento de página OnNavigatedTo.In this example, we initialize speech recognition in the OnNavigatedTo page event.

  1. Como los eventos generados por el reconocedor de voz se producen en un subproceso en segundo plano, se crea una referencia al distribuidor para efectuar actualizaciones en el subproceso de interfaz de usuario.Because events raised by the speech recognizer occur on a background thread, create a reference to the dispatcher for updates to the UI thread. OnNavigatedTo siempre se invoca en el subproceso de interfaz de usuario.OnNavigatedTo is always invoked on the UI thread.
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
  1. A continuación, inicializamos la instancia SpeechRecognizer.We then initialize the SpeechRecognizer instance.
this.speechRecognizer = new SpeechRecognizer();
  1. A continuación, agregamos y compilamos la gramática que define todas las palabras y frases que el SpeechRecognizerpuede reconocer.We then add and compile the grammar that defines all of the words and phrases that can be recognized by the SpeechRecognizer.

    Si no se especifica explícitamente una gramática, se usará una gramática de dictado predefinida de forma predeterminada.If you don't specify a grammar explicitly, a predefined dictation grammar is used by default. Por lo general, la gramática predeterminada es la mejor para el dictado general.Typically, the default grammar is best for general dictation.

    A continuación, llamamos inmediatamente a CompileConstraintsAsync sin agregar una gramática.Here, we call CompileConstraintsAsync immediately without adding a grammar.

SpeechRecognitionCompilationResult result =
      await speechRecognizer.CompileConstraintsAsync();

Controlar eventos de reconocimientoHandle recognition events

Puede capturar una sola utterance o frase breve llamando a RecognizeAsync o RecognizeWithUIAsync.You can capture a single, brief utterance or phrase by calling RecognizeAsync or RecognizeWithUIAsync.

No obstante, para capturar una sesión de reconocimiento continua y más prolongada, especificaremos escuchas de eventos para que se ejecuten en segundo plano mientras el usuario habla y definiremos los controladores para crear la cadena de dictado.However, to capture a longer, continuous recognition session, we specify event listeners to run in the background as the user speaks and define handlers to build the dictation string.

A continuación, usamos la propiedad ContinuousRecognitionSession de nuestro reconocedor para obtener un objeto SpeechContinuousRecognitionSession que proporcione métodos y eventos para administrar una sesión de reconocimiento continua.We then use the ContinuousRecognitionSession property of our recognizer to obtain a SpeechContinuousRecognitionSession object that provides methods and events for managing a continuous recognition session.

En particular, hay dos eventos que son fundamentales:Two events in particular are critical:

  • ResultGenerated, que se crea cuando el reconocedor genera algunos resultados.ResultGenerated, which occurs when the recognizer has generated some results.
  • Completed, que se crea cuando finaliza la sesión de reconocimiento continua.Completed, which occurs when the continuous recognition session has ended.

El evento ResultGenerated se genera a medida que el usuario habla.The ResultGenerated event is raised as the user speaks. El reconocedor escucha continuamente al usuario y genera periódicamente un evento que pasa un fragmento de entrada de voz.The recognizer continuously listens to the user and periodically raises an event that passes a chunk of speech input. Debes examinar la entrada de voz mediante la propiedad Result del argumento del evento y realizar las acciones correspondientes en el controlador de eventos como, por ejemplo, agregar el texto a un objeto StringBuilder.You must examine the speech input, using the Result property of the event argument, and take appropriate action in the event handler, such as appending the text to a StringBuilder object.

Como una instancia de SpeechRecognitionResult, la propiedad result es útil para determinar si desea aceptar la entrada de voz.As an instance of SpeechRecognitionResult, the Result property is useful for determining whether you want to accept the speech input. Una clase SpeechRecognitionResult proporciona dos propiedades para esto:A SpeechRecognitionResult provides two properties for this:

  • Status indica si el reconocimiento se realizó correctamente.Status indicates whether the recognition was successful. Recuerda que el reconocimiento puede crear un error por diversos motivos.Recognition can fail for a variety of reasons.
  • Confidence indica la confianza relativa en que el reconocedor comprendió las palabras correctas.Confidence indicates the relative confidence that the recognizer understood the correct words.

Estos son los pasos básicos para admitir el reconocimiento continuo:Here are the basic steps for supporting continuous recognition:

  1. A continuación, registramos el controlador para el evento de reconocimiento continuo ResultGenerated en el evento de página OnNavigatedTo.Here, we register the handler for the ResultGenerated continuous recognition event in the OnNavigatedTo page event.
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
        ContinuousRecognitionSession_ResultGenerated;
  1. Igualmente, comprobamos la propiedad Confidence.We then check the Confidence property. Si el valor de la propiedad Confidence es medio o mejor, anexamos el texto a StringBuilder.If the value of Confidence is Medium or better, we append the text to the StringBuilder. También actualizaremos la interfaz de usuario a medida que recopilemos entradas.We also update the UI as we collect input.

    Nota:    el evento ResultGenerated se genera en un subproceso en segundo plano que no puede actualizar la interfaz de usuario directamente.Note  the ResultGenerated event is raised on a background thread that cannot update the UI directly. Si un controlador necesita actualizar la interfaz de usuario (como [ hace el ejemplo de voz y TTS ] ), debe enviar las actualizaciones al subproceso de la interfaz de usuario mediante el método RunAsync del distribuidor.If a handler needs to update the UI (as the [Speech and TTS sample] does), you must dispatch the updates to the UI thread through the RunAsync method of the 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. A continuación, controlamos el evento Completed, que indica el final del dictado continuo.We then handle the Completed event, which indicates the end of continuous dictation.

    La sesión finaliza cuando se llama a los métodos StopAsync o CancelAsync, los cuales se describen en la sección siguiente.The session ends when you call the StopAsync or CancelAsync methods (described the next section). La sesión también puede finalizar cuando se produce un error o cuando el usuario deja de hablar.The session can also end when an error occurs, or when the user has stopped speaking. Comprueba la propiedad Status del argumento de evento para determinar por qué finalizó la sesión (SpeechRecognitionResultStatus).Check the Status property of the event argument to determine why the session ended (SpeechRecognitionResultStatus).

    A continuación, registramos el controlador para el evento de reconocimiento continuo Completed en el evento de página OnNavigatedTo.Here, we register the handler for the Completed continuous recognition event in the OnNavigatedTo page event.

speechRecognizer.ContinuousRecognitionSession.Completed +=
      ContinuousRecognitionSession_Completed;
  1. El controlador de eventos comprueba la propiedad Status para determinar si el reconocimiento se realizó correctamente.The event handler checks the Status property to determine whether the recognition was successful. También controla el caso en el que el usuario ha dejado de hablar.It also handles the case where the user has stopped speaking. A menudo, el elemento TimeoutExceeded se considera como un reconocimiento correcto, ya que significa que el usuario ha terminado de hablar.Often, a TimeoutExceeded is considered successful recognition as it means the user has finished speaking. Debes controlar este caso en el código para obtener una buena experiencia.You should handle this case in your code for a good experience.

    Nota:    el evento ResultGenerated se genera en un subproceso en segundo plano que no puede actualizar la interfaz de usuario directamente.Note  the ResultGenerated event is raised on a background thread that cannot update the UI directly. Si un controlador necesita actualizar la interfaz de usuario (como [ hace el ejemplo de voz y TTS ] ), debe enviar las actualizaciones al subproceso de la interfaz de usuario mediante el método RunAsync del distribuidor.If a handler needs to update the UI (as the [Speech and TTS sample] does), you must dispatch the updates to the UI thread through the RunAsync method of the 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";
            });
          }
        }
      }

Proporcionar comentarios sobre reconocimiento continuosProvide ongoing recognition feedback

Cuando la gente habla, a menudo se basan en el contexto para comprender lo que se dice.When people converse, they often rely on context to fully understand what is being said. Del mismo modo, el reconocedor de voz a menudo necesita contexto para proporcionar resultados de reconocimiento de alta confianza.Similarly, the speech recognizer often needs context to provide high-confidence recognition results. Por ejemplo, por sí mismas, las palabras "rebelar" y "revelar" no se distinguen si no se obtiene más contexto de las palabras de alrededor.For example, by themselves, the words "weight" and "wait" are indistinguishable until more context can be gleaned from surrounding words. Hasta que el reconocedor tenga la certeza de que una palabra o palabras se han reconocido correctamente, no generará el evento ResultGenerated.Until the recognizer has some confidence that a word, or words, have been recognized correctly, it will not raise the ResultGenerated event.

Esto puede provocar una experiencia que no resulte ideal para el usuario mientras continúa hablando, y no se proporcionarán resultados hasta que el reconocedor tenga la suficiente confianza para generar el evento ResultGenerated.This can result in a less than ideal experience for the user as they continue speaking and no results are provided until the recognizer has high enough confidence to raise the ResultGenerated event.

Controla el evento HypothesisGenerated para mejorar esta aparente falta de capacidad de respuesta.Handle the HypothesisGenerated event to improve this apparent lack of responsiveness. Este evento se crea siempre que el reconocedor genera un nuevo conjunto de posibles coincidencias de la palabra que se está procesando.This event is raised whenever the recognizer generates a new set of potential matches for the word being processed. El argumento del evento proporciona una propiedad Hypothesis que contiene las coincidencias actuales.The event argument provides an Hypothesis property that contains the current matches. Este muestra estas al usuario mientras continúa hablando y le asegura que el procesamiento todavía está activo.Show these to the user as they continue speaking and reassure them that processing is still active. En cuanto la confianza sea alta y se haya determinado un resultado de reconocimiento, reemplaza los resultados de la propiedad Hypothesis provisionales por la propiedad Result final proporcionada en el evento ResultGenerated.Once confidence is high and a recognition result has been determined, replace the interim Hypothesis results with the final Result provided in the ResultGenerated event.

En este apartado, agregamos el texto hipotético y puntos suspensivos ("...") al valor actual de la clase TextBox de salida.Here, we append the hypothetical text and an ellipsis ("…") to the current value of the output TextBox. El contenido del cuadro de texto se actualiza a medida que se generan nuevas hipótesis y hasta que se obtienen los resultados finales del evento ResultGenerated.The contents of the text box are updated as new hypotheses are generated and until the final results are obtained from the ResultGenerated event.

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 y detener el reconocimientoStart and stop recognition

Antes de iniciar una sesión de reconocimiento, comprueba el valor de la propiedad State del reconocedor de voz.Before starting a recognition session, check the value of the speech recognizer State property. El reconocedor de voz debe estar en estado Idle.The speech recognizer must be in an Idle state.

Después de comprobar el estado del reconocedor de voz, empezamos la sesión mediante una llamada al método StartAsync de la propiedad ContinuousRecognitionSession del reconocedor de voz.After checking the state of the speech recognizer, we start the session by calling the StartAsync method of the speech recognizer's ContinuousRecognitionSession property.

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

El reconocimiento puede detenerse de dos maneras:Recognition can be stopped in two ways:

  • StopAsync permite completar los eventos de reconocimiento pendientes (ten en cuenta que ResultGenerated continúa generándose hasta que se completan todas las operaciones de reconocimiento pendientes).StopAsync lets any pending recognition events complete (ResultGenerated continues to be raised until all pending recognition operations are complete).
  • CancelAsync finaliza la sesión de reconocimiento inmediatamente y descarta los resultados pendientes.CancelAsync terminates the recognition session immediately and discards any pending results.

Después de comprobar el estado del reconocedor de voz, finalizamos la sesión mediante una llamada al método CancelAsync de la propiedad ContinuousRecognitionSession del reconocedor de voz.After checking the state of the speech recognizer, we stop the session by calling the CancelAsync method of the speech recognizer's ContinuousRecognitionSession property.

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

Nota

Un evento ResultGenerated puede producirse después de una llamada a CancelAsync.A ResultGenerated event can occur after a call to CancelAsync.
Debido al multithreading, es posible que un evento ResultGenerated permanezca en la pila cuando se llame a CancelAsync.Because of multithreading, a ResultGenerated event might still remain on the stack when CancelAsync is called. Si es así, todavía se desencadenará el evento ResultGenerated.If so, the ResultGenerated event still fires.
Si estableces campos privados al cancelar la sesión de reconocimiento, confirma siempre sus valores en el controlador ResultGenerated.If you set any private fields when canceling the recognition session, always confirm their values in the ResultGenerated handler. Por ejemplo, no des por hecho que un campo se inicializa en el controlador si estableces su valor como nulo cuando canceles la sesión.For example, don't assume a field is initialized in your handler if you set them to null when you cancel the session.

 

MuestrasSamples