【コラム】

Java API、使ってますか?

20 音声認識/合成のためのAPI - Java Speech APIとJSR 113

20/60

Java Speech APIとは

Java Speech API(以下、JSAPI)はJavaアプリケーションに音声認識や音声合成の機能を組み込むためのAPIである。Java Speech API自身はJCPがスタートする前に発表されたのでJSRは存在せず、Sun Microsystemsのサイト上でその仕様が公開されている。

JSAPIを使用することで、Javaプログラムで音声の認識や合成を行うことができるようになる。たとえば、合成音声によってテキストを読み上げるというような処理の実装が容易に行える。

JSAPIの代表的な実装としてはオープンソースで開発されているFreeTTSがある。もっとも新しいバージョンは1.2.1で、商用の音声認識/合成ツールのような高度な機能は有していないが、JSAPIを試すには十分な機能を提供してくれる。今回はまずこのFreeTTSを用いて、JSAPIの音声合成機能を利用したプログラムを作ってみる。

FreeTTSを試す

FreeTTSはこのページより入手することができる。配布ファイルにはライブラリのほかにドキュメントやデモプログラムなどが含まれている。

ライブラリはlibディレクトリに格納されている。FreeTTSの実装は「freetts.jar」だ。また、JSAPIの実装はWindows環境ならば「jsapi.exe」を、UNIX(シェル)環境ならば「jsapi.sh」を実行するとライセンス文書が表示され、同意すれば「jsapi.jar」というファイルが生成される。これらをクラスパスに追加して利用する。

リスト1に、FreeTTSを利用してテキストを読み上げるプログラムの例を示す。このプログラムは、実行時にコマンドライン引数で指定した英文テキストを合成音声で読み上げる。

リスト1 SpeechSample.java

package sample.speech;

import java.beans.PropertyVetoException;
import java.util.Locale;
import javax.speech.AudioException;
import javax.speech.Central;
import javax.speech.EngineException;
import javax.speech.EngineStateError;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;

public class SpeechSample {
    private Synthesizer synthesizer = null;

    public SpeechSample() {
        // シンセザイザのモードを指定
        SynthesizerModeDesc desc = new SynthesizerModeDesc
            (null, "general", Locale.US, Boolean.FALSE, null);
        try {
            // シンセザイザを作成
            synthesizer = Central.createSynthesizer(desc);
            if (synthesizer == null) {
                System.err.println("ERROR! シンセザイザが見つかりません。");
                System.exit(1);
           }

            // ボイスを作成
            String voiceName = "kevin16";
            Voice voice = new Voice(voiceName, Voice.GENDER_DONT_CARE,
                            Voice.AGE_DONT_CARE, null);
            if (voice == null) {
                System.err.println(
                    "ERROR! シンセザイザがボイス "
                    + voiceName + " をサポートしていません。");
                System.exit(1);
            }

            // リソースの割り当て
            synthesizer.allocate();
            synthesizer.resume();
            // ボイスの設定
            synthesizer.getSynthesizerProperties().setVoice(voice);
        } 
        catch (EngineException ex) {
            ex.printStackTrace();
        } catch (PropertyVetoException ex) {
            ex.printStackTrace();
        } catch (AudioException ex) {
            ex.printStackTrace();
        }
    }

