Droid君に「ダァシェリイェス」としゃべらせてみる。

本エントリは、「Android Advent Calendar2011」という企画の1エントリに参加しています。このエントリは人気があり、裏バージョンも存在しています。私は、追加募集された裏バージョンの3日目に参加しています。

軽い気持ちで参加しましたが、初日、2日目、ともにエントリがハードな内容であったため、当初の方針の変更を試みましたが、力量不足のため中途半端なエントリになってしまいましたことをお断りしておきます。

・はじめに
ダァシェリイェス」は、特定のクラスタでは、伝説となっている単語です。Androidクラスタでは、「ジャッジメントですの!」や「ティロ・フィナーレ」のほうが受けがよいかと考えていましたが、音声合成のVoiceデータがアナウンサ調のためやめました。

早速ですが、実際のダァシェリイェスの合成音を効いてみてください。

私自身実際に「ダァシェリイェス」を聞いたことがありませんので、今回は想像をもとに、東芝日本語エンジンとTTSクラスを用いて、ダァシェリイェス合成音ファイルを作成しています。

Android用音声合成APIについて
 Google音声認識は、その完成度の高さから非常に人気のあるAPIです(実際はIntentで呼び出します)。それに比べて音声合成のAPIは、いまひとつぱっとしません。
音声合成は、API Level4から提供されている機能ですが、使用したことがない人が多数かと思います。
 大きな原因は、しばらく日本語エンジンが提供がされていないことかと思われましたが、昨年から有料ですが、日本語の音声合成エンジンがマーケットで提供され始められています。
また、今年の夏からは、無料の音声合成エンジンが提供されるなど状況は少しずつ変化してきました。なお、音声合成は、TTS(TextToSpeach)とも呼ばれます。

以下に現在入手可能である日本語エンジンを示します。

最初の2つは有料です。私は購入していませんので、そのクオリティに関してはわかりません。一方、N2 TTSは無料です。どの端末にもインストールできますが、音声合成のクライアントアプリを別途インストールしないと、サンプル以外の合成音以外を聞くことはできません。個人的感想ですが、ところどころなまっている気がします。(Google 翻訳で読み上げられる日本語に近いです)

最後に、一般には手に入れることはできませんが、ToshibaのRegzaTabletには、東芝音声合成エンジンがプリインストールされています。個人的にはこちらのほうが、品質が高い気がします。それでも少しなまりはあります。

・基本的使い方
前置きが長くなりましたが、Androidのリファレンスを開き、android.speech.ttsのTextToSpeechのクラスを参考に読み進めてください。
基本的な使用方法は、TechBoosterさんの「テキストの読み上げ(TextToSpeech)を利用する」を見てください。私の説明より、わかりやすい記事かと思います。

・Tips
このままでは、あまりにも内容のないエントリになってしまうので、Tipsなどを紹介します。

・発話完了イベント
当初このイベントが生じなく、かなりの期間悩みました。ポイントは2点あります。
最初にイベント通知を受け取るハンドラを作成しておきます。

1つ目のポイントは、setOnUtteranceCompletedListenerの登録は、初期化時ではなく、初期化完了イベントの後に行うことです。

    mTts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
        public void onUtteranceCompleted(String utteranceId) {
            Message m = Message.obtain(mHandler,MESSAGE_ID);
            mHandler.sendMessage(m);
        }
    });
    MESSAGE_IDは、識別用のIDですので、ユニークな任意の値で構いません。

2つめのポイントは、発話時のパラメータに、KEY_PARAM_UTTERANCE_IDの値を加えておくことです。

        HashMap<String, String> param = new HashMap<String, String>();
        param.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, ID);
        mTts.speak(mText, TextToSpeech.QUEUE_FLUSH, param);

この2点を守らないと作成したハンドラは、完了メッセージを受け取ることができません。

・wavファイルへの書き出し
synthesizeToFile(String text, HashMap<String, String> params, String filename)を使用します。通常、HashMap<String, String> paramsは、nullでかまいません。サンプルファイルも、これで作成しています。

・話者切り替え
言語切り替えは、setLanguageが準備されていますが、話者の切り替えは、メソッドが準備されていません。切り替えたい場合は、Intentで設定画面を呼び出すか、自分で設定画面を開いて、手動で切り替えることになります。
また、現在の話者に関する情報を取得するメソッドもありません。

・エンジンの切り替え
合成エンジンは、複数登録することができます。たとえば、RegzaTabletにN2 TTSエンジンもインストールできます。当初、合成エンジンも話者切り替え同様に、設定画面経由で切り替える必要がありました。
正確には、API Level8からsetEngineByPackageNameが使用できたようですが、API Level14で deprecatedになりました。API Level14では、TTSコンストラクタでエンジンの指定を行うことになっています。

・PitchとSpeechRateに関して
setPitch、setSpeechRateで値を指定しますが、変数の範囲が0.5から2までと変則的な値です。デフォルトは1です。

・読み上げ音声の品質をあげるために
音声合成エンジン一般に言えることですが、時々漢字を読み間違えるます。そのような場合はひらがなに直すか、東芝エンジンの場合、個人辞書に読みを登録する必要があります。またイントネーションがおかしい場合には、句点やスペースで区切るとなおる場合があります。

・エンジンの差異
エンジンの仕様としては、メソッドのみ規定されており、実装は各ベンダーに任されています。その弊害として以下のことが生じています。

1 エンジンごとに合成音の音量が異なります。そのためエンジンを切り替えると、スピーカの音量の調整が必要になります。
2 エンジンごとに同じパラメータでもピッチやレートの変化量が異なります。そのため、あるエンジンに調整した値を他のエンジンで使用すると、所望の合成音を得ることができません。

・サンプル音
ここまで読んでみても、音声合成がどのようなものかわかりづらいと思いますので、N2 TTSと東芝音声合成エンジンで作成したwavファイルのリンクを示します。興味のある人は、それぞれ再生してみてください。

読み上げる文章は、youtenさんのQAの文章を拝借しました。
原文は「まじめなエントリもネタなエントリもどちらも大歓迎です。ただし、ふらりと立ち寄った方のために、一般的に分かりやすいエントリでお願いします。
ですが、このまま再生すると、少し違和感が生じましたので、以下のように修正しています。
まじめなエントリーも、ネタなエントリーも、どちらも大歓迎です。ただし、ふらりと立ち寄ったかたのために、一般的に、分かりやすいエントリーでお願いします。

N2 TTS 女性
N2 TTS 男性
東芝 女性
東芝 男性

いづれデフォルトのパラメータで作成しています。

・おまけ
タイトルには、Droid君がしゃべるとなっているが、しゃべっているのは、RegzaTabletじゃないかとの突っ込みを受けそうなので、しゃべるDroid君を紹介します。

この前、秋葉原でみつけたDroid君の形をしたスピーカです。筐体は、あのDroid君人形をデッドコピーしたと思われるアジアンテーストあふれる品物です。天井部にスピーカー用の穴があいており後ろから、イヤフォンケーブルと給電用のUSBケーブルが出ています。音質はいまひとつですが、値段はDroid君人形と同等でしたので、お得な気がしています。

これで私のエントリは終了です。最後に、日本勢メーカの絶滅が危惧される中、来年もこの企画があることを祈っています。