Questo post è stato scritto da Massimo Bonanni

Nelle scorse settimane la piattaforma BING ha rilasciato la possibilità di utilizzare funzionalità di speech recognition all’interno delle applicazioni Windows Store Apps per Windows 8 e 8.1.

In questo post cercheremo di dare una visione di insieme su ciò che possiamo fare e come utilizzare le nuove funzionalità di riconoscimento vocale.

Prima di entrare nel dettaglio, il punto di partenza per scoprire tutte le funzionalità offerte da BING per gli sviluppatori è il BING Developer Center all’indirizzo http://it.bing.com/dev/en-us/dev-center

BING Speech Recognition Control

Un’operazione propedeutica per poter utilizzare le funzionalità di speech recognition è il download e l’installazione dell’assembly che contiene le API necessarie.

Per fare questo possiamo utilizzare l’Extension Manager di Visual Studio come mostrato in Figura 1:

clip_image002

Al momento della scrittura del post, come possiamo anche vedere nella precedente figura, il controllo ha tra gli ambienti di sviluppo supportati Visual Studio 11 (Visual Studio 2012). In realtà il package funziona anche con Visual Studio 2013 ma non lo troveremo in quest’ultimo se utilizziamo l’extension manager e dovremo installarlo dal sito.

Sottoscrizione al servizio di BING

Come tutti i servizi offerti dalla piattaforma BING, è necessario sottoscriversi ad un abbonamento tramite il Windows Azure Marketplace ed in particolare alla pagina dello Speech Recognition Control (https://datamarket.azure.com/dataset/bing/speechcontrol)

clip_image004

Il servizio non è disponibile, in questo momento, per gli account Microsoft Account italiani. Se avete, quindi, un live id italiano (cioè se avete dichiarato di risiedere in Italia) non potrete sottoscrivervi e utilizzare il servizio.

Esiste un abbonamento gratuito (di fatto l’unico disponibile ora) che prevede fino ad un massimo di 500.000 transazioni per mese (assolutamente sufficienti per test).

Il servizio di speech recognition prevede un’autenticazione con il protocollo OAUTH e, quindi, abbiamo la necessità di registrare la nostra applicazione (anche se di test) in modo da ottenere il ClientID e il SecretClient e permettere al sistema di tracciare le nostre transazioni.

Per registrare la nostra applicazione possiamo utilizzare la pagina di Windows Azure Marketplace https://datamarket.azure.com/developer/applications/

clip_image006

Quando registriamo l’applicazione (con il tasto Registra della precedente figura), inseriamo il ClientID (che deve essere univoco) e otteniamo il SecretClient:

clip_image008

In questo caso l’applicazione è un’applicazione Windows Store Apps per Windows 8.1 e possiamo inserire un URL di riendirizzamento “fasullo” (comunque obbligatorio).

Referenziare l’assembly dello Speech Recognition

Il passaggio successivo, ultimo prima di poter utilizzare le funzionalità di speech recognition, è quello di referenziare l’assembly (scaricato nel sistema tramite il package preso dalla Visual Studio gallery di cui sopra).

Per fare questo utilizziamo la funzionalità di “Add Reference…” di Visual Studio, scegliamo il nodo Windows, il nodo Extensions e l’assembly Bing.Speech, come mostrato nella seguente figura:

clip_image010

Referenziare l’assembly Bing.Speech produce la reference della dll “Microsoft Visual C++ 2013 Runtime Package” utilizzata da quest’ultimo.

La libreria runtime di Visual C++ da un errore di reference se utilizzate come piattaforma la Any CPU, quindi dovete necessariamente utilizzare o x86 o x64 durante i vostri test con Visual Studio e compilare per x86, x64 e ARM prima di distribuire la vostra applicazione.

Ultima operazione per poter utilizzare le classi contenute in Bing.Speech e accedere al servizio è la modifica del file di manifest per abilitare le capability “Internet Client” e “Microphone”:

clip_image012

Infine è necessario aprire il file di manifest utilizzando un editor XML (basta utilizzare l’opzione contestuale “Open with…” di Visual Studio) e aggiungere il seguente nodo XML:

<Extensions>

<Extension Category="windows.activatableClass.inProcessServer">

<InProcessServer>

<Path>Microsoft.Speech.VoiceService.MSSRAudio.dll</Path>

<ActivatableClass ActivatableClassId="Microsoft.Speech.VoiceService.MSSRAudio.Encoder" ThreadingModel="both" />

</InProcessServer>

</Extension>

<Extension Category="windows.activatableClass.proxyStub">

<ProxyStub ClassId="5807FC3A-A0AB-48B4-BBA1-BA00BE56C3BD">

<Path>Microsoft.Speech.VoiceService.MSSRAudio.dll</Path>

<Interface Name="IEncodingSettings" InterfaceId="C97C75EE-A76A-480E-9817-D57D3655231E" />

</ProxyStub>

</Extension>

<Extension Category="windows.activatableClass.proxyStub">

<ProxyStub ClassId="F1D258E4-9D97-4BA4-AEEA-50A8B74049DF">

<Path>Microsoft.Speech.VoiceService.Audio.dll</Path>

<Interface Name="ISpeechVolumeEvent" InterfaceId="946379E8-A397-46B6-B9C4-FBB253EFF6AE" />

<Interface Name="ISpeechStatusEvent" InterfaceId="FB0767C6-7FAA-4E5E-AC95-A3C0C4D72720" />

</ProxyStub>

</Extension>

</Extensions>

Se non aggiungiamo i punti di estensione precedenti otterremo una eccezione nel momento in cui tentiamo di utilizzare le funzionalità della piattaforma.

La classe SpeechRecognizer e il controllo SpeechRecognizerUx

Il modo più semplice per fornire le funzionalità di speech recognition è utilizzare la classe SpeechRecognizer e il controllo SpeechRecognizerUx.

La classe SpeechRecognizer si occupa di gestire lo stream proveniente dal microfono e comunicare con il servizio di BING ritornando, eventualmente, ciò che è stato analizzato mentre il controllo SpeechRecognizerUX permette di fornire all’utente l’interfaccia minima per gestire l’operazione di speech recognition.

Per utilizzare la UX fornita di default è sufficiente aggiungere il controllo SpeechRecognizerUx alla nostra finestra:

<Page

x:Class="BINGSpeechRecognition.MainPage"

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

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

xmlns:sp="using:Bing.Speech.Xaml"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

mc:Ignorable="d" Loaded="Page_Loaded">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid.RowDefinitions>

<RowDefinition Height="2*"/>

<RowDefinition Height="*"/>

<RowDefinition Height="Auto"/>

<RowDefinition Height="100"/>

</Grid.RowDefinitions>

<Border Margin="50" BorderBrush="{ThemeResource ButtonBorderThemeBrush}" BorderThickness="1">

<TextBlock x:Name="ResultText" FontSize="30" Margin="5"/>

</Border>

<Border Margin="50" BorderBrush="Red" BorderThickness="1" Grid.Row="1">

<TextBlock x:Name="ErrorText" FontSize="30" Margin="5" Foreground="red"/>

</Border>

<Button x:Name="StartButton" Grid.Row="2" Margin="10"

HorizontalAlignment="Center" FontSize="30">Avvia il riconoscimento</Button>

<sp:SpeechRecognizerUx x:Name="SpeechControl" Grid.Row="3"/>

</Grid>

</Page>

Da notare che dobbiamo utilizzare il namespace Bing.Speech.Xaml per essere abilitati a vedere il controllo SpeechRecognizerUx.

L’effettiva funzionalità di speech recognition è demandata alla classe SpeechRecognizer:

Private speechRecognizer As SpeechRecognizer

Private Sub Page_Loaded(sender As Object, e As RoutedEventArgs)

CreateSpeechRecognizer()

SpeechControl.SpeechRecognizer = speechRecognizer

End Sub

Private Sub CreateSpeechRecognizer()

Dim credentials = New SpeechAuthorizationParameters()

credentials.ClientId = "CLIENT ID"

credentials.ClientSecret = "CLIENT SECRET"

speechRecognizer = New SpeechRecognizer("it-IT", credentials)

End Sub

Creiamo l’istanza della classe SpeechRecognizer passando i parametri dell’autenticazione (ClientId e ClientSecret visti in precedenza) e la lingua desiderata (“it-IT” nell’esempio) e l’associamo al controllo SpeechRecognizerUx in modo che questo possa gestire le notifiche all’interfaccia e segnalare all’utente il momento in cui l’applicazione è in ascolto.

clip_image014

A questo punto non ci resta che avviare il riconoscimento vocale utilizzando il metodo RecognizeSpeechToTextAsync della classe SpeechRecognizer.

Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click

StartButton.IsEnabled = False

Try

Me.ResultText.Text = String.Empty

Me.ErrorText.Text = String.Empty

Dim result = Await speechRecognizer.RecognizeSpeechToTextAsync()

If result.TextConfidence <> SpeechRecognitionConfidence.Rejected Then

      Me.ResultText.Text = result.Text

Else

      Me.ErrorText.Text = "Rejected"

End If

Catch ex As Exception

      Me.ErrorText.Text = ex.Message

End Try

StartButton.IsEnabled = True

End Sub

Il risultato della chiamata (rigorosamente asincrona) al metodo RecognizeSpeechToTextAsync contiene le informazioni sull’eventuale testo “riconosciuto”. Il risultato è di tipo SpeechRecognitionResult le cui proprietà sono:

  • Text: eventuale testo riconosciuto;
  • TextConfidence: enumerazione di tipo SpeechRecognitionConfidence che indica il grado di attendibilità del riconoscimento. Se non è stato riconosciuto nulla si ha il valore Rejected.

Oltre a queste proprietà, la classe SpeechRecognitionResult fornisce anche il metodo GetAlternates per avere l’elenco delle stringhe alternative riconosciute dalla piattaforma (anch’esse di tipo SpeechRecognitionResult).

E’ opportuno gestire tramite un try..catch la chiamata alla piattaforma BING perché, in caso di mancanza di rete, potremmo ottenere un’eccezione.

SpeechRecognizer in dettaglio

La classe SpeechRecognizer espone una serie di metodi e di eventi utili per controllare il flusso di esecuzione del riconoscimento vocale, soprattutto se non si utilizza il controllo XAML e si devono implementare le funzioni di stop e cancellazione dell’operazione.

In particolare, oltre al già citato RecognizeSpeechToTextAsync, troviamo:

  • StopListeningAndProcessingAudio: ferma l’acquisizione dell’audio e avvia l’analisi dell’audio recuperato;
  • RequestCancelOperation: annulla il processo di riconoscimento vocale.

Oltre ai metodi abbiamo a disposizione anche degli eventi:

  • AudioCaptureStateChanged: viene sollevato quando cambia lo stato della sessione di riconoscimento vocale. L’enumerazione SpeechRecognizerAudioCaptureState dell’argomento dell’evento fornisce informazioni sullo stato della sessione (ad esempio Thinking quando la piattaforma sta elaborando un audio);
  • AudioLevelChanged: viene sollevato quando l’utente varia il volume dell’audio catturato dal microfono;
  • RecognizerResultRecieved: viene sollevato ogni volta che la piattaforma fornisce un risultato preliminare di riconoscimento vocale nello stato di Thinking. Tramite la proprietà IsHypothesis possiamo sapere se si tratta di un risultato preliminare o finale.

Possiamo, quindi, agevolmente sostituire il controllo fornito dalla piattaforma con un nostro controllo per la gestione del riconoscimento vocale.

Ricordate che è sempre opportuno segnalare all’utente quando l’operazione di riconoscimento vocale è attiva e fornire la possibilità di annullarla o completarla. Per quanto riguarda il completamento la piattaforma lo esegue automaticamente se si accorge di un momento di “vuoto” nell’audio ma in ambienti rumorosi l’utente potrebbe voler intervenire manualmente.