Синтез и распознавание речи от Google для Asterisk

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

Сразу переписал предложенный вариант на свою любимый php и оформил в виде AGI для вызова из Астериска. Хотел чтобы синтез можно было использовать одной строкой в диалпланет, как стандартную команду SayDigits():

Пример использования в extensions.ael:

s => { Answer();

Wait(1);

AGI(say.php,"Здравствуйте");

AGI(say.php,"Вас приветствует компания");

AGI(say.php,"Vasily!",en);

AGI(say.php,"Ваш звонок важен для нас!");

AGI(say.php,"Пожалуйста!");

AGI(say.php,"оставайтесь на линии");

AGI(say.php,"Вам обязательно ответят!");

 

};

И сам php код (должен быть /var/lib/asterisk/agi-bin/say.php):


#!/usr/bin/php -q

<?php

$agivars = array();

while (!feof(STDIN)) {

$agivar = trim(fgets(STDIN));

if ($agivar === '')

break;

 

$agivar = explode(':', $agivar);

$agivars[$agivar[0]] = trim($agivar[1]);

}

extract($agivars);

 

$text = $_SERVER["argv"][1];

if (isset($_SERVER["argv"][2])) $lang = $_SERVER["argv"][2];

else $lang = 'ru';

 

$md5 = md5($text);

 

$prefix = '/var/lib/asterisk/festivalcache/';

$filename = $prefix.$md5;

 

if (!file_exists($filename.'.alaw')) {

$wget = 'wget -U "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5" ';

$wget.= '"http://translate.google.com/translate_tts?q='.$text.'&tl='.$lang.'" -O '.$filename.'.mp3';

$ffmpeg = 'ffmpeg -i '.$filename.'.mp3 -ar 8000 -ac 1 -ab 64 '.$filename.'.wav -ar 8000 -ac 1 -ab 64 -f alaw '.$filename.'.alaw -map 0:0 -map 0:0';

$exec = $wget.' && '.$ffmpeg.' && rm '.$filename.'.mp3 '.$filename.'.wav';

exec($exec);

}

 

echo 'STREAM FILE "'.$filename.'" ""'."\n";

fgets(STDIN);

exit(0);

?>


В моем Asterisk основным кодеком является alaw, по этому mp3 конвертирую сразу в alaw.

После 10 минут восторга, я вспомнил, что у Google есть возможность распознавать речь (как в поиске с мобильного телефона). Полазил по интернетам и нашел статью Управление голосом. Распознавание русской речи, где лежит пример на php для распознавания речи средствами Google.

Переписал код в форму AGI и получил (/var/lib/asterisk/agi-bin/voice.php):

#!/usr/bin/php -q

<?

$agivars = array();

while (!feof(STDIN)) {

$agivar = trim(fgets(STDIN));

if ($agivar === '')

break;

 

$agivar = explode(':', $agivar);

$agivars[$agivar[0]] = trim($agivar[1]);

}

extract($agivars);

 

$filename = $_SERVER["argv"][1];

 

exec('flac -f -s '.$filename.'.wav -o '.$filename.'.flac');

 

$file_to_upload = array('myfile'=>'@'.$filename.'.flac');

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL,"https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=ru-RU");

curl_setopt($ch, CURLOPT_POST,1);

curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: audio/x-flac; rate=8000"));

curl_setopt($ch, CURLOPT_POSTFIELDS, $file_to_upload);

curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);

$result=curl_exec ($ch);

curl_close ($ch);

 

$json_array = json_decode($result, true);

$voice_cmd = $json_array["hypotheses"][0]["utterance"];

 

unlink($filename.'.flac');

unlink($filename.'.wav');

 

echo 'SET VARIABLE VOICE "'.$voice_cmd.'"'."\n";

fgets(STDIN);

echo 'VERBOSE ("'.$voice_cmd.'")'."\n";

fgets(STDIN);

exit(0);

?>

Google Speech API принимает звуковые файлы в формате flac и speex, из примера оставил flac.
В переменную ${VOICE} будет установлен распознанный текст.

Общий пример использование в extensions.ael:

