вторник, 22 ноября 2016 г.

Модификация интерактивного голосового переводчика (библиотека SpeechTranslateSpeech3.DLL)

В связи с частыми банами десктопных приложений, использующих сервис API Google Translate, было решено перевести модуль перевода ранней версии библиотеки - интерактивного голосового переводчика на API Yandex Translate. Модификация библиотеки (далее DLL) предназначена для голосового интерактивного перевода речевых фраз и предложений OFFTIME или REALTIME в автоматическом режиме, по задаваемым пользователем пороговому уровню, языку оригинала, языку перевода и задержке отслеживания окончания фразы (триггера "тишины").

Функционал интерактивного перевода включает: авто-отслеживание голоса, распознавание, перевод, озвучивание на языке перевода и перенаправление аудиопотока на заданное аудиоустройство. Что дает возможность перенаправления аудиопотока? Фактически данный голосовой переводчик можно использовать не только локально для себя, но и для интерактивного перевода речи удаленного абонента в VoIP приложениях (к примеру, вы говорите на русском, данный аудиопоток библиотекой после распознавания, перевода, речевого синтеза перевода перенаправляется голосовым переводчиком на заданное аудиоустройство, которое является входом по-умолчанию для VoIP приложения (допустим Skype), и абонент слышит уже перевод, скажем на итальянском). Для реализации данного режима потребуется с помощью VAC (Virtual Audio Cable*) создать следующую цепочку: голосовой переводчик -> виртуальный выход - виртуальный вход -> VoIP приложение. Два таких голосовых переводчика, установленных у двоих разноязычных абонентов, позволяют общаться им друг с другом на своих родных языках в псевдо REALTIME.
* 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/XE):
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(filename,                   // путь-имя файла для распознавания
                            myLang,                     // язык распознавания
                            toLang: pansichar;          // язык перевода
                            var
                            full_answer_google,         // полная строка ответа от сервиса
                            recognize_flag,             // признак распознавания
                            recognize_text: pansichar;  // распознанный текст
                            var
                            recognize_accuracy: integer;// достоверность распознавания, %
                            mcidx: boolean;             // режим воспроизведения потока MCI/DirectSound на заданное аудиоустройство
                            devnum: integer             // индекс аудиоустройства вывода
                            ); stdcall;

  start         : procedure(threshold_level,            // уровень порога срабатывания, %
                            delay_off:                  // задержка отключения, мс
                            integer;
                            myLang,                     // язык распознавания
                            toLang: pansichar;          // язык перевода
                            mcidx: boolean;             // режим воспроизведения MCI/DirectSound на аудиоустройство
                            devnum: integer             // индекс аудиоустройства вывода
                            ); stdcall;

  stop          : procedure; stdcall;
  setkey        : procedure(key: pansichar); stdcall;   // обновление API-ключа доступа
  set_thresholdlevel_delayoff_ruen: procedure(threshold_level,  // уровень порога срабатывания, %
                                              delay_off:        // задержка отключения, мс
                                              integer;
                                              myLang,           // язык распознавания
                                              toLang: pansichar;// язык перевода
                                              mcidx: boolean;   // режим воспр-я MCI/DirectSound на аудиоустройство
                                              devnum: integer   // индекс аудиоустройства вывода
                                              ); stdcall;


  LibHandle: THandle;

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

 start(100 - tr.Position,
       1000,
       pansichar(myLang.text),
       pansichar(toLang.text),
       false,
       0);
 end
...

{ примеры вызова }
// распознать OFFTIME из файла FLAC

var full_answer_google,          // полная строка ответа от сервиса
    recognize_flag,              // признак распознавания
    recognize_text: pansichar;   // распознанный текст
    recognize_accuracy: integer; // достоверность распознавания, %
begin
 memo1.Clear;

 recognize_flac('audio.flac',
                'ru',
                'it',
                full_answer_google,
                recognize_flag,
                recognize_text,
                recognize_accuracy);

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

// визуализация текущего уровня REALTIME (по таймеру или в потоке)
var temp: integer;
    //
    full_answer_google,          // полная строка ответа от сервиса
    recognize_flag,              // признак распознавания
    recognize_text: pansichar;   // распознанный текст
    recognize_accuracy: integer; // достоверность распознавания, %
begin
 if LibHandle<>0 then 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(recognize_flag);
   memo1.Lines.Add('Текст: ' + recognize_text);
   memo1.Lines.Add(format('Достоверность: %d', [recognize_accuracy]) + '%');
   memo1.Lines.Add('');
   memo1.Lines.Add(full_answer_google);
  end;
 end;
...

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

{ установка нового API-ключа }
begin
 setkey('bla-bla-bla');
...
Пример вызова из под VBS:
Dim Speak
speakon = true ' разрешаем голосовое сопровождение
Set Speak = CreateObject("sapi.spvoice")
' регистрируем COM объект DynamicWrapperX в тихом режиме
Dim WshShell
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run ("regsvr32.exe dynwrapx.dll /s"),3, true

' создаем объект DynamicWrapperX.2
Set Wrap = CreateObject("DynamicWrapperX.2")
Wrap.Register "user32.dll", "GetAsyncKeyState", "i=l", "f=s", "r=l"
Wrap.Register "SpeechTranslateSpeech3.dll", "start", "i=llssbl", "f=s", "r=s"

