вторник, 31 марта 2015 г.

Описание API вызова библиотеки GoogleSpeechRecognizeAPI3.DLL

Данная библиотека (далее DLL) для работы с сервисом GoogleSpeech RecognizeAPI через POST-запросы в ОС NT/2000/2003/XP/7/8 предназначена для распознавания речи OFFTIME и REALTIME в автоматическом режиме, по задаваемому пользователем пороговому уровню, языку и задержке отслеживания окончания фразы (триггера "тишины"). Также реализована функция голосового поиска.




Cистемные требования и зависимости:
  1. Win32-64 (NT/2003/XP/7/8)
  2. Требуется наличие Интернет-канала
  3. ssleay32.dll + libeay32.dll для работы с OpenSSL
  4. Необходим актуальный API-ключ для использования API ver.2.0!!!
Проекты на основе
  1. Интерактивный голосовой переводчик http://www.youtube.com/watch?v=Etch0Qj1R7Y
  2. Голосовой контроль плеера AIMP (Aimp_VoiceControl.dll) http://www.youtube.com/watch?v=eIqKQcD7FEg
  3. Голосовой контроль Arduino по каналу блютуз через HC-05 (VoiceControlArduino.DLL) http://www.youtube.com/watch?v=ELdbxYty76Y
  4. Голосовой модуль управления нагрузками USB.HID (VoiceControlHid.DLL) http://www.youtube.com/watch?v=aqzYZov_L1o
  5. Голосовой контроль Wi-Fi розетки Kankun KK-SP3 https://www.youtube.com/watch?v=znNhQBD0eeQ
Описание

DLL предоставляет универсальный доступ для других приложений вне зависимости от языка в среде Win32/64 bit. Для использования DLL в своих проектах соблюдайте соглашение об stdcall-вызовах. Тип соглашения о вызове объявляется после прототипа функции, будь то объявление функционального типа или же объявление функции.

Расшифровки

Таблица расшифровок параметров экспортируемой процедуры OFFTIME-распознавания Recognize_Flac():


Таблица расшифровок параметров экспортируемой процедуры REALTIME-распознавания Recognize():


Таблица расшифровок параметров экспортируемой процедуры Start():


Таблица расшифровок параметров экспортируемой процедуры Set_Thresholdlevel_Delayoff_Ruen():


Таблица расшифровок параметров экспортируемой функции Get_SoundLevel():


Таблица расшифровок параметров экспортируемой процедуры обновления ключа доступа setkey():


Пример динамического подключения (Delphi 6/7/2006/2009/2010/TDL/XE5):
var

  get_soundlevel: function: integer; stdcall;           // текущий уровень громкости
  recognize     : procedure(var
                            full_answer_google,         // полная строка ответа от сервиса
                            recognize_flag,             // признак распознавания
                            recognize_text: pansichar;  // распознанный текст
                            var
                            recognize_accuracy: integer // достоверность распознавания, %
                            ); stdcall;
  recognize_flac: procedure(var
                            filename,                   // путь-имя файла для распознавания
                            ruen,                       // язык распознавания
                            full_answer_google,         // полная строка ответа от сервиса
                            recognize_flag,             // признак распознавания
                            recognize_text: pansichar;  // распознанный текст
                            var
                            recognize_accuracy: integer // достоверность распознавания, %
                            ); stdcall;
  start         : procedure(threshold_level,            // уровень порога срабатывания, %
                            delay_off:                  // задержка отключения, мс
                            integer;
                            ruen:                       // язык распознавания
                            pansichar); stdcall;
  stop          : procedure; stdcall;
  setkey        : procedure(key: pansichar); stdcall;   // обновление API-ключа доступа
  getkey: function: pansichar; stdcall;                 // получение ключа, экспериментальная функция
  set_thresholdlevel_delayoff_ruen: procedure(threshold_level, // уровень порога срабатывания, %
                                              delay_off:       // задержка отключения, мс
                                              integer;
                                              ruen:            // язык распознавания
                                              pansichar); stdcall;


  LibHandle: THandle;


function LinkProc(ProcName: string):Pointer;
begin
 result:= GetProcAddress(LibHandle, PChar(ProcName))
end;

