Introduction
In this article I am explaining how to leverage the cloud to solve the problem of Text to Speech translation. It's pretty simple to archive such kind of functionality in Windows Phone 7 using the Bing API. Here I will show how we can retrieve a list of languages supported by the Microsoft Translator for the Speech API and speak the user's input text.
First of all we must obtain a valid Bing API AppID, let's use the following steps.
Step 1 : Open the following Url to register your application and follow the instructions to obtain a valid Bing API AppID.
http://www.bing.com/developers/appids.aspx
Step 2 : Enter required information and obtain a valid Bing API AppID.
After having registered your application, we will proceed with the Windows Phone 7 application development and invoke the cloud service.
Step 3 : Create a Windows Phone 7 application project.
Step 4 : To add a web reference of the Microsoft Translator Service, we need to add a service reference to the Windows Phone project. Right-click the Windows Phone Project in the Solution Explorer, and choose Add Service Reference. Please see the following pictures of that.
http://api.microsofttranslator.com/V2/Soap.svc
Step 5 : Now add a panorama page to the Windows Phone 7 project.
Step 6 : Create a UI as per application requirements; see the following 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 : First the Panorama item used in development for retrieving the supported speech languages. To retrieve the supported language we need to call a web service method "GetLanguagesForSpeakAsync". The GetLanguagesForSpeak method only returns the language codes, for example, en for English and fr for French etc. See the following UI and code snippet.
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 : The second Panorama item used in development for speaking the text using the SpeakAsync method takes four string parameters like AppId, SpeechText, SpeechLanguage, format. See the following UI and code snippet.
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 build the application and execute it.
Thank you for your time.