FreeTTS は Java の音声合成ライブラリ。
いわゆる text to speech を実現できる。
(日本語には対応していないっぽい)

Java Speech API (JSAPI 1.0) にも対応している。

開発しているのは Sun Microsystems Laboratories Speech Team.
Sun Microsystems Laboratories: Speech Integration Group

ライブラリのライセンスは BSD License.

FreeTTS のダウンロード

SourceForge.net にある FreeTTS のプロジェクトページから freetts-1.2.1-bin.zip をダウンロードする。
freetts-1.2.1-bin.zip には、ライブラリのJARファイル、ドキュメント、サンプルコードなどが入っている。
ライブラリの挙動を知りたくなることがけっこうあると思うので、FreeTTS のソースコード freetts-1.2.1-src.zip もダウンロードしておいたほうが便利かも。

FreeTTS のインストール

1. freetts-1.2.1-bin.zip を解凍。

2. freetts-1.2.1/lib 以下にある jsapi.exe (Windows用) や jsapi.sh (UNIX用) を使って jsapi.jar を取り出す(ライセンス承諾のためだけの作業)。

3. jsapi.jar と freetts-1.2.1/lib 以下にある jar ファイル (cmudict04.jar, cmulex.jar, cmutimelex.jar, cmu_time_awb.jar, cmu_us_kal.jar, en_us.jar, freetts.jar) をすべてクラスパスに通す。

freetts.jar と jsapi.jar をクラスパスに通すだけではきちんと動作しなかった。
cmu_us_kal.jar や cmu_time_awb.jar には音声データが入っているっぽい。

com.sun.speech.freetts.en.us.cmu_time_awb.AlanVoiceDirectory
com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory

Java Speech API (JSAPI 1.0) を通して FreeTTS を使うには、ホームディレクトリ <user.home> とか <java.home>/lib に speech.properties を設置する必要があるらしい。
FreeTTS - JSAPI 1.0 Setup
javax.speech.Central

my program -> JSAPI -> FreeTTS

が、今回は直接 FreeTTS を使ってみる。そのほうがラクそうだし。

my program -> JSAPI and FreeTTS

テキストを音声へ変換して再生してみる

サンプルコード。
JDK1.5系で動作した(1.4で動くかどうか不明)。


import com.sun.speech.freetts.*;
 
public class SpeechSample1 {
  
  public static void main(String[] args) {
 
    String message = "Hello world! This is a test. This is a test.";
    
    // FreeTTSのメインとなるクラスを取得
    VoiceManager vm = VoiceManager.getInstance();
    
    // Voice クラスのインスタンスを生成
    Voice v = vm.getVoice("kevin16");
    
    // 諸情報を出力
    System.out.println(
      v.getName() + ":" +
      v.getOrganization() + ":" +
      v.getDescription() + ":" +
      v.getGender() + ":" +
      v.getAge() + ":" +
      v.getRate() + ":" +
      v.getAudioPlayer().getClass());
    
    // 音声出力準備
    // 辞書と音声出力関連のオブジェクトやスレッドを割り当てているっぽい
    v.allocate();
 
    // 音量を設定
    v.setVolume(1.0f); // 0 to 1.0
    
    // デフォルトの速度で読み上げる
    v.speak(message);
 
    // 半分の速さにして読み上げる
    v.setRate(v.getRate() / 2.0f);
    v.speak(message);
 
    // 音声処理を終了
    v.deallocate();
    
    // 音声が全部再生されてから以下の処理を実行しているのを確認
    System.out.print("finished");
  }
}

コンソール出力結果:


kevin16:cmu:default 16-bit diphone voice:MALE:YOUNGER_ADULT:150.0:class com.sun.speech.freetts.audio.JavaStreamingAudioPlayer
finished

テキストを音声へ変換してwaveファイルとして出力してみる

サンプルコード。


import javax.sound.sampled.*;
import com.sun.speech.freetts.*;
import com.sun.speech.freetts.audio.*;
 
public class SpeechSample2 {
 
  public static void main(String[] args) {
 
    String message = "Hello world! This is a test. This is a test.";
 
    // FreeTTSのメインとなるクラスを取得
    VoiceManager vm = VoiceManager.getInstance();
 
    // 使えそうな Voice オブジェクトのリストを取得
    // Each call to getVoices() creates a new instance of each voice.
    Voice[] vlist = vm.getVoices();
 
    for(int i=0; i<vlist.length; i++){
      
      Voice v = vlist[i];
      
      // 諸情報を出力
      System.out.println(
        v.getName() + ":" +
        v.getOrganization() + ":" +
        v.getDescription() + ":" +
        v.getGender() + ":" +
        v.getAge() + ":" +
        v.getRate() + ":" +
        v.getAudioPlayer().getClass());
  
      String baseName = "20071103_freetts_" + v.getName(); // the base name of the audio file
      AudioFileFormat.Type type = AudioFileFormat.Type.WAVE;
      SingleFileAudioPlayer sfap = new SingleFileAudioPlayer(baseName, type);
  
      // 音声出力準備
      // 辞書と音声出力関連のオブジェクトやスレッドを割り当てているっぽい
      v.allocate();
  
      // 音量を設定
      v.setVolume(1.0f); // 0 to 1.0
  
      v.setAudioPlayer(sfap);
      // デフォルトの速度で読み上げる
      v.speak(message);
  
      // 半分の速さにして読み上げる
      v.setRate(v.getRate() / 2.0f);
      v.speak(message);
  
      // 音声処理を終了
      v.deallocate();
  
      // MultiFileAudioPlayer だと自動的にファイルを出力してくれるが、
      // SingleFileAudioPlayer では自分で close を呼び出したときに音声ファイルが出力される
      // SingleFileAudioPlayer#close は自動的に呼ばれない
      sfap.close();
    }
  }
}

デフォルトで使える Voice は、alan, kevin, kevin16 の3種類らしい。
alan の出力時にはエラーが発生。「ClusterUnitDatabase Error: getUnitIndex: can't find unit type pau_ax」や「ClusterUnitDatabase: can't find tree for pau_ax」が何行か出力された。

コンソール出力内容:


alan:cmu:default time-domain cluster unit voice:MALE:YOUNGER_ADULT:150.0:class com.sun.speech.freetts.audio.JavaStreamingAudioPlayer
ClusterUnitDatabase Error: getUnitIndex: can't find unit type pau_ax
(中略)
ClusterUnitDatabase: can't find tree for pau_ax
(中略)
Wrote synthesized speech to 20071103_freetts_alan.wav
kevin:cmu:default 8-bit diphone voice:MALE:YOUNGER_ADULT:150.0:class com.sun.speech.freetts.audio.JavaStreamingAudioPlayer
Wrote synthesized speech to 20071103_freetts_kevin.wav
kevin16:cmu:default 16-bit diphone voice:MALE:YOUNGER_ADULT:150.0:class com.sun.speech.freetts.audio.JavaStreamingAudioPlayer
Wrote synthesized speech to 20071103_freetts_kevin16.wav

出力された音声ファイル
-20071103_freetts_alan.wav(16KHz)
-20071103_freetts_kevin.wav(8KHz)
-20071103_freetts_kevin16.wav(16KHz)

参考URL

tags: zlashdot Text2Speech FreeTTS Java Text2Speech

Posted by NI-Lab. (@nilab)