アスタリスクのGoogle音声合成および認識

おはようございます



昨夜、Habrを見て、 Googleの記事の翻訳+アスタリスクIVRを見ました。私の脇の下で髪が動いていました。



音声合成、それは簡単です!

Festivalを収集してサンプルを探す必要はありません。 すべてが用意されており、シンプルで、Googleから提供されています。





すぐに提案されたオプションをお気に入りのphpにコピーし、Asteriskから呼び出すためにAGIの形式で設計しました。 標準のSayDigits()コマンドとして、 ダイアルプラネットの単一行として合成を使用することを望みました。



extensions.aelでの使用例:

s => { Answer(); Wait(1); AGI(say.php,""); AGI(say.php,"  "); AGI(say.php,"Habrahabr!",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); ?>
      
      





私のアスタリスクでは、メインのコーデックはalawなので、すぐにmp3をalawに変換します。



10分間の喜びの後、私はGoogleが音声を認識できることを思い出しました(携帯電話からの検索のように)。 インターネットに登って、 音声コントロールの記事を見つけました Googleを使用した音声認識のphpの例にあるロシア語音声の認識



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の例から、flacおよびspeex形式のサウンドファイルを受け入れます。

認識されたテキストは変数$ {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は、最大20秒のwavファイルを記録し、3秒の無音後に記録を終了します。

これはテストケースであるため、言われたことを聞き、認識されたテキストを合成します。



グーグル-よくできました!

これで、FestivalとSphinxを使用せずに純粋なアスタリスクが合成と音声認識をどのように教えることができるかが明らかになりました。



当局が音声IVRメニューをすばやく作成するように要求した場合、私たちはあなたを驚かせることができます!



によって追加されました



ユーザーのコメント int80hを読み、Google Translate APIからBing Translate APIへの移行について読んで、すべてに代替手段が必要だと考えました。



バージョン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); ?>
      
      





マイクロソフトはwav形式(mp3品質はゼロ)でサウンドを提供し、Bing AppIdを要求します(microsofttranslator.comから取得しました。存続期間を確認しましょう)。

合成の品質はGoogleよりも劣っているように見えましたが、名前の強調がより正確になっています。



 AGI(say.php,"",m); AGI(say.php,"",${},${}); ${} -   m  g (  = g) ${} - ru, en   (  = ru)
      
      





ロシア語のテキストはruでのみ機能し、英語では常に機能しますが、ruでは「壊れた」状態になります。

アクセントはテキスト( '母音の前)と句読点(たとえば!)で機能しますイントネーションを変更します。



PS:音声認識が空のテキストを生成する可能性があることを置き換えましたが、同じファイルを再度送信すると、すべてがスムーズに進み、これは奇妙です:-)



All Articles