Как стать автором
Обновить

Поговори со мной, Windows Phone

Время на прочтение 5 мин
Количество просмотров 13K
Пока еще Cortana не стала доступной для русскоговорящих пользователей Windows Phone 8.1, а это ожидается скоро, я предлагаю вам самим сделать веселое апрельское приложение, с помощью которого можно будет поговорить с телефоном, покомандовать им, а может быть и поиграть.

На деле это, оказывается, довольно просто.


В качестве примера предлагаю сделать детское приложение, которое тренирует в устном счете до 10-ти. Приложение будем писать на XAML/C#

Создаем приложение для Windows Phone — тип проекта Blank App (Windows Phone).

Все разрешения, которые необходимо добавить в манифест – это разрешение на использование микрофона. Никакие другие разрешения не нужны! Открываем файл Package.appxmanifest, заходим на закладку «Capabilities» в англоязычной Visual Studio или «Возможности» в русскоязычной и смело ставим галочку рядом со словом микрофон.

В файл MainPage.xaml добавим довольно простой XAML код:

    <StackPanel Orientation="Vertical" VerticalAlignment="Center">
        <TextBlock FontSize="48" x:Name="txtPrimer" HorizontalAlignment="Center" TextWrapping="Wrap"></TextBlock>
        <Button x:Name="btnOtvet" Click="btnOtvet_Click" HorizontalAlignment="Center">Задать задачку!</Button>
        <MediaElement x:Name="mediaEl" />
    </StackPanel>

Здесь у нас есть TextBlock для отображения текста примера, кнопка для запуска игры и MediaElement, который обычно используется для воспроизведения аудио/видео, а в нашем случае он будет «произносить» фразы.
Получим что-то вот такое:



В C# code behind ( файл MainPage.xaml.cs ) к пространствам имен, которые имеются в приложении по умолчанию, добавляем еще пространства:

using Windows.Media.SpeechSynthesis;
using Windows.Media.SpeechRecognition;

Как вы могли заметить, в XAML коде у нас объявлено событие нажатия на кнопку. В результате действия срабатывает метод btnOtvet_Click. Одного этого метода нам будет вполне достаточно.

Первой строчкой метода заблокируем кнопку (чтобы пользователь не мог вызвать метод еще раз до завершения выполнения текущего вызова).

Объявим переменную для распознавания голоса:

SpeechRecognizer speechRecognizer = null;  

Далее нам необходимо совершить проверку установлен ли у пользователя русский язык:

  try
            {
                Windows.Globalization.Language lan = new Windows.Globalization.Language("ru-RU");
                speechRecognizer = new SpeechRecognizer(lan);
            }
  catch
            {
                // отображаем сообщение и не продолжаем выполнение кода
                txtPrimer.Text = "У вас отсутствует русский язык. Установите язык в настройках";
                return;
            }

Здесь видно, что в случае если при создании экземпляра SpeechRecognizer с русским языком в качестве параметра произойдет ошибка, то в текстовом поле будет выведено сообщение и далее выполнение кода продолжено не будет.

Следующий кусок кода инициализирует массив значениями от 0 до 10-ти, после чего генерирует 2 случайных числа в промежутке от 0 до 5-ти. Эти числа выводятся в текстовом поле в качестве примера со знаком + между ними.

Создаем экземпляр SpeechRecognitionListConstraint, передав ему наш массив чисел в качестве параметра. Наш «голосовой движок» сможет распознать именно эти слова. Добавляем эти слова в SpeechRecognizer вызвав .CompileConstraintsAsync()
Задаем опции графического интерфейса UIOptions — то каким образом будет запрошен голосовой ответ.

            string[] chisla = { "ноль", "один", "два", "три", "четыре", "пять", "шесть", "семь", "восемь", "девять", "десять" };

            Random rnd = new Random();
            int number1 = rnd.Next(0, 6);
            int number2 = rnd.Next(0, 6);
            int result = number1 + number2;

            txtPrimer.Text = number1 + "+" + number2;

            var listConstraint = new SpeechRecognitionListConstraint(chisla, "числа");
            speechRecognizer.Constraints.Add(listConstraint);

            // компилируем наши слова
            await speechRecognizer.CompileConstraintsAsync();

            speechRecognizer.UIOptions.ExampleText = @"Сколько будет " + number1 + "+" + number2;
            speechRecognizer.UIOptions.AudiblePrompt = "Скажите ответ";
            speechRecognizer.UIOptions.IsReadBackEnabled = false; // не нужно повторять распознанное слово
            speechRecognizer.UIOptions.ShowConfirmation = false; // и подтверждение нам не нужно показывать

Настройки UIOptions отвечают за отображение такого вот окошка:



Теперь распознаем сказанное слово:

            SpeechRecognitionResult speechRecognitionResult = await speechRecognizer.RecognizeWithUIAsync();
            // если была отмена, то не продолжаем дальше
            if (speechRecognitionResult.Confidence == SpeechRecognitionConfidence.Rejected)
            {
                return;  
            }
            string TextToSay=""; // используем этот текст далее
            if (speechRecognitionResult.Text == chisla[result]) // проверяем правильное ли число было сказано
            {
                TextToSay = "Молодец!";
            }
            else
            {
                TextToSay = "Ошибочка";
            }

Если не хочется показывать окошко, для которого мы задавали внешний вид ранее, то можно в первой строчке использовать RecognizeAsync() вместо RecognizeWithUIAsync().

После того, как мы, молодцы такие, распознали текст и получили в переменную TextToSay значение «Молодец!» в случае верного ответа и «Ошибочка» в случае ошибочного, произнесем голосом этот результат. Вставляю сразу весь код воспроизведения (не такой он уж и большой):

 SpeechSynthesizer synth = new SpeechSynthesizer();
 VoiceInformation ruVoice = null;
 SpeechSynthesisStream stream=null;
            try
            {
                ruVoice = (from voice in Windows.Media.SpeechSynthesis.SpeechSynthesizer.AllVoices
                           where voice.Language == "ru-RU"
                           select voice).First();
            }
            catch { }

                if (ruVoice != null)
                {
                        synth.Voice = ruVoice;
                        stream = await synth.SynthesizeTextToStreamAsync(TextToSay);
                }
                mediaEl.SetSource(stream, stream.ContentType);
                mediaEl.Play();

Что здесь делаем? Объявляем и инициализируем объекты самого класса синтезатора речи, информации голоса и потока в который мы запишем нашу фразу. Далее запросом Linq из всех установленных голосов выбираем именно русский (можно еще и именно женский выбрать или мужской). В случае, если голос найден, присваиваем его нашему синтезатору речи и создаем поток из нашего текста («Молодец» или «Ошибочка»). Помните у нас в XAML коде был элемент для воспроизведения медиа с именем mediaEl? Вот ему мы задаем в качестве источника наш поток и запускаем воспроизведение. Отмечу, что синтез речи одинаков со «взрослой» полной Windows 8.1 для ПК и планшетов, то есть, при создании универсального приложения код может быть общим.

Все, что остается сделать, это «отморозить» нашу кнопку:

btnOtvet.IsEnabled = true;

На этом наш метод, да и весь код программы завершен. Остается протестировать в действии.


На фото – процесс тестирования приложения на Lumia 1020

Украшаем приложение веселой картинкой, выкладываем в Store, показываем друзьям, прикалываемся.

Исходный код приложения считалки-говорилки можно скачать по ссылке.
Теги:
Хабы:
+17
Комментарии 4
Комментарии Комментарии 4

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн