ここは、形態素・係り受け解析のページでちょこっと書いていた部分を独立させたぺージです
アンドロイドにデフォルトで入っている音声データは日本語に対応していません。

で、なんかないかと探してみたら、KDDIさんの「N2 TTS」という出力エンジンがありました。
これを使ってみます(N2 TTS自体は無料です)。

N2 TTSをインストールして、アプリを作ってしゃべらせてみます。

N2 TTSは優秀で、漢字もちゃんと認識します。変かな?という場合は、形態素解析で漢字をひらがなに開けば いいんじゃないでしょうか?

N2 TTSをインストール

開発元はKDDI

アンドロイドマーケット(Google Play)で「N2 TTS」で検索すればインストールできます。

N2というアイコンをタップして、設定。

「常に自分の設定を使用」にチェック。

「既定のエンジン」をタップ。
KDDILABS N2 TTSを選択。





「言語」をタップ。
「F01」は女性の声。
「M01」は男性の声。





「KDDILABS N2 TTS」にチェックが入っているのを確認。






ボリュームの設定

「設定」を開く











以上です。

TOP






表示サンプルとコード(javaとxmlで実装)

N2 TTSを使ってなんかしゃべるアプリです。

こんな感じ。





例によって、Eclipse + Android SDKの環境を使います。
今回のプロジェクト名は「Text2Speech」。
プラグインやJavascriptは使わず、Javaとxmlのみです。(target:Android 2.3.3)


【AndroidManifest.xml】

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wisteria.tts"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".Text2SpeechActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
</manifest>

【Text2SpeechActivity.java】

package com.wisteria.tts;

import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class Text2SpeechActivity extends Activity  implements OnInitListener, OnClickListener {
    /* Called when the activity is first created. */
private TextToSpeech tts;
    
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tts = new TextToSpeech(getApplicationContext(), this);
        
        Button Button4speech = (Button)findViewById(R.id.Button_s);
        Button4speech.setOnClickListener(this);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        tts.shutdown();
    }
    
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            tts.speak("準備OKです", TextToSpeech.QUEUE_FLUSH, null);
        } else {
            //
            
        }
    }
    
    @Override
    public void onClick(final View v) {
        TextView TextView4speech = (TextView)findViewById(R.id.EditText_s);
        tts.speak(TextView4speech.getText().toString(), TextToSpeech.QUEUE_FLUSH, null);
    }
    
    
}

これは、アプリのUIです。(プロジェクトフォルダー/res/layout/main.xml)

【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">
    
    <Button
        android:id="@+id/Button_s"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="しゃべってもらう" />
    
    <EditText
        android:id="@+id/EditText_s" 
        android:text="わたしはアンドロイドです。"
        android:layout_width="fill_parent"
        android:layout_height="300px"
        android:gravity="top"/>
    
    
</LinearLayout>


TOP

表示サンプルとコード(JavaScriptから呼び出す)

N2 TTSをJavaScriptから呼びさせるようにしてみました。

こっちの方が便利...なような気がしまして。
アプリのサンプル(Text2Speech.apk))はここからダウンロード
ターゲットはAndroid 2.3.3以上、動作確認:Xperia acro
WisteriaHillは貧乏なのでアンドロイドマーケットにまだ登録していません。
インストールの方法はネットで探してね。

こんな感じ。






【AndroidManifest.xml】

上と同じ


【Text2SpeechActivity.java】

package com.wisteria.tts;

import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.content.Context;


public class Text2SpeechActivity extends Activity  implements OnInitListener, OnClickListener {
    /* Called when the activity is first created. */
    private TextToSpeech tts;
    
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //
        WebView webView = new WebView(this);
    
    webView.getSettings().setJavaScriptEnabled(true);
    JavascriptAdapter jsobj = new JavascriptAdapter(this);
    webView.addJavascriptInterface(jsobj, "android_tts");
    webView.loadUrl("file:///android_asset/www/index.html");
        
    setContentView(webView);
        
        tts = new TextToSpeech(getApplicationContext(), this);
        
    }
    
    class JavascriptAdapter {
        //
        private Context con;
        public JavascriptAdapter(Context con) {
            this.con = con;
         }
        
        public void tts(String speech_text) {
            tts.speak(speech_text, TextToSpeech.QUEUE_FLUSH, null);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        tts.shutdown();
    }
    
    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {
            tts.speak("準備OKです", TextToSpeech.QUEUE_FLUSH, null);
        } else {
            //
            
        }
    }
    
    
}

【index.html】

<!DOCTYPE HTML>
<html>
<head>
<title>AAA</title>
    <meta name="viewport" content="width=device-width, initial-scale=1,minimum-scale=1, maximum-scale=1">     
    <meta charset="UTF-8">
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
    <script src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>

<script type="text/javascript" charset="utf-8">
    function speak_it(){
        var speech_content = document.getElementById("speech_content").value;
        android_tts.tts(speech_content);
    }
    
</script>

</head>
<body>
<input type="button" value="しゃべってくれ!" onClick="speak_it()">

<textarea id="speech_content" rows=5 cols=20></textarea>
</body>
</html>


TOP






N2 TTSのスピーチ終了を検知するコード



N2 TTSがインストールされているかどうかをチェックするコードも追加。

//使用するパッケージ
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import java.util.HashMap;
import java.util.Map;
import android.widget.Toast;
    ・
    ・
    ・
    ・
private TextToSpeech tts;
    ・
    ・
    ・
public void onCreate(Bundle savedInstanceState) {
    tts = new TextToSpeech(getApplicationContext(), new OnInitListener() {
            public void onInit(int status) {
                //スピーチ終了のリスナー
                tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
                        public void onUtteranceCompleted(String utteranceId) {
                //To Do
                        }
                    });
            }
        });

}


@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {
        tts.speak("TTS準備OKです", TextToSpeech.QUEUE_FLUSH, null);
    } else {
        //
        
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    resetMembers(); // forced clean
    
    tts.shutdown();


}


private void tts_speak(){
    //N2 TTSが入っているかチェック
    String res = package_check("jp.kddilabs.n2tts");
        if (res.equals("ok")){
            String UTTERANCE_ID = "SPEECH";//ここは何でもいいです
            HashMap<String, String> ttsparam = new HashMap<String, String>();
       ttsparam.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_ID);
       
            tts.speak("テキスト", TextToSpeech.QUEUE_FLUSH, ttsparam);
        }else if (res.equals("no")){
            Toast.makeText(satchActivity_simple.this, 
                    "音声出力エンジンのN2 TTSがみあたりません", 
                    Toast.LENGTH_LONG).show();
        }


}


private String package_check(String package_name){
        String exist_stat = "ok";
        //
        try  {  
          PackageManager packageManager = this.getPackageManager();  
          ApplicationInfo applicationInfo = packageManager.getApplicationInfo(package_name,PackageManager.GET_META_DATA);  
        
        
        }catch(NameNotFoundException exception){ 
            exist_stat = "no";
            
        }  
        
        return exist_stat;
}