This article is currently in the process of being translated into Italian (~99% done).
Riconoscimento vocale (far ascoltare WPF)
Nell'articolo precedente abbiamo discusso come possiamo trasformare del testo scritto in testo parlato usando la classe SpeechSynthesizer In quest'articolo faremo la cosa opposta, convertendo del testo parlato in testo scirtto. Per farlo useremo la classe SpeechRecognition, che si trova nell'assembly System.Speech. Questo assembly non fa parte della dotazione standard delle tue soluzioni, ma lo si può aggiungere facilmente. A seconda della versione di Visual Studio che utilizzi, il processo consiste in qualcosa del tipo:
Detto questo, iniziamo con un esempio di riconoscimento vocale estremamente semplice:
<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();
}
}
}
Questo è in realtà tutto ciò di cui hai bisogno: il testo nello screenshot sopra è stato dettato attraverso il microfono e quindi inserito nel controllo TextBox come testo, attraverso l'uso del riconoscimento vocale.
Non appena si inizializza un oggetto SpeechRecognizer, Windows avvia la sua applicazione di riconoscimento vocale, che farà tutto il lavoro e quindi invierà il risultato all'applicazione attiva, in questo caso la nostra.
Se non hai mai usato il riconoscimento vocale sul tuo computer prima, Windows ti guiderà attraverso una guida che ti aiuterà a iniziare e ad apportare alcune modifiche necessarie.
Questo primo esempio ti permetterà di dettare testo alla tua applicazione, il che è fantastico, ma che dire dei comandi? Windows e WPF lavoreranno effettivamente insieme qui e trasformeranno i tuoi pulsanti in comandi, raggiungibili tramite la voce, senza alcun lavoro aggiuntivo. Ecco un esempio:
<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");
}
}
}
Puoi provare a eseguire l'esempio e pronunciare uno dei comandi, ad es. "New" o "Open". Questo in realtà ti consente di dettare testo alla TextBox, mentre allo stesso tempo invochi i comandi dall'interfaccia utente - davvero fantastico!
Comandi specifici
Nell'esempio sopra, Windows passerà automaticamente alla modalità di dettatura non appena viene focalizzato su una casella di testo. Windows proverà quindi a distinguere tra dettato e comandi, ma questo può ovviamente essere difficile in determinate situazioni.
Pertanto, mentre gli esempi precedenti si sono concentrati sulla dettatura e l'interazione con gli elementi dell'interfaccia utente, questo esempio successivo si concentrerà sulla capacità di ascoltare e interpretare solo comandi specifici. Ciò significa anche che la dettatura verrà ignorata completamente, anche se i campi di input di testo sono attivi.
A tal fine, utilizzeremo la classe SpeechRecognitionEngine anziché la classe SpeechRecognizer . Un'enorme differenza tra le due è che la classe SpeechRecognitionEngine non richiede il riconoscimento vocale di Windows per essere in esecuzione e non ti porterà attraverso la guida al riconoscimento vocale. Invece, utilizzerà il riconoscimento vocale di base e ascolterà solo la grammatica che si inserisce nella classe.
Nel prossimo esempio, inseriremo una serie di comandi nel motore di riconoscimento. L'idea è che dovrebbe ascoltare due parole: un comando / proprietà e un valore, che in questo caso verranno utilizzati per modificare il colore, la dimensione e il peso del testo in un controllo Etichetta, basato esclusivamente sui comandi vocali. Prima di mostrarti l'intero esempio di codice, voglio concentrarmi sul modo in cui aggiungiamo i comandi al motore. Ecco il codice:
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));
Usiamo un GrammarBuilder per creare un insieme di regole grammaticali che possiamo caricare in SpeechRecognitionEngine. Esistono diversi metodi di aggiunta, quello più semplice è Append (). Questo metodo prende un elenco di scelte. Creiamo un'istanza Choices , con la prima parte di istruzione - il comando / proprietà a cui vogliamo accedere. Queste scelte vengono aggiunte al builder con il metodo Append ().
Ora, ogni volta che chiami un metodo append su GrammarBuilder, gli ordini di ascoltare una parola. Nel nostro caso, vogliamo che ascolti due parole, quindi creiamo un insieme secondario di scelte, che conterrà il valore per il comando / proprietà designato. Aggiungiamo un intervallo di valori per ciascuno dei possibili comandi: un set di valori per il comando peso, un set di valori per il comando colore e un set di valori per il comando dimensione. Sono tutti aggiunti nella stessa istanza Choices e quindi aggiunti al builder.
Alla fine, lo cariciamo nell'istanza SpeechRecognitionEngine chiamando il metodo LoadGrammer () , che accetta un'istanza Grammatica come parametro, in questo caso basata sulla nostra istanza GrammarBuilder.
Quindi, avendo spiegato questo, andiamo a dare un'occhiata all'intero esempio:
<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();
}
}
}
Nello screenshot, vedi l'applicazione risultante, dopo che ho usato i comandi vocali "weight bold" and "color blue". Bello vero?
Gli aspetti grammaticali dell'esempio sono già stati spiegati e l'interfaccia è molto semplice, quindi concentriamoci sul resto del Code-behind.
Utilizziamo un ToggleButton per abilitare o disabilitare l'ascolto, utilizzando i metodi RecognizeAsync () e RecognizeAsyncStop (). The RecognizeAsync () accetta un parametro che informa il motore di riconoscimento se deve eseguire un singolo riconoscimento o più riconoscimenti. Per il nostro esempio, vogliamo dare diversi comandi, quindi viene utilizzato Multiple. Quindi, per abilitare l'ascolto, basta fare clic sul pulsante e per disabilitarlo, basta fare di nuovo clic su di esso. Lo stato è visivamente rappresentato dal pulsante, che sarà "giù" quando abilitato e normale quando disabilitato.
Ora, oltre a costruire la grammatica, la parte più interessante è dove interpretiamo il comando. Questo viene fatto nell'evento SpeechRecognized , a cui ci colleghiamo nel costruttore. Usiamo il testo pienamente riconosciuto per aggiornare l'etichetta demo, per mostrare l'ultimo comando e quindi usiamo la proprietà Words per trovare i comandi.
Prima di tutto, controlliamo che abbia esattamente due parole: un comando / proprietà e un valore. In tal caso, controlliamo prima la parte del comando e, per ogni possibile comando, gestiamo il valore di conseguenza.
Per i comandi weight e color, possiamo convertire il valore in qualcosa che l'etichetta può capire automaticamente, usando un convertitore, ma per le dimensioni, interpretiamo i valori dati manualmente, poiché i valori che ho scelto per questo esempio non possono essere convertiti automaticamente. Si noti che è necessario gestire le eccezioni in tutti i casi, poiché un comando come "weight blue" proverà ad assegnare il valore blu a FontWeight, il che comporterà naturalmente un'eccezione.
Riassunto
Come sperato, il riconoscimento vocale con WPF è sia semplice che molto potente - specialmente l'ultimo esempio dà una buona idea di quanto sia potente! Con la possibilità di utilizzare la dettatura e / o comandi vocali specifici, puoi davvero fornire mezzi eccellenti per input alternativi nelle tue applicazioni