TOC

This article is currently in the process of being translated into Spanish (~99% done).

Audio y Vídeo:

Speech recognition (making WPF listen)

En el artículo anterior discutimos cómo podríamos transformar el texto en palabras habladas, usando la clase SpeechSynthesizer. En este artículo iremos al otro al revés, convirtiendo las palabras habladas en texto. Para hacerlo, utilizaremos la clase SpeechRecognition , que reside en el ensamblado System. Speech. Este conjunto no forma parte de sus soluciones de forma predeterminada, pero podemos agregarlo fácilmente. Dependiendo de la versión de Visual Studio que uste use, el proceso se parece a esto:

Teniendo esto en cuenta, comencemos con un ejemplo de reconocimiento de voz extremadamente simple:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.SpeechRecognitionTextSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SpeechRecognitionTextSample" Height="200" Width="300">
    <DockPanel Margin="10">
        <TextBox Margin="0,10" Name="txtSpeech" AcceptsReturn="True" />
    </DockPanel>
</Window>
using System;
using System.Speech.Recognition;
using System.Windows;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class SpeechRecognitionTextSample : Window
	{
		public SpeechRecognitionTextSample()
		{
			InitializeComponent();
			SpeechRecognizer speechRecognizer = new SpeechRecognizer();
		}
	}
}

Esto es en realidad todo lo que necesita: el texto de la captura de pantalla anterior se dicta a través de mis auriculares y luego se inserta en el control TextBox como texto, mediante el uso del reconocimiento de voz.

Tan pronto como inicialice un objeto SpeechRecognizer , Windows inicia su aplicación de reconocimiento de voz, que hará todo el trabajo duro, después envíe el resultado a la aplicación activa, en este caso la nuestra. Se parece a esto:

Si no ha utilizado el reconocimiento de voz en su computadora antes, Windows lo guiará a través de una guía que lo ayudará a comenzar y crear algunos ajustes necesarios.

Este primer ejemplo le permitirá dictar texto a su aplicación, lo cual es genial, pero ¿qué pasa con los comandos? Windows y WPF realmente trabajarán juntos aquí y convierten sus botones en comandos, accesibles a través del habla, sin ningún trabajo adicional. Aquí hay un ejemplo:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.SpeechRecognitionTextCommandsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SpeechRecognitionTextCommandsSample" Height="200" Width="300">
    <DockPanel Margin="10">
        <WrapPanel DockPanel.Dock="Top">
            <Button Name="btnNew" Click="btnNew_Click">New</Button>
            <Button Name="btnOpen" Click="btnOpen_Click">Open</Button>
            <Button Name="btnSave" Click="btnSave_Click">Save</Button>
        </WrapPanel>
        <TextBox Margin="0,10" Name="txtSpeech" AcceptsReturn="True" TextWrapping="Wrap" />
    </DockPanel>
</Window>
using System;
using System.Speech.Recognition;
using System.Windows;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class SpeechRecognitionTextCommandsSample : Window
	{
		public SpeechRecognitionTextCommandsSample()
		{
			InitializeComponent();
			SpeechRecognizer recognizer = new SpeechRecognizer();
		}

		private void btnNew_Click(object sender, RoutedEventArgs e)
		{
			txtSpeech.Text = "";
		}

		private void btnOpen_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show("Command invoked: Open");
		}

		private void btnSave_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show("Command invoked: Save");
		}
	}
}

Puede intentar ejecutar el ejemplo y luego pronunciar uno de los comandos, por ejemplo "Nuevo" o "Abierto". En realidad, esto le permite dictar texto en TextBox, mientras que al mismo tiempo invoca comandos desde la interfaz de usuario, ¡realmente genial!

Comandos específicos

En el ejemplo anterior, Windows entrará automáticamente en modo de dictado tan pronto como se le de atención a un cuadro de texto. Windows intentará distinguir entre dictado y comandos, pero esto, por supuesto, puede ser difícil en ciertas situaciones.

Entonces, si bien los ejemplos anteriores se han centrado en el dictado y la interacción con los elementos de la interfaz de usuario, este próximo ejemplo se centrará en la capacidad de escuchar e interpretar comandos específicos solamente. Esto también significa que el dictado se ignorará por completo, aunque los campos de entrada de texto tengan foco.

Para este propósito, usaremos la clase SpeechRecognitionEngine en lugar de la clase SpeechRecognizer . Una gran diferencia entre los dos es que la clase SpeechRecognitionEngine no requiere el reconocimiento de voz de Windows para ejecutarse y no te llevará a través de la guía de reconocimiento de voz. En su lugar, utilizará el reconocimiento de voz básico y escucharás solo la gramática que alimente a la clase.

En el siguiente ejemplo, alimentaremos un conjunto de comandos en el motor de reconocimiento. La idea es que debe escuchar dos palabras: un comando / propiedad y un valor, que en este caso se usará para cambiar el color, el tamaño y el peso del texto en un control Label, únicamente en función de sus comandos de voz. Antes the mostrarle el ejemplo de código completo, quiero centrarme en la forma en que agregamos los comandos al motor. Aquí está el código:

GrammarBuilder grammarBuilder = new GrammarBuilder();
Choices commandChoices = new Choices("weight", "color", "size");
grammarBuilder.Append(commandChoices);

Choices valueChoices = new Choices();
valueChoices.Add("normal", "bold");
valueChoices.Add("red", "green", "blue");
valueChoices.Add("small", "medium", "large");
grammarBuilder.Append(valueChoices);

speechRecognizer.LoadGrammar(new Grammar(grammarBuilder));

Utilizamos un GrammarBuilder para construir un conjunto de reglas gramaticales que podemos cargar en SpeechRecognitionEngine. Tiene varios métodos de agregar, siendo el más simple Append (). Este método toma una lista de opciones. Creamos una instancia de Opciones , con la primera parte de la instrucción del comando / propiedad al que queremos acceder. Estas opciones se agregan al generador con el método Append ().

Ahora, cada vez que llama a un método append en GrammarBuilder, le indica que escuche una palabra. En nuestro caso, queremos que escuche dos palabras, así que creamos un conjunto secundario de opciones, que mantendrá el valor del comando / propiedad designado. Agregamos un rango de valores para cada uno de los posibles comandos: un conjunto de valores para el comando de peso, un conjunto de valores para el comando de color y un conjunto de valores para el comando de tamaño. Todos están agregados a la misma instancia de Opciones y luego se agrega al generador.

Al final, lo cargamos en la instancia SpeechRecognitionEngine llamando al método LoadGrammer () , que toma una instancia de Grammar como parámetro: en este caso basado en nuestra instancia de GrammarBuilder.

Entonces, con eso explicado, echemos un vistazo a todo el ejemplo:

<Window x:Class="WpfTutorialSamples.Audio_and_Video.SpeechRecognitionCommandsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SpeechRecognitionCommandsSample" Height="200" Width="325"
        Closing="Window_Closing">
    <DockPanel>
        <WrapPanel DockPanel.Dock="Bottom" HorizontalAlignment="Center" Margin="0,10">
            <ToggleButton Name="btnToggleListening" Click="btnToggleListening_Click">Listen</ToggleButton>
        </WrapPanel>
        <Label Name="lblDemo" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48">Hello, world!</Label>
    </DockPanel>
</Window>
using System;
using System.Globalization;
using System.Speech.Recognition;
using System.Windows;
using System.Windows.Media;

namespace WpfTutorialSamples.Audio_and_Video
{
	public partial class SpeechRecognitionCommandsSample : Window
	{
		private SpeechRecognitionEngine speechRecognizer = new SpeechRecognitionEngine();

