Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1908, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Esempio di riconoscimento vocale con Visual Basic 2008 e Windows Vista ENU

Come probabilmente molti di voi sanno, Microsoft Windows Vista offre la possibilità di utilizzare un motore di riconoscimento vocale, tecnologia definita come Speech Recognition. In sostanza, è possibile inviare comandi vocali al sistema operativo semplicemente parlando a un microfono collegato al pc. Allo stato attuale (e penso anche futuro..) questo engine è disponibile solo su Windows Vista in inglese e non è disponibile sulla localizzazione italiana.

 

Per noi developer, è piuttosto semplice utilizzare nelle nostre applicazioni le funzionalità di riconoscimento vocale grazie all’infrastruttura offerta da Microsoft .NET Framework, incluso in Windows Vista dalla versione 3.0. Tali possibilità trovano il loro naturale sbocco nell’utilizzo in Windows Presentation Foundation. Unico limite, come detto, l’esclusività della localizzazione inglese di Vista.

 

Ciò premesso, in questo post vedremo come sia possibile aggiungere funzionalità di Speech Recognition alle proprie applicazioni WPF scritte con Microsoft Visual Basic 2008 e destinate alla localizzazione inglese di Windows Vista.

 

Dopo aver aperto Visual Studio 2008, create una nuova applicazione WPF per Visual Basic come già sapete fare. La prima operazione da compiere è aggiungere un riferimento all’assembly System.Speech.dll che offre classi per il Text-to-Speech e la Speech Recognition (comando Project|Add reference).

 

Fatto questo, stabiliamo il risultato da ottenere. Vogliamo far sì che alcuni controlli dell’interfaccia grafica, come per esempio un pulsante e la finestra dell’applicazione principale, rispondano ad alcuni comandi vocali in maniera analoga a quanto farebbero se utilizzassimo il mouse. Attivando l’editor dello XAML sul file Window1.xaml, possiamo definire una semplice interfaccia che contiene un pulsante e una Label che mostrerà alcuni messaggi di stato:

 

 

<Window x:Class="Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="300" Width="500">

    <StackPanel>

        <Label Height="30"  x:Name="StatusLabel" Margin="10,10,10,10"/>

        <Button Width="100"  Height="50" x:Name="Button1" Margin="10,10,10,10"

                Click="Button1_Click" Content="Click me!"/>

    </StackPanel>

</Window>

 

Ricordate che, già in modalità dichiarativa, va assegnato un gestore di evento Click a ciascun pulsante mediante l’attributo Click dell’elemento Button.

Passiamo ora all’editor di codice Visual Basic al fine di modificare il file di code-behind.

 

L’infrastruttura per il riconoscimento vocale viene offerta dal namespace System.Speech.Recognition che va importato insieme al namespace System.Speech.Recognition.SrgsGrammar, che permette di definire regole di grammatica personalizzate:

 

Imports System.Speech.Recognition

Imports System.Speech.Recognition.SrgsGrammar

 

A proposito delle regole di grammatica, va sottolineato che queste possono essere definite all’interno del codice oppure caricate da un file esterno a struttura Xml. Tali definizioni servono a stabilire quali parole debbano essere riconosciute dall’engine di Windows e devono rifarsi, per forza di cose, alle regole di pronuncia della lingua inglese. L’oggetto principale per lavorare col motore di riconoscimento vocale si chiama SpeechRecognizer e lo dichiariamo a livello di classe, per poi istanziarlo successivamente:

 

Class Window1

 

    Private recognizer As SpeechRecognizer

 

Fatto questo, passiamo a definire alcuni gestori di eventi relative alle attività che vogliamo gestire da comando vocale. In primo luogo, vogliamo che al caricamento della finestra principale venga mostrato un messaggio di benvenuto:

 

    Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        StatusLabel.Content = "Application started"

    End Sub

 

Consideriamo ora il seguente scenario: vogliamo inviare un comando vocale che faccia terminare l’esecuzione dell’applicazione. A riprova che è tutto vero e non simulato, aggiungiamo un gestore per l’evento Closing della Window che mostrerà un messaggio prima di chiudere l’applicazione (implementazione che faremo tra breve):

 

 

    Private Sub Window1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing

        MessageBox.Show("Application is shutting down")

    End Sub

 

Un altro importante gestore è per l’evento Click del pulsante che, in questo esempio, si occuperà di mostrare un semplice messaggio ma che nella realtà potrebbe fare di meglio:

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

        MessageBox.Show("You clicked me!")

    End Sub

 

Così facendo, otterremo lo stesso risultato sia facendo click sul pulsante che inviando il comando vocale di prossima implementazione.

 

Ora viene la parte più interessante. Innanzitutto va istanziato l’oggetto SpeechRecognizer. In questo modo, quando avvieremo l’applicazione, verrà automaticamente avviato anche l’engine di riconoscimento vocale di Windows. Quindi vanno previsti alcuni gestori di evento. La classe SpeechRecognizer espone diversi eventi, noi ne utilizzeremo tre: SpeechDetected che si verifica quando vengono pronunciate delle parole, SpeechRecognized, che si verifica quando le parole pronunciate vengono riconosciute dall’engine e verificate come aderenti alla grammatica specificata e SpeechRecognitionRejected che si verifica quando l’engine non è stato in grado di riconoscere le parole pronunciate. Quindi, tramite l’istruzione AddHandler, indichiamo i metodi che gestiranno tali eventi:

 

 

    Public Sub New()

 

        ' This call is required by the Windows Form Designer.

        InitializeComponent()

 

        ' Add any initialization after the InitializeComponent() call.

        recognizer = New SpeechRecognizer()

 

        AddHandler recognizer.SpeechDetected, AddressOf recognizer_SpeechDetected

        AddHandler recognizer.SpeechRecognitionRejected, AddressOf recognizer_SpeechRecognitionRejected

        AddHandler recognizer.SpeechRecognized, AddressOf recognizer_SpeechRecognized

 

Vanno poi definite le regole grammaticali in precedenza accennate. Questa attività si estrinseca mediante l’istanza della classe GrammarBuilder. Tramite il metodo Append, si aggiungono le parole secondo questa logica: la prima istruzione associa la prima parola della frase alla quale possono essere associate quelle indicate nella seconda istruzione. In altre parole, scrivendo il seguente codice potremo far riconoscere all’engine le seguenti combinazioni: “Button click”, “Button close”, “Application click” e “Application close”. Nessun altra parola o combinazione di parole verrà riconosciuta dall’engine. D’altra parte, per questo breve esempio, a noi bastano poche e semplici parole per inviare comandi vocali:

 

        Dim grammar As New GrammarBuilder()

        grammar.Append(New Choices("Button", "Application"))

        grammar.Append(New Choices("click", "close"))

 

        recognizer.LoadGrammar(New Grammar(grammar))

    End Sub

 

Il metodo LoadGrammar di SpeechRecognizer consente di caricare le regole grammaticali a partire da un oggetto GrammarBuilder oppure da un file esterno.

 

Gestiamo ora alcuni eventi. SpeechDetected si verifica, come detto, quando il motore di riconoscimento si accorge  che stiamo parlando. Ciò posto, vogliamo mostrare un semplice messaggio.

 

    Private Sub recognizer_SpeechDetected(ByVal sender As Object, ByVal e As SpeechDetectedEventArgs)

 

        StatusLabel.Content = "Speech engine has detected that you spoke something"

    End Sub

 

SpeechRecognitionRejected si verifica quando pronunciamo parole che non fanno parte delle regole grammaticali indicate, quindi mostriamo un messaggio di errore:

 

    Private Sub recognizer_SpeechRecognitionRejected(ByVal sender As Object, ByVal e As SpeechRecognitionRejectedEventArgs)

 

        MessageBox.Show("Sorry but the " & e.Result.Text & " phrase could not be recognized")

 

    End Sub

 

