Доброго времени суток. Недавно я загорелся вопросом создания голосового ассистента. Столкнулся с миллиардом проблем. Но всё же я решил свои вопросы.

Для начала скачиваем Visual Studio.

Теперь вам нужно скачать 3 microsoft пакета

  1. https://www.microsoft.com/en-us/download/details.aspx?id=3971
  2. https://www.microsoft.com/en-us/download/details.aspx?id=24003
  3. https://www.microsoft.com/en-us/download/details.aspx?id=24974

Когда вы будете скачивать, выбирайте х86 платформу (с ней проще и она не баганая).

Теперь. При выборе языка выбирайте любой с окончанием TELE (когда скачиваете вот это Microsoft Speech Platform — Server Runtime Languages), это обязательно.



По окончанию установки языкового пакета ничего не произойдет, не будет кнопок «завершить» или «finish», не пугайтесь, всё нормально.

Теперь проходим в Visual Studio, создаём новый проект(Windows Forms App)



Устанавливаем 1 label и не меняем его название:



Открываем «Solution explorer» или «Обозреватель проектов», так же можно в меню нажать на кнопку «Проект» или «Project» и 2добавить ссылку" или «Add reference».

У вас открывается вот такое окно:



Нажимаем на «browser» или «Обзор» и переходим в папку «C:\Program Files (x86)\Microsoft SDKs\Speech\v11.0\Assembly» и там будет лежать 1 DLL библиотека, выбираем её:



Опять добавляем ссылку, но уже стандартную. Ищем «System.Speech»(ниже узнаете зачем). Ставим галку и жмякаем на кнопку «Ок».



Переходим к коду! Для начала создаем событие для формы «shown». Сделать это можно, нажав на вкладке «Properties» на молнию:



Название переписывать не нужно! Просто 2 клика по полю для ввода.

В самом верху включаем в проект такие классы:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Speech.Recognition;
using System.IO;
using System.Speech.Synthesis;
using System.Diagnostics;
using System.Threading;

Теперь сразу под

public Form1()
        {
            InitializeComponent();
        }

Пишем

static Label l;

static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            if (e.Result.Confidence > 0.7) {
l.Text = e.Result.Text; 
if(e.Result.Text == "Как тебя зовут"){ //Делаем вот такое. Это всего лишь пример функции(ниже 
 //будет показано как исправить ошибку со speak, это отдельная функция! Не пугайтесь, все 
 //нормально
 speak("Меня зовут Судо.");
}
}// Вместо 0,7 ставим своё значение. 
//Это идентификатор схожести. Чем меньше, тем проще разобрать. Зависит от качества 
//микрофона
        }	

Мы создали переменную и класс который будет обрабатывать речь.

В наше событие «shown» запихиваем следующий кусок кода.

l = label1;
            
            System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("ru-ru"); 
//вместо ru-ru указываем свой язык, к примеру en-us и т.д. можно брать язык который стоит на 
//интерфейсе пользователя заменив new System.Globalization.CultureInfo("ru-ru") на 
// System.Globalization.CultureInfo.CurrentCulture
            SpeechRecognitionEngine sre = new SpeechRecognitionEngine(ci);
            sre.SetInputToDefaultAudioDevice();
          
            sre.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(sre_SpeechRecognized);
          

            Choices numbers = new Choices();
            numbers.Add(new string[] { "один", "два", "три", "четыре", "пять", "как тебя зовут" }); //наши слова для 
 //функций

   
            GrammarBuilder gb = new GrammarBuilder();
            gb.Culture = ci;
            gb.Append(numbers);


            Grammar g = new Grammar(gb);
            sre.LoadGrammar(g);

            sre.RecognizeAsync(RecognizeMode.Multiple);

Вот мы уже ловим слова. Потом вы создаете функции в функции

static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)

или можете создать обработчик функций.

Теперь мы делаем голосовое звучание нашего ассистента. Делаем новую функцию speak. Эта функция будет ловить текст и озвучивать его.

private void speak(string text)
        {
            SpeechSynthesizer speaker = new SpeechSynthesizer();
            speaker.Rate = 1;
            speaker.Volume = 100;
            speaker.Speak(text);
        } 

Поздравляю, ваш мини голосовой ассистент сделан. Его дорабатываем и он будет не хуже «Окей гугл».

По всем вопросам пишите в телеграм @Cp_Troia — помогу чем смогу.

Мой исходник. Перед тем как что-то сказать, скажите «Судо», а потом команду, к примеру «Открыть гугл хром» или «привет», команд там много, можно открыть даже блокнот и калькулятор, открыть ютуб и т.д.

Комментарии (5)


  1. Matisumi
    14.05.2019 11:23

    Эм… Идея-то классная, но статья написана неграмотно и так, будто писалась для детей младшего школьного возраста. Надо что-то с этим сделать.


  1. sami777
    14.05.2019 11:26
    +1

    Спасибо! Хорошая тема, даже захотелось то же попробовать повторить!
    К сожалению нашлись «умные», кто «заминусовал» тему.


    1. lair
      14.05.2019 11:49
      +1

      А заминусовали за полную практическую бесполезность. Такие игрушки делали лет двадцать назад, и все они упирались в необходимость жестко прописать команды, что делало их утомительными. Просто сравните с тем, как работают современные NLU-системы, типа LUIS, Amazon Lex или Dialogflow.


  1. lair
    14.05.2019 11:27

    То есть вы просто бросили готовый компонент на форму, и сделали голосовой ассистент "не хуже «Окей гугл»"? SRSLY?


    открыть гугл хром;open;chrome.exe
    открой гугл хром;open;chrome.exe
    запусти гугл хром;open;chrome.exe
    гугл хром;open;chrome.exe
    хром;open;chrome.exe
    гугл;open;chrome.exe

    Даже естественную вариативность языка не освоили, хотя казалось бы, сервисов для NLU — вагон.


  1. lair
    14.05.2019 12:05
    +1

    Отдельным пунктом, конечно, ужасает сам код. Весь разбирать не буду, одного пункта достаточно:


    static Label l;
    
    static void sre_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
    {
      //...
      l.Text = e.Result.Text; 
      //...
    }
    
    //Form_Shown
    l = label1;

    Такое ощущение, что автор ни C#/.NET, ни жизненный цикл Windows Forms не знает.