2008.02.02
岸本 俊夫

Ruby で MS Agent を使用する

 Microsoft Agent はデスクトップ上に“バーチャル秘書”を登場させ、音声合成で しゃべらせたり、音声認識で指令を受け取ったりできるようです(今のところそんな 賢い機能はありませんが)。

 Ruby を使えば、Visual Basic や VBScript よりもはるかに簡単に Microsoft Agent を制御することができます。

 ここでは Cygwin 版 Ruby で Microsoft Agent を制御する方法を紹介します。

1.Microsoft Agent とは

 Microsoft Agent とは、MS Office のイルカのようなもので、様々なキャラクタが アニメーションし、音声合成でしゃべるものです。最終的にはデスクトップ上で 動作する“秘書”機能だと思いますが、現段階ではただおもしろいだけ(ときには うっとうしい)です。

 MS Agent には次の機能があります。

  1. アニメーション
  2. 音声合成
  3. 音声認識

 (1)は Microsoft がいくつかのキャラクタをすでに用意しています。
 (2)は英語、日本語でしゃべることを確認しました。声質の方は何ともいえませんが。
 (3)はまだ US 英語しかないようです。

[Top] [Index]

2.MS Agent のインストール

 次のサイトが参考になります。

 <URL:http://members.jcom.home.ne.jp/shinonon/delphi/tips3.html>

 MS Agent は WindowsXP には標準で入っているようですが、その他の Windows の 場合は Microsoft のホームページからダウンロードしてインストールする必要が あります。

 <URL:http://www.microsoft.com/msagent/downloads.htm>

 以下の 5ファイルをダウンロードし、すべてをインストールします。 ダウンロードした .exe ファイルを実行すればインストールできます。

 (*1)のキャラクタファイルは複数種類ありますので、お好きなキャラクタのものを 入手してください。

[Top] [Index]

3.Ruby で MS Agent を制御する

 いきなりサンプルスクリプトをお見せします。可読性の高い Ruby はその方が話が 早いですから。

リスト1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
require 'win32ole'                                              #--(a)
agent = WIN32OLE.new( 'Agent.Control.2' )                       #--(b)
agent.connected = true                                          #--(c)
agent.characters.load( "Genie",
                       "c:/winnt/msagent/chars/genie.acs" )     #--(d)
$genie = nil

#   イベントを登録する。
#   IdleStart イベントを受けると、スクリプトを終了する。
ev = WIN32OLE_EVENT.new( agent, nil )
ev.on_event { |r|                                               #--(e)
    if( r[0] == "IdleStart" && r[1] == "Genie" )
        $genie.hide             # キャラを消去
        exit
    end
}
$genie = agent.characters.character( "Genie" )
$genie.show                     # キャラを表示                  #--(f)
$genie.moveTo( 200, 200 )       # キャラを移動
$genie.play( "Greet" )          # 「いらっしゃいませ」のジェスチャ
#$genie.languageID = 0x409       # 英語の指定
$genie.languageID = 0x411       # 日本語の指定
#$genie.speak( "Hello, I'm Genie. How are you ?" )
$genie.speak( "やぁ、私の名前はジェニー、元気かい?" )          #--(g)
$genie.play( "RestPose" )       # 「休め」のジェスチャ
$genie.play( "Hide" )           # 「消える」ジェスチャ          #--(h)

#   メッセージループ
#   これがないとイベントがブロックされる。
loop do
    WIN32OLE_EVENT.message_loop                                 #--(i)
end

#   念のため
$genie.hide                     # キャラを消去                  #--(j)
GC.start
──────────────────────────────────────

 (a)は Windows の COM を使用するのに必要です。あらかじめ Ruby ホームページの RAA からダウンロードしてインストールしてください。詳細は別資料を 参照してください。

 WIN32OLE
 <URL:http://homepage1.nifty.com/markey/ruby/win32ole/index.html>

 (b)で MS Agent をリンクします。'Agent.Control.2' の文字列は、レジストリを 「agent」でサーチして見つけました。Microsoft のドキュメントで探しましたが、 説明が見当たりませんでした。

 (c)を忘れるとエラー 0x80042502 になります。Microsoft のドキュメントでは 次のように書いてありますが、何のことやら原因が分かりません。
「agent.connected」を発見するまでずいぶん時間がかかりました。

Microsoft Agent was unable to start. 
Verify that Microsoft Agent is properly installed.

 (d)は好きなキャラクタに変更できます。インストール時に Microsoft の ホームページからダウンロードしたキャラクタファイルを選択します。

 (f)は省略できません。音声合成機能のみ利用する場合、キャラクタがじゃまになる ことがありますが、キャラクタを表示しないと音声合成機能が利用できないようです。

 (g)の所要時間は読み上げる文字列の長さに依存します。(h)の直後に (j)を実行すると (g)〜(h)を実行する前に (j)を実行してしまいます。つまり MS Agent の処理は 別スレッドで実行されているようです。したがって (g)〜(h)が終了したことを検出して (j)を実行するようにプログラムする必要があります。それが (i)です。

 (i)でイベントを捕捉して、イベントハンドラ (e)を呼び出す。

 本当は (h)の終了を捕捉したいのです。ジェスチャの種類はたくさんあり、上記の スクリプトでも「いらっしゃいませ」「休め」「消える」を使用しています。 ジェスチャの終了を捕捉する場合は、これらのどれであるかが識別できないと (h)の終了のタイミングが分かりません。Microsoft のドキュメントを調べましたが、 ジェスチャの種類を識別する方法が分かりませんでした。

 (e)ではアイドル状態になったというイベントを捕捉して、キャラクタを消去する ようにしました。これだと (h)が終了してからイベントが発生するまでに若干遅延が 発生するようで、応答性が悪いです。もっとよい方法があればいいのですが。

[Top] [Index]

[追記] イベントの捕捉

 Shusaku さんから (h)の終了を捕捉する方法を教えていただきました。
 ev.on_event ブロックを次のように変更します。Request オブジェクトの ID プロパティを比較します。

リスト2−1
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ev.on_event { |r|                                               #--(e)
    if( r[0] == "RequestComplete" && r[1].ID == $req.ID )
        $genie.hide             # キャラを消去
        exit
    end
}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 また (h)の行を次のように変更します。

リスト2−2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$req = $genie.play( "Hide" )    # 「消える」ジェスチャ          #--(h)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

 これでずいぶん応答性が改善されました。

(C) 2002 by KISHIMOTO Toshio (ALELE.NET), all rights reserved.
このドキュメントに関するお問い合わせは下記まで

/*history*/
0.12002.09.23TKOriginal
0.1.12002.12.03TK[追記]を追加した。
1.02008.02.02TK花ライオン用に変更。
/*eof*/