まゆたまガジェット開発逆引き辞典

電子工作やプログラミングのHowtoを逆引き形式で掲載しています。作りたいモノを決めて学んでいくスタイル。プログラマではないので、コードの汚さはお許しを。参照していないものに関しては、コピペ改変まったく問いません

TidalCyclesでライブコーディング 準備編

プログラミングをしつつ音を生成したりVJしたりする「ライブコーディング」が急にしたくなったので、環境構築のメモです。
今回は「TidalCycles」という音生成の環境を使って演奏していきます。
www.youtube.com

TidalCyclesのインストール(Mac)

1.下記から「Download.zip」をクリックし、ダウンロードする
tidal-bootstrap

2.下記からAppleIDでログインし、自分のOSに合ったcommand line toolsをダウンロードする
Sign in with your Apple ID - Apple Developer

3.「ユーティリティ」→「ターミナル」アプリを立ち上げ、下記を入力してエンターキーを押す

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


4.1.でダウンロードした中にある「tidal-bootstrap.command」をダブルクリックする。TidalCyclesのインストールが始まる。
途中「y/n (or press Enter to accept)」とキーボード入力を求められたら、「Y」キーを押してからエンターキーを押す
5.「プロセスが完了しました」という表示が出たら、ターミナルを終了させる
6.「アプリケーション」の中にある「SuperCollider」アプリをダブルクリックして立ち上げる
7.エディタが立ち上がるので、左の画面に下記を入力する

include("SuperDirt")

f:id:prince9:20181101114347p:plain

8.「include("SuperDirt")」の部分をマウスドラッグして選択し、エンターキーを押す
9.インストールが始まるので、しばし待つ。「-> SuperDirt」が出てきたら終了
10.SuperColliderを終了させ、再度起動させる
11.「SuperDirt.start;」と入力し、この部分をマウスドラッグで選択して「command+enter」キーを押す
12.右下に「SuperDirt: listening to Tidal on port 57120」と出たらOK
f:id:prince9:20181101114719p:plain

13.「アプリケーション」から「Atom」をダブルクリックして開く
14.「Atom」メニュー→「Preference」を選択し、「+Install」をクリックする
f:id:prince9:20181101132544p:plain

15.「Tydalcycles」と入力して、「Package」を押す
f:id:prince9:20181101132639p:plain

16.Tydalcyclesの「Install」をクリックしてインストールする
f:id:prince9:20181101132732p:plain

17.ターミナルを再度立ち上げ、「brew install ghc」と入力してエンターキーを押す

Tydalcyclesを動かす

1.SuperColliderで右下に「SuperDirt: listening to Tidal on port 57120」と出ているか確認する
2.Atomを立ち上げ、「Packages」→「TidalCycles」→「Boot TidalCycles」を選択する
3.「d1 $ sound "bd sn"」と入力する
4.「File」→「Save」を選択し、「Test.tidal」など、拡張子が「.tidal」にして保存する
5.「d1 $ sound "bd sn"」をドラッグして選択し、「command+enter」キーを押す

上記の5.でエラーが出た場合

1.下記から「Download Core」をクリックしてダウンロード、インストールする
www.haskell.org

2.ターミナルを立ち上げ、「cabal install tidal」と入力してエンターキーを押す
3.SuperColliderを立ち上げ「SuperDirt.start;」と入力し、この部分をマウスドラッグで選択して「command+enter」キーを押す
4.Atomで「Tydalcyclesを動かす」の4.で保存したファイルを開く
5.「Packages」→「TidalCycles」→「Boot TidalCycles」を選択する
6.「d1 $ sound "bd sn"」と入力する
7.音が鳴る。止めたいときは「hush」と入力して、この部分をマウスドラッグで選択して「command+enter」キーを押す

IBM Watsonで音声認識→テキスト変換をする(難易度:易)

この記事はVTuber Tech #2 Advent Calendar 2018 22 日目の記事です。
qiita.com

Advent Calendar投稿につき、加筆しています。

自己紹介

リアル/バーチャルで学芸員をしております、よーへんと申します。
プログラマーではありませんが、仕事でインタラクティブ作品を制作したり展示のお手伝いをしています。
バーチャルYouTuberとしてアート・テクノロジートークイベントの司会や配信をしている関係で、今回の記事を書いてみました。
エンジニア・プログラマーではないので、小目汚しのコードがあったらすみません。

概要

UnityとIBM Watsonの音声認識機能を使って、生配信でリアルタイムに日本語字幕を表示します。
一応YouTube公式でリアルタイム字幕機能はあるようですが、チャンネル1万人以上が対象のようです。
アーカイブの方が観る人多いんだから、自動字幕オンにしてもらえばいいじゃんというツッコミはなしで・・・

Watson公式でこんなページがありますが、現在仕様が変わっており全く使えません。Oh...
www.ibm.com

2018年10月末現在において、いちおう下記の方法で「日本語で」音声認識をしてテキスト化ができました。使用したのはUnity2018+iMac5Kです。
f:id:prince9:20181027203053p:plain

下記が実際の配信画面のスクショになります。
f:id:prince9:20181222000807p:plain

下記のリンクですでに似た記事がありますが、本記事は実際に運用した際のものになります。
qiita.com

システム概要

配信はバーチャルルーム作成サービス「cluster」とYouTubeLiveを使用しました。
clusterで配信専用のアカウントを司会アカウントとは別に作成し、ミキサー「AG06」のループバック機能を使って、配信専用アカウントで流れてきた音声すべてをUnity+Watsonの音声認識に通しています。
clusterの画面とUnityのゲームビューをOBSで合成し、clusterの音声とともにYouTubeに流しています。

やってみた所感

ウチが主催するトークイベントで、出演者さんの許可を得て試してみました。
認識精度はまずまずでしたが、「あー」「えー」などのタメも変換されてしまうため、そこだけ削除するスクリプトを入れるべきでした。
あとこもった喋り方をされる出演者さんの認識が極端に残念でした。
認識のタイムラグは1秒もなかったような気がしています(ただ音量確認のため実際配信された音声をモニタリングしていたので、もしかしたら2秒ほどラグがあったかもしれません)。

Watsonの登録をして、アセットをインストールする

下記のサイトを参照して、「アセットのインストール」までを行います(「サンプルを動かす」の前まで)。
kan-kikuchi.hatenablog.com

IDとパスワードをコピーする

1.IBM Cloudにログインしている状態で、「IBM Cloud」のロゴをクリックする
2.ダッシュボードが出てくるので、作成したプロジェクト名をクリックする
3.「資格情報」のところの「URL」「ユーザ名」「パスワード」をどこかにコピーしておく

サンプルを改良して、テキストを表示する

1.「IBM Watson SDK for Unity」をダウンロード&インポートすると、「Assets」に「Watson」というフォルダができているので、「Watson」→「Examples」→「ServiceExamples」の中の「ExampleStreaming」シーンをダブルクリックして開く
2.「Assets」フォルダに日本語フォントの「.ttf」ファイルをドラッグ&ドロップする
2.Hierarchyの「Canvas」→TextStreamingをクリックし、Inspectorの「Font」に2.のファイルをドラッグ&ドロップする
3.FontSizeを適切な大きさにする(30くらい)
4.Colorで色を変える
5.「Pos X」「Pos Y」で位置を調整する
6.Textの部分に日本語を入力し、表示されるか確認する

画像を表示する

テロップなどを出したい場合は下記のようにします。なお、OBSを使ってネット配信することを考え、Canvasのサイズを1280×720にしています。
下記の場合はOBSでクロマキー抜きをするため、画像ファイルの背景を緑色にしています。
f:id:prince9:20181027202652p:plain

1.Assetsに画像ファイルを読み込む
2.画像ファイルをクリックし、Texture Typeを「Sprite(2D and UI)」にする
f:id:prince9:20181027201519p:plain
3.「GameObject」メニュー→「UI」→「Image」を選び、Inspectorの「Source Image」に1.の画像をドラッグ&ドロップする
4.キーボードで画像を切り替えたい場合は、スクリプトを作ってこの「Image」にドラッグ&ドロップする
5.Hierarchyの「Canvas」をクリックし、下記のような設定にする
f:id:prince9:20181027201405p:plain
6..Hierarchyの「Canvas」→「Image」をクリックし、下記のような設定にする
f:id:prince9:20181027201608p:plain

音声認識をしてテキスト表示させる

1.Hierarchyの「ExampleStreaming」をクリックし、Inspectorに下記をコピペする。
・Service URL この記事の「IDとパスワードをコピーする」の3.でコピーした「URL」
・Username この記事の「IDとパスワードをコピーする」の3.でコピーした「ユーザ名」
・Password この記事の「IDとパスワードをコピーする」の3.でコピーした「パスワード」