    public void speak(String message) {
       try {
            // テキストの読み上げ
            synthesizer.speakPlainText(message, null);
            synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public void deallocateSynthesizer() {
        try {
            // リソースの開放
            synthesizer.deallocate();
        } catch (EngineException ex) {
            ex.printStackTrace();
        }

    }

    public static void main(String[] args) {
        String message = (args.length > 0) ? args[0] : "Hello World.";

        SpeechSample sample = new SpeechSample();
        sample.speak(message);
        sample.deallocateSynthesizer();
    } 
}

SpeechSampleクラスは、コンストラクタが呼び出されるとまずSynthesizerModeDescを使用してシンセザイザのモードを指定し、続いてSynthesizerオブジェクトを生成する。Synthesizerの生成は、CentralクラスのcreateSynthesizer()メソッドを用いて行う。

続いて、使用する音声を表すVoiceオブジェクトを生成する。そしてallocate()メソッドでSynthesizerにリソースを割り当て、SynthesizerPropertiesのsetVoice()メソッドを用いてボイスを設定する。

speak()メソッドでは引数に渡されたテキストの読み上げを行う。読み上げはSynthesizerオブジェクトに対してspeakPlainText()メソッドを呼び出せばよい。deallocateSynthesizer()メソッドではリソースの開放を行っている。

最後に、シンセザイザを有効にするため、リスト2のようなプロパティファイルを作成してユーザディレクトリに配置する。ここではシンセザイザを生成するためのCentralの実装としてcom.sun.speech.freetts.jsapi.FreeTTSEngineCentralを利用することを指定している。

リスト2 speech.properties

# Sample ResourceBundle properties file
FreeTTSSynthEngineCentral=com.sun.speech.freetts.jsapi.FreeTTSEngineCentral

これで、適当なテキストを引数に指定してSpeechSampleクラスを実行すれば、そのテキス]トが合成音声によって読み上げられるはずだ。

JSR 113: Java Speech API 2.0(JSAPI 2.0)

さて、JCPにはJava Speech APIの後継バージョンとして「JSR 113: Java Speech API 2.0」が登録されている。ちょうど6月11日にProposed Final Draft 2が公開され、今年第3四半期での正式リリースを目指して最終仕様の検討が進められている。

JSAPI 2.0では1.0との互換性を可能な限り確保するとしながらも、多くの点で変更が加えられている。その主たるものとしては、ターゲットがJava MEプラットフォーム(CLDC 1.0以上およびMIDP 1.0以上が対象)になっていることが挙げられる。クラス構成も大きく変更されており、たとえばJSAPI 1.0ではSynthesizerを生成するのにCentralクラスとSynthesizerModeDescクラスを利用していたのに対し、2.0ではEngineManagerクラスを用いてリスト3のように行う。

JSAPI 2.0でのSynthesizerの生成

Synthesizer synth = (Synthesizer)
        EngineManager.createEngine(SynthesizerMode.DEFAULT);

その他、2.0における主な変更点を以下に挙げる。

  • すべての浮動小数点の使用を廃止
  • AWTに依存しない
  • イベントキューをSpeechEventExecutorで統合
  • URLクラスの使用をStringクラスに置き換え
  • StringReaderの必要性を排除
  • Dictation機能の削除(ただし将来的には復活する可能性もある)
  • W3C SRGSのサポート
  • W3C SSMLのサポート
  • フィルタイベントにイベントマスクを追加
  • JSR 135(Mobile Media API)互換のAudioManagerの導入

JSR 113の参照実装の開発はExpert Groupにも名を連ねるConversayによって行われている。また、開発者向けのポータルサイトがConversations Developer Networkに開設されており、フォーラムでの議論Early Releaseの情報公開などが行われてる。

20/60

インデックス

連載目次
第60回 どうなる? 今後のJavaプラットフォーム(Java SE編)
第59回 どうなる? 今後のJavaプラットフォーム(Java EE編)
第58回 Java SE 7の要注目機能"クロージャ"はどうなるのか その6
第57回 Java SE 7の要注目機能"クロージャ"はどうなるのか その5
第56回 Java SE 7の要注目機能"クロージャ"はどうなるのか その4
第55回 Java SE 7の要注目機能"クロージャ"はどうなるのか その3
第54回 Java SE 7の要注目機能"クロージャ"はどうなるのか その2
第53回 Java SE 7の要注目機能"クロージャ"はどうなるのか
第52回 Early Draftが公開されたJSF 2.0
第51回 EJBから独立したJava Persistence 2.0
第50回 モバイルJavaの新しい潮流となるか - MSA 2.0のドラフト公開
第49回 やっぱり基本はServlet - Servlet 3.0のEarly Draftを読む
第48回 JOGLで3Dプログラミング その4
第47回 JOGLで3Dプログラミング その3
第46回 JOGLで3Dプログラミング その2
第45回 JOGLで3Dプログラミング
第44回 JARファイルを効率的にネットワーク転送するためのPack200形式
第43回 Early Draftで把握するEJB 3.1の新機能
第42回 次世代の携帯端末向けJava仕様"MIDP 3.0"はどうなるか その2
第41回 次世代の携帯端末向けJava仕様"MIDP 3.0"はどうなるか その1
第40回 リソースアダプタによる接続の仕組み
第39回 JCAを利用したシステム間接続
第38回 Java EEと外部システムの接続性を支えるJCAがバージョンアップ
第37回 Javaのモジュラリティ強化を担う"スーパーパッケージ"とは
第36回 JSR 308対応のコンパイラを試す
第35回 公開されたJSR 308のEarly Draftを検証する
第34回 スクリプト言語とJavaを結びつけるJSR 223
第33回 Java EE環境に統一されたコンポーネントモデルを提供するJSR 299 その2
第32回 Java EE環境に統一されたコンポーネントモデルを提供するJSR 299 その1
第31回 Javaの文法がそのまま使えるスクリプト言語"BeanShell"
第30回 Javaアプリケーションにオブジェクトのキャッシュ機構を提供するJCache API
第29回 Javaアプリケーションからのリソース管理を可能にするJSR 284
第28回 XMLデータソースへの問い合わせはJSR 225で
第27回 Portlet Specification 2.0をもっと手軽に利用する
第26回 次期Javaポートレット仕様となるJSR 286
第25回 JSFとポートレットをつなげるJSR 301
第24回 Webサービス向けのポートレット仕様「WSRP」
第23回 高い相互運用性を実現するポートレットAPI - JSR 168
第22回 Java EE環境でタスクのスケジューリングを可能にするJSR 236
第21回 Java EE環境でのスレッドプログラミングを可能にするJSR 237
第20回 音声認識/合成のためのAPI - Java Speech APIとJSR 113
第19回 JSR 291でJavaプラットフォームにダイナミックコンポーネントモデルを導入
第18回 JAX-RSで簡単RESTful - JSR 311
第17回 待望のServlet 3.0がJSRに登場 - JSR 315
第16回 アノテーションを使ってバグ退治 - JSR 305
第15回 アノテーションをさらに広い範囲で利用可能にするJSR 308
第14回 Webアプリケーション開発の要となるか - JSF 2.0がJSRに登場
第13回 Webサービス経由でのJMX Agentへの接続を可能にするJSR 262
第12回 Javaアプリケーションのモジュール化をサポートするJava Module System
第11回 "NIO.2"がやってきた - JSR 203: More New I/O APIs for the Java Platform
第10回 JSR 295: Beans Bindingの参照実装を試す
第9回 けっこう便利! 単位を扱うAPI -- JSR 275: Units Specification
第8回 アノテーションでバリデーション - JSR 303: Bean Validator
第7回 Swing開発の救世主となるか - Swing Application Framework
第6回 JavaBeansのプロパティを同期させるバインディングAPI
第5回 誰よりも早く"Java SE 7"を睨む
第4回 日時情報の取り扱いを改善する JSR 310: Date and Time API
第3回 古いAPIも進化している!? - JSR 919: JavaMail 1.4
第2回 JSR 1 リアルタイムJava仕様
第1回 JCPによって進められるJava関連技術の標準化

もっと見る

提供:マイナビ

会員登録はこちら

大学・大学院・短大・専門学生向けの就職情報サイト「マイナビ2010」「マイナビ2009」に今すぐ登録しよう!  大手企業からベンチャー企業までの約13,000社の企業情報を公開、エントリーが可能です。2010年卒予定の方は「マイナビ2010」に、2009年卒予定の方は「マイナビ2009」に登録してください。

毎日コミュニケーションズはプライバシーマークを取得しています。



人気記事

一覧

イチオシ記事

新着記事