{ инициализация }
var tmp: string;
begin
 LibHandle:= LoadLibrary('test\GoogleSpeechRecognizeAPI3.dll');
 if LibHandle<>0 then begin
  // старт модуля
  start:= LinkProc('start');
  // стоп модуля
  stop := LinkProc('stop');
  // задание порога, времени задержки и языка распознавания REALTIME
  set_thresholdlevel_delayoff_ruen:= LinkProc('set_thresholdlevel_delayoff_ruen');
  // получение уровня сигнала REALTIME
  get_soundlevel:= LinkProc('get_soundlevel');
  // получение результатов распознавания REALTIME
  recognize     := LinkProc('recognize');
  // получение результатов распознавания OFFTIME (из файла)
  recognize_flac:= LinkProc('recognize_flac');
  // установка нового ключа доступа
  setkey:= LinkProc('setkey');
  // получение нового ключа доступа
  getkey:= LinkProc('getkey');
 end;

 tmp:= getkey;
 //setkey(pansichar(tmp)); // экспериментальная функция
 start(100 - tr.Position, 1000, 'ru');
...

{ деинициализация }
begin
 stop;
 FreeLibrary(LibHandle)
...

{ примеры вызова }

// распознать OFFTIME из файла FLAC
var full_answer_google,          // полная строка ответа от сервиса
    recognize_flag,              // признак распознавания
    recognize_text: pansichar;   // распознанный текст
    recognize_accuracy: integer; // достоверность распознавания, %
    //
    ruen, text: pansichar;
begin
 memo1.Clear;
 if checkbox1.Checked then ruen:= 'ru'
  else ruen:= 'en';

 text:= pansichar(edit1.text);
 recognize_flac(text,
                ruen,
                full_answer_google,
                recognize_flag,
                recognize_text,
                recognize_accuracy);

 // результаты
 memo1.Lines.Add(format('%s', [full_answer_google]));
 memo1.Lines.Add('');
 memo1.Lines.Add(format('%s', [recognize_flag]));
 memo1.Lines.Add(format('Текст: %s', [recognize_text]));
 memo1.Lines.Add(format('Достоверность: %d', [recognize_accuracy]) + '%');
...

// визуализация текущего уровня REALTIME (по таймеру или в потоке)
var temp: integer;
    //
    full_answer_google,          // полная строка ответа от сервиса
    recognize_flag,              // признак распознавания
    recognize_text: pansichar;   // распознанный текст
    recognize_accuracy: integer; // достоверность распознавания, %
begin
 temp:= get_soundlevel;
 panel2.Height:= panel1.Height * temp div 100;
 label1.Caption:= format('%d', [temp]) + '%';

 // распознать REALTIME по превышению порога с задержкой
 inc(gl_inc);
 if gl_inc > 1000 div timer1.Interval then begin
  gl_inc:= 0;
  memo1.Clear;

  full_answer_google:= '';
  recognize(full_answer_google,
            recognize_flag,
            recognize_text,
            recognize_accuracy);

  // результаты
  memo1.Lines.Add(format('%s', [full_answer_google]));
  memo1.Lines.Add('');
  memo1.Lines.Add(format('%s', [recognize_flag]));
  memo1.Lines.Add(format('Текст: %s', [recognize_text]));
  memo1.Lines.Add(format('Достоверность: %d', [recognize_accuracy]) + '%');
 end;
...

// задание параметров задержки и порога REALTIME
set_thresholdlevel_delayoff_ruen(20 {%}, 1000 {мс}, 'ru')
...

{ установка нового API-ключа }
begin
 setkey('bla-bla-bla');
...
 Пример динамического подключения (C++ Builder):
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}


// ГЛОБАЛЬНЫЕ ---------------------------------------------------------------

HINSTANCE LibHandle;

// описываем прототипы функции согласно соглашению STDCALL (см. мое описание)
typedef void (__stdcall *start)(int threshold_level, int delay_off, unsigned char * ruen);
typedef void (__stdcall *stop);
int ((__stdcall *level)());
typedef void (__stdcall *recognize)(unsigned char *& full_answer_google,
                                    unsigned char *& recognize_flag,
                                    unsigned char *& recognize_text,
                                    int& recognize_accuracy);
typedef void (__stdcall *set_thresholdlevel_delayoff_ruen)(int threshold_level, int delay_off, unsigned char * ruen);
typedef void (__stdcall *setkey)(unsigned char * key);

FARPROC astart;
FARPROC astop;
FARPROC arecognize;
FARPROC aset_thresholdlevel_delayoff_ruen;
FARPROC asetkey;

unsigned char * full_answer_google; // полная строка ответа от сервиса
unsigned char * recognize_flag;     // признак распознавания
unsigned char * recognize_text;     // распознанный текст
int recognize_accuracy;             // достоверность распознавания, %
int gl_inc;



// инициализация и динамическое подключение DLL
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 LibHandle = LoadLibrary("test\\GoogleSpeechRecognizeAPI3.dll"); // указание отн.пути в билдере
 if (LibHandle!=0) {
  Memo1->Lines->Add("Библиотека найдена и загружена");

  astart = GetProcAddress(LibHandle, "start");
  astop  = GetProcAddress(LibHandle, "stop");
  level = (int ((__stdcall *)()))GetProcAddress(LibHandle, "get_soundlevel");
  arecognize = GetProcAddress(LibHandle, "recognize");
  aset_thresholdlevel_delayoff_ruen = GetProcAddress(LibHandle, "set_thresholdlevel_delayoff_ruen");

  asetkey = GetProcAddress(LibHandle, "setkey");
  //((setkey)asetkey)(""); // в случае обновления Google API ключа доступа следует его тут ввести

  // активируем внутренний поток захвата в библиотеке
  ((start)astart)(10,    // чувствительность 10%
                  1000,  // время триггера паузы
                  "ru"); // rus по-умолчанию
 }
}


// обрабатываем закрытие приложения
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
 if (LibHandle) {
  // деактивируем поток захвата
  ((stop)astop);
  FreeLibrary(LibHandle);
  }
}


// визуализация текущего уровня REALTIME
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 if (LibHandle!=0) {
  // визуализация
  int temp = level();
  Panel2->Height = (int)(Panel1->Height * temp / 100);
  Label2->Caption = IntToStr(temp) + "%";

  // получить результаты распознавания REALTIME из внутреннего потока библиотеки
  gl_inc++;
  if (gl_inc > 1000 / Timer1->Interval) {
   gl_inc = 0;
   Memo1->Clear();

   full_answer_google = "";
   recognize_flag = "";
   recognize_text = "";

   ((recognize)arecognize)(full_answer_google,
                           recognize_flag,
                           recognize_text,
                           recognize_accuracy);

   // отобразить результаты
   Memo1->Lines->Add(AnsiString((char *)full_answer_google));
   Memo1->Lines->Add(AnsiString((char *)recognize_flag));
   Memo1->Lines->Add("Текст: " + AnsiString((char *)recognize_text));
   Memo1->Lines->Add("Достоверность: " + IntToStr(recognize_accuracy) + "%");
   }
  }
}


// задаемся новыми параметрами
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
 ((set_thresholdlevel_delayoff_ruen)aset_thresholdlevel_delayoff_ruen)(100 - tr->Position,
   1000,
   ComboBox1->Text.c_str());
}


Использование под Windows 7/8 любой битности (32/64)

Проведите запуск скрипта 'adminregOS32-64.bat' правой кнопкой мыши от имени Администратора:
@echo off
echo This script must be run with Admin Privilegies
echo.

:: Checking system version
Set "xOS=x64"& If "%PROCESSOR_ARCHITECTURE%"=="x86" If Not Defined PROCESSOR_ARCHITEW6432 Set "xOS=x32"
echo System is %xOS%
echo.

if "%xOS%"=="x64" call :Reg_x64
if "%xOS%"=="x32" call :Reg_x32

echo.
pause
exit /B


:Reg_x32
  echo Registering x32 library

  copy /y "%~dp0lib\GoogleSpeechRecognizeAPI3.dll" "%windir%\System32\*"
  copy /y "%~dp0lib\libeay32.dll" "%windir%\System32\*"
  copy /y "%~dp0lib\libFLAC.dll" "%windir%\System32\*"
  copy /y "%~dp0lib\ssleay32.dll" "%windir%\System32\*"

  reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f

  if %errorlevel%==0 (echo Registration - OK.) else (echo Registration - FAILED !!! Code: %errorlevel%)
  echo Registering x32 library
Exit /B