2.「Watson」→「Examples」→「ServiceExamples」→「Scripts」→「ExampleStreaming」をダブルクリックし、スクリプトを編集できるようにする
3.日本語が使えるように下記のように追加する
・public bool Active { 〜以下の部分に、「_service.RecognizeModel = "ja-JP_BroadbandModel";」を追加する

追加後:

_service.DetectSilence = true;
                _service.EnableWordConfidence = true;
                _service.EnableTimestamps = true;
                _service.SilenceThreshold = 0.01f;
                _service.MaxAlternatives = 0;
                _service.EnableInterimResults = true;
                _service.OnError = OnError;
                _service.InactivityTimeout = -1;
                _service.ProfanityFilter = false;
                _service.SmartFormatting = true;
                _service.SpeakerLabels = false;
                _service.WordAlternativesThreshold = null;

                //日本語設定
                _service.RecognizeModel = "ja-JP_BroadbandModel";

                _service.StartListening(OnRecognize, OnRecognizeSpeaker);

3.テキストの表示を変えるため、下記のように編集する
・string text = string.Format 〜を削除するかコメントアウトして、「string text = string.Format("{0}", alt.transcript);」と書き換える

コメントアウト&追加後:

foreach (var alt in res.alternatives)
                {
                    //string text = string.Format("{0} ({1}, {2:0.00})\n", alt.transcript, res.final ? "Final" : "Interim", alt.confidence);
                    
                    //表示されるテキスト
                     string text = string.Format("{0}", alt.transcript);

                    Log.Debug("ExampleStreaming.OnRecognize()", text);
                    ResultsField.text = text;
                }

4.マイクを用意し、接続する。MacWindowsもOSの環境設定のサウンドの項目で入力(マイク)を設定する
5.再生ボタンを押して、マイクに向かってしゃべる

難易度高ですが、認識をチューニングしたい(カスタムモデルを使いたい)という場合は合わせて下記をご覧ください。
qiita.com

女声から男声、女声(低)から女声(高)にボイスチェンジする

女声から男声はあまり資料がないので、もし成功された方はぜひメモを残してほしい・・・
というわけで、設定をミスったときのための自分メモです。
すべて無料のものを使っています。

ボイスチェンジのパターン

地声の女声(低)→男声のボイスチェンジ
地声の女声(低)→某エヴァのシンちゃん
地声の女声(低)→女声(高)

地声の女声(さらに低)→女声(もっと低)

でやってみました。

 

比較のための地声


私はわりと音域が広いようで、低い声からロリ声まで出ます(疲れますが)。
比較として、ガチの地声(低い女声)とロリな地声(高い女声)をまず用意しました。

・ガチの地声(低い女声)

・ロリな地声(高い女声)

 さらに低い地声はちょっと微妙だったので、掲載をパスしました。

ボイスチェンジ 女声→男声


・使用アプリは「恋声」→「REAPER」
恋声で変換とEQ、REAPERでノイズを取りました。REAPERで使用したのはVST「ReaFir」の「Subtract」のみ

恋声設定

f:id:prince9:20181022050237p:plain

f:id:prince9:20181022050212p:plain

 

ボイスチェンジ 女声→某エヴァのシンちゃん

使用アプリはREAPERのみ。ボイスチェンジはVSTの「RoVee」を使用

 

■REAPER設定

f:id:prince9:20181022050259p:plain

f:id:prince9:20181022050312p:plain

f:id:prince9:20181022050323p:plain

f:id:prince9:20181022050335p:plain

ボイスチェンジ 地声の女声(低)→女声(高)


これはロリ地声のほうがやはり良かったです。EQの設定が甘い感。自分のロリ声の波形に近づけるEQにしないとよくなりませんね。
使用アプリはREAPERのみ。ボイスチェンジはVSTの「RoVee」を使用しました。

■REAPER設定

f:id:prince9:20181022050358p:plain

f:id:prince9:20181022050409p:plain

f:id:prince9:20181022050418p:plain

f:id:prince9:20181022050429p:plain

ボイスチェンジ 地声の女声(さらに低)→女声(もっと低)

これが最もヘッドホンやスピーカーによって違いが出ました。あるヘッドホンだと良くても、あるスピーカーでは地声と変わらず・・・みたいな。

さらに低く発声した地声を恋声によってフォルマントのみ変更。
これが最もEQをいじくると結果が変わりました。

田中敦子さんみたいにしたかったと供述しており・・・

恋声で変換とEQ、REAPERでノイズを取りました。REAPERで使用したのはVST「ReaFir」の「Subtract」のみ。

恋声設定

f:id:prince9:20181022193443p:plain

f:id:prince9:20181022193457p:plain

VRChatやclusterでVR機器を使ってボイスチェンジする

最近流行りのボイスチェンジですが、意外と設定がややこしかったのでメモ代わりです。
VRChatとcluster(バーチャルルーム)で使用する想定です。
これらだけでなく、アプリ自体にサウンドの入出力設定の項目がない=デフォルトのサウンド設定を使うアプリも同様の設定でいけると思われます。
(VRChatやclusterなど、Unityベースのアプリ)
「VoiceMeeter Banana」のアプリは使用しません。

仮想サウンドミキサーの設定をする

1.下記から「VoiceMeeter Banana」をダウンロード&インストールする
www.vb-audio.com

2.Windowsサウンド設定の項目を開き、下記のように「再生」のタブに「Voice Meeter Aux Input」「VoiceMeeter Input」があるか確認する
f:id:prince9:20181021185832p:plain

3.今度は「録音」のタブに「Voice Meeter Aux Output」「VoiceMeeter Output」があるか確認する
f:id:prince9:20181021190011p:plain

4.「再生」のタブの「スピーカー」を右クリックし、「既定のデバイス」を選択する。Viveのイヤホン端子を既定のデバイスにする
f:id:prince9:20181021185832p:plain

5.「録音」のタブの「VoiceMeeter Output」を右クリックし、「既定のデバイス」を選択する

ボイスチェンジャーアプリの設定をする

1.ボイスチェンジャーアプリを立ち上げ、サウンド設定の項目を開く
2.下記のように設定する。双方とも同じで、Inputが「Viveのマイク(3-HTC Vive)」・Outputが「VoiceMeeter Input」
恋声など単体で動くアプリの場合:
f:id:prince9:20181021190622p:plain

VSTボイスチェンジャーの場合(:
f:id:prince9:20181021190659p:plain

恋声VSTで出力する場合(恋声のボイスをVSTでさらに加工する場合)
まず、こちらから「VB-Cable Virtual Audio Device」をダウンロード&インストールします
www.vb-audio.com


さらに、下記2つのアプリの設定をします。
恋声:
録音デバイス:「Viveのマイク(3-HTC Vive)」
再生デバイス:「CABLE Input」
↑すみません、スクショ撮り忘れです

VST使用可能アプリ(REAPERやCubaseなど):
f:id:prince9:20181021195946p:plain


3.ボイスチェンジできるようにしておく

StreamVRの設定

VRChatやclusterなど、ベースがUnityのアプリはデフォルトのサウンド設定を使うようになっています。
1.StreamVRを立ち上げ、「StreamVR▼」の▼をクリックし、「設定」を選ぶ
2.「設定」の「オーディオ」を選択し、下記のように設定する
f:id:prince9:20181021191045p:plain

3.VRChatもしくはclusterを立ち上げ、マイクをオンにする

UnityでiPhoneを使ってライトをコントロールする

下記ではMIDI機器を使用しましたが、今度はiPhoneでライトをコントロールしました。
prince9.hatenablog.com

ただタッチで細かい操作は事故りそうなので、個人的にはMIDI機器使用が確実と思われます。

f:id:prince9:20181016201155g:plain

プロジェクトファイルはこちらです。
www.dropbox.com

今回はOSCという通信規格を用います。Unityで使用するにあたり、hecomiさんのuOSCをお借りしました。
ありがとうございます。
tips.hecomi.com

iPhoneアプリ「TouchOSC」を使用する

※TouchOSC以外を使う場合は1.のみ行って、次の「OSCアプリの出力を調べる」に進んでください

1.使用するPCのIPアドレスを調べて、メモする
Macの場合:
minto.tech
WIndowsの場合:
https://laboradian.com/find-ip-on-windows10/laboradian.com
2.App Storeで「TouchOSC」アプリをダウンロードする
※「Mrmr」など無料のものもありますが、「TouchOSC」が個人的に使いやすかったです
3.立ち上げると下記のような設定画面が出てくるので、「CONNECTIONS」→「OSC」をタップする。
f:id:prince9:20181016195251p:plain
すでにUIが出ている場合は●ボタンを押す
f:id:prince9:20181016195526p:plain
4.「Host」に1.でメモしたPC側のIPアドレスを入力して、そのまま「完了」ボタンを押していく
f:id:prince9:20181016195411p:plain
5.「LAYOUT」を「Automat5」にする
6.右上の「Done」ボタンを押す

uOSCを読み込んで、OSCアプリの出力を調べる

1.下記にアクセスし、「.unitypackage」をクリックしてダウンロードする
github.com
2.Unityのプロジェクトを作成し、先ほどダウンロードした「.unitypackage」ファイルを「Assets」フォルダにドラッグ&ドロップする
3.「Import」ボタンを押して読み込む
4.「Assets」を右クリックし、「Create」→「C# Script」を選択する
5.4.に「OSCDataTestScript」等名前をつける
6.「GameObject」メニュー→「Create Empty」で空のオブジェクトを作成する
7.「Assets」フォルダ→「uOSC」→「Scripts」→「uOscServer」を「GameObject」にドラッグ&ドロップする
8.Hierarchyにある「GameObject」に「OSCDataTestScript」をドラッグ&ドロップする
9.Hierarchyにある「GameObject」をクリックし、「Inspector」→「Port」に「8000」と入力する
10.「Ctrl(Macはcommand) + Shift + C」キーを押して、コンソール画面を出す
11.「OSCDataTestScript」をダブルクリックして、下記のスクリプトを入力する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using uOSC;

public class OSCDataTestScript : MonoBehaviour {




	// Use this for initialization
	void Start()
    {
        var server = GetComponent<uOscServer>();
        server.onDataReceived.AddListener(OnDataReceived);
		
    }

    void OnDataReceived(Message message)
    {
        // address
        var msg = message.address + ": ";

      

        // values
        foreach (var value in message.values)
        {
            msg += value.GetString() + " ";
        }
        //どのUIかを出力
Debug.Log("どのUIか = " + message.address);

/*
下記のDebug.LogはUIを動かしてどんな値が出力されるのかを表示する。
アプリによってint・float・string・ byte[]いずれかで出力されるので、
分からない場合は下記の「(float)message.values[0]」の「float」を「int・string・ byte[]」いずれかに変えて、エラーが出ないものにすると良いかも。
stringの場合は、下記のように数値に変えてやる必要あり
文字列から数値へ変換:
float f1 = float.Parse("105.6");

 */
        Debug.Log("値 = " + (float)message.values[0]);
    }
	
	// Update is called once per frame
	void Update () {
		
		
	}
}


12.Unityの実行ボタン(再生ボタンみたいなやつ)を押す
13.TouchOSCなどのOSCアプリ(IPhoneアプリ)を立ち上げ、UIをタッチしてみる
14.Unityの「Console」ウィンドウに「どのUIを操作したか」「どんな値か」が表示されているのを確認する
f:id:prince9:20181016195135p:plain
15.すべてのUIをタッチして、「どのUIか」の値をメモっておく。「/toggleA_1」「/1/faderA」など

オブジェクトと照明を作成する

1.新しくプロジェクトを作成し、先ほどダウンロードした「.unitypackage」ファイルを「Assets」フォルダにドラッグ&ドロップする
2.「Import」ボタンを押して読み込む
3.適当にオブジェクトとライトをを配置して、名前をつける
4.「GameObject」メニュー→「Create Empty」で空のオブジェクトを作成する(ライトを増やすことを想定して)
5.4.に名前をつける(ここでは「Lights」にしました)
6.ライトを5.にドラッグ&ドロップする

スクリプトを書く

1.「Assets」フォルダ→「uOSC」→「Scripts」→「uOscServer」を「GameObject」にドラッグ&ドロップする
2.「Assets」を右クリックし、「Create」→「C# Script」を選択する
3.2.に「OSCTestScript」等名前をつける
4.Hierarchyにある「Lights」に「OSCTestScript」をドラッグ&ドロップする
5.Hierarchyにある「Lights」をクリックし、「Inspector」→Portに「8000」と入力する
f:id:prince9:20181016145826p:plain
6.「OSCTestScript」をダブルクリックして、下記のスクリプトを入力する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using uOSC;

//Lightsをクリックして、Portに「8000」と入力しておく
public class OSCDataTestScript : MonoBehaviour {
    //ライト指定
public GameObject slight1;


	void Start()
    {
        //OSC関連
        var server = GetComponent<uOscServer>();
        server.onDataReceived.AddListener(OnDataReceived);

        
    }

    void OnDataReceived(Message message)
    {
     

      //TouchOSCを使った場合、データはfloatで出る(toggleDataがデータ)
var toggleData = (float)message.values[0];

float LIntensity1 = slight1.GetComponent<Light>().intensity;
Color lightC1 = slight1.GetComponent<Light>().color;
      
      
        foreach (var value in message.values)
        {
            //処理を書く。「message.address == "/toggleA_1"」の「" "」の部分は「uOSCを読み込んで、OSCアプリの出力を調べる」14.の項目で
出力された値を入力する
            

            LIntensity1 = (message.address == "/toggleA_1" && toggleData == 1.0f) ? 10.0f //いちばん左下のトグル(ボタン)をOnにすると、ライトもOn
            : (message.address == "/toggleA_1" && toggleData == 0.0f) ? 0.0f //Offにすると、ライトもOff
            : (message.address == "/1/faderA") ? toggleData * 10.0f //いちばん左のスライダーを動かすと、ライトの明るさが変わる
            : slight1.GetComponent<Light>().intensity = LIntensity1; //他のボタンなどを操作したときはそのまま

            lightC1 =  (message.address == "/1/rotaryA") ? Color.HSVToRGB(toggleData, 1,1) //左上の半円のスライダー?を動かすと、色相(色味)が変わる
            : (message.address == "/toggleA_2" && toggleData == 1.0f) ? Color.HSVToRGB(0,0,1) //いちばん下の左から2番目のトグル(ボタン)をOnにすると、ライトの色を白にする
            :  (message.address == "/toggleA_2" && toggleData == 0.0f) ? Color.HSVToRGB(0,0,0)  //Offにすると、ライトの色が黒にする
            : slight1.GetComponent<Light>().color = lightC1;  //他のボタンなどを操作したときはそのまま

           


        }

        //最終的な照明の明るさと色
        slight1.GetComponent<Light>().intensity = LIntensity1;
        slight1.GetComponent<Light>().color = lightC1;
    }
	
	// Update is called once per frame
	void Update () {
        
	}
}

7.Hierarchyにある「Lights」をクリックし、Inspectorの「Slight 1」にライトをドラッグ&ドロップする
8.Unityの実行ボタンを押して、iPhoneのOSCアプリを動かしてみる

スクリプト解説

三項演算子による条件分岐

基本的には下記と同じですが、今回はライトのON/OFFを「Color.clear(色)」ではなく「intensity(明るさ)」の値で管理しました。
同様に「If〜else」「Swtich〜case」を使わず、三項演算子で短く条件分岐を書いています。
prince9.hatenablog.com

・ライトのON/OFFを三項演算子で条件分岐

float LIntensity1 = slight1.GetComponent<Light>().intensity;
 LIntensity1 = (message.address == "/toggleA_1" && toggleData == 1.0f) ? 10.0f //いちばん左下のトグル(ボタン)をOnにすると、ライトもOn
            : (message.address == "/toggleA_1" && toggleData == 0.0f) ? 0.0f //Offにすると、ライトもOff
 : slight1.GetComponent<Light>().intensity = LIntensity1; //他のボタンなどを操作したときはそのまま
slight1.GetComponent<Light>().intensity = LIntensity1;


・ライトの明るさを三項演算子で条件分岐

float LIntensity1 = slight1.GetComponent<Light>().intensity;
//いちばん左のスライダーを動かすと、ライトの明るさが変わる
 LIntensity1 = (message.address == "/1/faderA") ? toggleData * 10.0f
 //他のボタンなどを操作したときはそのまま
 : slight1.GetComponent<Light>().intensity = LIntensity1;
slight1.GetComponent<Light>().intensity = LIntensity1;

・ライトの色を三項演算子で条件分岐

Color lightC1 = slight1.GetComponent<Light>().color;
 //左上の半円のスライダー?を動かすと、色相(色味)が変わる
 lightC1 =  (message.address == "/1/rotaryA") ? Color.HSVToRGB(toggleData, 1,1)
 //他のボタンなどを操作したときはそのまま
            : slight1.GetComponent<Light>().color = lightC1; 
TouchOSCのどのUIを操作したか

「 "/toggleA_1"」はTouchOSCアプリのどのUIを動かしたかを示します。この場合は「いちばん左下のトグル(ボタン)」になります。
「"/1/faderA"」は「いちばん左の緑色のフェーダー」、「"/1/rotaryA"」は「いちばん左上の緑色の半円のUI」になります。
どのUIがどれに該当するのかは、「uOSCを読み込んで、OSCアプリの出力を調べる」14.の項目で調べています。
ちなみにTouchOSCの「Automat5」を使用した場合は、下記のようになります。
f:id:prince9:20181016200551p:plain

Unityで一定時間ごとに色(色相)を変える

OSCアプリやMIDIのフェーダでオブジェクトの色を変えようとしてた過程でできたので、忘れずにメモ。
Unityの公式リファレンスで「一定時間ごとにライトが明るくなったり暗くなったりする」というサンプルがありますが、それを改良した形です。
RGBで計算するとややこしいことになるので、色相(色味)のみを変えることにしました。
RGBからHSVへの正確な計算式もあるようですが、かなりややこしいのと使うのは照明程度なので今回はパスしました。
f:id:prince9:20181016055356g:plain

オブジェクトを設置する

1.「GameObject」メニュー→「3D Object」→「Cube」で適当にキューブを作る

スクリプトを書く

1.「Assets」を右クリックし、「Create」→「C# Script」を選択する
2.「HSVTestScript」等、名前をつける
3.Hierarchyにある「Cube」に「HSVTestScript」をドラッグ&ドロップする
4.Hierarchyにある「Cube」をクリックし、Inspectorの「HSVTestScript(script)」の中にある「Cube 1」を探す
5.「Cube 1」に、Hierarchyにある「Cube」ドラッグする
6.「HSVTestScript」をダブルクリックして、下記のスクリプトを入力する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorHSVrScript : MonoBehaviour {
//色が変わるタイミング(時間)を「Cube」のInspector(Duration)で指定、初期値は1.0F
public float duration = 1.0F;
//Hierarchyにある「Cube」を「Cube 1」にドラッグする(「Cube」のInspectorにあり)
	public GameObject cube1;

	// Use this for initialization
	void Start () {

	}
	
	// Update is called once per frame
	void Update () {
		//durationの時間ごとに色が変わる
		float phi = Time.time / duration * 2 * Mathf.PI;
		float amplitude = Mathf.Cos(phi) * 0.5F + 0.5F;
		//色をRGBではなくHSVで指定
		cube1.GetComponent<Renderer>().material.color = Color.HSVToRGB(amplitude, 1,1);
		
	}
}

UnityでMIDI機器を使ってオブジェクトと照明の色をコントロールする

VR上でのライブ演出の作業が必要となり、PCキーボードやマウス制御では事故ると思ってMIDI機器を引っぱり出しました。
いろいろ大変だったので、Keijiro Takahashiさんが作成された「MidiJack」をお借りして制御します。
今回はKORGの「nanoPAD1(初代)」を使いました。「nanoPAD2」や10月下旬に販売される新しいnanoPAD2でもいけると思います。

f:id:prince9:20181015231629g:plain

プロジェクトファイルはこちらです。
www.dropbox.com

※照明のところで、MIDIナンバーのコメントが一部違っています。このサイトに掲載しているスクリプトは修正済みです。スクリプトの実行に影響はないですが、すみません

※2 三項演算子と「Input.GetKeyDown」「Input.GetKeyUp」の相性が極めて悪いようです。
これらを使う場合は、素直に公式の下記を使います。
docs.unity3d.com


下記はMIDI機器のドライバがすでにインストール済みとして進めます。

MidiJackを読み込む

1.下記のURLにアクセスする
github.com

2.緑色のボタンの「Clone or Download」をクリックし、「Download ZIP」をクリックしてダウンロードする
3.ダウンロードしたものを解凍する
4.プロジェクトを作成し、「MidiJack-master」フォルダ→「MidiJack.unitypackage」をUnityの「Assets」フォルダにドラッグ&ドロップする
5.「Import」ボタンを押して読み込む

オブジェクトと照明を作成する

1.適当にオブジェクトと照明をを配置して、名前をつける
f:id:prince9:20181015211143p:plain

2.「GameObject」メニュー→「Create Empty」で空のオブジェクトを作成する
3.2.に名前をつける(ここでは「Cubes」にしました)
4.オブジェクトと照明を3.にドラッグ&ドロップして、下記のような構成にする
f:id:prince9:20181015211554p:plain

スクリプトを書く

5.「Assets」を右クリックし、「Create」→「C# Script」を選択する
6.5.に「MIDITestScript」等名前をつける
7.Hierarchyにある「Cubes」に「MIDITestScript」をドラッグ&ドロップする
8.「MIDITestScript」をダブルクリックして、下記のスクリプトを入力する

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MidiJack;

//https://github.com/keijiro/MidiJack

//注意: 下記の「MIDITestScript」がファイル名と同じかチェックする。違う場合はファイル名に書き直す
public class MIDITestScript : MonoBehaviour {
	

//「Cubes」をクリックしてInspectorを開き、mycubeオブジェクト3つとSpot Lightオブジェクト3つをドラッグする
public GameObject cube1,cube2,cube3,slight1,slight2,slight3;

/* 
色を配列に登録
        UnityではRGB値で指定できないので、RGB値の後に「f/255f」をつける
        例: RGB値 165,42,42(茶色)
           public Color Brown = new Color(165f/255f,42f/255f,42f/255f);
        */

//キュープ用の色の配列
Color[] collors = new Color[] { Color.white,Color.red, Color.green, new Color(0f/255f,206f/255f,209f/255f)};

//照明用の色の配列、照明を消すには「Color.clear」を使っているのでちょっと無理やり感
Color[] lcollors = new Color[] {Color.clear,Color.green, Color.yellow, new Color(188f/255f,6f/255f,12f/255f)};

	void NoteOn(MidiChannel channel, int note, float velocity)
    {
        //Debug.Log("NoteOn: " + channel + "," + note + "," + velocity);

         Color c1 = cube1.GetComponent<Renderer>().material.color;
          Color c2 = cube2.GetComponent<Renderer>().material.color;
           Color c3 = cube3.GetComponent<Renderer>().material.color;

            Color lightC1 = slight1.GetComponent<Light>().color;
            Color lightC2 = slight2.GetComponent<Light>().color;
            Color lightC3 = slight3.GetComponent<Light>().color;



//下記、三項演算子を使った条件分岐(キューブの色)          
c1 = (note == 39) ? collors[1] //nanoPadの1
: (note == 36) ? collors[0] //nanoPadの7
: cube1.GetComponent<Renderer>().material.color = c1; //その他のキーが押されたとき、状態を保持

c2 = (note == 48) ? collors[2] //nanoPadの2
: (note == 38) ? collors[0] //nanoPadの8
: cube2.GetComponent<Renderer>().material.color = c2; //その他のキーが押されたとき、状態を保持

c3 = (note == 45) ? collors[3] //nanoPadの3
: (note == 40) ? collors[0] //nanoPadの9
: cube3.GetComponent<Renderer>().material.color = c3; //その他のキーが押されたとき、状態を保持

cube1.GetComponent<Renderer>().material.color = c1;
cube2.GetComponent<Renderer>().material.color = c2;
cube3.GetComponent<Renderer>().material.color = c3;

/* 
上記を条件分岐の「if」で書き直すとこちら
if(note == 39)
    {
     cube1.GetComponent<Renderer>().material.color = collors[1];
    }
    else if(note == 36)
    {
    cube1.GetComponent<Renderer>().material.color = collors[0];
    }

    〜略
*/

/* 
上記を条件分岐の「switch〜case」で書き直すとこちら
switch (note) {

    case 39: 
        cube1.GetComponent<Renderer>().material.color = collors[1];
        break;

    case 36:   
        cube1.GetComponent<Renderer>().material.color = collors[0];
        break;

    〜略

    default:    
        Debug.Log("エラー");
        break;
}
*/

//下記、三項演算子を使った条件分岐(照明の色)         
lightC1 = (note == 43) ? lcollors[1] //nanoPadの4
: (note == 42) ? lcollors[0] //nanoPadの10
: slight1.GetComponent<Light>().color = lightC1; //その他のキーが押されたとき、状態を保持

lightC2 = (note == 51) ? lcollors[2] //nanoPadの5
: (note == 44) ? lcollors[0] //nanoPadの11
: slight2.GetComponent<Light>().color = lightC2; //その他のキーが押されたとき、状態を保持

lightC3 = (note == 49) ? lcollors[3] //nanoPadの6
: (note == 46) ? lcollors[0] //nanoPadの12
: slight3.GetComponent<Light>().color = lightC3; //その他のキーが押されたとき、状態を保持

slight1.GetComponent<Light>().color = lightC1;
slight2.GetComponent<Light>().color = lightC2;
slight3.GetComponent<Light>().color = lightC3;

/* 
長くなるが、こちらのほうが無理がなくていいかも
if(note == 43)
    {
     slight1.SetActive(true);
    }
    else if(note == 42)
    {
    slight1.SetActive(flase);
    }
*/

  
    }

    void NoteOff(MidiChannel channel, int note)
    {
       
		Debug.Log("NoteOff: " + note);
    }

 

	void OnEnable()
    {
        MidiMaster.noteOnDelegate += NoteOn;
        MidiMaster.noteOffDelegate += NoteOff;
        
    }

    void OnDisable()
    {
        MidiMaster.noteOnDelegate -= NoteOn;
        MidiMaster.noteOffDelegate -= NoteOff;
        
    }


	// Use this for initialization
	void Start () {
  	
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

スクリプト解説 三項演算子

nanoPadのボタンに割り振られている番号(MIDIナンバー)がバラバラだったため、やむなく条件分岐で処理を書くことにしました。
switch〜caseやif〜elseなどを使えば楽なのですが、スクリプトが長くなりがちです。
今回はこれら条件分岐を短めに書く「三項演算子」を使いました。
注意点としては、演算子なのでif〜elseの「else」に該当する部分が省略できないことです。

以下、例1-3すべて同じ動きをします。

例1: if文

string s;
        if (note == 39)
        {
            s = "No.1 0n";
        }
        else if (note == 48)
        {
            s = "No.1 0ff";
        }
        else {
            s = "Other 0ff";
        }

例2: switch文

string s;
switch (note) {
	case 39:
		 s = "No.1 0n";
		break;
	case 48:
		s = "No.1 0ff";
		break;

	default:
		s = "Other 0ff";
		break;
}

例3: 三項演算子

string s;
s = (note == 39) ? "No.1 0n"
: (note == 48) ? "No.1 0ff"
: "Other 0ff";

swtich文と比較すると分かりやすいかと思われます。

= (演算子の式1) ?  式1の条件が真のときの処理
:  (演算子の式2) ? 式2の条件が真のときの処理
: すべてが当てはまらないときの処理;


となっています。

スクリプト解説 照明の色について

ifやswitchを書かないようにしていたので、「Color.clear」で無理やり照明を消しています。これに関してはifかswitchを使って、「slight1.SetActive(trueまたはfalse);」にしたほうがよかったかもしれません。