最終更新:
moonlight_aska 2011年06月05日(日) 14:03:54履歴
音声合成を使ってAndroidをしゃべらすには, TextToSpeechクラスを使う.
現時点では日本語はサポートされていない(英語, フランス語, ドイツ語, イタリア語, スペイン語のに)ので, 今回は英語で試してみる.

現時点では日本語はサポートされていない(英語, フランス語, ドイツ語, イタリア語, スペイン語のに)ので, 今回は英語で試してみる.

- TextToSpeechActivity.java
- TextToSpeechのインスタンスを生成する.
- "声の高さ"シークバーの値が変更された場合, pitchを計算する. (0.1 <= pitch <= 2.0)
- "読上げ速度"シークバーの値が変更された場合, rateを計算する. (0.1 <= rate <= 2.0)
- "読上げ"ボタンがクリックされると, TextToSpeech#setPitchメソッド, setSpeechRateメソッドを使って, 声の高さや読み上げ速度を設定する.
- もし, 読上げ途中ならTextToSpeech#stopメソッドで, 読上げを中止する.
- TextToSpeech#speakメソッドを使って, エディットテキストに書かれている英文を読上げる.
- OnInitListener#onInitメソッドは, TextToSpeechエンジンの準備ができたことを知らせるコールバックである. 初期化が成功した場合, TextToSpeech#setLanguageメソッドを使って, 言語を英語(US)に設定する.
- 終了(onDestroy)する際には, TextToSpeech#shutdownメソッドを使って, リソースを解放する.
package com.moonlight_aska.android.texttospeech;
import java.util.Locale;
import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.text.SpannableStringBuilder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SeekBar;
public class TextToSpeechActivity extends Activity implements View.OnClickListener, TextToSpeech.OnInitListener {
private TextToSpeech tts;
private EditText inpText;
private Button spkBtn, clsBtn;
private SeekBar pitchBar, rateBar;
private float pitch = 1.0f;
private float rate = 1.0f;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// TTSのインスタンス生成
tts = new TextToSpeech(this, this);
spkBtn = (Button)findViewById(R.id.speak_button_id);
spkBtn.setOnClickListener(this);
clsBtn = (Button)findViewById(R.id.clear_button_id);
clsBtn.setOnClickListener(this);
inpText = (EditText)findViewById(R.id.input_text_id);
pitchBar = (SeekBar)findViewById(R.id.pitch_id);
rateBar = (SeekBar)findViewById(R.id.rate_id);
pitchBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
// pitchを計算
pitch = progress / 50.0f;
if(pitch < 0.1f)
pitch = 0.1f;
}
});
pitch = pitchBar.getProgress() / 50.0f;
rateBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
// speech rateを計算
rate = progress / 50.0f;
if(rate < 0.1f)
rate = 0.1f;
}
});
rate = rateBar.getProgress() / 50.0f;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == spkBtn) {
if(tts != null) {
if(tts.setPitch(pitch) == TextToSpeech.ERROR) {
Log.e("TTS", "Ptich(" + pitch + ") set error.");
}
if(tts.setSpeechRate(rate) == TextToSpeech.ERROR) {
Log.e("TTS", "Speech rate(" + rate + ") set error.");
}
SpannableStringBuilder sp = (SpannableStringBuilder)inpText.getText();
if(sp.toString().length() > 0) {
if(tts.isSpeaking()) {
// 読上げ中ならストップ
tts.stop();
}
// テキスト読上げ
tts.speak(sp.toString(), TextToSpeech.QUEUE_FLUSH, null);
}
}
}
else if(v == clsBtn) {
// テキストクリア
inpText.setText("");
}
}
@Override
public void onInit(int status) {
// TODO Auto-generated method stub
if(status == TextToSpeech.SUCCESS) {
// 言語をUSに設定
Locale locale = Locale.US;
if(tts.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE) {
tts.setLanguage(locale);
}
else {
Log.e("TTS", "Not support locale.");
}
else {
Log.e("TTS", "Init error.");
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(tts != null) {
// リソースを解放
tts.shutdown();
}
}
}
- res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/message_label"
/>
<EditText android:id="@+id/input_text_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pitch_label"
/>
<SeekBar android:id="@+id/pitch_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="50"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rate_label"
/>
<SeekBar android:id="@+id/rate_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="50"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<Button android:id="@+id/speak_button_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/speak_button_label"
/>
<Button android:id="@+id/clear_button_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clear_button_label"
/>
</LinearLayout>
</LinearLayout>
コメントをかく