BLOGブログ

2019.09.30UE4UE/ Network

[UE4] UE 4.23 の新機能!Open Sound Control Plugin について

執筆バージョン: Unreal Engine 4.23

エンジニアの加藤です。 今回は、UE 4.23 で追加された Open Sound Control Plugin について解説します。

※ この Plugin は Beta 扱いとなりますので、今後のアップデートで使用方法が大きく変更される恐れがあります。ご注意ください。

Open Sound Control について

Open Sound Control (OSC) は通信プロトコルの一種です。元々は MIDI の代替として電子楽器を制御する目的で設計・開発されたものですが、柔軟性が高いため、音楽以外の分野でも主にリアルタイムパラメータ制御のために使用されています。

通信方式に関する規定はないのですが、UDP が採用されることが多く、今回紹介する Plugin も UDP を用いて送受信を行う実装となっています。

なお、OSC Packet を送信する側を OSC Client、受信する側を OSC Server と呼びます。

OSC Message

OSC で送信されるデータの中身 (OSC Packet の content) は、OSC Message もしくは OSC Bundle のどちらかの形式となります。

下の画像は OSC Message の中身の例となります。

関数名 (OSC Address) と引数の型 (OSC Type Tag String) と引数 (OSC Argument(s)) を並べたものだと考えればわかりやすいかと思います (厳密な解説ではないので、詳細は仕様ページ (The Open Sound Control 1.0 Specification | opensoundcontrol.org) をご確認ください)。

OSC Address が URL ライクな階層構造となっているのが特徴です。OSC Type Tag String の i は int32、f は float32 を表しています。

なお、今回は OSC Bundle の解説・使用はしませんが、Plugin は OSC Bundle の送受信にも対応しているようです。

サンプルの作成・解説

Plugin の動作確認のために OSC Message 送信用 PC と受信用 PC を計 2 台用意するのは面倒なので、OSC Message を自分宛てに送信し、それを受信して処理を行うお手軽なサンプルを作成したいと思います。

Plugin の有効化

OSC Support” という名前の Plugin がありますので、Enabled にチェックを入れ、案内に従い Editor を再起動します。

“Open Sound Control” で検索しても出てこないので注意してください。

BP_OSCClient (送信側) の作成

Actor を Parent とする BP_OSCClient を作成し、OSC Packet の送信を担当させようと思います。キーボードの X を押すたびに、同じ OSC Message が送信されるようにします 。

下の画像のようにノードを組んでみました (画像クリックで拡大されます)。

OSC Packet を送信するためには OSCClient オブジェクトが必要となります。これを生成するのが CreateOSCClient ノードです。引数の SendIPAddress と Port には、送信先の IP アドレスと Port を指定します。今回は自分宛に送信したいので、SendIPAddress にはループバックアドレスを指定し、Port は適当に 55555 としています (SendIPAddress が空もしくは “0” でも、ループバックアドレスを指定したのと同じ扱いになるようです)。

送信する OSC Message を作成するために、その構成要素である OSC Address を先に作成します。上の画像では、「OSC Address は OSC Container と OSC Method で構成されている」ということを意識し、ConvertStringToOSCAddress ノードでまず OSC Method を指定してから OSCAddressPushContainer ノードで OSC Container を付加する、という作り方をしましたが、ConvertStringToOSCAddress ノードの引数に OSC Address そのもの (今回の場合は “/XXX/YYY/PrintFloatValues”) を直接与えてしまっても動作に影響はありません。

OSC Address を作成したら、SetOSCMessageAddress ノードで OSC Message に OSC Address をセットし、続いて Add《型名》 ノードで OSC Argument を付加します。ここでは、float(32)、int64、float(32) の順で OSC Argument を付加しました。これで OSC Message の作成が完了しました。

OSC Message の送信には SendOSCMessage ノードを使用します。

BP_OSCServer (受信側) の作成

Actor を Parent とする BP_OSCServer を作成し、こちらは OSC Packet の受信を担当させます。

OSC Client のときと同じように、OSC Packet を受信するためには OSCServer オブジェクトが必要となりますので、CreateOSCServer ノードでこれを生成します。ReceiveIPAddress と Port は CreateOSCClient ノードで指定したものと同じにします。

OnOSCAddressPatternMatchesPath に OSC Address を与えて Event を Bind させることで、与えた OSC Address を持つ OSC Packet の受信時に、Bind した Event を実行させることができます。”PrintFloatValues” という OSC Method を受信していますので、GetAllFloats ノードで float(32) 型の OSC Argument をすべて列挙し、PrintString でスクリーンに表示させるようにしました。

OSC Address の内容に依らず、OSC Message を受信したときに Call される OnOSCMessageReceived もあります。こちらを使用する場合は、OSC Message 受信後に OSC Address を見て、実行する処理を決定する流れになるかと思います。好きな方を使用してください。

動作確認

BP_OSCClient の AutoReceiveInput を Player 0 に指定した上で、BP_OSCClient と BP_OSCServer を Level 上に配置し、Play してキーボードの X を押してみます。

OSC Message の送信と受信が成功し、OSC Argument の float 値が PrintString で表示されることを確認できました。

(おまけ) Wireshark で OSC Packet の中身を確認する

上記の例はローカル内で OSC Packet の送信と受信を行っているので当たり前なのですが、全然通信を行っている感じがありません。そこで、プロトコル解析ソフトウェアである Wireshark を利用して、本当に UDP 通信で OSC Packet の送信が行われているのかを確認した上で本記事を終了したいと思います。

ループバックアドレスに対するパケットを検出したいので、Npcap Loopback Adapter をキャプチャ対象とします (Npcap がインストールされている必要があります)。

“udp.port==55555” でフィルタリングすることで、Port 55555 上で送受信された UDP 通信のパケットだけが表示されるようになります。

該当の OSC Packet を見つけることができました。このパケットが OSC Packet であることを Wireshark が検知してくれているので、内容がわかりやすく表示されています。OSC Type Tag String (“,fhf” の部分) については Blueprint でノードを組む際に意識していませんでしたが、適切に付加されていることがわかります (h は int64 型を表す Tag となります)。