Text-To-Speechで発話終了イベントが飛んでこない

Text-To-Speech Engineを触ってみているのだけれども、その発話終了イベントである、 OnUtteranceCompletedListener が返ってこない、という現象に遭遇しました。

いろいろ調べた結果、こういう風になりました。

// ttsオブジェクトを作成
TextToSpeech tts = new TextToSpeech(getApplicationContext(), new OnInitListener() {
        public void onInit(int status) {
            // 発話終了のListnerを登録
            tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
                    public void onUtteranceCompleted(String utteranceId) {
                        Log.d(TAG, "Speech Completed! :" + utteranceId);
                    }
                });
        }
    });

// UTTERANCE_IDを入れる
HashMap<String, String> param = new HashMap<String, String>();
param.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, id);

// 発話
tts.speak(ttsText, TextToSpeech.QUEUE_ADD, param);

ポイントは以下の二つでした。

  • 1. onInitの中で setOnUtteranceCompletedListener を呼ぶ
  • 2. UTTERANCE_IDを入れる


1. の理由はText-To-Speechエンジンは初期化にかなり時間がかかるのに、初期化が終了した後でないと setOnUtteranceCompletedListener が有効にならないみたいなのです。なので、onInitで確実に初期化後に呼び出されるようにします。

2. はなぜかは不明(ソース嫁ですよね…)ですが、 UTTERANCE_IDを設定しないと、 OnUtteranceCompleted が呼ばれないようです。また、OnUtteranceCompletedの引数であるutteranceIdにはここで設定したidが入って返ってきます。

何度か試したのですが、エミュレータだとやはりかなり重いです。実機だともうちょっと早くなるかもですけど。

Android用日本語音声合成ライブラリ

日本語音声読み上げは、東芝の人がAndroidのイベント「Android Bazaar」でデモしていたそうです。

また、AQUESTという会社からも日本語音声合成のライブラリが出ているみたいです。β版およびサンプルプログラムは無償でダウンロードできるようです。

日本語音声合成生成サービス

決まった音声を出力するだけであれば、Studio To Speakというサイトで、音声合成して結果をwavで受け取ることができます。いろいろなキャラクターで音声を設定できたりするので便利なのではないでしょうか。

ただし、

本サービスまたは合成音声データを使用した営業活動(その準備行為、予備行為を含みます。)を行なってはならないものとします。

利用規約にありますので、おそらく有料アプリケーションに使うことはできないと思います。