:Reg_x64
  copy /y "%~dp0lib\GoogleSpeechRecognizeAPI3.dll" "%windir%\SysWOW64\*"
  copy /y "%~dp0lib\libeay32.dll" "%windir%\SysWOW64\*"
  copy /y "%~dp0lib\libFLAC.dll" "%windir%\SysWOW64\*"
  copy /y "%~dp0lib\ssleay32.dll" "%windir%\SysWOW64\*"

  reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f

  if %errorlevel%==0 (echo Registration - OK.) else (echo Registration - FAILED !!! Code: %errorlevel%)
  echo Registering x64 library
Exit /B
Видеоинструкции использования библиотеки в Windows 7/8 (64 bit):



Пример использования функции голосового поиска из скрипта VBS
' RunGoogleSpeechRecognizeAPI3.VBS
' Запуск интерактивного голосового поиска
' Разработчик: Бадло Сергей Григорьевич
' H-page: http://raxp.radioliga.com
' Ограничения: Win OS 32/64 bit

' подключаем голосовое сопровождение
' при надоедливости голоса speakon = false
Dim Speak
speakon = true ' разрешаем голосовое сопровождение
Set Speak = CreateObject("sapi.spvoice")

' создаем объект DynamicWrapperX
Set Wrap = CreateObject("DynamicWrapperX.2")

' подключаем библиотеки
Wrap.Register "user32.dll", "GetAsyncKeyState", "i=l", "f=s", "r=l"
Wrap.Register "GoogleSpeechRecognizeAPI3.dll", "start", "i=lls", "f=s", "r=s"
Wrap.Register "GoogleSpeechRecognizeAPI3.dll", "setvoicesearch", "i=b", "f=s", "r=s"
Wrap.setvoicesearch true
Wrap.start 8, 1000, "ru"

' Информируем пользователя о начале работы
if (speakon = true) then
Speak.Speak "Готов к голосовому поиску."
End if

Do While Wrap.GetAsyncKeyState(27) = "0"
WScript.Sleep 1000 'кол-во миллисекунд
Loop ' завершение цикла

' озвучиваем
if (speakon = true) then
 Speak.Speak "Программа завершена."
End if
Под Windows 7/8 любой битности (32/64) проведите запуск скрипта 'adminregOS32-64.bat' правой кнопкой мыши от имени Администратора:
@echo off
echo This script must be run with Admin Privilegies
echo.

:: Checking system version
Set "xOS=x64"& If "%PROCESSOR_ARCHITECTURE%"=="x86" If Not Defined PROCESSOR_ARCHITEW6432 Set "xOS=x32"
echo System is %xOS%
echo.

if "%xOS%"=="x64" call :Reg_x64
if "%xOS%"=="x32" call :Reg_x32

echo.
pause
exit /B

:Reg_x32
  echo Registering x32 library

  copy /y "%~dp0\GoogleSpeechRecognizeAPI3.dll" "%windir%\System32\*"
  copy /y "%~dp0\libeay32.dll" "%windir%\System32\*"
  copy /y "%~dp0\libFLAC.dll" "%windir%\System32\*"
  copy /y "%~dp0\ssleay32.dll" "%windir%\System32\*"

  copy /y "%~dp0dynwrapx\32\dynwrapx.dll" "%windir%\System32\*"
  regsvr32 /s "%windir%\System32\dynwrapx.dll"

  reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f

  if %errorlevel%==0 (echo Registration - OK.) else (echo Registration - FAILED !!! Code: %errorlevel%)
  echo Registering x32 library
Exit /B

:Reg_x64
  copy /y "%~dp0\GoogleSpeechRecognizeAPI3.dll" "%windir%\SysWOW64\*"
  copy /y "%~dp0\libeay32.dll" "%windir%\SysWOW64\*"
  copy /y "%~dp0\libFLAC.dll" "%windir%\SysWOW64\*"
  copy /y "%~dp0\ssleay32.dll" "%windir%\SysWOW64\*"

  copy /y "%~dp0dynwrapx\32\dynwrapx.dll" "%windir%\SysWOW64\*"
  regsvr32 /s "%windir%\SysWOW64\dynwrapx.dll"

  reg.exe ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA /t REG_DWORD /d 0 /f

  if %errorlevel%==0 (echo Registration - OK.) else (echo Registration - FAILED !!! Code: %errorlevel%)
  echo Registering x64 library
