【Unity】Juliusでリアルタイム音声認識する方法を紹介します!
Juliusは商用利用可能なオープンソースの音声認識エンジンです。今回はUnityでJuliusを利用してマイクで話した言葉をリアルタイムでテキストに変換する方法についてまとめます。
Juliusを利用するための準備
Juliusは簡易的に使えるように音声認識パッケージを配布しています。今回はディクテーションキット(自動口述筆記)を利用して音声認識をしたいと思います。最初にディクテーションキット version 4.5をダウンロードして解凍して下さい。
dictation-kit-4.5/run-win-gmm.batを実行して「こんにちは」と話しかけて音声認識されるか確認して下さい。
プログラムから利用するためにモジュールモードで起動できるようにします。dictation-kit-4.5/run-win-gmm.batを開いてオプションを書き換えます。
-demoと-charconvオプションを削除して-moduleオプションを追加します。
実行してモジュールモードでの起動を確認して下さい。
Module mode readyと表示されればモジュールモードで起動しています。
Juliusを利用したコーディング
Juliusをモジュールモードで起動しするとローカルホストにサーバーが立ち上がります。Socketを利用して127.0.0.1のポート番号10500へ接続します。
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync("127.0.0.1", 10500);
ループしてJuliusサーバーからのレスポンスを待ちます。レスポンスはXML形式のUTF8のバイト配列で送られてくるのでEncoding.UTF8.GetStringを利用して文字列化しています。
byte[] buffer = new byte[1024];
ArraySegment<byte> segment = new ArraySegment<byte>(buffer, 0, buffer.Length);
while (true)
{
int byteReceived = await socket.ReceiveAsync(segment, SocketFlags.None);
string xml = Encoding.UTF8.GetString(buffer, 0, byteReceived);
}
XMLは以下のような形式で送られてきます。
<RECOGOUT>
<SHYPO RANK="1" SCORE="-4150.723145">
<WHYPO WORD="" CLASSID="<s>" PHONE="silB" CM="0.745"/>
<WHYPO WORD="おはよう" CLASSID="おはよう+感動詞" PHONE="o h a y o:" CM="0.809"/>
<WHYPO WORD="ござい" CLASSID="ござい+動詞" PHONE="g o z a i" CM="0.928"/>
<WHYPO WORD="ます" CLASSID="ます+助動詞" PHONE="m a s u" CM="0.861"/>
<WHYPO WORD="。" CLASSID="</s>" PHONE="silE" CM="1.000"/>
</SHYPO>
</RECOGOUT>
本来ならXMLパーサーを使うべきですが、今回は処理を簡単にするためにWORD属性の文字列を連結して</RECOGOUT>で文章の終了とします。Regexを利用して正規表現でWORD属性の文字列を取得します。
Match match = Regex.Match(str, "WORD=\"([^\"]*)\"");
if(match.Success)
{
message += match.Value[6..(match.Value.Length - 1)];
}
プログラムを終了するときに接続を閉じます。
socket.Shutdown(SocketShutdown.Both);
socket.Close();
全ソースコード JuliusTest.cs
using System;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UnityEngine;
public class JuliusTest : MonoBehaviour
{
Socket socket = null;
void Start()
{
Task.Run(() => Connect());
}
void OnDisable()
{
if(socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
async void Connect()
{
socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync("127.0.0.1", 10500);
byte[] buffer = new byte[1024];
ArraySegment<byte> segment = new ArraySegment<byte>(buffer, 0, buffer.Length);
string message = "";
while (true)
{
int byteReceived = await socket.ReceiveAsync(segment, SocketFlags.None);
string xml = Encoding.UTF8.GetString(buffer, 0, byteReceived);
string[] strs = xml.Split('\n');
foreach (var str in strs)
{
Match match = Regex.Match(str, "WORD=\"([^\"]*)\"");
if(match.Success)
{
message += match.Value[6..(match.Value.Length - 1)];
}
else if(str.Contains("</RECOGOUT>"))
{
Debug.Log(message);
message = "";
}
}
}
}
}
確認用シーンの作成と実行
確認用のUnityシーンを作成します。ヒエラルキーで適当なゲームオブジェクトを作成しインスペクターでJuliusTest.csを追加します。
Juliusをモジュールモードで起動した後でUnityを実行します。
喋った言葉がログ表示されることを確認して下さい。
マイクからの音声をテキストに変換することができました。
字幕やコミュニケーションツールなどに使えそうですね。
関連ページ
こちらのページも合わせてご覧下さい。