Grazie all’oggetto e possiamo accedere al testo pronunciato.

Da ultimo, la parte più interessante ossia l’evento SpeechRecognized che si verifica quando il testo pronunciato al microfono viene riconosciuto dall’engine. Tra le varie combinazioni possibili, sopra accennate, ce ne interessano in particolare due: “Button click” per simulare la pressione del pulsante e “Application close” per far chiudere l’applicazione. Ecco il codice:

 

    Private Sub recognizer_SpeechRecognized(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)

        Select Case e.Result.Text.ToUpper

            Case Is = "BUTTON CLICK"

 

                Button1.RaiseEvent(New System.Windows.RoutedEventArgs(Button.ClickEvent))

 

            Case Is = "APPLICATION CLOSE"

                Application.Current.Shutdown()

 

            Case Else

                MessageBox.Show("The phrase " & e.Result.Text & " contains valid words but doesn't match valid results")

        End Select

    End Sub

 

Punti di interesse in quest’ultimo gestore:

 

1.    per generare programmaticamente l’evento Click di un pulsante, in WPF si può ricorrere al metodo di istanza RaiseEvent che accetta, come argomento, un Routed event corrispondente all’evento di interesse. Questa non è l’unica metodologia, ma è la più rapida;

2.    per chiudere l’applicazione chiamiamo il metodo Application.Current.Shutdown. Questo farà si che venga prima mostrato il messaggio indicato nel gestore di evento Window1_Closing;

3.    abbiamo previsto una situazione (Case Else) in cui l’utente pronunci parole effettivamente previste nella grammatica custom ma che non corrispondono alle combinazioni di nostro interesse (es. “Application click”).

 

Dopo tanta fatica, premiamo F5 per avviare l’applicazione. Come potete vedere nella prima figura, all’avvio viene mostrato un messaggio nella nostra finestra e viene attivato l’engine di riconoscimento vocale:

 

 

Se non lo avete già fatto, accendete il microfono e pronunciate le parole “Button click” oppure “Click me” (questo perchè WPF è in grado di inviare all’engine il contenuto di taluni controlli, come per esempio la proprietà Content dei Button). Il meraviglioso risultato che otterrete dall’invio del comando vocale sarà il seguente:

 

 

 

Ora provate a pronunciare le parole “Application click”. Senza essere troppo sorpresi, l’applicazione mostrerà un messaggio in cui si evidenzia che le parole pronunciate e riconosciute correttamente fanno parte della grammatica ma non rientrano in una delle azioni da noi previste, come in figura:

 

 

 

Ora provate a pronunciare qualcos’altro J  Dovrebbe apparire un messaggio come quello della seguente figura, in cui si viene avvisati del mancato riconoscimento vocale:

 

 

Da ultimo, pronunciate le parole “Application close”. Come dalla seguente figura, verrà dapprima mostrato un messaggio che ci avvisa della chiusura imminente dell’applicazione, che effettivamente viene terminata dopo l’OK:

 

 

 

È davvero un grande peccato che la disponibilità della Speech Recognition sia attualmente in essere solo per la localizzazione inglese di Windows Vista. Come avete infatti potuto osservare, in questo modo si possono eseguire le stesse azioni sia utilizzando i controlli dell’interfaccia, sia inviando comandi vocali.

 

Spero comunque che questo post sia stato utile a coloro che, per preferenza o per necessità, utilizzano Microsoft Windows Vista in inglese e che considerano l’utilità del riconoscimento vocale nelle proprie applicazioni.

 

Alessandro

Print | posted on domenica 7 settembre 2008 19:47 | Filed Under [ .NET Framework Visual Basic Windows 7 ]

Powered by:
Powered By Subtext Powered By ASP.NET