Google TTSを利用してAsteriskのIVRで日本語読み上げ

phone
© Mathew MacQuarrie.

実は電話が大の苦手なのでプライベートで発信することはほぼありえないし必要最低限以下しか受けない。電話をかける方は自分次第だが、受ける方は自分の都合ではないのでかかってきてしまったものは仕方ない。でも、受けたいわけではないのでIP電話のPBXのAsteriskにIVRで対応させて、どうしても用事がある人の電話だけを取り次いで貰うようにしている。そのときに、イエデンを鳴らすと共に携帯やタブレットも鳴らすようにしているので取次ぎ漏れが少なくなるようにしている。(電話受けたくないといいつつ矛盾してるけど)

で、これまでIVRのメッセージはSVOXに喋らせて音声ファイルとして用意したり、Festival Speech Synthesis System(とFestvox)とAsteriskを連携させて英語のTTSをローマ字+工夫で無理やり日本語っぽく喋るようにしていた。
特にFestivalは英語を喋るようにするまでが一苦労だし、Asteriskとの連携も大変だし、無理やり日本語っぽく喋らせるのも難しい。しかも苦労も虚しくはっきりした日本語にはならないので何て言ってるのかわからないと言われる始末。むしろAndroidのSVOXに喋らせたのを音声ファイルにして再生する方が少しのたどたどしさと時々交じる変なイントネーションさえ我慢すれば日本語としては遥かに聞きやすい。

まぁ、TTSで日本語を喋れるのは限られるしLinuxやFreeBSDで動くものは皆無で、まともに喋るのはかなりお高い商用だったりするので個人で気軽に導入できるようなものではなく、これまでは半分諦めていた。

ところが、今回偶然みつけたGoogle TTSを利用するAGIは凄い。サーバー側で必要とするものはとても少なく、嘘みたいにあっけなく簡単に明瞭な日本語を喋らせることができる。もう目から鱗がポロポロポロってくらいよ。

GitHub: https://github.com/zaf/asterisk-googletts
説明: Text to speech for asterisk using Google Translate

ページの説明はとても少ないけどそれでも十分にわかるほど簡単。
ページ下部のDownloadからファイルを取ってきて解凍し、Asteriskのagi-binのディレクトリにgoogletts.agiを置くだけ。この1ファイルだけで良い。
FreeBSDのportsやパッケージでAsteriskをインストールしたならagi-binは/usr/local/share/asterisk/agi-bin、Linuxは流儀次第だけど/var/lib/asterisk/agi-binとか?
googletts.agiはperlのスクリプトだけど特に変更は必要無さげ。

その他に必要なものは説明に書いてある通りなので全部用意する。
FreeBSDだと以下のようにインストール。

# cd /usr/ports/lang/perl5.20
# make instatll clean

# cd /usr/ports/www/p5-libwww
# make install clean

# cd /usr/ports/security/p5-Crypt-SSLeay
# make install clean

# cd /usr/ports/audio/sox
# make install clean

# cd /usr/ports/audio/mpg123
# make install clean

最初のperlは他のportsを入れたときに依存関係で既に入ってるかも。上の例ではperl5.20にしてるけど他のバージョンの方が良ければそれで。sox作成時に依存関係を満たすためにサウンド関係の他のportsが一緒に入ることになるが、オプション決定のメニューが表示されたら基本的にはデフォルトの選択オプションのまま[Enter]で構わない。

あとはAsteriskのダイヤルプランの編集。

/usr/local/etc/asterisk/extensions.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
exten => 1234,1,Answer()
exten => 1234,n,Wait(1)
  ;;Play mesage in English:
exten => 1234,n,agi(googletts.agi,"This is a simple google text to speech test in english.",en)
  ;;Play message in Spanish:
exten => 1234,n,agi(googletts.agi,"Esta es una simple prueba en español.",es)
  ;;Play message in Greek:
exten => 1234,n,agi(googletts.agi,"Αυτό είναι ένα απλό τέστ στα ελληνικά.",el)
  ;;Play message in Japanese:
exten => 1234,n,agi(googletts.agi,"これは、日本の簡単なテストです。良い一日を。",ja)
  ;;Play message in simplified Chinese:
exten => 1234,n,agi(googletts.agi,"这是一个简单的测试,在中国。有一个愉快的一天。",zh-CN)
exten => 1234,n,agi(googletts.agi,"昨日、近所の吉野家行ったんです。吉野家。",ja)
exten => 1234,n,agi(googletts.agi,"そしたらなんか人がめちゃくちゃいっぱいで座れないんです。 ",ja)
exten => 1234,n,agi(googletts.agi,"で、よく見たらなんか垂れ幕下がってて、150円引き、とか書いてあるんです。 ",ja)
exten => 1234,n,agi(googletts.agi,"もうね、アホかと。馬鹿かと。 ",ja)
exten => 1234,n,agi(googletts.agi,"お前らな、150円引き如きで普段来てない吉野家に来てんじゃねーよ、ボケが。 ",ja)
exten => 1234,n,agi(googletts.agi,"150円だよ、150円。 ",ja)
exten => 1234,n,agi(googletts.agi,"なんか親子連れとかもいるし。一家4人で吉野家か。おめでてーな。 ",ja)
exten => 1234,n,agi(googletts.agi,"よーしパパ特盛頼んじゃうぞー、とか言ってるの。もう見てらんない。 ",ja)
exten => 1234,n,Congestion(10)
exten => 1234,n,Hangup()

上は先の説明ページのサンプルにちょい付け足しただけ。
これをextensions.confの[default]の中の番号別内線関係あたりに挿入する。
あとはAsteriskを再起動するなりダイヤルプランだけ再読込させるなりで終わり。
たったこれだけで日本語で喋ってくれる。(他の言語も)

内線1234にかけると開始時に1秒待って一方的に喋って最後にプ-プ-プ切断待ち(切断)で終わり。
それは応答しただけでIVRじゃないだろというツッコミは無しで。説明ページのもう一つのサンプルがIVRだけど、読み上げの部分は結局同じ。

聞いてみればわかるけど漢字は日本語TTSでよくあるように盛大に読み間違える。だから漢字はそのまま書くより平仮名に直すなりした方が良い。あと、イントネーションも無茶苦茶な部分がある。やはり平仮名にするとマシになる。でも数字は例えば上の例だと150は「いち・ご・ぜろ」ではなくちゃんと「ひゃくごじゅう」と読んでる。声は明瞭だけど標準設定だと読み上げ速度がのんびりしすぎてるかな。

googletts.agiをエディタで開き最初の方にある$speedを標準の1から1.3 から1.5程度に変更する。これで普通の速度になる。

my $speed = 1.5;

googletts.agiを書き換えずにextensions.confから読み上げ速度の指定ができるかどうかは不明。

で、説明ページのリンクを見ると書いたテキストを翻訳して読み上げるとかテキストファイルを読み上げるとかもできるみたい。Googleの音声を認識してテキストにするAPIを使うスクリプトも用意されているみたいで、気づいてないけどもしかしたらいろいろとんでもなく凄いのかも。

続く

関連記事: