Использование Google Speech API для управления компьютером

Добрый день всем хабражителям.

На хабре уже писалось несколько статей о использовании Google Speech API, в том числе о его применении при создании Умного дома.

В этой статье я хочу рассказать как можно написать небольшую программку для голосового управления компьютером.

Кому интересно, прошу под кат.


Для разработки я использую Embarcadero RAD Studio XE и несколько бесплатных вспомогательных компонентов (JEDI Core, JEDI VCL, New Audio Components for Delphi, Synapse, uJSON, CoolTrayIcon)

В статье «Используем Google Voice Search в своем приложении .NET» было описано как работает Google Speech API и какие есть тонкости.

Опишу алгоритм моей программы и некоторые нюансы использования вспомогательных компонентов.

1. Запись звука в формате FLAC

Для этого я использую компонент New Audio Components for Delphi. Звук записываем в формат FLAC с частотой 8 кГц и сохраняем в файл.

За запись отвечает VCL компонент DXAudioIn1, в нем же прописаны настройки записи (1 канал и частота 8 кГц)

Далее данные с DXAudioIn1 идут на FastGainIndicator1 у которого на OnGainData стоит обработка уровней, если уровень упал N раз ниже установленного (красный указатель), то происходит остановка записи и отправка данных в Google.
Так же я сделал возможность начать автоматическую запись при превышении уровня на какой-то порог M раз (синий указатель).

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

И в конце данные с FastGainIndicator1 идут на компонент FLACOut1, который и осуществляет запись непосредственно в файл в формате FLAC.

За начало записи отвечает процедура StartRecord.

2. Отправка файла в Google для распознавания и прием ответа

Записанный файл с помощью библиотеки Synapse отправляется в Google на распознавание.

Какие есть тонкости при работе с Synapse и тем, что данные нужно отправлять используя HTTPS?

а) Необходимо наличие библиотек libeay32.dll и ssleay32.dll
б) В uses необходимо подключить файл SSL_OpenSSL

За отправку файла отвечает функция HTTPPostFile.

Вызывается она просто:
HTTPPostFile('https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU', 'userfile', ExtractFilename(OutFileName), Stream, StrList);

, где
Stream — это поток TFileStream в который мы читаем наш записанный файл в формате FLAC.
StrList — это TStringList с ответом от Google.

Сама функция HTTPPostFile довольно проста, но есть в ней и тонкости:

function TMainForm.HTTPPostFile(Const URL, FieldName, FileName: String; Const Data: TStream; Const ResultData: TStrings): Boolean;
const
  CRLF = #$0D + #$0A;
var
  HTTP: THTTPSend;
  Bound, Str: String;
begin
  Bound := IntToHex(Random(MaxInt), 8) + '_Synapse_boundary';
  HTTP := THTTPSend.Create;
  try
    Str := '--' + Bound + CRLF;
    Str := Str + 'content-disposition: form-data; name="' + FieldName + '";';
    Str := Str + ' filename="' + FileName + '"' + CRLF;
    Str := Str + 'Content-Type: audio/x-flac; rate=8000' + CRLF + CRLF;
    HTTP.Document.Write(Pointer(Str)^, Length(Str));
    HTTP.Document.CopyFrom(Data, 0);
    Str := CRLF + '--' + Bound + '--' + CRLF;
    HTTP.Document.Write(Pointer(Str)^, Length(Str));
    HTTP.MimeType := 'audio/x-flac; rate=8000, boundary=' + Bound;
    Result := HTTP.HTTPMethod('POST', URL);
    ResultData.LoadFromStream(HTTP.Document);
  finally
    HTTP.Free;
  end;
end;


3. Парсинг строки ответа от Google и выполнение команды

Строка ответа от Google приходит в формаnе JSON, например:

{«status»:0,«id»:«5e34348f2887c7a3cc27dc3695ab4575-1»,«hypotheses»:[{«utterance»:«блокнот»,«confidence»:0.7581704}]}

Для парсинга я использую библиотеку uJSON.

Что означают поля ответа:
поле status = 0 — запись успешно распознана
поле status = 5 — запись не распознана
поле id — это уникальный идентификатор запроса
поле hypotheses — результат распознования, в нем 2 подполя:
utterance — распознанная фраза
confidence — достоверность распознавания

Отправка файла, разбор ответа, поиск и выполнение команды я вынес в отдельный поток JvThreadRecognize.

Списки команд хранятся в файле MSpeechCommand.ini, пример файла:

блокнот;notepad.exe
свернуть все программы;script\Show_Desktop.scf
заблокировать компьютер;script\Lock_Workstation.cmd
выключить компьютер;script\Halt_Workstation.cmd
перезагрузить компьютер;script\Reboot_Workstation.cmd
завершить сеанс;script\Logoff_Workstation.cmd
запустить qip;C:\Program Files\QIP Infium\infium.exe
интернет;firefox.exe


Итоги: Данная программа не претендует на звание законченной, это лишь пример использования Google Speech API для выполнения некоторых команд на компьютере (пока это только запуск приложений и выполнение системных команд). Но никто не мешает доработать её и научить двигать мышкой, набирать текст в текстовом редакторе и т.д.

Готовая сборка программы и исходники (GPLv3) доступны на code.google.com/p/mspeech

Буду рад услышать конструктивную критику и пожелания. Спасибо.
Share post

Similar posts

Comments 12

    0
    Режима постояннного поиска команд нету? :-[
      0
      Есть, это называется «Максимальный уровень сигнала для начала записи» и «Кол. срабатываний на макс. уровень» и рядом с ними галка для активации режима.

      То есть работает режим так: постоянно анализируется уровень сигнала с микрофона, как только он превысит порог N раз, то начинается запись, как только уровень опуститься ниже минимума M раз, запись прекратиться и данные улетят в Google для распознавания.

      Но постоянный поиск — это постоянная отправка запросов в Google и некоторые задержки в приеме команд, т.к. все делается в один поток. Как бы Google не обиделся при большом потоке шелухи.
        +1
        Пробовал сделать похожу программу — получилась такая штука: youtu.be/zNIlF-dxn-s

        А вообще в Anodrid 4.0+ есть «непрерывное» распознавание речи. Если бы его использовать для распознавания, то проблемы с активацией не было бы.
          0
          я бы предложил ещё добавить сюда ключевую фразу для активации. т.е. что б можно иметь что-то вроде диалога: -компьютер; — слушаю; — включи музыку. для распознания ключевой фразы можно использовать встроенную в windows7 систему распознавания, ну или что-то простенькое своё, если есть такая возможность.
            0
            >>Пробовал сделать похожу программу — получилась такая штука: youtu.be/zNIlF-dxn-s

            Это скорее аналог Siri для PC, у меня же это программ для управления компьютером в чистом виде.

            >>ключевую фразу для активации. т.е. что б можно иметь что-то вроде диалога: -компьютер; — слушаю; — включи музыку. для распознания ключевой фразы можно использовать встроенную в windows7 систему распознавания, ну или что-то простенькое своё, если есть такая возможность.

            С этим как раз есть сложности, свой алгоритм распознавания изобретать очень трудоемко, для этого есть специализированные аппаратные решения, которые как раз и использует Google.

            Насколько я знаю, встроенная в Windows система распознавания не поддерживает русский язык.
              0
              >>> А вообще в Anodrid 4.0+ есть «непрерывное» распознавание речи. Если бы его использовать для распознавания, то проблемы с активацией не было бы.

              Нужно поковыряться, что там придумали на этот счет. Возможно они используют возможности DSP процессора телефона, на обычном PC такое сложно сделать.
                0
                Оказывается я не один над подобной программой работаю
                Вот так работает моя программа
                  0
                  >>Оказывается я не один над подобной программой работаю
                  >>Вот так работает моя программа

                  Мой проект несколько иной, у меня не стоит задача создания ИИ на основе нейронных сетей или чего то подобного. Я просто управляю компьютером посредством голосовых команд, логика тут жесткая, никакой полемики с компьютером я не веду, дана команда, если она распознана, то выполняется какое-то действие.
                    0
                    Программу планирую научить не только болтать, но и выполнять команды.
                    Программа создавалась для бытового робота
                    0
                    Можем попробовать объединить усилия, если интересно, то черкни в аську 161867489
                      0
                      Программа интересна. Хотел увидеть исходники, но, к сожалению, не нашёл их. Там только скомпиленные проекты.
                      Если можно и не жалко просьба выкинуть исходники :-)

                    Only users with full accounts can post comments. Log in, please.