Compartir a través de


Dictado continuo

Obtenga información sobre cómo capturar y reconocer la entrada de voz de dictado continuo de forma larga.

API importantes: SpeechContinuousRecognitionSession, ContinuousRecognitionSession

En el reconocimiento de voz, ha aprendido a capturar y reconocer la entrada de voz relativamente corta mediante los métodos RecognizeAsync o RecognizeWithUIAsync de un objeto SpeechRecognizer, por ejemplo, al redactar un mensaje de servicio de mensajes corto (SMS) o al formular una pregunta.

Para sesiones de reconocimiento de voz continuas más largas, como dictado o correo electrónico, use la propiedad ContinuousRecognitionSession de speechRecognizer para obtener un objeto SpeechContinuousRecognitionSession.

Nota:

La compatibilidad del lenguaje de dictado depende del dispositivo en el que se ejecuta la aplicación. Para 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. Para obtener más información, consulte Especificar el idioma del reconocedor de voz.

Configurar

La aplicación necesita algunos objetos para administrar una sesión de dictado continua:

  • Instancia de un objeto SpeechRecognizer.
  • Referencia a un distribuidor de interfaz de usuario para actualizar la interfaz de usuario durante el dictado.
  • Una manera de realizar un seguimiento de las palabras acumuladas habladas por el usuario.

En este caso, declaramos una instancia de SpeechRecognizer como un campo privado de la clase de código subyacente. La aplicación debe almacenar una referencia en otro lugar si quieres que el dictado continuo persista más allá de una sola página de Lenguaje de marcado de aplicación extensible (XAML).

private SpeechRecognizer speechRecognizer;

Durante el dictado, el reconocedor genera eventos a partir de un subproceso en segundo plano. 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 los eventos de reconocimiento.

Aquí, declaramos un campo privado que se inicializará más adelante con el distribuidor de la interfaz de usuario.

// 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, debe controlar los eventos de reconocimiento generados por el reconocedor de voz. Estos eventos proporcionan los resultados del reconocimiento para fragmentos de expresiones de usuario.

Aquí, usamos un objeto StringBuilder para contener todos los resultados de reconocimiento obtenidos durante la sesión. Los nuevos resultados se anexan a StringBuilder a medida que se procesan.

private StringBuilder dictatedTextBuilder;

Inicialización

Durante la inicialización del reconocimiento de voz continuo, debe:

  • Capture el distribuidor para el subproceso de interfaz de usuario si actualiza la interfaz de usuario de la aplicación en los controladores de eventos de reconocimiento continuo.
  • Inicialice el reconocedor de voz.
  • Compile la gramática de dictado integrada. Nota El reconocimiento de voz requiere al menos una restricción para definir un vocabulario reconocible. Si no se especifica ninguna restricción, se usa una gramática de dictado predefinida. Consulte Reconocimiento de voz.
  • Configure los agentes de escucha de eventos para eventos de reconocimiento.

En este ejemplo, inicializamos el reconocimiento de voz en el evento de página OnNavigatedTo.

  1. Dado que los eventos generados por el reconocedor de voz se producen en un subproceso en segundo plano, cree una referencia al distribuidor para las actualizaciones del subproceso de la interfaz de usuario. OnNavigatedTo siempre se invoca en el subproceso de la interfaz de usuario.
this.dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
  1. A continuación, inicializamos la instancia de SpeechRecognizer.
this.speechRecognizer = new SpeechRecognizer();
  1. A continuación, agregamos y compilamos la gramática que define todas las palabras y frases que el SpeechRecognizer puede reconocer.

    Si no especifica explícitamente una gramática, se usa de forma predeterminada una gramática de dictado predefinida. Normalmente, la gramática predeterminada es la mejor para el dictado general.

    Aquí, llamamos a CompileConstraintsAsync inmediatamente sin agregar una gramática.

SpeechRecognitionCompilationResult result =
      await speechRecognizer.CompileConstraintsAsync();

Controlar eventos de reconocimiento

Puede capturar una sola expresión o frase breve llamando a RecognizeAsync o RecognizeWithUIAsync.

Sin embargo, para capturar una sesión de reconocimiento continua más larga, especificamos agentes de escucha de eventos que se ejecutarán en segundo plano a medida que el usuario habla y define controladores para crear la cadena de dictado.

A continuación, usamos la propiedad ContinuousRecognitionSession de nuestro reconocedor para obtener un objeto SpeechContinuousRecognitionSession que proporciona métodos y eventos para administrar una sesión de reconocimiento continuo.

En particular, dos eventos son críticos:

  • ResultGenerated, que se produce cuando el reconocedor ha generado algunos resultados.
  • Completado, que se produce cuando finaliza la sesión de reconocimiento continuo.

El evento ResultGenerated se genera cuando el usuario habla. El reconocedor escucha continuamente al usuario y genera periódicamente un evento que pasa un fragmento de entrada de voz. Debe examinar la entrada de voz mediante la propiedad Result del argumento de evento y realizar las acciones adecuadas en el controlador de eventos, como anexar el texto a un objeto StringBuilder.

Como instancia de SpeechRecognitionResult, la propiedad Result es útil para determinar si desea aceptar la entrada de voz. SpeechRecognitionResult proporciona dos propiedades para esto:

  • El estado indica si el reconocimiento se realizó correctamente. El reconocimiento puede producir un error por diversos motivos.
  • La confianza indica la confianza relativa de que el reconocedor entendió las palabras correctas.

