C/C++プログラマの管理者が, Androidプログラムにチャレンジ. AndroidプログラミングのTipsをメモっていく予定です.

音声合成を使って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>



コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu


逆引き(基礎編)

画面表示/操作(49)

フラグメント(1)

逆引き(応用編)

Firebase(2)

AD



管理人/副管理人のみ編集できます