s => {

Answer();

Wait(1);

AGI(say.php,"Здравствуйте");

AGI(say.php,"Пожалуйста");

AGI(say.php,"Скажите имя сотрудника");

Record(/tmp/${UNIQUEID}.wav,3,20);

AGI(say.php,"Вы сказали");

Playback(/tmp/${UNIQUEID});

AGI(voice.php,/tmp/${UNIQUEID});

AGI(say.php,"Система услышала");

AGI(say.php,"${VOICE}");

Hangup();

};

Record записывает wav файл максимальной длиной 20 секунд и заканчивает запись после 3 секунд тишины.
Так как это тестовый пример мы прослушиваем сказанное и потом синтезируем распознаный текст.

Что можно сказать, Google — молодцы!
Теперь понятно как чистый Asterisk обучить синтезу и распознаванию речи, без использования Festival и Sphinx.

И если начальство попросит быстро сделать голосовую IVR менюшку, мы сможем удивить!

P.S.
Версия 2.0
say.php с возможностью синтеза речи через Microsoft Translator:


#!/usr/bin/php -q

<?php

$agivars = array();

while (!feof(STDIN)) {

$agivar = trim(fgets(STDIN));

if ($agivar === '')

break;

$agivar = explode(':', $agivar);

$agivars[$agivar[0]] = trim($agivar[1]);

}

extract($agivars);

 

$text = $_SERVER["argv"][1];

if (isset($_SERVER["argv"][2]) && in_array($_SERVER["argv"][2], array('g','m'))) $voice = $_SERVER["argv"][2];

else $voice = 'g';

if (isset($_SERVER["argv"][3])) $lang = $_SERVER["argv"][3];

else $lang = 'ru';

 

$md5 = md5($text.$voice.$lang);

 

$prefix = '/var/lib/asterisk/festivalcache/';

$appid = 'T0CQJrrwQ1NcJFlJshEfWTzaI18B4TzVvBKx9CDoLvf8*';

$filename = $prefix.$md5;

 

if (!file_exists($filename.'.alaw')) {

if ($voice == 'm') {

$ext = '.wav';

exec('wget "http://api.microsofttranslator.com/V2/Http.svc/Speak?language='.$lang.'&format=audio/wav&options=MaxQuality&appid='.$appid.'&text='.$text.'" -O '.$filename.$ext);

} else {

$ext = '.mp3';

exec('wget -U "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5" "http://translate.google.com/translate_tts?q='.$text.'&tl='.$lang.'" -O '.$filename.$ext);

}

 

if (@filesize($filename.$ext) > 0) {

exec('ffmpeg -i '.$filename.$ext.' -ar 8000 -ac 1 -ab 64 -f alaw '.$filename.'.alaw -map 0:0');

}

 

unlink($filename.$ext);

}

 

if (file_exists($filename.'.alaw')) {

echo 'STREAM FILE "'.$filename.'" ""'."\n";

fgets(STDIN);

} else {

echo 'VERBOSE ("Speech Error!")'."\n";

fgets(STDIN);

}

exit(0);

?>


Microsoft отдает звук в формате wav (у mp3 качество нулевое) и просит какой-то Bing AppId (взял с сайта microsofttranslator.com, посмотрим сколько проживет).
Качество синтеза мне показалось хуже чем у Google, но ударение в именах ставит более правильно.

AGI(say.php,»Здравствуйте»,m);

 

AGI(say.php,»Здравствуйте»,${ГОЛОС},${ЯЗЫК});

${ГОЛОС} — может быть m или g (если опустить = g)

${ЯЗЫК} — ru, en и прочее (если опустить = ru)

Русский текст будет работать только при ru, английский будет всегда, но при ru будет «ломаным».
В тексте работают ударения (‘ перед гласной) и знаки препинания (например !) меняют интонацию.

PS: Заменил, что распознавание речи может выдавать пустой текст, но при повторной отправке того же файла, все проходит гладко, странно это 🙂

Вы можете следить за ответами к этой записи через RSS.
Вы можете оставить отзыв или трекбек со своего сайта.

Ваш отзыв

К сожалению, по вашему запросу ничего не найдено.