TOC

This article has been localized into Portuguese by the community.

Áudio e Vídeo:

Reconhecimento de fala (fazendo o WPF ouvir)

No artigo anterior, discutimos como poderíamos transformar o texto em palavras faladas, usando a classe SpeechSynthesizer. Neste artigo, vamos ao contrário, transformando palavras faladas em texto. Para fazer isso, usaremos a classe SpeechRecognition , que reside no assembly System.Speech. Este conjunto não faz parte de suas soluções por padrão, mas podemos adicioná-lo facilmente. Dependendo de qual versão do Visual Studio você usa, o processo é algo como isto:

Com isso resolvido, vamos começar com um exemplo de reconhecimento de fala extremamente simples:

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

Isso é realmente tudo o que você precisa - o texto na captura de tela acima foi ditado pelo meu fone de ouvido e inserido no controle TextBox como texto, por meio do uso do reconhecimento de fala.

Assim que você inicializa um objeto SpeechRecognizer , o Windows inicia seu aplicativo de reconhecimento de fala, que fará todo o trabalho pesado e enviará o resultado para o aplicativo ativo, neste caso o nosso. Se parece com isso:

Se você ainda não usou o reconhecimento de fala no computador, o Windows o guiará por um guia que o ajudará a iniciar e fará alguns ajustes necessários.

Este primeiro exemplo permitirá que você dite o texto para o seu aplicativo, o que é ótimo, mas e os comandos? O Windows e o WPF funcionarão juntos aqui e transformarão seus botões em comandos, acessíveis através da fala, sem nenhum trabalho extra. Aqui está um exemplo:

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

Você pode tentar executar o exemplo e, em seguida, falar de um dos comandos, por exemplo "Novo" ou "Aberto". Isso realmente permite que você dite o texto para o TextBox, enquanto ao mesmo tempo invoca comandos da interface do usuário - muito legal mesmo!

Comandos específicos

No exemplo acima, o Windows entrará automaticamente no modo de ditado assim que o foco for dado a uma caixa de texto. O Windows tentará distinguir entre ditado e comandos, mas isso pode ser difícil em certas situações.

Portanto, embora os exemplos acima tenham se concentrado no ditado e na interação com elementos da interface do usuário, este próximo exemplo enfocará a capacidade de ouvir e interpretar apenas comandos específicos. Isso também significa que o ditado será ignorado completamente, mesmo que os campos de entrada de texto tenham foco.

Para este propósito, usaremos a classe SpeechRecognitionEngine em vez da classe SpeechRecognizer . Uma diferença enorme entre os dois é que a classe SpeechRecognitionEngine não requer o reconhecimento de voz do Windows para ser executado e não o levará através do guia de reconhecimento de voz. Em vez disso, usará o reconhecimento de voz básico e ouvirá apenas a gramática que você insere na classe.

No próximo exemplo, vamos alimentar um conjunto de comandos no mecanismo de reconhecimento. A idéia é que ele deve ouvir duas palavras: um comando / propriedade e um valor, que nesse caso será usado para alterar a cor, tamanho e peso do texto em um controle Label, exclusivamente com base em seus comandos de voz. Antes de mostrar o exemplo de código inteiro, quero focar na maneira como adicionamos os comandos ao mecanismo. Aqui está o 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));

Nós usamos um GrammarBuilder para construir um conjunto de regras gramaticais que podemos carregar no SpeechRecognitionEngine. Ele possui vários métodos de acréscimo, com o mais simples deles sendo Append (). Este método leva uma lista de opções. Criamos uma instância Choices , com a primeira parte da instrução - o comando / propriedade que queremos acessar. Essas opções são incluídas no construtor com o método Append ().

Agora, toda vez que você chama um método de acréscimo no GrammarBuilder, você o instrui a ouvir uma palavra. Em nosso caso, queremos que ele ouça duas palavras, portanto, criamos um conjunto secundário de escolhas, que manterá o valor para o comando / propriedade designado. Adicionamos um intervalo de valores para cada um dos comandos possíveis - um conjunto de valores para o comando peso, um conjunto de valores para o comando color e um conjunto de valores para o comando size. Eles são todos adicionados à mesma instância Choices e, em seguida, anexados ao construtor.

No final, nós o carregamos na instância do SpeechRecognitionEngine chamando o método LoadGrammer () , que usa uma instância de Gramática como parâmetro - nesse caso, baseado em nossa instância do GrammarBuilder.

Então, com isso explicado, vamos dar uma olhada no exemplo inteiro:

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

Na imagem, você vê o aplicativo resultante, depois que eu usei os comandos de voz "peso em negrito" e "cor azul" - muito legal, certo?

Os aspectos gramaticais do exemplo já foram explicados e a interface é muito simples, então vamos nos concentrar no resto do Code-behind.

Usamos um ToggleButton para ativar ou desativar a escuta, usando os métodos RecognizeAsync () e RecognizeAsyncStop (). O RecognizeAsync () recebe um parâmetro que informa ao mecanismo de reconhecimento se deve fazer um único reconhecimento ou vários reconhecimentos. Para nosso exemplo, queremos dar vários comandos, então Multiple é usado. Então, para habilitar a escuta, basta clicar no botão e, para desativá-lo, basta clicar novamente. O estado é representado visualmente pelo botão, que ficará "inativo" quando ativado e normal quando desativado.

Agora, além de construir a gramática, a parte mais interessante é onde interpretamos o comando. Isso é feito no evento SpeechRecognized , ao qual nos conectamos no construtor. Usamos o texto totalmente reconhecido para atualizar o rótulo de demonstração, para mostrar o comando mais recente e, em seguida, usamos a propriedade Words para aprofundar o comando real.

Primeiramente, nós verificamos se há exatamente duas palavras - um comando / propriedade e um valor. Se for esse o caso, nós verificamos a parte do comando primeiro, e para cada comando possível, lidamos com o valor de acordo.

Para os comandos de peso e cor, podemos converter o valor em algo que o rótulo pode entender automaticamente, usando um conversor, mas para os tamanhos, interpretamos os valores fornecidos manualmente, pois os valores que eu escolhi para este exemplo não podem ser convertido automaticamente. Lembre-se de que você deve manipular exceções em todos os casos, pois um comando como "weight blue" tentará atribuir o valor azul ao FontWeight, o que naturalmente resultará em uma exceção.

Resumo

Como você pode ver, o reconhecimento de fala com o WPF é fácil e muito poderoso - especialmente o último exemplo deve lhe dar uma boa idéia do quão poderoso ele é! Com a capacidade de usar ditado e / ou comandos de voz específicos, você pode realmente fornecer excelentes meios para entrada alternativa em seus aplicativos.


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!