音声認識+VOICEROID+FaceRigでリアルタイムアバタートーキング

@toRisouPさんの[音声認識で「結月ゆかり実況」動画を作る](http://qiita.com/toRisouP/items/979326f0ea5e944e1d3b)に触発されて、AmiVoice経由の音声認識からRealSenseSDKのSpeechRecognitionに切り替えてみました。他、オリジナルのソフトを使用していますが、ご容赦ください。

###追記
**RealSenseのSDKのバージョンがR5以降だと、RealSenseのデバイスチェックが入る？のか未搭載のPCだと日本語の認識パッケージが入らないことがあるようです（未確認情報）**
できればSDKのバージョンがR4になっているものをお勧めします。

テスト動作のツイート
<blockquote class="twitter-tweet" lang="ja"><p lang="ja" dir="ltr">FaceRig(+Live2D)+SpeechRecognition+ボイロGUI乗っ取りツール+ボイロ <a href="https://t.co/yXYN201jgq">https://t.co/yXYN201jgq</a> お借りしました <a href="https://t.co/W55JVkNpav">https://t.co/W55JVkNpav</a> 参考資料 <a href="https://t.co/3Hior0VNXh">pic.twitter.com/3Hior0VNXh</a></p>&mdash; tatsuro matsubara (@blkcatman) <a href="https://twitter.com/blkcatman/status/689456693479014401">2016, 1月 19</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

他の記事と共通部分もあるので、自分でやったことを書きます。それ以外は各自で補完お願いします。

##簡単な仕組みについて

マイク入力からSpeech Recognition([RealSenseSDK](https://software.intel.com/en-us/intel-realsense-sdk/download))のサンプルで音声認識、名前付きパイプでプロセス間通信機能追加してテキスト送信
↓
[自作のVoiceroidGUI乗っ取りツール(VoiceroidTServer)](https://github.com/blkcatman/VoiceroidTalker)でVOICEROIDのGUI操作してVOICROIDの発声
↓
VOICEROIDから仮想マイク([NETDUETTO β](http://netduetto.net/download/)か[Virtual Audio Cable](http://software.muzychenko.net/eng/vac.htm))として音声出力
↓
[FaceRig](http://store.steampowered.com/app/274920/)のLipSync機能仕様、仮想ライン入力(上のマイクに紐付けされてる）で口パク

##DF_SpeechRecognition.csの書き換え

C#版のサンプルから、SpeechRecognition.csに次のように行を追加して、自作のソフトとプロセス間通信させました。例外処理の手続きを書いていないので、VoiceroidTServerを起動していないと例外落ちすると思います。やっつけでゴメンナサイ・・・

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;//追加箇所
using System.IO.Pipes;//追加箇所

namespace voice_recognition.cs
{
    class VoiceRecognition
    {
        MainForm form;
        PXCMAudioSource source;
        PXCMSpeechRecognition sr;

        string[] simpleNames = { "Yukari", "Maki", "Zunko", "Akane", "Aoi", "Koh" };//追加箇所

        void OnRecognition(PXCMSpeechRecognition.RecognitionData data)
        {
            if (data.scores[0].label < 0)
            {
                form.PrintConsole(data.scores[0].sentence);
                //この行から追加
                using (NamedPipeClientStream client = new NamedPipeClientStream("voiceroid_talker" + simpleNames[0]))
                {
                    client.Connect(1000);
                    //サーバにーメッセージを送信する
                    byte[] buffer = UnicodeEncoding.Unicode.GetBytes(data.scores[0].sentence);
                    client.Write(buffer, 0, buffer.Length);
                    byte[] response = new byte[4];
                    client.Read(response, 0, response.Length);
                    client.Close();
                }
                //追加行ここまで
                if (data.scores[0].tags.Length > 0)
                    form.PrintConsole(data.scores[0].tags);
            }
```

##FaceRigのアバターについて

また、FaceRigのアバターについては、Limさんの[結月ゆかりのLive2Dアバター](http://library.live2d.com/Libraries/view/000024/Lim)を使用させていただきました。
(Twitterの動画では一部Live2Dのフリー版の制限機能に引っかかったので、一部パーツを削ってます。)

FaceRigへの追加の仕方は、[このページ](https://steamcommunity.com/app/274920/discussions/8/487876568226165070/)に載ってますが、英文なので簡単にまとめると、
1. C:/Program Files (x86)/SteamSteamApps/Common/Facerig/Mod/VP/PC_CustomData/Objects のフォルダを開く
2. Live2Dで.moc形式で書き出したときの名前のフォルダを作成(model.mocならmodelという名前のフォルダを作る)
3. フォルダ内に.mocファイル、.jsonファイル、書き出したときに生成されたフォルダ(model.mocで書き出したなら、model.1024かmodel.2048というフォルダ名)を入れる
4. FaceRigでアバター変更(失敗するとFaceRigが強制終了するようになるので、フォルダごと消して、立ち上げなおしてから2.からやりなおし)

##やってみた感想
RealSenseSDKのSpeechRecognitionが優秀すぎて、AmiVoiceが完全に霞みました…単語入力の手間が無いってすばらしいです。
しゃべってから認識まで2秒ぐらいのロスがありますが、原稿を見てしゃべらない限りはほとんど気にならないです。
現行の自作ソフトのVoiceroidTServerは、VOICEROIDのスピーチが終了したことを検出できないので、音声の再生終了前にテキストを送ってしまうと止まってしまうので、改善していきたいところです。
今後はUnityに持っていく方法を模索するため、FaceRigの代わりにUnityのAssetにあるOpenCVの顔認識について突っ込んでいきたいところです。