Добрый день всем хабражителям.
На хабре уже писалось несколько статей о использовании 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
свернуть все программы;scriptShow_Desktop.scf
заблокировать компьютер;scriptLock_Workstation.cmd
выключить компьютер;scriptHalt_Workstation.cmd
перезагрузить компьютер;scriptReboot_Workstation.cmd
завершить сеанс;scriptLogoff_Workstation.cmd
запустить qip;C:Program FilesQIP Infiuminfium.exe
интернет;firefox.exe
Итоги: Данная программа не претендует на звание законченной, это лишь пример использования Google Speech API для выполнения некоторых команд на компьютере (пока это только запуск приложений и выполнение системных команд). Но никто не мешает доработать её и научить двигать мышкой, набирать текст в текстовом редакторе и т.д.
Готовая сборка программы и исходники (GPLv3) доступны на code.google.com/p/mspeech/
Буду рад услышать конструктивную критику и пожелания. Спасибо.
Автор: Sleuthhound