Sunday, September 25, 2011

Text to speech in windows phone 7

How to use cloud-based Microsoft Translator Service in windows phone 7 to translate text to speech.

In this article I am going to explain how we can take the leverage of cloud to solve the problem for Text to Speech translation. It’s pretty simple to archive such kind of functionality in windows phone 7 using Bing API. Here I will show how we can retrieve a list of languages supported by Microsoft Translator for the Speech API and speak the user’s input text.

First of all we must obtain a valid Bing API AppID, lets follow the below steps.

Step -1 Open below mentioned url to register your application. And follow the instructions to obtain a valid Bing API AppID.

http://www.bing.com/developers/appids.aspx
1

Step-2 Enter required information and obtain a valid Bing API AppID.

2


Once you register your application now we will be moving ahead with the windows phone 7 application developments and invoke the cloud service.

Step-3 Create a windows phone 7 application project.

WP_001

Step-4 To add web reference of the Microsoft Translator Service, we need to add a service reference to Windows Phone project. Right - click the Windows Phone Project in solution explorer, and choose Add Service Reference. Please see below pictures for the same.

http://api.microsofttranslator.com/V2/Soap.svc


WP_002

WP_003

WP_004

Step-5 Now adds a panorama page to windows phone 7 project.

WP_005

Step-6 creates a UI as per application requirement see below xaml code snippet. Here I have added three panorama items.



<Grid x:Name="LayoutRoot">
<controls:Panorama Title="text to speech" Name="panoSpeech" Foreground="Blue" FontFamily="Comic Sans MS">
<!--Panorama item one-->
<controls:PanoramaItem Header="Language(s)" Foreground="Plum" FontFamily="DengXian" FontSize="72">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<DataTemplate x:Key="LanguageTemplate">
<TextBlock Foreground="White" Margin="0,0,0,0" Text="{Binding Name}" />
</DataTemplate>
</StackPanel.Resources>
<ListBox HorizontalAlignment="Left" ItemTemplate="{StaticResource LanguageTemplate}" Margin="20,10,0,20" Name="ListLanguages" Width="441">
</ListBox>
</StackPanel>
</controls:PanoramaItem>

<!--Panorama item two-->
<controls:PanoramaItem Header="Speech" Foreground="Yellow">
<StackPanel Orientation="Vertical" Margin="20,0,0,0">
<TextBox Name="TextToSpeachText" Text="This Pavan Pareta, Microsoft Most Value able proffesional. He has written an application for windows phone 7" TextWrapping="Wrap" Height="350" />
<Button Content="S p e a k" Height="90" Margin="0,30,0,0" Name="btnSpeak" Width="338" Click="btnSpeak_Click" />
</StackPanel>
</controls:PanoramaItem>

<!--Panorama item three-->
<controls:PanoramaItem Header="Speak" Foreground="Violet">
<StackPanel Orientation="Vertical">
<Image Height="auto" Name="image1" Stretch="None" Width="auto" Margin="50 60 80 0" Source="/speak.jpg" />
</StackPanel>
</controls:PanoramaItem>
</controls:Panorama>
</Grid>


Step-7 Fist Panorama item used to develop for retrieving supported speech languages. To retrieve the supported language we need to call web service method “GetLanguagesForSpeakAsync”. The GetLanguagesForSpeak method only returns the language codes, for example, en for English and fr for French etc. see blow UI and code snippet.


WP_006


GetLanguagesForSpeakAsync takes two methods like AppID and object.

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
try
{
FrameworkDispatcher.Update();
var objTranslator = new ServiceReference1.LanguageServiceClient();
objTranslator.GetLanguagesForSpeakCompleted += new EventHandler<GetLanguagesForSpeakCompletedEventArgs>(translator_GetLanguagesForSpeakCompleted);
objTranslator.GetLanguagesForSpeakAsync(AppId, objTranslator);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

void translator_GetLanguagesForSpeakCompleted(object sender, GetLanguagesForSpeakCompletedEventArgs e)
{
var objTranslator = e.UserState as ServiceReference1.LanguageServiceClient;
objTranslator.GetLanguageNamesCompleted += new EventHandler<GetLanguageNamesCompletedEventArgs>(translator_GetLanguageNamesCompleted);
objTranslator.GetLanguageNamesAsync(AppId, "en", e.Result, e.Result);
}

void translator_GetLanguageNamesCompleted(object sender, GetLanguageNamesCompletedEventArgs e)
{
var codes = e.UserState as ObservableCollection<string>;
var names = e.Result;
var languagesData = (from code in codes
let cindex = codes.IndexOf(code)
from name in names
let nindex = names.IndexOf(name)
where cindex == nindex
select new TranslatorLanguage()
{
Name = name,
Code = code
}).ToArray();
this.Dispatcher.BeginInvoke(() =>
{
this.ListLanguages.ItemsSource = languagesData;
});
}

Step-8 Second Panorama item used to develop for speak text using SpeakAsync method takes four string parameters like AppId, SpeechText, SpeechLanguage, format. See below UI and code snippet.


WP_007


private void btnSpeak_Click(object sender, RoutedEventArgs e)
{
var languageCode = "en";
var language = this.ListLanguages.SelectedItem as TranslatorLanguage;
if (language != null)
{
languageCode = language.Code;
}
var objTranslator = new ServiceReference1.LanguageServiceClient();
objTranslator.SpeakCompleted += translator_SpeakCompleted;
objTranslator.SpeakAsync(AppId, this.TextToSpeachText.Text, languageCode, "audio/wav");

panoSpeech.DefaultItem = panoSpeech.Items[(int)2];

}

void translator_SpeakCompleted(object sender, ServiceReference1.SpeakCompletedEventArgs e)
{
var client = new WebClient();
client.OpenReadCompleted += ((s, args) =>
{
SoundEffect se = SoundEffect.FromStream(args.Result);
se.Play();
});
client.OpenReadAsync(new Uri(e.Result));
}


Step-9 Now builds the application and executes it.

WP_008WP_009WP_010

Download source code here

Thank you for your time.