cluster OSCHandleを使用して、照明エフェクトを制御する(サンプルあり)

2025/02/11に公開

clusterにとうとうOSCが実装されました。
https://note.com/cluster_official/n/n75b56c4448ee
今回は照明エフェクトをOSCで制御してみたのでOSCのちょっとした説明と、作ったスクリプトの紹介です。音楽系イベントなどでぜひ使ってみてください。

まずはOSCを受信してみる

まずはシンプルにOSCを受信して、ログに出力してみましょう。ドキュメントにサンプルスクリプトが載っています。
https://docs.cluster.mu/script/interfaces/OscHandle.html

このスクリプトをPlayerScriptに設定し、

受信したOSCメッセージをログに出力する
_.oscHandle.onReceive(messages => {
  const lines = [];

  messages.forEach((message, i) => {
    const { address, timestamp, values } = message;

    lines.push(`== message [${i + 1}/${messages.length}]`);
    lines.push(`address: ${address}`);
    lines.push(`timestamp: ${new Date(timestamp).toLocaleString()}`);

    values.forEach((value, j) => {
      lines.push(`= value [${j + 1}/${values.length}]`);

      lines.push(`getInt(): ${value.getInt()}`);
      lines.push(`getFloat(): ${value.getFloat()}`);
      lines.push(`getAsciiString(): ${value.getAsciiString()}`);
      lines.push(`getBlobAsUint8Array(): ${value.getBlobAsUint8Array()}`);
      lines.push(`getBlobAsUtf8String(): ${value.getBlobAsUtf8String()}`);
      lines.push(`getBool(): ${value.getBool()}`);
    });
  });

  _.log(lines.join("\n"));
});

同じオブジェクトのScriptable Itemでは以下のコードでPlayerScriptをインタラクトしたプレイヤーにセットします。

Playerスクリプトをインタラクトしたプレイヤーにセット
$.onInteract((playerHandle) => {
    $.setPlayerScript(playerHandle);
});

QLC+からOSCを送信する

今回はOSCを送信するソフトウェアとして、QLC+を使用します。
https://www.qlcplus.org/
以下の手順でOSCを送信できるように設定します。

  • QLC+を開いて、画面下のタブからInput/Outputs (入力/出力設定)を開く
  • OSCの出力先にするIPアドレスのOSC欄のOutput (出力)にチェックを入れる
  • スパナとドライバーのボタンからOSCプラグイン設定を開き、Output AddressにOSCの出力先にするIPアドレスを設定し、Output Port9000を設定する

先ほどの受信したOSCメッセージをログに出力するサンプルスクリプトを、ワールドにアップロードしてそのオブジェクトをインタラクトします。これでインタラクトしたユーザーのPCでOSCが受信状態になります。
QLC+では画面下のタブからSimple Desk(シンプル卓)を開き、1~512番までのフェーダーを操作することで、OSCメッセージが送信され、OSCメッセージの内容がログに出力されるはずです。

OSCってなに?

まずはOSCの仕組みについて知っておきましょう。UDP通信の方式で、以下のような構造のデータをやり取りします。

/address/0 int:255 float:0.5

OSCではアドレス、数値の型と数値の3つのメッセージがやりとりされ、一つのアドレスで複数の数値を送信することも可能です。このような構造をOSCメッセージと呼びます。

cluster scriptでOSCを使用する

まずclusterスクリプトでOSCを受信するには、Playerスクリプト上でoscHandle.onReceiveを呼び出して使用します。

oscHandle.onReceive
_.oscHandle.onReceive(messages => {
});

コールバックで渡されるmessagesに、受信されたOSCメッセージが配列で渡されます。(配列で複数の)

次のように取得されたmessagesからOSCメッセージをひとつづつ取得して、アドレスごとに処理を分岐することができます。