		public SpeechRecognitionCommandsSample()
		{
			InitializeComponent();
			speechRecognizer.SpeechRecognized += speechRecognizer_SpeechRecognized;

			GrammarBuilder grammarBuilder = new GrammarBuilder();
			Choices commandChoices = new Choices("weight", "color", "size");
			grammarBuilder.Append(commandChoices);

			Choices valueChoices = new Choices();
			valueChoices.Add("normal", "bold");
			valueChoices.Add("red", "green", "blue");
			valueChoices.Add("small", "medium", "large");
			grammarBuilder.Append(valueChoices);

			speechRecognizer.LoadGrammar(new Grammar(grammarBuilder));
			speechRecognizer.SetInputToDefaultAudioDevice();
		}

		private void btnToggleListening_Click(object sender, RoutedEventArgs e)
		{
			if(btnToggleListening.IsChecked == true)
				speechRecognizer.RecognizeAsync(RecognizeMode.Multiple);
			else
				speechRecognizer.RecognizeAsyncStop();
		}

		private void speechRecognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
		{
			lblDemo.Content = e.Result.Text;
			if(e.Result.Words.Count == 2)
			{
				string command = e.Result.Words[0].Text.ToLower();
				string value = e.Result.Words[1].Text.ToLower();
				switch(command)
				{
					case "weight":
						FontWeightConverter weightConverter = new FontWeightConverter();
						lblDemo.FontWeight = (FontWeight)weightConverter.ConvertFromString(value);
						break;
					case "color":
						lblDemo.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(value));
						break;
					case "size":
						switch(value)
						{
							case "small":
								lblDemo.FontSize = 12;
								break;
							case "medium":
								lblDemo.FontSize = 24;
								break;
							case "large":
								lblDemo.FontSize = 48;
								break;
						}
						break;
				}
			}
		}

		private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			speechRecognizer.Dispose();
		}
	}
}

En la captura de pantalla, ves la aplicación resultante, después de haber usado los comandos de voz "grueso en negrita" y "color azul", bastante bien, ¿verdad?

Los aspectos gramaticales del ejemplo ya se han explicado y la interfaz es muy simple, así que centrémonos en el resto del código subyacente.

Utilizamos un ToggleButton para habilitar o deshabilitar la escucha, utilizando los métodos RecognizeAsync () y RecognizeAsyncStop (). El RecognizeAsync () toma un parámetro que informa al motor de reconocimiento si debe hacer un solo reconocimiento o múltiples reconocimientos. Para nuestro ejemplo, queremos dar varios comandos, por lo que se usa Multiple. Entonces, para habilitar la escucha, simplemente haga clic en el botón, y para deshabilitarlo, simplemente haga clic nuevamente. El estado es visualmente representado por el botón, que estará "abajo" cuando esté habilitado y normal cuando esté deshabilitado.

Ahora, además de construir la Gramática, la parte más interesante es donde interpretamos el comando. Esto se hace en el evemto SpeechRecognized , que conectamos en el constructor. Usamos el texto completamente reconocido para actualizar la etiqueta de demostración, para mostrar el último comando, y luego usamos la propiedad Words (Palabras) para profundizar en el comando real.

En primer lugar, verificamos que tenga exactamente dos palabras: un comando / propiedad y un valor. Si ese es el caso, primero verificamos la parte del comando y para cada posible comando, manejamos el valor en consecuencia.

Para los comandos de grueso y color, podemos convertir el valor en algo que la etiqueta pueda entender automáticamente, usando un convertidor, pero para los tamaños, interpreta los valores dados manualmente, ya que los valores que he elegido para este ejemplo no se pueden convertir automáticamente. Tenga en cuenta que debe manejar excepciones en todos los casos, ya que un comando como "weight blue" intentará asignar el valor azul a FontWeight, lo que naturalmente dará como resultado un excepción.

Resumen

Como puede ver, el reconocimiento de voz con WPF es fácil y muy poderoso, especialmente el último ejemplo debería darle una buena idea de lo ¡poderoso! que es. Con la capacidad de usar dictados y / o comandos de voz específicos, realmente puede proporcionar excelentes medios para una entrada alternativa en sus aplicaciones.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!