サイト移転のお知らせ:http://techbooster.org/に移転しました

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

7月 7, 2010   //   by kkato   //   アプリケーション  //  4 Comments

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

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

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

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

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

TextToSpeechクラス

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

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

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

簡単ですね。

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

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

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

TextToSpeech(Context context, TextToSpeech.OnInitListener listener)

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


void onInit(int status)

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

言語(ロケール)の設定

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

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

int isLanguageAvailable(Locale locale)

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


int setLanguage(Locale locale)

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

テキストの読み上げ

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


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

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

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

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

サンプルソース

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

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);
		}
	}
}

関連する記事:

Sponsored Link

4 Comments

技術書新刊 発売中

アンドロイドアカデミアには、CIやテスト、互換検証など実務に生きるノウハウをあつめています

技術書新刊 発売中

Android Next!はAndroid 7.0に対応したはじめての技術書です!


The Web Explorer 2はCSSの中央寄せやWebAudioなど未来を読み解く一冊です


Revised TypeScript in DefinitelylandはTypeScript 2.0(β)に対応した解説書です。インストールから型定義まで幅広くサポートしています


技術書をかこう!はエンジニアらしい執筆環境を構築、HowTo本です