Android端末で音声合成を使ってみる


Pocket

タイトルの通りで、アンドロイド端末で音声合成を試してみました。

今回使用したのは、ドコモが公開しているWebAPIを使ってみました。
このAPIのすごいところはボイスロイド製品などを開発している株式会社エーアイのライブラリを使用している点で、選択できる音声の種類も多い(11ボイス)し、合成音声のクオリティも高いと思います。
加えて、Android用ライブラリも用意されていて実装も簡単という。

 

1.準備

まずは、ここからSDKをダウンロードしてきます。
ダウンロードしたファイルを解凍して、libsフォルダに入っている下記ファイルをAndroidStudioプロジェクトのlibsフォルダにコピーします。
・docomo-aitalk-android-sdk-1.0.1.jar
・docomo-common-android-sdk-1.0.2.jar
・jackson-annotations-2.2.3.jar
・jackson-core-2.2.3.jar
・jackson-databind-2.2.3.jar

コピーしたらGradleプロジェクトのsyncを行って準備完了です。

※使用しているAndroidStudioのバージョンによっては、ビルド時に”duplicate files …”というエラーがでるので、その場合は、build.gradleに下記を追加します。

android{
  省略
  packagingOptions {
    exclude "META-INF/LICENSE"
    exclude "META-INF/NOTICE"
  }
}

 

2.実装方法

SSMLを使用して合成音声を取得するサンプルコードです。

<uses-permission android:name="android.permission.INTERNET"/>

INTERNETパーミッションを使用するので、マニフェストに追加。

 
・Activity

@Override
protected void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);

  AuthApiKey.initializeAuth(/* Your Api Key */);

}

ActivityのonCreateでAPIKeyを設定して初期化します。

 
・音声取得と再生処理を非同期タスクとして実装

public class AiTalkTask extends AsyncTask<String, Void, Void>{
    private String mSpeaker;

    public AiTalkTask(String speaker) {
        mSpeaker = speaker;
    }

    @Override
    protected Void doInBackground(String... params) {
        // 現在日時と引数テキストをじゃべる
        Calendar now = Calendar.getInstance();

        try {
            AiTalkSsml ssml = new AiTalkSsml();
            ssml.startVoice(mSpeaker);
            ssml.addDate(AiTalkSsml.DATE_TYPE_YMD, now);
            ssml.addTime(AiTalkSsml.TIME_TYPE_HMS12, now);
            ssml.addBreak(500);
            ssml.addText(params[0]);
            ssml.endVoice();

            AiTalkTextToSpeech speech = new AiTalkTextToSpeech();
            byte[] result = speech.requestAiTalkSsmlToSound(ssml.makeSsml());

            // スピーカー出力
            int bufSize = AudioTrack.getMinBufferSize(16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
            speech.convertByteOrder16(result);
            AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, bufSize, AudioTrack.MODE_STREAM);
            at.play();
            at.write(result, 0, result.length);
            Thread.sleep(result.length / 32);
        } catch (SdkException e) {
            Log.d("SDK_ERROR", e.getErrorCode() + "/" + e.getMessage());
        } catch (ServerException e) {
            Log.d("SERVER_ERROR", e.getErrorCode() + "/" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

【14~20行目】
しゃべらせる文言を設定します。
今回の例では、まず現在の日付と時間をしゃべってから、少しの時間(500ms)あけて、任意文章をじゃべらせています。

startVoice(String speaker)で、読手を指定します。指定できるのは
["nozomi", "seiji", "akari", "anzu", "hiroshi", "kaho", "koutarou", "maki", "nanako", "osamu", "sumire"]
の11種類です。

詳しくは、解凍したフォルダに入っているjavaDoc参照。

 
【22~23行目】
サーバーへリクエストを行い、音声ファイルを取得します。
取得できる音声フォーマットはaudio/L16,サンプリングレート16000,モノラルです。

 
【26~30行目】
取得した音声を再生します。
27行目はAudioTrackで再生するため、ビッグエンディアンをリトルエンディアンに変換しています。
こちらもjavadocが参考になると思います。

 
あとは、必要な場面でタスクを実行してあげるだけ。
・Activity

AiTalkTask task = new AiTalkTask("nozomi");
task.execute("ほげほげ");

こんな感じで、簡単に音声合成を行うことができます。

 
 

あとがき

とりあえず、いろんなん声で、あんなことやこんなことをしゃべらせる。
ただそれだけで結構楽しめます(*^_^*)。

 
 

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>