Con l’arrivo di Windows 8.1 sono arrivate anche una miriade di API con nuove funzionalità interessanti.
Una di queste, già presente tra le API a disposizione di chi sviluppa per Windows Phone 8, è quella relativa al Text To Speech (TTS), cioè alla possibilità che abbiamo di far “parlare” la nostra Windows Store App.
Per chi conosce le API a disposizione di WP8, le API per Windows 8.1 prevedono un approccio differente.
Le nuove API, dato un testo o un file SSML, permettono di ottenere uno stream audio (vedremo in seguito di che tipo) che, per essere riprodotto, deve essere dato in pasto ad un MediaElement.
La seguente figura mostra il flusso da seguire per far parlare la nostra app:
Supponendo di avere la seguente interfaccia XAML (molto semplice):
x:Class="Text2Speech.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Text2Speech"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Name="txtText" Grid.Row="0" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="200" Margin="10"/>
<Button Grid.Row="1" Content="Text2Speech" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Click="Button_Click"/>
<MediaElement x:Name="Audio"/>
</Grid>
</Page>
Il codice necessario per far pronunciare, nella lingua di default, il testo inserito nel textbox è il seguente:
Dim synthStream As Windows.Media.SpeechSynthesis.SpeechSynthesisStream
Try
synthStream = Await synth.SynthesizeTextToStreamAsync(txtText.Text)
Catch ex As Exception
synthStream = Nothing
End Try
If synthStream Is Nothing Then
Dim dialog = New MessageDialog("Error during Synthetize")
Await dialog.ShowAsync()
Else
Audio.AutoPlay = True
Audio.SetSource(synthStream, synthStream.ContentType)
Audio.Play()
End If
End Using
La classe da utilizzare per “sintetizzare” il testo è la SpeechSynthesizer.
Utilizzando il metodo SynthesizeTextToStreamAsync (rigorosamente asincrono), otteniamo lo stream di sintesi vocale (di tipo SpeechSynthesisStream) che possiamo impostare come sorgente di un MediaElement e riprodurlo.
La classe SpeechSynthesizer espone anche il metodo SynthesizeSsmlToStreamAsync per eseguire la sintesi di un file SSML (per lo standard SSML vedere http://www.w3.org/TR/speech-synthesis/) il cui funzionamento è identico al precedente.
Infine, la stessa classe può essere utilizzata per recuperare l’insieme delle lingue disponibili nel sistema. La proprietà statica InstalledVoices restituisce la collezione di VoiceInformation relative a tutte le lingue installate nel sistema. Attualmente ci sono 17 lingue disponibili (ma non l’italiano).
In ogni caso, se volessimo la prima lingua italiana presente nel sistema (qualora esistesse), potremmo scrivere:
Dim italianVoice = voices.Where(Function(v) v.Language = "it-IT").FirstOrDefault()
ItalianVoice e’ un’istanza di classe VoiceInformation al cui interno troviamo le informazioni relative alla voce:
Per impostare la lingua desiderata prima di eseguire lo speech, utilizziamo la proprietà Voice della classe SpeechSynthesizer.
Dim voices = Windows.Media.SpeechSynthesis.SpeechSynthesizer.AllVoices
Dim italianVoice = voices.Where(Function(v) v.Language = "it-IT").FirstOrDefault()
If italianVoice IsNot Nothing Then
synth.Voice = italianVoice
End If
End Sub
Per maggiori informazioni sul namespace relativo al Text To Speech, l’indirizzo MSDN è http://msdn.microsoft.com/en-us/library/windows/apps/windows.media.speechsynthesis.aspx
Un esempio (C#, Javascript e C++) è disponibile all’ indirizzo http://code.msdn.microsoft.com/windowsapps/Speech-synthesis-sample-6e07b218
Commenti