Синтез голосовой речи из текста в Windows Phone 8 (text-to-speech)

С выходом Windows Phone 8 SDK появилась возможность управлять устройством голосом. Для того, чтобы это стало возможным необходимо две вещи — распознование голосовых команд (чтобы пользователь мог управлять устройством) и синтез голосовой речи из текста (чтобы устройство могло озвучить результат).

Чтобы использовать возможности работы с речью необходимо установить ID_CAP_SPEECH_RECOGNITION capability в манифесте проекта:

Для синтеза речи в WP8 используется объект SpeechSynthesizer. Самый простой вариант генерации голосовой речи состоит из двух строк кода:

private async void OnSayButtonClick(object sender, RoutedEventArgs e)
{
  SpeechSynthesizer speech = new SpeechSynthesizer();
  await speech.SpeakTextAsync(Content.Text);
}

Голос, который будет использоваться в этом случае будет определяться исходя из региональных настроек устройства. При необходимости можно изменить используемый голос, при этом выбрать национальность и пол говорящего. Список всех голосов можно получить через статическое свойство InstalledVoices.All.

Разместим ListPicker на странице:

<toolkit:ListPicker x:Name="Voices">
  <toolkit:ListPicker.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding DisplayName}"/>
        <TextBlock Text="-" Margin="5,0"/>
        <TextBlock Text="{Binding Language}"/>
      </StackPanel>
    </DataTemplate>
  </toolkit:ListPicker.ItemTemplate>
  <toolkit:ListPicker.FullModeItemTemplate>
    <DataTemplate>
      <StackPanel Margin="0,0,0,20">
        <TextBlock Text="{Binding DisplayName}"/>
        <TextBlock Text="{Binding Language}"/>
        <TextBlock Text="{Binding Gender}"/>
      </StackPanel>
    </DataTemplate>
  </toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>

И заполним его списком установленных голосов:

Voices.ItemsSource = InstalledVoices.All;

Для того, чтобы использовать выбранный голос при синтезе речи необходимо вызвать метод SetVoice для объекта SpeechSynthesizer:

private async void OnSayButtonClick(object sender, RoutedEventArgs e)
{
  string content = Content.Text;

  SpeechSynthesizer speech = new SpeechSynthesizer();
  speech.SetVoice((VoiceInformation)Voices.SelectedItem);
  await speech.SpeakTextAsync(content);
}

На этом мы получили приложение, которое воспроизводит заданный текст:

Для более точной настройки речи можно воспользоваться специальным языком SSML (Speech Synthesis Markup Language), который также поддерживается в WP8. Для этого у объекта SpeechSynthesizer поддерживаются два метода – SpeakSsmlAsync (проигрывает SSML из текстовой переменной) и SpeakSsmlFromUriAsync (проигрывает SSML из файла).

private async void OnSaySsmlButtonClick(object sender, RoutedEventArgs e)
{
  SpeechSynthesizer speech = new SpeechSynthesizer();
  await speech.SpeakSsmlAsync(@"<speak version=""1.0"" xmlns=""http://www.w3.org/2001/10/synthesis"" xml:lang=""ru-Ru"">
    <voice gender=""female"">
      Здравствуйте, Александр!<break/>
      Рада вас видеть!
    </voice>

    <voice gender=""male"">
      Здравствуйте, Ирина! И я очень рад.
    </voice>
  </speak>");
}