Exit /B
Запуск скрипта после регистрации осуществляется командным файлом 'runVOICESEARCH.cmd' со следующим содержимым:
@echo off
Set "xOS=x64"& If "%PROCESSOR_ARCHITECTURE%"=="x86" If Not Defined PROCESSOR_ARCHITEW6432 Set "xOS=x32"
echo System is %xOS%
echo.

if "%xOS%"=="x64" start "" "%windir%\syswow64\wscript.exe" "%~dp0RunVOICESEARCH.vbs"
if "%xOS%"=="x32" start "" "%windir%\system32\wscript.exe" "%~dp0RunVOICESEARCH.vbs"
Все, теперь голосовой поиск у вас работает в любом браузере по-умолчанию :)

ПОРЯДОК ИСПОЛЬЗОВАНИЯ
  1. Под Windows 7/8 любой битности (32/64) проведите запуск скрипта 'adminregOS32-64.bat' правой кнопкой мыши от имени Администратора.
  2. Для распознавания OFFTIME речевого фрагмента в формате FLAC используйте процедуру Recognize_Flac().
  3. Процедуры инициализации потока Start() и завершения Stop(без параметров) вызываются однократно при начале и окончании отслеживания.
  4. Процедура Set_Thresholdlevel_Delayoff_Ruen() предназначена для изменения параметров (порогового уровня срабатывания триггера тишины, интервала отслеживания окончания фразы и языка) REALTIME.
  5. Процедура Recognize() вернет результаты распознавания отслеживаемой фразы по срабатыванию триггера тишины.
  6. В случае недействительности текущего API-ключа доступа следует установить новый перед вызовом процедуры инициализации потока Start().
  7. Видеоинструкция по использованию библиотеки под ОС Windows 7 64bit https://www.youtube.com/watch?v=vuNDWSHYCSk
  8. Видеоинструкция по использованию библиотеки под ОС Windows 8 64bit https://www.youtube.com/watch?v=W-ZXztT914U
Некоторые замечания
  1. Некоторые разработчики пытаются совместить две моих библиотеки 'GoogleTranslateAPI.DLL' и 'GoogleSpeechRecognizeAPI3.DLL' (библиотеки можно использовать хоть из Excel). Как следствие сталкиваются с необходимостью синхронизации потоков и остановки распознавания на время воспроизведения аудиопотока. Так вот, все это уже давно реализовано в библиотеке 'SpeechTranslateSpeech.DLL'. 
  2. При желании для автораспознавания вы можете использовать альтернативный сервис YANDEX-а и обертку над ним YandexSpeechRecognizeAPI.DLL
  3. Мини-FAQ. Распознавание и синтез речи 

скачать 

6 комментариев:

  1. В связи с нововведениями Google библиотека обновлена.

    ОтветитьУдалить
  2. В архив библиотеки 'GoogleSpeechRecognizeAPI3.DLL' добавил скрипт 'RunVOICESEARCH.vbs' с примером вызова и использования голосового поиска.

    ОтветитьУдалить
  3. Здравствуйте raxp, где можно скачать архив библиотеки 'GoogleSpeechRecognizeAPI3.DLL'?

    ОтветитьУдалить
    Ответы
    1. Здравствуйте, Андрей. Архив можно скачать по указанной ссылке в конце поста, либо отсюда https://yadi.sk/d/kXBPJgqpmmepg (пароль 1).

      Удалить
    2. Спасибо за оперативный ответ! Всё скачал и открыл, буду изучать!

      Удалить
  4. Внимание! Отвечая на вопросы: да, работает и сейчас под Win7,8,10/64bit. Единственное и важное условие - порог срабатывания библиотеки должен быть > уровня фонового шума, иначе запись будет бесконечно и распознавания вы не дождетесь. То же касается всех проектов с использованием библиотеки, например контроля Arduino или AIMP-плеера.

    ОтветитьУдалить

В комментариях уважайте собеседника, внимательно читайте посты и не додумывайте. Просьбы и предложения из разряда: «можно ваш Skype/Viber/телефон», «напишите мне в vk/FB», а также другие им подобные — игнорируются. Выход новых версий ПО, внешняя ссылка, переставшая работать с течением времени и т.п. не является основанием для претензий. Желающие спокойно подискутировать и высказаться — Welcome. Желающие спонсировать блог — Donate. Нарушение этих простых правил ведет к бану и удалению комментариев без предупреждения.