OSCメッセージごとに処理を分岐させる
_.oscHandle.onReceive(messages => {
    messages.forEach((message, i) => {
        switch (message.address) {
            case "/light/intensity:
                // ここに/light/intensityのOSCメッセージが受信されたときの処理
                break;
            case "/light/color":
                // ここに/light/colorのOSCメッセージが受信されたときの処理
                break;
            default:
                break;
        }
    });
});

message.valuesでOSCメッセージに含まれる値の配列を取得できます。
valuesの配列の中に含まれるそれぞれの要素から値を取得するには、取得する値の型に応じた関数を使用する必要があります。
https://docs.cluster.mu/script/classes/OscValue.html#getFloat

_.oscHandle.onReceive(messages => {
    messages.forEach((message, i) => {
        switch (message.address) {
            case "/light/intensity:
                message.values.forEach((value, j) => {
                    // ここで、それぞれの値を取り出す処理などを書く
                    $.log(value.getFloat()); // valueをFloatとして取得
                });
                break;
            ...
        }
    });
});

受信したOSCメッセージは、sendToでほかのアイテムに送信できます。

_.sendTo(itemHandle, "intensity", message.values[0].getFloat());

受信側のスクリプトはこのようになります。

$.onReceive((messageType, arg, sender) => {
    switch (messageType) {
        case "intensity":
                $.log(arg); //OSCを受信して送信されたメッセージintensityの値をログに出力
            break;
        default:
            break;
    }
}, { player: true });

サンプルプロジェクト

改変など自由にご利用下さい。
https://github.com/Dolphiiiin/ClusterOscLighting/releases

サンプルプロジェクトの構成

ClusterOscLighting/
├─ Materials/
├─ Scenes/
│  ├─ QlcSampleScene `QLC+によるDMXサンプル`
│  ├─ S2lSampleScene `Sound2Lightによるオーディオリアクティブサンプル`
├─ Scripts/
│  ├─ qlc/
│  │  ├─ qlcListner_player.js `QLC+からのOSCを受信するPlayerスクリプト`
│  │  ├─ qlcMaterial_item.js `qlcListnerからのOSCをマテリアルに反映するItemスクリプト`
│  ├─ s2l/
│  │  ├─ s2lListner_player.js `Sound2LightからのOSCを受信するPlayerスクリプト`
│  │  ├─ s2lMaterial_item `s2lListner_playerからのOSCをマテリアルに反映するItemスクリプト`
│  ├─ attachOscListner_item.js `PlayerスクリプトをプレイヤーにセットするためのItemスクリプト`

QlcSampleScene

QLC+でビームライトの色、明るさをコントロールするサンプルです。
アップロードし、ボタンを押してOSC受信状態にすることで、シンプル卓からR,G,B,Intensityの順でコントロールが可能です。
(QLC+の詳細な使い方は割愛しますが、個々の工夫次第ではとても細かなステージ演出が可能になります)
https://x.com/Dolphiiiin_/status/1888959718003216637

S2lSampleScene

Sound2Lightでマイク入力から入力されたオーディオをリアルタイムに分析し、4つの周波数帯域でビームライトを点滅させるサンプルです。
https://github.com/ETCLabs/Sound2Light/releases/tag/v0.0.3.1.0.2

Sound2Lightのセットアップ

Sound2Lightを開き、画面左中央のSettingsを開き、以下に設定を変更します。

項目 設定値
OSC IP Address OSCの出力先アドレス
OSC Protcool UDP
OSC UDP Tx Port 9000
OSC UDP Rx Port 無視
Console Type 無視
Input ソースにする音源があ流れる音声デバイス

画面下のOSC Messageの列で、左からChannnelNumberをChannnel 1 Channel 2の順に設定し、それぞれのModeをLevelに設定してください。

サンプルをアップロードして、ボタンを押してOSC受信状態にしたうえで音楽を再生することで音楽に合わせて照明が点滅するはずです。
https://x.com/Dolphiiiin_/status/1888944332771889242

Discussion