Estos son los pasos básicos para admitir el reconocimiento continuo:

  1. Aquí, registramos el controlador para el evento de reconocimiento continuo ResultGenerated en el evento de página OnNavigatedTo.
speechRecognizer.ContinuousRecognitionSession.ResultGenerated +=
        ContinuousRecognitionSession_ResultGenerated;
  1. A continuación, comprobamos la propiedad Confidence. Si el valor de Confianza es Medio o superior, anexamos el texto a StringBuilder. También actualizamos la interfaz de usuario a medida que recopilamos la entrada.

    Tenga en cuenta que el evento ResultGenerated se genera en un subproceso en segundo plano que no puede actualizar la interfaz de usuario directamente. Si un controlador necesita actualizar la interfaz de usuario (como lo hace el ejemplo de [Voz y TTS], debe enviar las actualizaciones al subproceso de la interfaz de usuario a través del método RunAsync del distribuidor.

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, se controla el evento Completed , que indica el final del dictado continuo.

    La sesión finaliza cuando se llama a los métodos StopAsync o CancelAsync (descritos en la sección siguiente). La sesión también puede finalizar cuando se produce un error o cuando el usuario ha dejado de hablar. Compruebe la propiedad Status del argumento de evento para determinar por qué finalizó la sesión (SpeechRecognitionResultStatus).

    Aquí, registramos el controlador para el evento De reconocimiento continuo completado en el evento de página OnNavigatedTo.

speechRecognizer.ContinuousRecognitionSession.Completed +=
      ContinuousRecognitionSession_Completed;
  1. El controlador de eventos comprueba la propiedad Status para determinar si el reconocimiento se realizó correctamente. También controla el caso en el que el usuario ha dejado de hablar. A menudo, timeoutExceeded se considera un reconocimiento correcto, ya que significa que el usuario ha terminado de hablar. Debe controlar este caso en el código para obtener una buena experiencia.

    Tenga en cuenta que el evento ResultGenerated se genera en un subproceso en segundo plano que no puede actualizar la interfaz de usuario directamente. Si un controlador necesita actualizar la interfaz de usuario (como lo hace el ejemplo de [Voz y TTS], debe enviar las actualizaciones al subproceso de la interfaz de usuario a través del método RunAsync del distribuidor.

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 de reconocimiento continuos

Cuando las personas conversan, a menudo dependen del contexto para comprender completamente lo que se dice. Del mismo modo, el reconocedor de voz a menudo necesita contexto para proporcionar resultados de reconocimiento de alta confianza. Por ejemplo, por sí mismos, las palabras "weight" y "wait" son indistinguibles hasta que se puede obtener más contexto de las palabras circundantes. Hasta que el reconocedor tenga cierta confianza de que se haya reconocido correctamente una palabra o palabras, no generará el evento ResultGenerated.

Esto puede dar lugar a una experiencia menos que ideal para el usuario a medida que continúa hablando y no se proporcionan resultados hasta que el reconocedor tenga una confianza lo suficientemente alta como para generar el evento ResultGenerated.

Controle el evento HypothesisGenerated para mejorar esta aparente falta de capacidad de respuesta. Este evento se genera cada vez que el reconocedor genera un nuevo conjunto de posibles coincidencias para la palabra que se está procesando. El argumento de evento proporciona una propiedad Hipótesis que contiene las coincidencias actuales. Mostrarlos al usuario a medida que continúa hablando y tranquilizarlos de que el procesamiento sigue activo. Una vez que la confianza es alta y se ha determinado un resultado de reconocimiento, reemplace los resultados provisionales de hipótesis por el resultado final proporcionado en el evento ResultGenerated.

Aquí, anexamos el texto hipotético y los puntos suspensivos ("...") al valor actual del textBox de salida. 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.

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 reconocimiento

Antes de iniciar una sesión de reconocimiento, compruebe el valor de la propiedad Speech Recognizer State . El reconocedor de voz debe estar en estado Inactivo .

Después de comprobar el estado del reconocedor de voz, iniciamos la sesión llamando al método StartAsync de la propiedad ContinuousRecognitionSession del reconocedor de voz.

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

El reconocimiento se puede detener de dos maneras:

  • StopAsync permite que se completen los eventos de reconocimiento pendientes (ResultGenerated sigue generando hasta que se completen todas las operaciones de reconocimiento pendientes).
  • CancelAsync finaliza la sesión de reconocimiento inmediatamente y descarta los resultados pendientes.

Después de comprobar el estado del reconocedor de voz, se detiene la sesión llamando al método CancelAsync de la propiedad ContinuousRecognitionSession del reconocedor de voz.

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

Nota:

Un evento ResultGenerated puede producirse después de una llamada a CancelAsync.
Debido a la multithreading, es posible que un evento ResultGenerated siga estando en la pila cuando se llame a CancelAsync. Si es así, el evento ResultGenerated todavía se activa.
Si establece campos privados al cancelar la sesión de reconocimiento, confirme siempre sus valores en el controlador ResultGenerated. Por ejemplo, no suponga que se inicializa un campo en el controlador si los establece en NULL al cancelar la sesión.

 

Muestras