' озвучиваем
if (speakon = true) then
 Speak.Speak "Переводчик русской речи на английский запущен."
End if
res = Wrap.start(30, 1000, "ru", "en", 0, 0)

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

' озвучиваем
if (speakon = true) then
 Speak.Speak "Переводчик отключен."
End if
ПОРЯДОК ИСПОЛЬЗОВАНИЯ
  1. Для распознавания OFFTIME речевого фрагмента в формате FLAC используйте процедуру Recognize_Flac().
  2. Процедуры инициализации Start() и завершения Stop (без параметров) вызываются однократно в начале и окончании использования.
  3. Процедура Set_Thresholdlevel_Delayoff_Ruen() предназначена для изменения параметров (порогового уровня срабатывания триггера тишины, интервала отслеживания окончания фразы, языка распознавания и перевода-озвучивания) REALTIME.
  4. Процедура Recognize() вернет результаты распознавания отслеживаемой фразы по срабатыванию триггера тишины.
  5. На Windows Vista/7/8/8.1 (32/64 bit) запускать 'regdynwrapx.bat' правой кнопкой мыши от имени Администратора.
  6. В случае недействительности текущего API-ключа доступа следует установить новый перед вызовом процедуры инициализации потока Start().

РЕСУРСЫ ПО ТЕМАТИКЕ
  1. Описание API вызова библиотеки YandexSpeechRecognition.DLL
  2. Описание API вызова библиотеки GoogleSpeechRecognizeAPI3.DLL (под Windows синтез и распознавание)
  3. Описание API вызова библиотеки SpeechTranslateSpeech.DLL (переводчик с голосовым вводом на одном языке и речевым синтезом на другом)
  4. Голосовой контроль Wi-Fi розетки Kankun KK-SP3 через VoIP приложение Zello
  5. Голосовой контроль нагрузками HID устройства
  6. Голосовой контроль Arduino по беспроводному BlueTooth-каналу
  7. Голосовой контроль плеера AIMP
  8. Голосовой контроль-оффлайн на Arduino. Библиотека Uspeech (без модулей Voice Recognition for Arduino, без EasyVR, без GoogleSpeechRecognition API, все только средствами буратинки) 

скачать добро

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

  1. Уважаемый, как скачать это добро? Ссылка ведёт на http://radioliga.com, с требованием регистрации, а где там зарегистрироваться я не нашёл.

    Очень нужную вещь делаете, давно искал библиотеку на делфи, для преобразования голоса в текст.

    ОтветитьУдалить
    Ответы
    1. Нет там требования регистрации. Авторизация <> регистрация. Ошибка 403 = доступ запрещен.

      Удалить
  2. "давно искал библиотеку на делфи, для преобразования голоса в текст."
    - библиотека SpeechTranslateSpeech3.DLL не для этого заточена (она для голосового распознавания - перевода и синтеза перевода голосом). Для вашей цели больше подойдет >> YandexSpeechRecognizeAPI.DLL <<

    ОтветитьУдалить
    Ответы
    1. Поскольку yandex может быть в своем репертуаре, то вот библиотека GoogleSpeechRecognizeAPI3

      Удалить
  3. При распознавании из файла флак - он моментально удаляется и ответка приходит так же моментально "не распознано", не может так быстро отправляться файл и приходить ответ распознавания.

    ОтветитьУдалить
    Ответы
    1. Перешел в ОС Windows 7/64 bit. Скачал архив gsr3.zip, распаковал, запустил adminregOS32-64.bat. Настроил микшер на микрофон по-умолчанию, запустил демо, снял птичку с voice search (чтобы не ждать пока браузер запуститься, впрочем это и неважно). Подстроил уровень срабатывания, произнес "тест 1 2 3". Получил распознанный текст http://ipic.su/img/img7/fs/Bezymyannyj.1512984158.png

      Что я делаю не так? По поводу оффлайн-распознавания: в архиве *.flac файла нет, откуда вы его взяли и с каким битрейтом записывали? Flac касается только Google, Yandex работает с MP3. Cкорость отправки зависит от скорости вашего соединения с Интернетом, размер файла flac редко превышает пару десятков килобайт.

      Удалить
  4. 500 килобайт. как раз этот флак файл сгенерировался в Description API call library SpeechTranslateSpeech3.DLL - с моей записью голоса. Оттуда и взял.
    Да, после регистрации библиотек сработало. В гугле даже апи не нужно получать? Ограничений нет?

    ОтветитьУдалить
    Ответы
    1. 1- 500 кБ это порядка 20 сек записи, нехилое такое предложение по длительности )

      2- в архиве лежит полезный 'Описание API вызова библиотеки GoogleSpeechRecognizeAPI3.DLL.txt', который мало кто читает. В частности 'Порядок использования, пункт 1'. Подобная автоматическая единократная процедура нужна для копирования 32-х битной библиотеки в каталог SysWOW64 в 64-х битных системах и возможности ее исполнения в виртуальном окружении. Более подробно о данном механизме в ОС Windows можно почитать тут тут

      3- в библиотеку заложен механизм получения/парсинга актуального некоммерческого APIKEY, но можно задавать и свой.

      4- ограничение есть, как и всегда во всех бесплатных сервисах, по количеству запросов в сутки с одного IP c одним APIKEY. Далее GoogleAPI выставляет капчу и блокирует последующие запросы.

      Удалить

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