ラズベリーパイに日本語で喋らせる[その1]Google Cloud Text-To-Speech


夜な夜なRaspberryPI搭載のVoice Kit V2で遊んでます。今回はGoogleのText−To-Speech APIを使用して、こいつにテキストを読み上げさせてみます。なおここで実装しているサンプルはVoice Kitだけでなく通常のRaspberry PiやLinuxでも動きます。(Macでも少し手を加えればOK)

前段

↓楽しいVoice Kit↓

Voice Kit同梱のaiyライブラリというものがあり、これを使用すれば一応ラズパイに喋らせることはできるのですが、無残にもこのText−To-Speech(以下TTS)ライブラリがまだ日本語に対応していないという。サポートされてるのヨーロッパ言語のみ・・・。ちきしょう。

しかし、GoogleのText−To-Speech API自体は日本語に対応しているので、そちらを直接叩くことで日本語で話させることができます。Text−To-Speech APIは無料ではないので気になる料金面から実装サンプルまで調べてみました。

Google Text-To-Speech API

その名の通り、テキストをスピーチ(音声)に変換する読み上げAPIです。文字列投げたら音声ファイルにして返してくれるイメージですね。大変便利なAPIなんですが無料では使えません。料金詳細については公式を見ていただくとして・・・

料金

ポイントはここですね(2020.03.03現在)

機能 1 か月あたりの無料枠 有料使用
標準(非 WaveNet)音声 0〜400 万文字 100 万文字あたり $4.00(USD)
WaveNet 音声 0〜100 万文字 100 万文字あたり $16.00(USD)

1ヶ月に変換させた文字数で決まるみたいです。非WaveNetとWaveNetで料金が違います。WaveNetとは一言で言うと『自然な音声』でして、Google HomeやAndroidのGoogleアシスタントで使用されている音声がそれです。こっちの方が料金が高いです。しかしGoogle様のご厚意により太っ腹な無料枠が用意されているので、ちょこちょこっと利用するぐらいなら無料枠で収まりそうですね。

ちなみにどんな音声なのか公式サイトで実際に聞くことができます。

サポートされている音声と言語

日本語は男性・女性、それぞれ非WaveNetとWaveNetで2種類ごとあるようですね。

WaveNetの方が自然で音声もクリアな気がします。でも非WaveNet(Standard)もそんなに悪いもんじゃないですね・・。

ではText−To-Speechを

やりましょう。しかし実装前に準備が必要です。全部公式に書いてます。

クイックスタート: クライアント ライブラリの使用

まずはGoogle Cloud Platformお約束の認証キーのダウンロードです。上記公式の通りに実施してください。手順の概要を書いておくと、

  1. GCPでプロジェクトを作成(もしくは既存のものを選択)
  2. 課金が有効になっているか確認(要はクレジットカードの登録です)
  3. Cloud Text-to-SpeechAPIを有効化する
  4. サービスアカウントキーを作成する
  5. キーファイル(JSON)をダウンロード

とこんな感じ。

その後も公式に書いてある通りですが、まずは環境変数を通して

$ export GOOGLE_APPLICATION_CREDENTIALS="JSONファイルのパス"
fish shellなら↓
$ set -x  GOOGLE_APPLICATION_CREDENTIALS "JSONファイルのパス"

pipでライブラリをインストールします。(環境によってはpip3で)

$ pip install --upgrade google-cloud-texttospeech

準備は以上で完了です。

Text-To-Speechサンプル

ではサンプルです。これは公式のものと違って日本語対応してます。

📄サンプル
#!/usr/bin/env python3
import sys
import subprocess
from google.cloud import texttospeech

client = texttospeech.TextToSpeechClient()
voice = texttospeech.types.VoiceSelectionParams(
    language_code='ja-JP',
    name='ja-JP-Wavenet-D')
audio_config = texttospeech.types.AudioConfig(
    audio_encoding=texttospeech.enums.AudioEncoding.LINEAR16)

while True:
    print('何か入力してエンターを押してね(CTRL+Cで終了)')
    synthesis_input = texttospeech.types.SynthesisInput(text=input())
    response = client.synthesize_speech(synthesis_input, voice, audio_config)
    with open('output.wav', 'wb') as f:
        f.write(response.audio_content)
    subprocess.run(['aplay', 'output.wav'])

実行してしばらく待つと入力が促されるので何か入力してエンターキーを押します。すると入力された文字列をAPIに投げ、返ってきた音声ファイルをWAVで保存、再生するという流れです。

保存したWAVファイルは aplay というコマンドで再生しています。ALSAドライバを使用しているラズパイなら問題なく動くと思いますが、他のディストリビューションやMacなどでは動かないと思うので、適宜wavを再生できるコマンドに置き換えるなどしてください。

なおVoice Kitなら、いちいちWAVファイルに落とさなくても、バイトストリームから直接再生できます。

📄Voice Kit版
#!/usr/bin/env python3
import sys
import subprocess
from google.cloud import texttospeech
from aiy.voice.audio import play_wav

client = texttospeech.TextToSpeechClient()
voice = texttospeech.types.VoiceSelectionParams(
    language_code='ja-JP',
    name='ja-JP-Wavenet-D')
audio_config = texttospeech.types.AudioConfig(
    audio_encoding=texttospeech.enums.AudioEncoding.LINEAR16)

while True:
    print('何か入力してエンターを押してね(CTRL+Cで終了)')
    synthesis_input = texttospeech.types.SynthesisInput(text=input())
    response = client.synthesize_speech(synthesis_input, voice, audio_config)
    play_wav(response.audio_content)

ソースを見ればそんなに難しくないと思いますが、

  • VoiceSelectionParamsのコンストラクタで、言語と音声を設定できる。音声は先程のリンク先から選ぶ
  • audio_encodingでLINEAR16またはMULAWを選ぶとWAVで保存できる(公式サンプルの通りMP3にすると再生が面倒なんです)
  • SynthesisInputでtextを渡しているがSSMLでも渡せる

SSMLとは音声のマークアップ言語です。

音声合成マークアップ言語(SSML)

実物を見れば分かると思いますが、テキストを音声に変換する際、ここは強調してとか、ここで1秒休んで、とか、そういった細かな指示をするための言語みたいです。凝った音声を作りたければ便利そうですね。ただし料金は発話する文字数ではなくAPIに渡す文字数なので、SSMLを使った方が当然文字数は増えます。といっても短い文章を喋られせるぐらいならあまり神経質にならなくても大丈夫そうですがね・・・。一度作った音声ファイルを保存しておけば何度再生しても料金は発生しませんしね。

 

いやはや、なんとかこれでかなりナチュラルな音声発話ができるようになりました。

次回はこれのAmazon版であるAmazon Pollyを検証してみたいと思います。

関連する記事


コメントする

メールアドレスが公開されることはありません。

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください