Unityで手っ取り早くマイクの音声を文字列にする

今のご時世でUnityでマイク入力を文字列に変換する方法を調べて、これが一番手っ取り早いかなぁ～と
[Windows.Speech](https://docs.unity3d.com/ja/current/ScriptReference/Windows.Speech.DictationRecognizer.DictationResultDelegate.html)もやってみましたが[動かない](https://issuetracker.unity3d.com/issues/windows-windows-dot-speech-dot-dictationrecognizer-results-in-an-unknown-error)ので[IntelRealsenseSDK](https://software.intel.com/en-us/intel-realsense-sdk/download)になりました。
*※IntelRealsenseのカメラがなくても動きます*

# 1.IntelRealsenseSDKのダウンロード

[IntelRealsenseSDK](https://software.intel.com/en-us/intel-realsense-sdk/download)のページからFree DownloadでSDKをダウンロードします。
（ユーザ登録とか必要でめんどくさい）

その後、
![e5b0a33c9c64a31e6dc577a04536ab3d.png](https://qiita-image-store.s3.amazonaws.com/0/79067/5ae2ac3d-5380-f642-a32b-e1a6a2914683.png)

Intel RealSense SDK for WindowsのDwonloadボタンを押します。

![c1668ccdc29d0c54dfd1c9c473261e72.png](https://qiita-image-store.s3.amazonaws.com/0/79067/a1f98644-bdba-8bd3-6117-50a30ab7de7f.png)

どのバージョンとどのインストーラ―をダウンロードしますか？って聞かれるので
【2016 R2】でめんどくさいので【intel_rs_sdk_offline_package】をダウンロードしました。
（別にwebsetupでも良いかと思います）

# 2.IntelRealsenseSDKのインストール

ダウンロードしたインストーラーを実行します。
何をインストールしますか？　聞かれるので、Unity用のSDKと日本語解析するモジュールをインストールします。
具体的には

- Intel RealSense SDK
 - Universal Windows Platform Extension
- Intel RealSense SDK Runtime
 - Core （必ずチェックが入ってる）
- Speech Recognition and Synthesis
 - Japanese
 - Speech Recognition and Synthesis

これだけ入れればOKです

![1.png](https://qiita-image-store.s3.amazonaws.com/0/79067/87f73e46-6e6d-bd0b-dce1-fb5f97e7084a.png)

![2.png](https://qiita-image-store.s3.amazonaws.com/0/79067/c4e39255-87a9-fa59-e7c2-b6e0ef493d9c.png)

チェック後、インストールを行います。

# 3.Unity上で必要なPackageを入れる

Unityで必要なPackageは以下のところにありますので
【C:\Program Files (x86)\Intel\RSSDK\framework\Unity\UnityCSharp.unitypackage】
パッケージをインポートします。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/79067/5a06ad4f-ddbf-2a81-ee52-5d89f6ff2a45.png)

# 4.サンプルコード

こんな感じのサンプルコードです。
適当なオブジェクトに貼り付けて実行です

```csharp:VoiceInputTest.cs
using UnityEngine;

public class VoiceInputTest : MonoBehaviour
{
    private PXCMSession session;
    private PXCMAudioSource source;
    private PXCMSpeechRecognition sr;
    private PXCMSpeechRecognition.Handler handler;

    public void Start()
    {
        session = PXCMSession.CreateInstance();
        source = session.CreateAudioSource();

        PXCMAudioSource.DeviceInfo dinfo = null;

        source.QueryDeviceInfo(0, out dinfo);
        source.SetDevice(dinfo);
        Debug.Log(dinfo.name);

        session.CreateImpl<PXCMSpeechRecognition>(out sr);

        PXCMSpeechRecognition.ProfileInfo pinfo;
        sr.QueryProfile(out pinfo);
        pinfo.language = PXCMSpeechRecognition.LanguageType.LANGUAGE_JP_JAPANESE;
        sr.SetProfile(pinfo);

        handler = new PXCMSpeechRecognition.Handler();
        handler.onRecognition = (x) => Debug.Log(x.scores[0].sentence);
        sr.SetDictation();
        sr.StartRec(source, handler);
    }

    void OnDisable()
    {
        if (sr != null)
        {
            sr.StopRec();
            sr.Dispose();
        }

        if (session != null)
            session.Dispose();
    }

}
```

もし、複数マイクがある場合は
`source.QueryDeviceInfo(0, out dinfo);`
ここの0を1とか2とかして試してみてください

# 5.実行

実行してマイクでなにかしゃべるとコンソールに表示されます

![c8e36cc51d8681936fe5952d52c8c5bc.png](https://qiita-image-store.s3.amazonaws.com/0/79067/9dcbf8b9-291d-4c88-b2c1-312d3f95adef.png)

---
# うまくいかないパターン

- マイクデバイスが違う
 - コンソールに出てくるマイクの名前を確認してください
- LANGUAGE_JP_JAPANESEをLANGUAGE_US_ENGLISHにするとなんかコンソールに出る
 - SDKを一度removeして再度インストールしてみてください

# サンプル２

よくわからないと言われたのでラムダ式を使わないパターンを想像で書いてみました
想像で書いたので違うかもしれません。
（Syntaxチェックすらしてません）

```csharp:VoiceInputTest.cs
using UnityEngine;

public class VoiceInputTest : MonoBehaviour
{
    private PXCMSession session;
    private PXCMAudioSource source;
    private PXCMSpeechRecognition sr;
    private PXCMSpeechRecognition.Handler handler;
    
    private const string matchstr = "あああ";

    public void Start()
    {
        session = PXCMSession.CreateInstance();
        source = session.CreateAudioSource();

        PXCMAudioSource.DeviceInfo dinfo = null;

        source.QueryDeviceInfo(0, out dinfo);
        source.SetDevice(dinfo);
        Debug.Log(dinfo.name);

        session.CreateImpl<PXCMSpeechRecognition>(out sr);

        PXCMSpeechRecognition.ProfileInfo pinfo;
        sr.QueryProfile(out pinfo);
        pinfo.language = PXCMSpeechRecognition.LanguageType.LANGUAGE_JP_JAPANESE;
        sr.SetProfile(pinfo);

        handler = new PXCMSpeechRecognition.Handler();
        handler.onRecognition = OnRecognition;
        sr.SetDictation();
        sr.StartRec(source, handler);
    }

    private void OnRecognition(PXCMSpeechRecognition.RecognitionData data)
    {
        if(matchstr.Equals(data.scores[0].sentence)
        {
           Debug.Log("同じ文字");
        }else{
           Debug.Log("違う文字");
        }
    }

    void OnDisable()
    {
        if (sr != null)
        {
            sr.StopRec();
            sr.Dispose();
        }

        if (session != null)
            session.Dispose();
    }

}
```