テキストの読み上げ(TextToSpeech)を利用する


今回はテキストの読み上げ機能(TextToSpeech)を説明します。

TextToSpeechはAndroid1.6から実装された機能で、その名の通り、音声合成を利用してテキストを読み上げる機能です。

テキスト読み上げ機能を利用したアプリケーションを使うにあたって注意することがあります。動作させる実機に音声データがインストールされている必要があります

インストールされているかどうかは、設定からテキスト読み上げ(音声合成などの場合もあり)を選択して確認できます。下の画像の用に音声データをインストールがグレーアウトされていない状態ですと、インストールされていませんので選択してインストールします。インストール自体はAndroidMarketからダウンロードして行います。

それでは説明に入ります。

TextToSpeechクラス

テキスト読み上げ、音声合成と聞くと難しく感じてしまうかもしれませんがAndroidではTextToSpeechというクラスが用意されており、簡単に利用することができます。

手順としては以下の通りです。

  1. オブジェクトの生成(初期化)
  2. 言語の設定
  3. 読み上げをする文章を指定してspeakメソッドを呼び出す

簡単ですね。

あとはアプリを終了する時に忘れずにリソースの破棄を行えばいいだけです。音声の速度や、声の高さ(ピッチ)も簡単に変更することができます。

オブジェクトの生成(初期化)

コンストラクタにコンテキストと初期化完了のリスナ(TextToSpeech.OnInitListener)を指定します。

1
TextToSpeech(Context context, TextToSpeech.OnInitListener listener)

onInitメソッドをオーバーライドして初期化完了のイベントを受け取ります。

1
void onInit(int status)

statusは成功の場合:TextToSpeech.SUCCESSが、失敗の場合:TextToSpeech.ERRORが渡されます。

言語(ロケール)の設定

初期化が成功した場合、次にロケールを設定します。

  • isLanguageAvailableメソッドで任意のロケールが利用可能か確認
  • setLanguageメソッドでロケールを設定
1
int isLanguageAvailable(Locale locale)

戻り値がTextToSpeech.LANG?AVAILABLE 以上の値であれば利用可能ですので、

1
int setLanguage(Locale locale)

で設定します。こちらの戻り値もisLanguageAvailableと同様に利用可能かどうかの値が返ってきます。

テキストの読み上げ

さて、実際にテキストの読み上げを行うには下記のメソッドを呼び出します。

1
int speak(String text, int queueMode, HashMap<String,String> params)

キューモードは以下の通りです。

  • TextToSpeech.QUEUE_ADD:再生キューへエントリを追加
  • TextToSpeech.QUEUE_FLUSH:再生待ちのエントリをドロップしてエントリを実行

パラメータは実行後に呼びされるメソッドの引数に渡す値などが設定できますが不要であればnullを指定することも可能です。詳細はドキュメントを参照してください。

サンプルソース

EditTextに入力した文字列を読み上げるサンプルです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package org.jpn.techbooster.sample;
 
import java.util.Locale;
import java.util.Queue;
 
import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
 
public class TextSpeechSample extends Activity
                                implements View.OnClickListener, TextToSpeech.OnInitListener {
    final private Float SPEECH_SLOW = 0.5f;
    final private Float SPEECH_NORMAL = 1.0f;
    final private Float SPEECH_FAST = 1.5f;
    final private Float PITCH_LOW = 0.5f;
    final private Float PITCH_NORMAL = 1.0f;
    final private Float PITCH_HIGH = 1.5f;
    private TextToSpeech    tts;
    private Button buttonSpeech;
    private Button buttonSlow;
    private Button buttonNormal;
    private Button buttonFast;
    private Button buttonLowPitch;
    private Button buttonNormalPitch;
    private Button buttonHighPitch;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        // ボタンのClickListenerの登録
        buttonSpeech = (Button)findViewById(R.id.ButtonSpeech);
        buttonSpeech.setOnClickListener(this);
        buttonSlow = (Button)findViewById(R.id.ButtonSlow);
        buttonSlow.setOnClickListener(this);
        buttonNormal = (Button)findViewById(R.id.ButtonNormal);
        buttonNormal.setOnClickListener(this);
        buttonFast = (Button)findViewById(R.id.ButtonFast);
        buttonFast.setOnClickListener(this);
        buttonLowPitch = (Button)findViewById(R.id.ButtonLowPitch);
        buttonLowPitch.setOnClickListener(this);
        buttonNormalPitch = (Button)findViewById(R.id.ButtonNormalPitch);
        buttonNormalPitch.setOnClickListener(this);
        buttonHighPitch = (Button)findViewById(R.id.ButtonHighPitch);
        buttonHighPitch.setOnClickListener(this);
 
        // TextToSpeechオブジェクトの生成
        tts = new TextToSpeech(this, this);
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != tts) {
            // TextToSpeechのリソースを解放する
            tts.shutdown();
        }
    }
 
    @Override
    public void onInit(int status) {
        if (TextToSpeech.SUCCESS == status) {
            Locale locale = Locale.ENGLISH;
            if (tts.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) {
                tts.setLanguage(locale);
            } else {
                Log.d("", "Error SetLocale");
            }
        } else {
            Log.d("", "Error Init");
        }
    }
 
    private void speechText() {
        String string = ((EditText)findViewById(R.id.EditTextSpeech)).getText().toString();
        if (0 < string.length()) {
            if (tts.isSpeaking()) {
                // 読み上げ中なら止める
                tts.stop();
            }
 
            // 読み上げ開始
            tts.speak(string, TextToSpeech.QUEUE_FLUSH, null);
        }
    }
 
    @Override
    public void onClick(View v) {
        if (buttonSpeech == v) {
            speechText();
        } else if (buttonSlow == v) {
            // 再生速度の設定
            tts.setSpeechRate(SPEECH_SLOW);
        } else if (buttonNormal == v) {
            // 再生速度の設定
            tts.setSpeechRate(SPEECH_NORMAL);
        } else if (buttonFast == v) {
            // 再生速度の設定
            tts.setSpeechRate(SPEECH_FAST);
        } else if (buttonLowPitch == v) {
            // 再生ピッチの設定
            tts.setPitch(PITCH_LOW);
        } else if (buttonNormalPitch == v) {
            // 再生ピッチの設定
            tts.setPitch(PITCH_NORMAL);
        } else if (buttonHighPitch == v) {
            // 再生ピッチの設定
            tts.setPitch(PITCH_HIGH);
        }
    }
}
6 Comments