Up:[[Tutorial]]     Previous:[[エージェント間のメッセージのやりとり]]     Next:[[視覚に関する操作]]

#contents

*音声認識 [#t40318dd]
ここではSIGVerseで音声認識を行う方法を説明します。

※NIIサーバではSIGVerseのバージョン101104以降で正常に動作します。また、音声認識を行うためには、SIGVerseのインストール時にJulius(音声認識を行うソフト)やdictation-kitの場所を指定する必要があります。指定方法は[[こちら>SIGVerseのインストール(NIIサーバ)]]
**音声データ(waveファイル)の音声認識 [#pc99087f]
ここではあらかじめ用意されているサンプルの音声データ(waveファイル)を音声認識してみたいと思います。

***コントローラ作成 [#m6feace7]
音声データを受け取り、音声認識を行うエージェントのコントローラを作成します。
 $ cd ~/sigverse-<version>/bin/NewWorld
 $ emacs soundRecog.cpp

soundRecog.cpp

#highlight(cpp){{
 #include <Controller.h>
 #include <ControllerEvent.h>
 #include <RawSound.h>
 #include <Logger.h>
 #include <Text.h>
 
 
 class AgentController : public Controller
 {
 public:
 
   //音声データを受け取った時に呼出される関数onRecvSoundの利用を宣言します。
   void  onRecvSound(RecvSoundEvent &evt);
 };
 
 void AgentController::onRecvSound(RecvSoundEvent &evt)
 {
   //音声データを取得します。
   RawSound * sound = evt.getRawSound(); 
  
  //音声ヘッダを取得します。
   RawSoundHeader &h = sound->getHeader();
   LOG_MSG(("channel = %d", h.getChannelNum()));
   LOG_MSG(("sampling rate = %u", h.getSamplingRate()));
 
  //エンディアンを得ます。
   RawSoundEndian endian = h.getEndian();
   LOG_MSG(("endian : %s", endian == RAW_SOUND_LITTLE_ENDIAN? "little": "big"));
 
   // 生の WAVデータを取得します。
   int datalen = sound->getDataLen();
   char * data = sound->getData();
 
   // 音声認識結果をテキストで取得します。
   Text * text = getText(*sound);
   if (text) { 
 
     // 音声認識結果を表示します。
     const char * str = text->getString();
     LOG_MSG(("text : %s", str));
 
     // 必要なくなったらテキストデータをdeleteします。
     delete text;
   }
 
 }
 
 extern "C"  Controller * createController ()
 {
   return new AgentController;
 }
}}
音声認識した結果を表示するサンプルです。

***コンパイル [#gdda3ca6]
Makefileを修正します。
 $ emacs Makefile

オブジェクトファイルの指定のところをsoundRecog.soを指定します。

 #オブジェクトファイルの指定
 OBJS     = soundRecog.so

#ref(makefile_sound)


コンパイルします。
 $ make

***世界ファイル作成 [#l5f5ce8b]
 $ cd ..
 $ emacs xml/soundRecog.xml

soundRecog.xml
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
 <world name="myworld4">
 
   <gravity x="0.0" y="-9.8" z="0.0"/>
 
 <!--音声データ受信エージェントRobot-niiの設定-->
   <instanciate class="Robot-nii.xml"> 
 
         <set-attr-value name="name" value="robot_000"/>
         <set-attr-value name="language" value="c++"/> 
 
 <!--音声データ受信者のコントローラ指定-->
         <set-attr-value name="implementation"
 value="./NewWorld/soundRecog.so"/>
 
 <!--動力学演算をfalseに設定-->
         <set-attr-value name="dynamics" value="false"/>
 
 <!--エージェントの位置(x,y,z)-->
        <set-attr-value name="x" value="0.0"/>
        <set-attr-value name="y" value="60.0"/>
        <set-attr-value name="z" value="-60.0"/>
 
 </instanciate>
}}
これで準備完了です。

***SIGVerse,Juliusの起動 [#q211f39e]
まずSIGVerseを起動します。
 $ ./sigserver.sh -p 9001 -w soundRecog.xml &
次にJuliusを起動します。エンターキーを押してコマンドを続行します。
 $ ./sigjsp.sh -p 9001
sigjsp.shというシェルスクリプトでJuliusを起動します。このときシミュレーションサーバが起動しているポート番号を-pオプションで指定してJuliusが起動したことをシミュレーションサーバに知らせます。

以下のようなメッセージが表示されればJuliusは正常に起動しています。正常に起動しない場合は[[Juliusの設定>#w9e5b872]]を参照ください。

 Stat: adin_tcpip: waiting connection...
 ===================================
   julius adinnet port connect ok!
 Stat: server-client: connect from 127.0.0.1
 Stat: adin_tcpip: connected
 ===================================
 ***************************************
 ***   julius successfully started   ***
 ***************************************
 *******************************************************
   connect to SimServer (localhost:9111) ok
 *******************************************************
 clerkName (socio.iir.nii.ac.jp)
 send COMM_REQUEST_PROVIDE_SERVICE ok
 waiting for connection ... (accept sock: 7)
 [SYS]  socio.iir.nii.ac.jp:7500  : service provider
 [SYS]  127.0.0.1 connected

***SIGViewerから音声データの送信 [#jac958b8]

SIGVerse,Juliusが起動している状態で、クライアント側でSIGViewerを起動し、サーバに接続します。接続が完了するとロボット型エージェントが立っているのが見えると思います。

次にSIM_STRL_CMDがSTARTとなっている状態で、"send"ボタンを押してシミュレーションを開始し、右上にあるCommandタブをクリックします。一番上の入力欄はgeneralとvoiceを選択できるようになっています。ここではvoiceを選択します。次に"送信対象選択"ボタンをクリックしてロボット型エージェントをクリックします。次に"Send Voice"ボタンをクリックします。

#ref(sound_1.jpg)

送信する音声データを選択するダイアログが表示されるので、SIGViewerをインストールしている場所、デフォルトでは

C:\Program Files\SIGViewer_<version>\SIGViewer\release

にあるsample.wavを選択して、音声データを送信します。
すると以下のようなメッセージが表示され、
「貧乏参考ください」という音声認識結果が表示されると思います。

 connection accepted. (sock=8)
 waiting for connection ... (accept sock: 7)
 connection accepted. (sock=8)
 
 waiting for connection ... (accept sock: 7)
 [MSG]  robot_000(127.0.0.1) channel = 0
 [MSG]  robot_000(127.0.0.1) sampling rate = 0
 [MSG]  robot_000(127.0.0.1) endian : little
 [MSG]  robot_000(127.0.0.1) text : 貧乏参考ください。

音声データ(sample.wav)を聞いていみると「リンゴを三個ください」と言っているので、少し間違って認識されているのがわかります。

※SIGVerseを終了してもJuliusだけが起動しつづていることがありますので注意してください。以下のコマンドで起動中のプロセスを確認できます。

 $ ps aux | grep <username>

**Juliusの設定 [#w9e5b872]
SIGVerseはjuliusのモジュールモードを使って通信を行います.また、音声データはadinnetというjuliusの提供するネットワーク経由での音声入力ポートを使用します.
juliusとシミュレーションサーバの通信を行うためのポート番号が他のユーザーと重複している場合Juliusは正常に起動しません。ここではこれらのポート番号の設定方法を説明します。

***Juliusサーバの設定 [#ee41288b]
まずディクテーションキットを自分のホームディレクトリにコピーします。(またはサイトからダウンロードしてきます。)
 $ cp -r /usr/local/share/dictation-kit-v4.0 ~/
次にコピーしたディレクトリの中にSIGVerse用に設定されたJulius設定ファイルがすでに用意されています。この設定ファイルを修正します。

ダウンロードした場合は設定ファイルをこちらに置き換えてください。
#ref(fast.jconf)
 $ emacs ~/dictation-kit-v4.0/fast.jconf

ここでサーバモジュールモード、adinnetのポート番号を設定します。以下の2点を修正します。

-サーバモジュールモードのポート番号

 ######################################################################
 #### サーバーモジュールモード
 ######################################################################
 -module         # サーバーモジュールモードで起動

   ↓
 ######################################################################
 #### サーバーモジュールモード
 ######################################################################
 -module 10511        # サーバーモジュールモードで起動


-adinnetポート番号

 ######################################################################
 #### 音声入力ソース
 ######################################################################
 ## どれかを選んでください(デフォルト:mfcfile)
  
 (省略)
  -input adinnet

   ↓

 ######################################################################
 #### 音声入力ソース
 ######################################################################
 ## どれかを選んでください(デフォルト:mfcfile)
  
 (省略)
 -input adinnet 
 -adport 10522

ここではadinnetポート番号を10511, モジュールポート番号を10522としました。他のユーザーと重複しにくい番号に変更することをお勧めします。

***シミュレーションサーバの設定 [#t8869d80]
次にシミュレーションサーバの設定を行います。
Julius起動時にシミュレーションサーバは以下の設定ファイルを読み込みます。見てみましょう。

 $ emacs /home/<usrname>/sigverse-<version>/share/sigverse/etc/sigjsp.conf

デフォルトでは以下のようになっています。

 # ************************************************************
 #  sigjsp configuration file
 # ************************************************************
 
 # ======================================================
 #  SimServer hostname and port number
 # ======================================================
 SERVER=localhost
 PORT=7000 
 
 
 # ======================================================
 #  Port number that sigjsp waiting for connection
 # ======================================================
 SERVICE_PORT=7500 
  
 
 # ======================================================
 #  julius port number
 # ======================================================
 JULIUS_MODULE_PORT=10500
 JULIUS_ADINNET_PORT=5530 
  
 
 # ======================================================
 #  julius path (not directory, path to executable)
 # ======================================================
 JULIUS_PATH=/usr/local/bin/julius
 
 # ======================================================
 #  julius config file
 #
 #  [remark]
 #  when relative path is specified, actual path is
 #  calculated from current directory.
 #  (ex)
 #  JULIUS_CONFIG_FILE=fast.jconf
 #  $ pwd
 #  /home/somebody
 #  $ sigjsp
 #  ---> sigjsp searches for /home/somebody/fast.jconf
 # ======================================================
 JULIUS_CONFIG_FILE=/usr/local/share/dictation-kit-v4.0/fast.jconf   
 
 
 # ======================================================
 #  some wait time to finish starting julius (in msec)
 # ======================================================
 # DELAY_TIME_FOR_START_JULIUS=3000

ここでは以下の設定が行えます。
-シミュレーションサーバのポート番号(デフォルト7000)
-Juliusサービスプロバイダのポート番号(デフォルト7500)
-Juliusモジュールのポート番号(デフォルト10500)
-Juliusのadinnetポート番号(デフォルト5530)

-Juliusの実行ファイルの場所
-Juliusの設定ファイルの場所

これらのポート番号はJuliusで設定されているデフォルトのポート番号の値に設定されています。これらの値を先ほど設定したポート番号に変更します。
 
 JULIUS_MODULE_PORT=10500
 JULIUS_ADINNET_PORT=5530 

    ↓
 JULIUS_MODULE_PORT=10511
 JULIUS_ADINNET_PORT=10522 

次にJuliusサービスプロバイダのポート番号を重複しにくい番号に変更します。

 SERVICE_PORT=7500 
    ↓
 SERVICE_PORT=10533

次にJulius設定ファイルの場所を変更します。

 JULIUS_CONFIG_FILE=/usr/local/share/dictation-kit-v4.0/fast.jconf
    ↓
 JULIUS_CONFIG_FILE=/home/<username>/dictation-kit-v4.0/fast.jconf

また、これらのポート番号や設定ファイルはsigjsp.shの実行時に指定することもできます。何も指定しなければ上記の設定ファイルで指定した値になります。

         % sigjsp.sh [-p <number>] [-sp <number>] [-mp <number>] [-ap <number>] [-e <path>] [-C <config.jconf>]

 OPTION :
	-p <number>  : シミュレーションサーバのポート番号
	-sp <number> : Juliusサービスプロバイダのポート番号
	-mp <number> : Juliusモジュールモードポート番号
	-ap <number> : adinnetポート番号
	-e <path>	   : Juliusの場所 (デフォルト: /usr/local/bin/julius)
	-C <config.jconf;> : Juliusの設定ファイルの場所

これで設定は完了です。Juliusが正常に起動することを確認してください。

***(null)と表示されてしまう場合 [#yc262c9c]
juliusの設定ファイルfast.jconfに以下の一行を追加して実行してみてください。
***音声認識結果が(null)と表示されてしまう場合 [#yc262c9c]
Juliusの設定ファイルfast.jconfに以下の一行を追加して実行してみてください。
 -charconv EUC-JP UTF-8

**音声データ(マイクからの入力)の音声認識 [#w8e9ffc0]
次にマイクで録音した音声データをSIGVerseで音声認識する方法を説明します。

※クライアントpcにマイクが接続されていることが前提となります。

***コントローラ編集 [#a43d5b9a]
先ほど作成したコントローラsoundRecog.cppを編集します。

 $ cd ~/sigverse-<version>/bin/NewWorld
 $ emacs soundRecog.cpp

#highlight(cpp:firstline[38]){{
    // 音声認識結果を表示します。
    const char * str = text->getString();
    LOG_MSG(("text : %s", str));
}}
の下に以下のコードを追加します。(これがなくても音声認識はできます)
#highlight(cpp:firstline[41]){{
    if(strstr(str, "こんにちは"))
      {
        // 自分自身を得ます
        SimObj *my = getObj(myname());
 
        // 手を挙げます。
         my->setJointAngle("RARM_JOINT2", DEG2RAD(90));
      }
}}
これは「こんにちは」という認識結果が得られた場合に手を挙げるというものです。

それではコンパイルして実行してみましょう。
 $ make

***録音した音声データの認識 [#ycb258d6]
シミュレーションサーバを起動します。
 $ ./sigserver.sh -p 9001 -w soundRecog.xml &

Juliusを起動します。
 $ ./sigjsp.sh -p 9001

次にSIGViewerを起動してサーバに接続し、先ほどと同様にシミュレーションを開始し、右上のcommタブをクリック、voiceを選択、送信対象者指定します。そして"Rec Start"ボタンをクリックして録音を開始します。
#ref(sound_2.jpg)

マイクに向かって「こんにちは」としゃべってみてください。録音が終わったら"Rec End"ボタンをクリックします。この時SIGViewerの左下に「captured voice save to (Capture.wav)と表示されたら正常に音声データは録音されています。

#ref(sound_3.jpg)

次に"Send Voice"ボタンをクリックして先ほど録音したCapture.wavを選択します。先ほどのサンプルファイルsample.wavと同じ場所にCapture.wavが作成されています。

「こんにちは」と音声認識されればロボットが手を挙げると思います。ロボットが手を挙げるまでチャレンジしてみてください。

#highlight(end)
//**他のエージェントへ音声データ送信 [#b4d2b5db]

Up:[[Tutorial]]     Previous:[[エージェント間のメッセージのやりとり]]     Next:[[視覚に関する操作]]

Front page   Edit Diff Backup Upload Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes